feat(ct): vue set props (#16058)

This commit is contained in:
sand4rt 2022-07-29 20:45:06 +02:00 committed by GitHub
parent d73f9b7b88
commit 4a47e275c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 6 deletions

View file

@ -49,6 +49,7 @@ export interface ComponentFixtures {
hooksConfig?: any, hooksConfig?: any,
}): Promise<Locator>; }): Promise<Locator>;
unmount(locator: Locator): Promise<void>; unmount(locator: Locator): Promise<void>;
setProps<Props = { [key: string]: any }>(locator: Locator, props: Props): Promise<void>
} }
export const test: TestType< export const test: TestType<

View file

@ -108,14 +108,14 @@ function render(component) {
if (component.kind === 'object') { if (component.kind === 'object') {
// Vue test util syntax. // 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') if (key === 'default')
children.push(value); children.push(value);
else else
slots[key] = value; slots[key] = value;
} }
props = component.options.props || {}; props = component.options?.props || {};
for (const [key, value] of Object.entries(component.options.on || {})) for (const [key, value] of Object.entries(component.options?.on || {}))
listeners[key] = value; listeners[key] = value;
} }
@ -155,9 +155,13 @@ function createDevTools() {
}; };
} }
const appKey = Symbol('appKey');
const componentKey = Symbol('componentKey');
window.playwrightMount = async (component, rootElement, hooksConfig) => { window.playwrightMount = async (component, rootElement, hooksConfig) => {
const wrapper = render(component);
const app = createApp({ const app = createApp({
render: () => render(component) render: () => wrapper
}); });
setDevtoolsHook(createDevTools(), {}); setDevtoolsHook(createDevTools(), {});
@ -165,6 +169,7 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => {
await hook({ app, hooksConfig }); await hook({ app, hooksConfig });
const instance = app.mount(rootElement); const instance = app.mount(rootElement);
instance.$el[appKey] = app; instance.$el[appKey] = app;
instance.$el[componentKey] = wrapper;
for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || [])
await hook({ app, hooksConfig, instance }); await hook({ app, hooksConfig, instance });
}; };
@ -176,4 +181,11 @@ window.playwrightUnmount = async element => {
app.unmount(); 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;
};

View file

@ -23,6 +23,7 @@ export const fixtures: Fixtures<
PlaywrightTestArgs & PlaywrightTestOptions & { PlaywrightTestArgs & PlaywrightTestOptions & {
mount: (component: any, options: any) => Promise<Locator>; mount: (component: any, options: any) => Promise<Locator>;
unmount: (locator: Locator) => Promise<void>; unmount: (locator: Locator) => Promise<void>;
setProps: (locator: Locator, props: { [key: string]: any }) => Promise<void>;
}, },
PlaywrightWorkerArgs & PlaywrightWorkerOptions & { _ctWorker: { context: BrowserContext | undefined, hash: string } }, PlaywrightWorkerArgs & PlaywrightWorkerOptions & { _ctWorker: { context: BrowserContext | undefined, hash: string } },
{ _contextFactory: (options?: BrowserContextOptions) => Promise<BrowserContext>, _contextReuseEnabled: boolean }> = { { _contextFactory: (options?: BrowserContextOptions) => Promise<BrowserContext>, _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<string> { async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: ObjectComponentOptions = {}): Promise<string> {

View file

@ -40,5 +40,6 @@ declare global {
interface Window { interface Window {
playwrightMount(component: Component, rootElement: Element, hooksConfig: any): Promise<void>; playwrightMount(component: Component, rootElement: Element, hooksConfig: any): Promise<void>;
playwrightUnmount(element: Element, rootElement: Element): Promise<void>; playwrightUnmount(element: Element, rootElement: Element): Promise<void>;
playwrightSetProps(element: Element, props: { [key: string]: any }): Promise<void>;
} }
} }

View file

@ -10,6 +10,13 @@ test('props should work', async ({ mount }) => {
await expect(component).toContainText('Submit') await expect(component).toContainText('Submit')
}) })
test('update props should work', async ({ mount, setProps }) => {
const component = await mount(<Button title='Submit'></Button>);
await expect(component).toContainText('Submit');
await setProps(component, { title: 'Loading' });
await expect(component).toContainText('Loading');
})
test('event should work', async ({ mount }) => { test('event should work', async ({ mount }) => {
const messages = [] const messages = []
const component = await mount(<Button title='Submit' v-on:submit={data => { const component = await mount(<Button title='Submit' v-on:submit={data => {

View file

@ -17,6 +17,17 @@ test('props should work', async ({ mount }) => {
await expect(component).toContainText('Submit') await expect(component).toContainText('Submit')
}) })
test('update props should work', async ({ mount, setProps }) => {
const component = await mount(Button, {
props: {
title: 'Submit'
}
});
await expect(component).toContainText('Submit');
await setProps(component, { title: 'Loading' });
await expect(component).toContainText('Loading');
})
test('event should work', async ({ mount }) => { test('event should work', async ({ mount }) => {
const messages = [] const messages = []
const component = await mount(Button, { const component = await mount(Button, {

View file

@ -16,6 +16,17 @@ test('props should work', async ({ mount }) => {
await expect(component).toContainText('Submit') await expect(component).toContainText('Submit')
}) })
test('update props should work', async ({ mount, setProps }) => {
const component = await mount(Button, {
props: {
title: 'Submit'
}
});
await expect(component).toContainText('Submit')
await setProps(component, { title: 'Loading' });
await expect(component).toContainText('Loading');
})
test('event should work', async ({ mount }) => { test('event should work', async ({ mount }) => {
const messages = [] const messages = []
const component = await mount(Button, { const component = await mount(Button, {