From e5cc78af676d7a22f3ba388d943f40abee99ab67 Mon Sep 17 00:00:00 2001 From: sand4rt Date: Thu, 4 Aug 2022 03:14:00 +0200 Subject: [PATCH] chore(ct): change setProps to rerender (#16204) --- packages/playwright-ct-vue/index.d.ts | 25 ++++++++----------- packages/playwright-ct-vue/registerSource.mjs | 4 +-- packages/playwright-test/src/mount.ts | 18 ++++++------- packages/playwright-test/types/component.d.ts | 12 ++++----- .../ct-vue-vite/src/components/Button.vue | 3 --- .../ct-vue-vite/src/components/Counter.vue | 21 ++++++++++++++++ .../ct-vue-vite/src/notation-jsx.spec.tsx | 21 ++++++++++------ .../ct-vue-vite/src/notation-vue.spec.js | 22 ++++++++++------ .../ct-vue-vite/src/notation-vue.spec.ts | 19 +++++++++----- 9 files changed, 91 insertions(+), 54 deletions(-) create mode 100644 tests/components/ct-vue-vite/src/components/Counter.vue diff --git a/packages/playwright-ct-vue/index.d.ts b/packages/playwright-ct-vue/index.d.ts index 5f60f387cc..684e7a1e89 100644 --- a/packages/playwright-ct-vue/index.d.ts +++ b/packages/playwright-ct-vue/index.d.ts @@ -34,25 +34,22 @@ export type PlaywrightTestConfig = Omit & { } }; -interface MountResult extends Locator { +export interface MountOptions> { + props?: Props, + slots?: Record, + on?: Record, + hooksConfig?: any, +} + +interface MountResult> extends Locator { unmount(): Promise; - setProps(props: Partial): Promise + rerender(options: { props: Props }): Promise } export interface ComponentFixtures { mount(component: JSX.Element): Promise; - mount(component: any, options?: { - props?: { [key: string]: any }, - slots?: { [key: string]: any }, - on?: { [key: string]: Function }, - hooksConfig?: any, - }): Promise; - mount(component: any, options: { - props: Props, - slots?: { [key: string]: any }, - on?: { [key: string]: Function }, - hooksConfig?: any, - }): Promise>; + mount(component: any, options?: MountOptions): Promise; + mount(component: any, options: MountOptions>): Promise>; } export const test: TestType< diff --git a/packages/playwright-ct-vue/registerSource.mjs b/packages/playwright-ct-vue/registerSource.mjs index 057d54b70a..dfd6f6e1a7 100644 --- a/packages/playwright-ct-vue/registerSource.mjs +++ b/packages/playwright-ct-vue/registerSource.mjs @@ -181,11 +181,11 @@ window.playwrightUnmount = async element => { app.unmount(); }; -window.playwrightSetProps = async (element, props) => { +window.playwrightRerender = async (element, options) => { const component = element[componentKey].component; if (!component) throw new Error('Component was not mounted'); - for (const [key, value] of Object.entries(props)) + for (const [key, value] of Object.entries(options.props || {})) component.props[key] = value; }; diff --git a/packages/playwright-test/src/mount.ts b/packages/playwright-test/src/mount.ts index d5a875ed6e..9fee000f89 100644 --- a/packages/playwright-test/src/mount.ts +++ b/packages/playwright-test/src/mount.ts @@ -15,13 +15,13 @@ */ import type { Fixtures, Locator, Page, BrowserContextOptions, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, BrowserContext } from './types'; -import type { Component, JsxComponent, ObjectComponentOptions } from '../types/component'; +import type { Component, JsxComponent, MountOptions } from '../types/component'; let boundCallbacksForMount: Function[] = []; interface MountResult extends Locator { - unmount: (locator: Locator) => Promise; - setProps: (props: { [key: string]: any }) => Promise; + unmount(locator: Locator): Promise; + rerender(options: Omit): Promise; } export const fixtures: Fixtures< @@ -48,7 +48,7 @@ export const fixtures: Fixtures< }, mount: async ({ page }, use) => { - await use(async (component: JsxComponent | string, options?: ObjectComponentOptions) => { + await use(async (component: JsxComponent | string, options?: MountOptions) => { const selector = await (page as any)._wrapApiCall(async () => { return await innerMount(page, component, options); }, true); @@ -60,10 +60,10 @@ export const fixtures: Fixtures< await window.playwrightUnmount(element, rootElement); }); }, - setProps: async (props: { [key: string]: any }) => { - await locator.evaluate(async (element, props) => { - return await window.playwrightSetProps(element, props); - }, props); + rerender: async (options: Omit) => { + await locator.evaluate(async (element, options) => { + return await window.playwrightRerender(element, options); + }, options); } }); }); @@ -71,7 +71,7 @@ export const fixtures: Fixtures< }, }; -async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: ObjectComponentOptions = {}): Promise { +async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: MountOptions = {}): Promise { let component: Component; if (typeof jsxOrType === 'string') component = { kind: 'object', type: jsxOrType, options }; diff --git a/packages/playwright-test/types/component.d.ts b/packages/playwright-test/types/component.d.ts index 82fdec613c..e1a96c9bd0 100644 --- a/packages/playwright-test/types/component.d.ts +++ b/packages/playwright-test/types/component.d.ts @@ -17,13 +17,13 @@ export type JsxComponent = { kind: 'jsx', type: string, - props: {[key: string]: any}, + props: Record, children: (Component | string)[], }; -export type ObjectComponentOptions = { - props?: { [key: string]: any }, - slots?: { [key: string]: any }, +export type MountOptions = { + props?: Record, + slots?: Record, on?: { [key: string]: Function }, hooksConfig?: any, }; @@ -31,7 +31,7 @@ export type ObjectComponentOptions = { export type ObjectComponent = { kind: 'object', type: string, - options?: ObjectComponentOptions + options?: MountOptions }; export type Component = JsxComponent | ObjectComponent; @@ -40,6 +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; + playwrightRerender(element: Element, props: Omit): Promise; } } diff --git a/tests/components/ct-vue-vite/src/components/Button.vue b/tests/components/ct-vue-vite/src/components/Button.vue index 8df50e23b3..334a3d0364 100644 --- a/tests/components/ct-vue-vite/src/components/Button.vue +++ b/tests/components/ct-vue-vite/src/components/Button.vue @@ -3,9 +3,6 @@ defineProps({ title: { type: String, required: true - }, - emits: { - submit: null, } }) diff --git a/tests/components/ct-vue-vite/src/components/Counter.vue b/tests/components/ct-vue-vite/src/components/Counter.vue new file mode 100644 index 0000000000..6e211660b7 --- /dev/null +++ b/tests/components/ct-vue-vite/src/components/Counter.vue @@ -0,0 +1,21 @@ + + + + + + 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 954ea93b33..df4b20f286 100644 --- a/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx +++ b/tests/components/ct-vue-vite/src/notation-jsx.spec.tsx @@ -1,20 +1,27 @@ import { test, expect } from '@playwright/experimental-ct-vue' import Button from './components/Button.vue' +import Counter from './components/Counter.vue' import DefaultSlot from './components/DefaultSlot.vue' import NamedSlots from './components/NamedSlots.vue' test.use({ viewport: { width: 500, height: 500 } }) test('props should work', async ({ mount }) => { - const component = await mount() + const component = await mount(); - await expect(component).toContainText('Submit'); - await component.setProps({ title: 'Loading' }); - await expect(component).toContainText('Loading'); +test('renderer and keep the component instance intact', async ({ mount }) => { + const component = await mount(); + await expect(component.locator('#rerender-count')).toContainText('9001') + + await component.rerender({ props: { count: 1337 } }) + await expect(component.locator('#rerender-count')).toContainText('1337') + + await component.rerender({ props: { count: 42 } }) + await expect(component.locator('#rerender-count')).toContainText('42') + + await expect(component.locator('#remount-count')).toContainText('1') }) test('event should work', async ({ mount }) => { @@ -71,7 +78,7 @@ test('slot should emit events', async ({ mount }) => { test('should run hooks', async ({ page, mount }) => { const messages = [] page.on('console', m => messages.push(m.text())) - await mount(, { + await mount(