mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-12 11:50:22 +03:00
chore(ct): change setProps to rerender (#16204)
This commit is contained in:
parent
e4efc300c7
commit
e5cc78af67
25
packages/playwright-ct-vue/index.d.ts
vendored
25
packages/playwright-ct-vue/index.d.ts
vendored
@ -34,25 +34,22 @@ export type PlaywrightTestConfig = Omit<BasePlaywrightTestConfig, 'use'> & {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
interface MountResult<Props = { [key: string]: any }> extends Locator {
|
export interface MountOptions<Props = Record<string, unknown>> {
|
||||||
|
props?: Props,
|
||||||
|
slots?: Record<string, unknown>,
|
||||||
|
on?: Record<string, Function>,
|
||||||
|
hooksConfig?: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MountResult<Props = Record<string, unknown>> extends Locator {
|
||||||
unmount(): Promise<void>;
|
unmount(): Promise<void>;
|
||||||
setProps(props: Partial<Props>): Promise<void>
|
rerender(options: { props: Props }): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComponentFixtures {
|
export interface ComponentFixtures {
|
||||||
mount(component: JSX.Element): Promise<MountResult>;
|
mount(component: JSX.Element): Promise<MountResult>;
|
||||||
mount(component: any, options?: {
|
mount(component: any, options?: MountOptions): Promise<MountResult>;
|
||||||
props?: { [key: string]: any },
|
mount<Props>(component: any, options: MountOptions<Required<Props>>): Promise<MountResult<Props>>;
|
||||||
slots?: { [key: string]: any },
|
|
||||||
on?: { [key: string]: Function },
|
|
||||||
hooksConfig?: any,
|
|
||||||
}): Promise<MountResult>;
|
|
||||||
mount<Props>(component: any, options: {
|
|
||||||
props: Props,
|
|
||||||
slots?: { [key: string]: any },
|
|
||||||
on?: { [key: string]: Function },
|
|
||||||
hooksConfig?: any,
|
|
||||||
}): Promise<MountResult<Props>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const test: TestType<
|
export const test: TestType<
|
||||||
|
@ -181,11 +181,11 @@ window.playwrightUnmount = async element => {
|
|||||||
app.unmount();
|
app.unmount();
|
||||||
};
|
};
|
||||||
|
|
||||||
window.playwrightSetProps = async (element, props) => {
|
window.playwrightRerender = async (element, options) => {
|
||||||
const component = element[componentKey].component;
|
const component = element[componentKey].component;
|
||||||
if (!component)
|
if (!component)
|
||||||
throw new Error('Component was not mounted');
|
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;
|
component.props[key] = value;
|
||||||
};
|
};
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Fixtures, Locator, Page, BrowserContextOptions, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, BrowserContext } from './types';
|
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[] = [];
|
let boundCallbacksForMount: Function[] = [];
|
||||||
|
|
||||||
interface MountResult extends Locator {
|
interface MountResult extends Locator {
|
||||||
unmount: (locator: Locator) => Promise<void>;
|
unmount(locator: Locator): Promise<void>;
|
||||||
setProps: (props: { [key: string]: any }) => Promise<void>;
|
rerender(options: Omit<MountOptions, 'hooksConfig'>): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fixtures: Fixtures<
|
export const fixtures: Fixtures<
|
||||||
@ -48,7 +48,7 @@ export const fixtures: Fixtures<
|
|||||||
},
|
},
|
||||||
|
|
||||||
mount: async ({ page }, use) => {
|
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 () => {
|
const selector = await (page as any)._wrapApiCall(async () => {
|
||||||
return await innerMount(page, component, options);
|
return await innerMount(page, component, options);
|
||||||
}, true);
|
}, true);
|
||||||
@ -60,10 +60,10 @@ export const fixtures: Fixtures<
|
|||||||
await window.playwrightUnmount(element, rootElement);
|
await window.playwrightUnmount(element, rootElement);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setProps: async (props: { [key: string]: any }) => {
|
rerender: async (options: Omit<MountOptions, 'hooksConfig'>) => {
|
||||||
await locator.evaluate(async (element, props) => {
|
await locator.evaluate(async (element, options) => {
|
||||||
return await window.playwrightSetProps(element, props);
|
return await window.playwrightRerender(element, options);
|
||||||
}, props);
|
}, options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -71,7 +71,7 @@ export const fixtures: Fixtures<
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: ObjectComponentOptions = {}): Promise<string> {
|
async function innerMount(page: Page, jsxOrType: JsxComponent | string, options: MountOptions = {}): Promise<string> {
|
||||||
let component: Component;
|
let component: Component;
|
||||||
if (typeof jsxOrType === 'string')
|
if (typeof jsxOrType === 'string')
|
||||||
component = { kind: 'object', type: jsxOrType, options };
|
component = { kind: 'object', type: jsxOrType, options };
|
||||||
|
12
packages/playwright-test/types/component.d.ts
vendored
12
packages/playwright-test/types/component.d.ts
vendored
@ -17,13 +17,13 @@
|
|||||||
export type JsxComponent = {
|
export type JsxComponent = {
|
||||||
kind: 'jsx',
|
kind: 'jsx',
|
||||||
type: string,
|
type: string,
|
||||||
props: {[key: string]: any},
|
props: Record<string, any>,
|
||||||
children: (Component | string)[],
|
children: (Component | string)[],
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ObjectComponentOptions = {
|
export type MountOptions = {
|
||||||
props?: { [key: string]: any },
|
props?: Record<string, any>,
|
||||||
slots?: { [key: string]: any },
|
slots?: Record<string, any>,
|
||||||
on?: { [key: string]: Function },
|
on?: { [key: string]: Function },
|
||||||
hooksConfig?: any,
|
hooksConfig?: any,
|
||||||
};
|
};
|
||||||
@ -31,7 +31,7 @@ export type ObjectComponentOptions = {
|
|||||||
export type ObjectComponent = {
|
export type ObjectComponent = {
|
||||||
kind: 'object',
|
kind: 'object',
|
||||||
type: string,
|
type: string,
|
||||||
options?: ObjectComponentOptions
|
options?: MountOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Component = JsxComponent | ObjectComponent;
|
export type Component = JsxComponent | ObjectComponent;
|
||||||
@ -40,6 +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>;
|
playwrightRerender(element: Element, props: Omit<MountOptions, 'hooksConfig'>): Promise<void>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,6 @@ defineProps({
|
|||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
|
||||||
emits: {
|
|
||||||
submit: null,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
21
tests/components/ct-vue-vite/src/components/Counter.vue
Normal file
21
tests/components/ct-vue-vite/src/components/Counter.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<span id="remount-count">{{ remountCount }}</span>
|
||||||
|
<span id="rerender-count">{{ count }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let remountCount = 0
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
count: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
remountCount++
|
||||||
|
</script>
|
||||||
|
|
@ -1,20 +1,27 @@
|
|||||||
import { test, expect } from '@playwright/experimental-ct-vue'
|
import { test, expect } from '@playwright/experimental-ct-vue'
|
||||||
import Button from './components/Button.vue'
|
import Button from './components/Button.vue'
|
||||||
|
import Counter from './components/Counter.vue'
|
||||||
import DefaultSlot from './components/DefaultSlot.vue'
|
import DefaultSlot from './components/DefaultSlot.vue'
|
||||||
import NamedSlots from './components/NamedSlots.vue'
|
import NamedSlots from './components/NamedSlots.vue'
|
||||||
|
|
||||||
test.use({ viewport: { width: 500, height: 500 } })
|
test.use({ viewport: { width: 500, height: 500 } })
|
||||||
|
|
||||||
test('props should work', async ({ mount }) => {
|
test('props should work', async ({ mount }) => {
|
||||||
const component = await mount(<Button title='Submit'></Button>)
|
const component = await mount(<Button title="Submit" />)
|
||||||
await expect(component).toContainText('Submit')
|
await expect(component).toContainText('Submit')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('update props should work', async ({ mount }) => {
|
test('renderer and keep the component instance intact', async ({ mount }) => {
|
||||||
const component = await mount(<Button title='Submit'></Button>);
|
const component = await mount(<Counter count={9001} />);
|
||||||
await expect(component).toContainText('Submit');
|
await expect(component.locator('#rerender-count')).toContainText('9001')
|
||||||
await component.setProps({ title: 'Loading' });
|
|
||||||
await expect(component).toContainText('Loading');
|
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 }) => {
|
test('event should work', async ({ mount }) => {
|
||||||
@ -71,7 +78,7 @@ test('slot should emit events', async ({ mount }) => {
|
|||||||
test('should run hooks', async ({ page, mount }) => {
|
test('should run hooks', async ({ page, mount }) => {
|
||||||
const messages = []
|
const messages = []
|
||||||
page.on('console', m => messages.push(m.text()))
|
page.on('console', m => messages.push(m.text()))
|
||||||
await mount(<Button title='Submit'></Button>, {
|
await mount(<Button title="Submit" />, {
|
||||||
hooksConfig: { route: 'A' }
|
hooksConfig: { route: 'A' }
|
||||||
})
|
})
|
||||||
expect(messages).toEqual(['Before mount: {\"route\":\"A\"}, app: true', 'After mount el: HTMLButtonElement'])
|
expect(messages).toEqual(['Before mount: {\"route\":\"A\"}, app: true', 'After mount el: HTMLButtonElement'])
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { test, expect } from '@playwright/experimental-ct-vue'
|
import { test, expect } from '@playwright/experimental-ct-vue'
|
||||||
import Button from './components/Button.vue'
|
import Button from './components/Button.vue'
|
||||||
|
import Counter from './components/Counter.vue'
|
||||||
import DefaultSlot from './components/DefaultSlot.vue'
|
import DefaultSlot from './components/DefaultSlot.vue'
|
||||||
import NamedSlots from './components/NamedSlots.vue'
|
import NamedSlots from './components/NamedSlots.vue'
|
||||||
import Component from './components/Component.vue'
|
import Component from './components/Component.vue'
|
||||||
@ -15,17 +16,24 @@ test('props should work', async ({ mount }) => {
|
|||||||
await expect(component).toContainText('Submit')
|
await expect(component).toContainText('Submit')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('update props should work', async ({ mount }) => {
|
test('renderer and keep the component instance intact', async ({ mount }) => {
|
||||||
const component = await mount(Button, {
|
const component = await mount(Counter, {
|
||||||
props: {
|
props: {
|
||||||
title: 'Submit'
|
count: 9001
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await expect(component).toContainText('Submit');
|
await expect(component.locator('#rerender-count')).toContainText('9001')
|
||||||
await component.setProps({ title: 'Loading' });
|
|
||||||
await expect(component).toContainText('Loading');
|
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 }) => {
|
test('event should work', async ({ mount }) => {
|
||||||
const messages = []
|
const messages = []
|
||||||
const component = await mount(Button, {
|
const component = await mount(Button, {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { test, expect } from '@playwright/experimental-ct-vue'
|
import { test, expect } from '@playwright/experimental-ct-vue'
|
||||||
|
|
||||||
import Button from './components/Button.vue'
|
import Button from './components/Button.vue'
|
||||||
|
import Counter from './components/Counter.vue'
|
||||||
import DefaultSlot from './components/DefaultSlot.vue'
|
import DefaultSlot from './components/DefaultSlot.vue'
|
||||||
import NamedSlots from './components/NamedSlots.vue'
|
import NamedSlots from './components/NamedSlots.vue'
|
||||||
import Component from './components/Component.vue'
|
import Component from './components/Component.vue'
|
||||||
@ -16,15 +17,21 @@ test('props should work', async ({ mount }) => {
|
|||||||
await expect(component).toContainText('Submit')
|
await expect(component).toContainText('Submit')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('update props should work', async ({ mount }) => {
|
test('renderer and keep the component instance intact', async ({ mount }) => {
|
||||||
const component = await mount(Button, {
|
const component = await mount<{ count: number }>(Counter, {
|
||||||
props: {
|
props: {
|
||||||
title: 'Submit'
|
count: 9001
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await expect(component).toContainText('Submit')
|
await expect(component.locator('#rerender-count')).toContainText('9001')
|
||||||
await component.setProps({ title: 'Loading' })
|
|
||||||
await expect(component).toContainText('Loading')
|
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 }) => {
|
test('event should work', async ({ mount }) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user