From 69a6db45fda78f103c9b829534cb1c5027a70e2b Mon Sep 17 00:00:00 2001 From: sand4rt Date: Tue, 7 May 2024 18:49:56 +0200 Subject: [PATCH] chore(ct): revert adapters imports and template --- packages/playwright-ct-angular/index.d.ts | 13 +- .../playwright-ct-angular/registerSource.mjs | 147 +++++++----------- .../ct-angular/tests/injection.spec.ts | 9 +- .../ct-angular/tests/template.spec.ts | 44 ------ 4 files changed, 59 insertions(+), 154 deletions(-) delete mode 100644 tests/components/ct-angular/tests/template.spec.ts diff --git a/packages/playwright-ct-angular/index.d.ts b/packages/playwright-ct-angular/index.d.ts index c67b1a867e74c..583574f12b52b 100644 --- a/packages/playwright-ct-angular/index.d.ts +++ b/packages/playwright-ct-angular/index.d.ts @@ -17,24 +17,18 @@ import type { Locator } from 'playwright/test'; import type { JsonObject } from '@playwright/experimental-ct-core/types/component'; import type { TestType } from '@playwright/experimental-ct-core'; -import type { Provider, Type } from '@angular/core'; +import type { Type } from '@angular/core'; export type ComponentEvents = Record; export interface MountOptions { props?: Partial | Record, // TODO: filter props and handle signals - providers?: Provider[], on?: ComponentEvents; hooksConfig?: HooksConfig; } -export interface MountTemplateOptions extends MountOptions { - imports?: Type[]; -} - export interface MountResult extends Locator { unmount(): Promise; - update(options: { props?: Partial, on?: Partial, @@ -42,11 +36,6 @@ export interface MountResult extends Locator { } export interface ComponentFixtures { - mount( - template: string, - options?: MountTemplateOptions - ): Promise>; - mount( component: Type, options?: MountOptions diff --git a/packages/playwright-ct-angular/registerSource.mjs b/packages/playwright-ct-angular/registerSource.mjs index b18aab7e483ba..4d54eeea15c85 100644 --- a/packages/playwright-ct-angular/registerSource.mjs +++ b/packages/playwright-ct-angular/registerSource.mjs @@ -17,10 +17,7 @@ // @ts-check // This file is injected into the registry as text, no dependencies are allowed. -/** - * @typedef {{type: string} & import('./index').MountTemplateOptions} TemplateInfo - * @typedef {{type: import('@angular/core').Type} & import('./index').MountOptions | TemplateInfo} ComponentInfo - */ +/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */ import 'zone.js'; import { @@ -33,95 +30,35 @@ import { platformBrowserDynamicTesting, } from '@angular/platform-browser-dynamic/testing'; -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting(), -); - -window.playwrightMount = async (component, rootElement, hooksConfig) => { - __pwAssertIsNotJsx(component); - - for (const hook of window.__pw_hooks_before_mount || []) - await hook({ hooksConfig, TestBed }); - - const fixture = await __pwRenderComponent(component); - - for (const hook of window.__pw_hooks_after_mount || []) - await hook({ hooksConfig }); - - __pwFixtureRegistry.set(rootElement.id, fixture); -}; - -window.playwrightUnmount = async rootElement => { - const fixture = __pwFixtureRegistry.get(rootElement.id); - if (!fixture) - throw new Error('Component was not mounted'); - - /* Unsubscribe from all outputs. */ - for (const subscription of Object.values(__pwOutputSubscriptionRegistry.get(fixture) ?? {})) - subscription?.unsubscribe(); - __pwOutputSubscriptionRegistry.delete(fixture); - - fixture.destroy(); - fixture.nativeElement.replaceChildren(); -}; - -/** - * @param {{type: import('@angular/core').Type} & import('./index').MountOptions | {type: string} & import('./index').MountTemplateOptions} component - */ -window.playwrightUpdate = async (rootElement, component) => { - __pwAssertIsNotJsx(component); - - const fixture = __pwFixtureRegistry.get(rootElement.id); - if (!fixture) - throw new Error('Component was not mounted'); - - __pwUpdateProps(fixture, component); - __pwUpdateEvents(fixture, component.on); - - fixture.detectChanges(); -}; - /** @type {WeakMap>} */ const __pwOutputSubscriptionRegistry = new WeakMap(); /** @type {Map} */ const __pwFixtureRegistry = new Map(); +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); + /** - * @param {ComponentInfo} component + * @param {ObjectComponent} component */ async function __pwRenderComponent(component) { - /** @type {import('@angular/core').Type} */ - let componentClass; - - if (__pwIsTemplate(component)) { - const templateInfo = /** @type {TemplateInfo} */(component); - componentClass = defineComponent({ - standalone: true, - selector: 'pw-template-component', - imports: templateInfo.imports, - template: templateInfo.type, - })(class {}); - } else { - componentClass = /** @type {import('@angular/core').Type} */(component.type); - } - - const componentMetadata = reflectComponentType(componentClass); + const componentMetadata = reflectComponentType(component.type); if (!componentMetadata?.isStandalone) throw new Error('Only standalone components are supported'); TestBed.configureTestingModule({ - imports: [componentClass], - providers: component.providers, + imports: [component.type], }); await TestBed.compileComponents(); - const fixture = TestBed.createComponent(componentClass); + const fixture = TestBed.createComponent(component.type); fixture.nativeElement.id = 'root'; - __pwUpdateProps(fixture, component); + __pwUpdateProps(fixture, component.props); __pwUpdateEvents(fixture, component.on); fixture.autoDetectChanges(); @@ -131,19 +68,10 @@ async function __pwRenderComponent(component) { /** * @param {import('@angular/core/testing').ComponentFixture} fixture - * @param {ComponentInfo} componentInfo */ -function __pwUpdateProps(fixture, componentInfo) { - if (!componentInfo.props) - return; - - if (__pwIsTemplate(componentInfo)) { - Object.assign(fixture.componentInstance, componentInfo.props); - } else { - for (const [name, value] of Object.entries(componentInfo.props)) - fixture.componentRef.setInput(name, value); - } - +function __pwUpdateProps(fixture, props = {}) { + for (const [name, value] of Object.entries(props)) + fixture.componentRef.setInput(name, value); } /** @@ -168,14 +96,45 @@ function __pwUpdateEvents(fixture, events = {}) { __pwOutputSubscriptionRegistry.set(fixture, outputSubscriptionRecord); } -function __pwAssertIsNotJsx(component) { +window.playwrightMount = async (component, rootElement, hooksConfig) => { if (component.__pw_type === 'jsx') throw new Error('JSX mount notation is not supported'); -} -/** - * @param {ComponentInfo} component - */ -function __pwIsTemplate(component) { - return typeof component.type === 'string'; -} + for (const hook of window.__pw_hooks_before_mount || []) + await hook({ hooksConfig, TestBed }); + + const fixture = await __pwRenderComponent(component); + + for (const hook of window.__pw_hooks_after_mount || []) + await hook({ hooksConfig }); + + __pwFixtureRegistry.set(rootElement.id, fixture); +}; + +window.playwrightUnmount = async rootElement => { + const fixture = __pwFixtureRegistry.get(rootElement.id); + if (!fixture) + throw new Error('Component was not mounted'); + + /* Unsubscribe from all outputs. */ + for (const subscription of Object.values(__pwOutputSubscriptionRegistry.get(fixture) ?? {})) + subscription?.unsubscribe(); + __pwOutputSubscriptionRegistry.delete(fixture); + + fixture.destroy(); + fixture.nativeElement.replaceChildren(); +}; + +window.playwrightUpdate = async (rootElement, component) => { + if (component.__pw_type === 'jsx') + throw new Error('JSX mount notation is not supported'); + + const fixture = __pwFixtureRegistry.get(rootElement.id); + if (!fixture) + throw new Error('Component was not mounted'); + + __pwUpdateProps(fixture, component.props); + __pwUpdateEvents(fixture, component.on); + + fixture.detectChanges(); +}; diff --git a/tests/components/ct-angular/tests/injection.spec.ts b/tests/components/ct-angular/tests/injection.spec.ts index cc5f01087a8f2..c284ca1b1a53c 100644 --- a/tests/components/ct-angular/tests/injection.spec.ts +++ b/tests/components/ct-angular/tests/injection.spec.ts @@ -1,9 +1,10 @@ -import { InjectComponent, TOKEN } from "@/components/inject.component"; -import { expect, test } from "@playwright/experimental-ct-angular"; +import { InjectComponent, TOKEN } from '@/components/inject.component'; +import { expect, test } from '@playwright/experimental-ct-angular'; +import type { HooksConfig } from 'playwright'; test('inject a token', async ({ mount }) => { - const component = await mount(InjectComponent, { - providers: [{ provide: TOKEN, useValue: { text: 'has been overwritten' }}] + const component = await mount(InjectComponent, { + hooksConfig: { injectToken: true }, }); await expect(component).toHaveText('has been overwritten'); }); diff --git a/tests/components/ct-angular/tests/template.spec.ts b/tests/components/ct-angular/tests/template.spec.ts deleted file mode 100644 index 52e0263e364c0..0000000000000 --- a/tests/components/ct-angular/tests/template.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ButtonComponent } from "@/components/button.component"; -import { expect, test } from "@playwright/experimental-ct-angular" - -test('render a template', async ({ mount }) => { - const component = await mount('

{{ 1 + 1 }}

'); - - await expect(component).toHaveText('2'); -}) - -test('render a template with child components', async ({ mount }) => { - const component = await mount('', { - imports: [ButtonComponent] - }); - - await expect(component.getByRole('button')).toContainText('Click'); -}) - -test('render a template with inputs', async ({ mount }) => { - const component = await mount('', { - imports: [ButtonComponent], - props: { - title: 'Click', - } - }); - - await expect(component.getByRole('button')).toContainText('Click'); -}) - -test('render a template with outputs', async ({ mount }) => { - let _message: string; - const component = await mount('', { - imports: [ButtonComponent], - props: { - title: 'Click', - onSubmit(message: string) { - _message = message; - } - } - }); - - await component.getByRole('button').click(); - - await expect(async () => {expect(_message).toBe('hello')}).toPass(); -})