mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(ct): svelte rerender (#17940)
This commit is contained in:
parent
0f820aa7f3
commit
3a281364d8
7
packages/playwright-ct-svelte/index.d.ts
vendored
7
packages/playwright-ct-svelte/index.d.ts
vendored
@ -42,22 +42,23 @@ type JsonObject = { [Key in string]?: JsonValue };
|
||||
|
||||
type Slot = string | string[];
|
||||
|
||||
export interface MountOptions<Component extends SvelteComponent> {
|
||||
export interface MountOptions<Component extends SvelteComponent = SvelteComponent> {
|
||||
props?: ComponentProps<Component>;
|
||||
slots?: Record<string, Slot> & { default?: Slot };
|
||||
on?: Record<string, Function>;
|
||||
hooksConfig?: JsonObject;
|
||||
}
|
||||
|
||||
interface MountResult extends Locator {
|
||||
interface MountResult<Component extends SvelteComponent> extends Locator {
|
||||
unmount(): Promise<void>;
|
||||
rerender(options: Omit<MountOptions<Component>, 'hooksConfig'|'slots'>): Promise<void>
|
||||
}
|
||||
|
||||
interface ComponentFixtures {
|
||||
mount<Component extends SvelteComponent>(
|
||||
component: new (...args: any[]) => Component,
|
||||
options?: MountOptions<Component>
|
||||
): Promise<MountResult>;
|
||||
): Promise<MountResult<Component>>;
|
||||
}
|
||||
|
||||
export const test: TestType<
|
||||
|
||||
@ -66,6 +66,8 @@ function createSlots(slots) {
|
||||
return svelteSlots;
|
||||
}
|
||||
|
||||
const svelteComponentKey = Symbol('svelteComponent');
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
let componentCtor = registry.get(component.type);
|
||||
if (!componentCtor) {
|
||||
@ -98,11 +100,11 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
}));
|
||||
rootElement[svelteComponentKey] = svelteComponent;
|
||||
|
||||
for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || [])
|
||||
await hook({ hooksConfig, svelteComponent });
|
||||
|
||||
for (const [key, listener] of Object.entries(component.options?.on || {}))
|
||||
svelteComponent.$on(key, event => listener(event.detail));
|
||||
|
||||
for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || [])
|
||||
await hook({ hooksConfig, svelteComponent });
|
||||
};
|
||||
|
||||
window.playwrightUnmount = async rootElement => {
|
||||
@ -112,4 +114,14 @@ window.playwrightUnmount = async rootElement => {
|
||||
svelteComponent.$destroy();
|
||||
};
|
||||
|
||||
const svelteComponentKey = Symbol('svelteComponent');
|
||||
window.playwrightRerender = async (rootElement, component) => {
|
||||
const svelteComponent = /** @type {SvelteComponent} */ (rootElement[svelteComponentKey]);
|
||||
if (!svelteComponent)
|
||||
throw new Error('Component was not mounted');
|
||||
|
||||
for (const [key, listener] of Object.entries(component.options?.on || {}))
|
||||
svelteComponent.$on(key, event => listener(event.detail));
|
||||
|
||||
if (component.options?.props)
|
||||
svelteComponent.$set(component.options.props);
|
||||
};
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { update, remountCount } from '../store'
|
||||
import { createEventDispatcher } from "svelte";
|
||||
export let count;
|
||||
const dispatch = createEventDispatcher();
|
||||
update();
|
||||
</script>
|
||||
|
||||
<div on:click={() => dispatch('submit', 'hello')}>
|
||||
<div id="props">{count}</div>
|
||||
<div id="remount-count">{remountCount}</div>
|
||||
<slot name="main" />
|
||||
<slot />
|
||||
</div>
|
||||
4
tests/components/ct-svelte-vite/src/store/index.ts
Normal file
4
tests/components/ct-svelte-vite/src/store/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export let remountCount = 0;
|
||||
export function update() {
|
||||
remountCount++;
|
||||
}
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
import { test, expect } from '@playwright/experimental-ct-svelte';
|
||||
import Button from './components/Button.svelte';
|
||||
import Counter from './components/Counter.svelte';
|
||||
import DefaultSlot from './components/DefaultSlot.svelte';
|
||||
import NamedSlots from './components/NamedSlots.svelte';
|
||||
import MultiRoot from './components/MultiRoot.svelte';
|
||||
@ -32,6 +33,36 @@ test('render props', async ({ mount }) => {
|
||||
await expect(component).toContainText('Submit')
|
||||
})
|
||||
|
||||
test('renderer updates props without remounting', async ({ mount }) => {
|
||||
const component = await mount(Counter, {
|
||||
props: { count: 9001 }
|
||||
})
|
||||
await expect(component.locator('#props')).toContainText('9001')
|
||||
|
||||
await component.rerender({
|
||||
props: { count: 1337 }
|
||||
})
|
||||
await expect(component).not.toContainText('9001')
|
||||
await expect(component.locator('#props')).toContainText('1337')
|
||||
|
||||
await expect(component.locator('#remount-count')).toContainText('1')
|
||||
})
|
||||
|
||||
test('renderer updates event listeners without remounting', async ({ mount }) => {
|
||||
const component = await mount(Counter)
|
||||
|
||||
const messages: string[] = []
|
||||
await component.rerender({
|
||||
on: {
|
||||
submit: (data: string) => messages.push(data)
|
||||
}
|
||||
})
|
||||
await component.click();
|
||||
expect(messages).toEqual(['hello'])
|
||||
|
||||
await expect(component.locator('#remount-count')).toContainText('1')
|
||||
})
|
||||
|
||||
test('emit an submit event when the button is clicked', async ({ mount }) => {
|
||||
const messages = []
|
||||
const component = await mount(Button, {
|
||||
|
||||
14
tests/components/ct-svelte/src/components/Counter.svelte
Normal file
14
tests/components/ct-svelte/src/components/Counter.svelte
Normal file
@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { update, remountCount } from '../store'
|
||||
import { createEventDispatcher } from "svelte";
|
||||
export let count;
|
||||
const dispatch = createEventDispatcher();
|
||||
update();
|
||||
</script>
|
||||
|
||||
<div on:click={() => dispatch('submit', 'hello')}>
|
||||
<div id="props">{count}</div>
|
||||
<div id="remount-count">{remountCount}</div>
|
||||
<slot name="main" />
|
||||
<slot />
|
||||
</div>
|
||||
4
tests/components/ct-svelte/src/store/index.ts
Normal file
4
tests/components/ct-svelte/src/store/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export let remountCount = 0;
|
||||
export function update() {
|
||||
remountCount++;
|
||||
}
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
import { test, expect } from '@playwright/experimental-ct-svelte';
|
||||
import Button from './components/Button.svelte';
|
||||
import Counter from './components/Counter.svelte';
|
||||
import Component from './components/Component.svelte';
|
||||
import DefaultSlot from './components/DefaultSlot.svelte';
|
||||
import NamedSlots from './components/NamedSlots.svelte'
|
||||
@ -33,6 +34,36 @@ test('render props', async ({ mount }) => {
|
||||
await expect(component).toContainText('Submit')
|
||||
})
|
||||
|
||||
test('renderer updates props without remounting', async ({ mount }) => {
|
||||
const component = await mount(Counter, {
|
||||
props: { count: 9001 }
|
||||
})
|
||||
await expect(component.locator('#props')).toContainText('9001')
|
||||
|
||||
await component.rerender({
|
||||
props: { count: 1337 }
|
||||
})
|
||||
await expect(component).not.toContainText('9001')
|
||||
await expect(component.locator('#props')).toContainText('1337')
|
||||
|
||||
await expect(component.locator('#remount-count')).toContainText('1')
|
||||
})
|
||||
|
||||
test('renderer updates event listeners without remounting', async ({ mount }) => {
|
||||
const component = await mount(Counter)
|
||||
|
||||
const messages: string[] = []
|
||||
await component.rerender({
|
||||
on: {
|
||||
submit: (data: string) => messages.push(data)
|
||||
}
|
||||
})
|
||||
await component.click();
|
||||
expect(messages).toEqual(['hello'])
|
||||
|
||||
await expect(component.locator('#remount-count')).toContainText('1')
|
||||
})
|
||||
|
||||
test('emit an submit event when the button is clicked', async ({ mount }) => {
|
||||
const messages = []
|
||||
const component = await mount(Button, {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user