From 4a47e275c81797590fb2301db1de1c9f2e24d692 Mon Sep 17 00:00:00 2001 From: sand4rt Date: Fri, 29 Jul 2022 20:45:06 +0200 Subject: [PATCH] feat(ct): vue set props (#16058) --- packages/playwright-ct-vue/index.d.ts | 1 + packages/playwright-ct-vue/registerSource.mjs | 24 ++++++++++++++----- packages/playwright-test/src/mount.ts | 9 +++++++ packages/playwright-test/types/component.d.ts | 1 + .../ct-vue-vite/src/notation-jsx.spec.tsx | 7 ++++++ .../ct-vue-vite/src/notation-vue.spec.js | 11 +++++++++ .../ct-vue-vite/src/notation-vue.spec.ts | 11 +++++++++ 7 files changed, 58 insertions(+), 6 deletions(-) diff --git a/packages/playwright-ct-vue/index.d.ts b/packages/playwright-ct-vue/index.d.ts index 5981c4725d..918fe4f012 100644 --- a/packages/playwright-ct-vue/index.d.ts +++ b/packages/playwright-ct-vue/index.d.ts @@ -49,6 +49,7 @@ export interface ComponentFixtures { hooksConfig?: any, }): Promise; unmount(locator: Locator): Promise; + setProps(locator: Locator, props: Props): Promise } export const test: TestType< diff --git a/packages/playwright-ct-vue/registerSource.mjs b/packages/playwright-ct-vue/registerSource.mjs index b33eb0d5b8..057d54b70a 100644 --- a/packages/playwright-ct-vue/registerSource.mjs +++ b/packages/playwright-ct-vue/registerSource.mjs @@ -108,14 +108,14 @@ function render(component) { if (component.kind === 'object') { // Vue test util syntax. - for (const [key, value] of Object.entries(component.options.slots || {})) { + for (const [key, value] of Object.entries(component.options?.slots || {})) { if (key === 'default') children.push(value); else slots[key] = value; } - props = component.options.props || {}; - for (const [key, value] of Object.entries(component.options.on || {})) + props = component.options?.props || {}; + for (const [key, value] of Object.entries(component.options?.on || {})) listeners[key] = value; } @@ -155,9 +155,13 @@ function createDevTools() { }; } +const appKey = Symbol('appKey'); +const componentKey = Symbol('componentKey'); + window.playwrightMount = async (component, rootElement, hooksConfig) => { + const wrapper = render(component); const app = createApp({ - render: () => render(component) + render: () => wrapper }); setDevtoolsHook(createDevTools(), {}); @@ -165,15 +169,23 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { await hook({ app, hooksConfig }); const instance = app.mount(rootElement); instance.$el[appKey] = app; + instance.$el[componentKey] = wrapper; for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) await hook({ app, hooksConfig, instance }); }; -window.playwrightUnmount = async element => { +window.playwrightUnmount = async element => { const app = /** @type {import('vue').App} */ (element[appKey]); if (!app) throw new Error('Component was not mounted'); app.unmount(); }; -const appKey = Symbol('appKey'); +window.playwrightSetProps = async (element, props) => { + const component = element[componentKey].component; + if (!component) + throw new Error('Component was not mounted'); + + for (const [key, value] of Object.entries(props)) + component.props[key] = value; +}; diff --git a/packages/playwright-test/src/mount.ts b/packages/playwright-test/src/mount.ts index 4cc0cc6326..19347a6992 100644 --- a/packages/playwright-test/src/mount.ts +++ b/packages/playwright-test/src/mount.ts @@ -23,6 +23,7 @@ export const fixtures: Fixtures< PlaywrightTestArgs & PlaywrightTestOptions & { mount: (component: any, options: any) => Promise; unmount: (locator: Locator) => Promise; + setProps: (locator: Locator, props: { [key: string]: any }) => Promise; }, PlaywrightWorkerArgs & PlaywrightWorkerOptions & { _ctWorker: { context: BrowserContext | undefined, hash: string } }, { _contextFactory: (options?: BrowserContextOptions) => Promise, _contextReuseEnabled: boolean }> = { @@ -61,6 +62,14 @@ export const fixtures: Fixtures< }); }); }, + + setProps: async ({}, use) => { + await use(async (locator: Locator, props: { [key: string]: any }) => { + return await locator.evaluate(async (element, props) => { + return await window.playwrightSetProps(element, props); + }, props); + }); + } }; async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: ObjectComponentOptions = {}): Promise { diff --git a/packages/playwright-test/types/component.d.ts b/packages/playwright-test/types/component.d.ts index 872d1810c8..82fdec613c 100644 --- a/packages/playwright-test/types/component.d.ts +++ b/packages/playwright-test/types/component.d.ts @@ -40,5 +40,6 @@ declare global { interface Window { playwrightMount(component: Component, rootElement: Element, hooksConfig: any): Promise; playwrightUnmount(element: Element, rootElement: Element): Promise; + playwrightSetProps(element: Element, props: { [key: string]: any }): Promise; } } 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 50c6de2caa..483140f559 100644 --- a/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx +++ b/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx @@ -10,6 +10,13 @@ test('props should work', async ({ mount }) => { await expect(component).toContainText('Submit') }) +test('update props should work', async ({ mount, setProps }) => { + const component = await mount(); + await expect(component).toContainText('Submit'); + await setProps(component, { title: 'Loading' }); + await expect(component).toContainText('Loading'); +}) + test('event should work', async ({ mount }) => { const messages = [] const component = await mount(