From f3d3231b29aa7d58e55dc52f25e84c3cc1dd1d72 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 12 Jul 2022 08:37:33 -0800 Subject: [PATCH] feat(ct): allow configuring apps per test (#15551) --- packages/playwright-ct-react/.npmignore | 2 ++ packages/playwright-ct-react/hooks.d.ts | 18 ++++++++++++ packages/playwright-ct-react/hooks.mjs | 29 +++++++++++++++++++ packages/playwright-ct-react/index.d.ts | 2 +- packages/playwright-ct-react/package.json | 4 +++ .../playwright-ct-react/registerSource.mjs | 10 +++++-- packages/playwright-ct-svelte/.npmignore | 2 ++ packages/playwright-ct-svelte/hooks.d.ts | 18 ++++++++++++ packages/playwright-ct-svelte/hooks.mjs | 29 +++++++++++++++++++ packages/playwright-ct-svelte/index.d.ts | 1 + packages/playwright-ct-svelte/package.json | 4 +++ .../playwright-ct-svelte/registerSource.mjs | 10 ++++++- packages/playwright-ct-vue/hooks.d.ts | 5 ++-- packages/playwright-ct-vue/hooks.mjs | 15 +++++++--- packages/playwright-ct-vue/index.d.ts | 2 +- packages/playwright-ct-vue/registerSource.mjs | 13 +++++---- packages/playwright-ct-vue2/.npmignore | 2 ++ packages/playwright-ct-vue2/hooks.d.ts | 20 +++++++++++++ packages/playwright-ct-vue2/hooks.mjs | 29 +++++++++++++++++++ packages/playwright-ct-vue2/index.d.ts | 1 + packages/playwright-ct-vue2/package.json | 4 +++ .../playwright-ct-vue2/registerSource.mjs | 14 +++++++-- packages/playwright-test/src/mount.ts | 6 ++-- packages/playwright-test/types/component.d.ts | 3 +- .../ct-react-vite/playwright/index.ts | 12 ++++++++ .../components/ct-react-vite/src/App.spec.tsx | 11 +++++++ .../ct-svelte-vite/playwright/index.ts | 11 +++++++ .../ct-svelte-vite/src/lib/Counter.spec.ts | 14 +++++++++ .../ct-vue-vite/playwright/index.js | 11 +++++-- .../ct-vue-vite/src/notation-jsx.spec.tsx | 9 ++++++ .../ct-vue-vite/src/notation-vue.spec.ts | 10 +++---- .../ct-vue2-cli/playwright/index.js | 11 +++++++ .../ct-vue2-cli/src/notation-jsx.spec.tsx | 9 ++++++ .../ct-vue2-cli/src/notation-vue.spec.ts | 12 ++++++++ 34 files changed, 320 insertions(+), 33 deletions(-) create mode 100644 packages/playwright-ct-react/hooks.d.ts create mode 100644 packages/playwright-ct-react/hooks.mjs create mode 100644 packages/playwright-ct-svelte/hooks.d.ts create mode 100644 packages/playwright-ct-svelte/hooks.mjs create mode 100644 packages/playwright-ct-vue2/hooks.d.ts create mode 100644 packages/playwright-ct-vue2/hooks.mjs diff --git a/packages/playwright-ct-react/.npmignore b/packages/playwright-ct-react/.npmignore index 5aac845c35..dd4553cbc5 100644 --- a/packages/playwright-ct-react/.npmignore +++ b/packages/playwright-ct-react/.npmignore @@ -7,3 +7,5 @@ !registerSource.mjs !index.d.ts !index.js +!hooks.d.ts +!hooks.mjs diff --git a/packages/playwright-ct-react/hooks.d.ts b/packages/playwright-ct-react/hooks.d.ts new file mode 100644 index 0000000000..36ac2620fa --- /dev/null +++ b/packages/playwright-ct-react/hooks.d.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export declare function beforeMount(callback: (params: { hooksConfig: any }) => Promise): void; +export declare function afterMount(callback: (params: { hooksConfig: any }) => Promise): void; diff --git a/packages/playwright-ct-react/hooks.mjs b/packages/playwright-ct-react/hooks.mjs new file mode 100644 index 0000000000..b7cea242c4 --- /dev/null +++ b/packages/playwright-ct-react/hooks.mjs @@ -0,0 +1,29 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const __pw_hooks_before_mount = []; +const __pw_hooks_after_mount = []; + +window.__pw_hooks_before_mount = __pw_hooks_before_mount; +window.__pw_hooks_after_mount = __pw_hooks_after_mount; + +export const beforeMount = callback => { + __pw_hooks_before_mount.push(callback); +}; + +export const afterMount = callback => { + __pw_hooks_after_mount.push(callback); +}; diff --git a/packages/playwright-ct-react/index.d.ts b/packages/playwright-ct-react/index.d.ts index 485cb0e658..95760bed6b 100644 --- a/packages/playwright-ct-react/index.d.ts +++ b/packages/playwright-ct-react/index.d.ts @@ -35,7 +35,7 @@ export type PlaywrightTestConfig = Omit & { }; interface ComponentFixtures { - mount(component: JSX.Element): Promise; + mount(component: JSX.Element, options?: { hooksConfig?: any }): Promise; } export const test: TestType< diff --git a/packages/playwright-ct-react/package.json b/packages/playwright-ct-react/package.json index 7ce4b6c03d..1eda0f20bc 100644 --- a/packages/playwright-ct-react/package.json +++ b/packages/playwright-ct-react/package.json @@ -19,6 +19,10 @@ "./register": { "types": "./register.d.ts", "default": "./register.mjs" + }, + "./hooks": { + "types": "./hooks.d.ts", + "default": "./hooks.mjs" } }, "dependencies": { diff --git a/packages/playwright-ct-react/registerSource.mjs b/packages/playwright-ct-react/registerSource.mjs index 88588c60ae..6d23f88373 100644 --- a/packages/playwright-ct-react/registerSource.mjs +++ b/packages/playwright-ct-react/registerSource.mjs @@ -68,6 +68,12 @@ function render(component) { })); } -window.playwrightMount = async component => { - ReactDOM.render(render(component), document.getElementById('root')); +window.playwrightMount = async (component, rootElement, hooksConfig) => { + for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) + await hook({ hooksConfig }); + + ReactDOM.render(render(component), rootElement); + + for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) + await hook({ hooksConfig }); }; diff --git a/packages/playwright-ct-svelte/.npmignore b/packages/playwright-ct-svelte/.npmignore index 5aac845c35..dd4553cbc5 100644 --- a/packages/playwright-ct-svelte/.npmignore +++ b/packages/playwright-ct-svelte/.npmignore @@ -7,3 +7,5 @@ !registerSource.mjs !index.d.ts !index.js +!hooks.d.ts +!hooks.mjs diff --git a/packages/playwright-ct-svelte/hooks.d.ts b/packages/playwright-ct-svelte/hooks.d.ts new file mode 100644 index 0000000000..36ac2620fa --- /dev/null +++ b/packages/playwright-ct-svelte/hooks.d.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export declare function beforeMount(callback: (params: { hooksConfig: any }) => Promise): void; +export declare function afterMount(callback: (params: { hooksConfig: any }) => Promise): void; diff --git a/packages/playwright-ct-svelte/hooks.mjs b/packages/playwright-ct-svelte/hooks.mjs new file mode 100644 index 0000000000..b7cea242c4 --- /dev/null +++ b/packages/playwright-ct-svelte/hooks.mjs @@ -0,0 +1,29 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const __pw_hooks_before_mount = []; +const __pw_hooks_after_mount = []; + +window.__pw_hooks_before_mount = __pw_hooks_before_mount; +window.__pw_hooks_after_mount = __pw_hooks_after_mount; + +export const beforeMount = callback => { + __pw_hooks_before_mount.push(callback); +}; + +export const afterMount = callback => { + __pw_hooks_after_mount.push(callback); +}; diff --git a/packages/playwright-ct-svelte/index.d.ts b/packages/playwright-ct-svelte/index.d.ts index fe227236b2..d5de0826df 100644 --- a/packages/playwright-ct-svelte/index.d.ts +++ b/packages/playwright-ct-svelte/index.d.ts @@ -39,6 +39,7 @@ interface ComponentFixtures { props?: Props, slots?: { [key: string]: any }, on?: { [key: string]: Function }, + hooksConfig: any, }): Promise; } diff --git a/packages/playwright-ct-svelte/package.json b/packages/playwright-ct-svelte/package.json index 5d29d6177c..a03db97db1 100644 --- a/packages/playwright-ct-svelte/package.json +++ b/packages/playwright-ct-svelte/package.json @@ -19,6 +19,10 @@ "./register": { "types": "./register.d.ts", "default": "./register.mjs" + }, + "./hooks": { + "types": "./hooks.d.ts", + "default": "./hooks.mjs" } }, "dependencies": { diff --git a/packages/playwright-ct-svelte/registerSource.mjs b/packages/playwright-ct-svelte/registerSource.mjs index 21305231f3..e7b9c1d55b 100644 --- a/packages/playwright-ct-svelte/registerSource.mjs +++ b/packages/playwright-ct-svelte/registerSource.mjs @@ -32,7 +32,7 @@ export function register(components) { registry.set(name, value); } -window.playwrightMount = async (component, rootElement) => { +window.playwrightMount = async (component, rootElement, hooksConfig) => { let componentCtor = registry.get(component.type); if (!componentCtor) { // Lookup by shorthand. @@ -50,10 +50,18 @@ window.playwrightMount = async (component, rootElement) => { if (component.kind !== 'object') throw new Error('JSX mount notation is not supported'); + + for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) + await hook({ hooksConfig }); + const wrapper = new componentCtor({ target: rootElement, props: component.options?.props, }); + + for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) + await hook({ hooksConfig }); + for (const [key, listener] of Object.entries(component.options?.on || {})) wrapper.$on(key, event => listener(event.detail)); }; diff --git a/packages/playwright-ct-vue/hooks.d.ts b/packages/playwright-ct-vue/hooks.d.ts index 5076dfb06f..1a02376063 100644 --- a/packages/playwright-ct-vue/hooks.d.ts +++ b/packages/playwright-ct-vue/hooks.d.ts @@ -14,6 +14,7 @@ * limitations under the License. */ -import { App } from 'vue'; +import { App, ComponentPublicInstance } from 'vue'; -export declare function onApp(callback: (app: App, appConfig: any) => Promise): void; +export declare function beforeMount(callback: (params: { app: App, hooksConfig: any }) => Promise): void; +export declare function afterMount(callback: (params: { app: App, hooksConfig: any, instance: ComponentPublicInstance }) => Promise): void; diff --git a/packages/playwright-ct-vue/hooks.mjs b/packages/playwright-ct-vue/hooks.mjs index b050f74957..b7cea242c4 100644 --- a/packages/playwright-ct-vue/hooks.mjs +++ b/packages/playwright-ct-vue/hooks.mjs @@ -14,9 +14,16 @@ * limitations under the License. */ -const __pw_hooks_on_app = []; -window.__pw_hooks_on_app = __pw_hooks_on_app; +const __pw_hooks_before_mount = []; +const __pw_hooks_after_mount = []; -export const onApp = callback => { - __pw_hooks_on_app.push(callback); +window.__pw_hooks_before_mount = __pw_hooks_before_mount; +window.__pw_hooks_after_mount = __pw_hooks_after_mount; + +export const beforeMount = callback => { + __pw_hooks_before_mount.push(callback); +}; + +export const afterMount = callback => { + __pw_hooks_after_mount.push(callback); }; diff --git a/packages/playwright-ct-vue/index.d.ts b/packages/playwright-ct-vue/index.d.ts index 386da99ded..0edc26608a 100644 --- a/packages/playwright-ct-vue/index.d.ts +++ b/packages/playwright-ct-vue/index.d.ts @@ -40,7 +40,7 @@ interface ComponentFixtures { props?: Props, slots?: { [key: string]: any }, on?: { [key: string]: Function }, - appConfig?: any, + hooksConfig?: any, }): Promise; } diff --git a/packages/playwright-ct-vue/registerSource.mjs b/packages/playwright-ct-vue/registerSource.mjs index 6d6fe85a46..f0adca1eb9 100644 --- a/packages/playwright-ct-vue/registerSource.mjs +++ b/packages/playwright-ct-vue/registerSource.mjs @@ -155,14 +155,15 @@ function createDevTools() { }; } -window.playwrightMount = async (component, rootElement) => { +window.playwrightMount = async (component, rootElement, hooksConfig) => { const app = createApp({ render: () => render(component) }); setDevtoolsHook(createDevTools(), {}); - if (component.kind === 'object') { - for (const onAppCallback of /** @type {any} */(window).__pw_hooks_on_app || []) - await onAppCallback(app, /** @type {any} */(component.options)?.appConfig) - } - app.mount(rootElement); + + for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) + await hook({ app, hooksConfig }); + const instance = app.mount(rootElement); + for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) + await hook({ app, hooksConfig, instance }); }; diff --git a/packages/playwright-ct-vue2/.npmignore b/packages/playwright-ct-vue2/.npmignore index 5aac845c35..7a0486227c 100644 --- a/packages/playwright-ct-vue2/.npmignore +++ b/packages/playwright-ct-vue2/.npmignore @@ -7,3 +7,5 @@ !registerSource.mjs !index.d.ts !index.js +!hooks.d.ts +!hooks.js diff --git a/packages/playwright-ct-vue2/hooks.d.ts b/packages/playwright-ct-vue2/hooks.d.ts new file mode 100644 index 0000000000..74d9b5d788 --- /dev/null +++ b/packages/playwright-ct-vue2/hooks.d.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CombinedVueInstance, Vue } from 'vue/types/vue'; + +export declare function beforeMount(callback: (params: { hooksConfig: any }) => Promise): void; +export declare function afterMount(callback: (params: { hooksConfig: any, instance: CombinedVueInstance> }) => Promise): void; diff --git a/packages/playwright-ct-vue2/hooks.mjs b/packages/playwright-ct-vue2/hooks.mjs new file mode 100644 index 0000000000..b7cea242c4 --- /dev/null +++ b/packages/playwright-ct-vue2/hooks.mjs @@ -0,0 +1,29 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const __pw_hooks_before_mount = []; +const __pw_hooks_after_mount = []; + +window.__pw_hooks_before_mount = __pw_hooks_before_mount; +window.__pw_hooks_after_mount = __pw_hooks_after_mount; + +export const beforeMount = callback => { + __pw_hooks_before_mount.push(callback); +}; + +export const afterMount = callback => { + __pw_hooks_after_mount.push(callback); +}; diff --git a/packages/playwright-ct-vue2/index.d.ts b/packages/playwright-ct-vue2/index.d.ts index 4a56ae3fea..f45c64d3ee 100644 --- a/packages/playwright-ct-vue2/index.d.ts +++ b/packages/playwright-ct-vue2/index.d.ts @@ -40,6 +40,7 @@ interface ComponentFixtures { props?: Props, slots?: { [key: string]: any }, on?: { [key: string]: Function }, + hooksConfig: any, }): Promise; } diff --git a/packages/playwright-ct-vue2/package.json b/packages/playwright-ct-vue2/package.json index e27bf97972..2183fa2c72 100644 --- a/packages/playwright-ct-vue2/package.json +++ b/packages/playwright-ct-vue2/package.json @@ -19,6 +19,10 @@ "./register": { "types": "./register.d.ts", "default": "./register.mjs" + }, + "./hooks": { + "types": "./hooks.d.ts", + "default": "./hooks.mjs" } }, "dependencies": { diff --git a/packages/playwright-ct-vue2/registerSource.mjs b/packages/playwright-ct-vue2/registerSource.mjs index 052a4c1f20..ef3a33c9d0 100644 --- a/packages/playwright-ct-vue2/registerSource.mjs +++ b/packages/playwright-ct-vue2/registerSource.mjs @@ -134,9 +134,17 @@ function render(component, h) { return wrapper; } -window.playwrightMount = async (component, rootElement) => { - const mounted = new Vue({ +window.playwrightMount = async (component, rootElement, hooksConfig) => { + const config = hooksConfig || /** @type {any} */(component).options?.hooksConfig; + + for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) + await hook({ hooksConfig }); + + const instance = new Vue({ render: h => render(component, h), }).$mount(); - rootElement.appendChild(mounted.$el); + rootElement.appendChild(instance.$el); + + for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) + await hook({ hooksConfig, instance }); }; diff --git a/packages/playwright-test/src/mount.ts b/packages/playwright-test/src/mount.ts index ec95796084..0f6ba6749b 100644 --- a/packages/playwright-test/src/mount.ts +++ b/packages/playwright-test/src/mount.ts @@ -88,7 +88,7 @@ async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: // WebKit does not wait for deferred scripts. await page.waitForFunction(() => !!window.playwrightMount); - const selector = await page.evaluate(async ({ component }) => { + const selector = await page.evaluate(async ({ component, hooksConfig }) => { const unwrapFunctions = (object: any) => { for (const [key, value] of Object.entries(object)) { if (typeof value === 'string' && (value as string).startsWith('__pw_func_')) { @@ -110,11 +110,11 @@ async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: document.body.appendChild(rootElement); } - await window.playwrightMount(component, rootElement); + await window.playwrightMount(component, rootElement, hooksConfig); // When mounting fragments, return selector pointing to the root element. return rootElement.childNodes.length > 1 ? '#root' : '#root > *'; - }, { component }); + }, { component, hooksConfig: options.hooksConfig }); return selector; } diff --git a/packages/playwright-test/types/component.d.ts b/packages/playwright-test/types/component.d.ts index dfabc6d867..b51ad91765 100644 --- a/packages/playwright-test/types/component.d.ts +++ b/packages/playwright-test/types/component.d.ts @@ -25,6 +25,7 @@ export type ObjectComponentOptions = { props?: { [key: string]: any }, slots?: { [key: string]: any }, on?: { [key: string]: Function }, + hooksConfig?: any, }; export type ObjectComponent = { @@ -37,6 +38,6 @@ export type Component = JsxComponent | ObjectComponent; declare global { interface Window { - playwrightMount(component: Component, rootElement: Element): Promise; + playwrightMount(component: Component, rootElement: Element, hooksConfig: any): Promise; } } diff --git a/tests/components/ct-react-vite/playwright/index.ts b/tests/components/ct-react-vite/playwright/index.ts index 896b6ec818..3d3b46bdc0 100644 --- a/tests/components/ct-react-vite/playwright/index.ts +++ b/tests/components/ct-react-vite/playwright/index.ts @@ -1 +1,13 @@ +//@ts-check + import '../src/index.css'; + +import { beforeMount, afterMount } from '@playwright/experimental-ct-react/hooks'; + +beforeMount(async ({ hooksConfig }) => { + console.log(`Before mount: ${JSON.stringify(hooksConfig)}`); +}); + +afterMount(async ({}) => { + console.log(`After mount`); +}); diff --git a/tests/components/ct-react-vite/src/App.spec.tsx b/tests/components/ct-react-vite/src/App.spec.tsx index e920f642b9..459de3579a 100644 --- a/tests/components/ct-react-vite/src/App.spec.tsx +++ b/tests/components/ct-react-vite/src/App.spec.tsx @@ -7,3 +7,14 @@ test('should work', async ({ mount }) => { const component = await mount(); await expect(component).toContainText('Hello Vite + React!'); }); + +test('should configure app', async ({ page, mount }) => { + const messages: string[] = []; + page.on('console', m => messages.push(m.text())); + await mount(, { + hooksConfig: { + route: 'A' + } + }); + expect(messages).toEqual(['Before mount: {\"route\":\"A\"}', 'After mount']); +}); diff --git a/tests/components/ct-svelte-vite/playwright/index.ts b/tests/components/ct-svelte-vite/playwright/index.ts index e69de29bb2..2cc871dee0 100644 --- a/tests/components/ct-svelte-vite/playwright/index.ts +++ b/tests/components/ct-svelte-vite/playwright/index.ts @@ -0,0 +1,11 @@ +//@ts-check + +import { beforeMount, afterMount } from '@playwright/experimental-ct-svelte/hooks'; + +beforeMount(async ({ hooksConfig }) => { + console.log(`Before mount: ${JSON.stringify(hooksConfig)}`); +}); + +afterMount(async ({}) => { + console.log(`After mount`); +}); diff --git a/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts b/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts index 35a4a7dd81..f0c2e9920b 100644 --- a/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts +++ b/tests/components/ct-svelte-vite/src/lib/Counter.spec.ts @@ -33,3 +33,17 @@ test('should work', async ({ mount }) => { await component.click(); expect(values).toEqual([{ count: 1 }]); }); + +test('should configure app', async ({ page, mount }) => { + const messages: string[] = []; + page.on('console', m => messages.push(m.text())); + await mount(Counter, { + props: { + units: 's', + }, + hooksConfig: { + route: 'A' + } + }); + expect(messages).toEqual(['Before mount: {\"route\":\"A\"}', 'After mount']); +}); diff --git a/tests/components/ct-vue-vite/playwright/index.js b/tests/components/ct-vue-vite/playwright/index.js index 3fd36c7d6f..e08043798b 100644 --- a/tests/components/ct-vue-vite/playwright/index.js +++ b/tests/components/ct-vue-vite/playwright/index.js @@ -1,5 +1,10 @@ -import { onApp } from '@playwright/experimental-ct-vue/hooks'; +//@ts-check +import { beforeMount, afterMount } from '@playwright/experimental-ct-vue/hooks'; -onApp(async (app, addConfig) => { - console.log(`App ${!!app} configured with config: ${JSON.stringify(addConfig)}`); +beforeMount(async ({ app, hooksConfig }) => { + console.log(`Before mount: ${JSON.stringify(hooksConfig)}, app: ${!!app}`); +}); + +afterMount(async ({ instance }) => { + console.log(`After mount el: ${instance.$el.constructor.name}`); }); diff --git a/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx b/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx index 4d604f5362..50c6de2caa 100644 --- a/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx +++ b/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx @@ -60,3 +60,12 @@ test('slot should emit events', async ({ mount }) => { await component.locator('text=Main Content').click(); expect(clickFired).toBeTruthy(); }) + +test('should run hooks', async ({ page, mount }) => { + const messages = [] + page.on('console', m => messages.push(m.text())) + await mount(, { + hooksConfig: { route: 'A' } + }) + expect(messages).toEqual(['Before mount: {\"route\":\"A\"}, app: true', 'After mount el: HTMLButtonElement']) +}) diff --git a/tests/components/ct-vue-vite/src/notation-vue.spec.ts b/tests/components/ct-vue-vite/src/notation-vue.spec.ts index 8663b410aa..c5b1baee6f 100644 --- a/tests/components/ct-vue-vite/src/notation-vue.spec.ts +++ b/tests/components/ct-vue-vite/src/notation-vue.spec.ts @@ -67,16 +67,14 @@ test('optionless should work', async ({ mount }) => { await expect(component).toContainText('test') }) -test('should configure app', async ({ page, mount }) => { +test('should run hooks', async ({ page, mount }) => { const messages = [] page.on('console', m => messages.push(m.text())) - const component = await mount(Button, { + await mount(Button, { props: { title: 'Submit' }, - appConfig: { - route: 'A' - } + hooksConfig: { route: 'A' } }) - expect(messages).toEqual(['App true configured with config: {\"route\":\"A\"}']) + expect(messages).toEqual(['Before mount: {\"route\":\"A\"}, app: true', 'After mount el: HTMLButtonElement']) }) diff --git a/tests/components/ct-vue2-cli/playwright/index.js b/tests/components/ct-vue2-cli/playwright/index.js index e69de29bb2..8d96634b19 100644 --- a/tests/components/ct-vue2-cli/playwright/index.js +++ b/tests/components/ct-vue2-cli/playwright/index.js @@ -0,0 +1,11 @@ +//@ts-check + +import { beforeMount, afterMount } from '@playwright/experimental-ct-vue2/hooks'; + +beforeMount(async ({ hooksConfig }) => { + console.log(`Before mount: ${JSON.stringify(hooksConfig)}`); +}); + +afterMount(async ({ instance }) => { + console.log(`After mount el: ${instance.$el.constructor.name}`); +}); diff --git a/tests/components/ct-vue2-cli/src/notation-jsx.spec.tsx b/tests/components/ct-vue2-cli/src/notation-jsx.spec.tsx index 555068065f..a6928e89cf 100644 --- a/tests/components/ct-vue2-cli/src/notation-jsx.spec.tsx +++ b/tests/components/ct-vue2-cli/src/notation-jsx.spec.tsx @@ -60,3 +60,12 @@ test('slot should emit events', async ({ mount }) => { await component.locator('text=Main Content').click(); expect(clickFired).toBeTruthy(); }) + +test('should run hooks', async ({ page, mount }) => { + const messages = [] + page.on('console', m => messages.push(m.text())) + await mount(, { + hooksConfig: { route: 'A' } + }) + expect(messages).toEqual(['Before mount: {\"route\":\"A\"}', 'After mount el: HTMLButtonElement']) +}) diff --git a/tests/components/ct-vue2-cli/src/notation-vue.spec.ts b/tests/components/ct-vue2-cli/src/notation-vue.spec.ts index 47e5024b30..b86a011d6c 100644 --- a/tests/components/ct-vue2-cli/src/notation-vue.spec.ts +++ b/tests/components/ct-vue2-cli/src/notation-vue.spec.ts @@ -60,3 +60,15 @@ test('named slots should work', async ({ mount }) => { await expect(component).toContainText('Main Content') await expect(component).toContainText('Footer') }) + +test('should run hooks', async ({ page, mount }) => { + const messages = [] + page.on('console', m => messages.push(m.text())) + await mount(Button, { + props: { + title: 'Submit' + }, + hooksConfig: { route: 'A' } + }) + expect(messages).toEqual(['Before mount: {\"route\":\"A\"}', 'After mount el: HTMLButtonElement']) +})