test(ct): update child (#22712)

This commit is contained in:
Sander 2023-05-02 00:20:46 +02:00 committed by GitHub
parent 5b69c4cf52
commit 79408ff7a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 277 additions and 56 deletions

View File

@ -17,9 +17,9 @@ import { useLayoutEffect, useRef, useState } from "react"
_remountCount++;
}
}, [])
return <div onClick={() => props.onClick?.('hello')}>
<div data-testid="props">{ props.count }</div>
<div data-testid="remount-count">{ remountCount }</div>
return <button onClick={() => props.onClick?.('hello')}>
<span data-testid="props">{ props.count }</span>
<span data-testid="remount-count">{ remountCount }</span>
{ props.children }
</div>
</button>
}

View File

@ -1,5 +1,6 @@
import { test, expect } from '@playwright/experimental-ct-react';
import Counter from '@/components/Counter';
import DefaultChildren from '@/components/DefaultChildren';
test('update props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />);
@ -12,6 +13,17 @@ test('update props without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update child props without remounting', async ({ mount }) => {
const component = await mount(<DefaultChildren><Counter count={9001} /></DefaultChildren>);
await expect(component.getByTestId('props')).toContainText('9001');
await component.update(<DefaultChildren><Counter count={1337} /></DefaultChildren>);
await expect(component).not.toContainText('9001');
await expect(component.getByTestId('props')).toContainText('1337');
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update callbacks without remounting', async ({ mount }) => {
const component = await mount(<Counter />);
@ -29,7 +41,26 @@ test('update callbacks without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update slots without remounting', async ({ mount }) => {
test('update child callbacks without remounting', async ({ mount }) => {
const component = await mount(<DefaultChildren><Counter /></DefaultChildren>);
const messages: string[] = [];
await component.update(
<DefaultChildren>
<Counter
onClick={(message) => {
messages.push(message);
}}
/>
</DefaultChildren>
);
await component.getByRole('button').click();
expect(messages).toEqual(['hello']);
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update children without remounting', async ({ mount }) => {
const component = await mount(<Counter>Default Slot</Counter>);
await expect(component).toContainText('Default Slot');
@ -39,3 +70,22 @@ test('update slots without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update grandchild without remounting', async ({ mount }) => {
const component = await mount(
<DefaultChildren>
<Counter>Default Slot</Counter>
</DefaultChildren>
);
await expect(component.getByRole('button')).toContainText('Default Slot');
await component.update(
<DefaultChildren>
<Counter>Test Slot</Counter>
</DefaultChildren>
);
await expect(component.getByRole('button')).not.toContainText('Default Slot');
await expect(component.getByRole('button')).toContainText('Test Slot');
await expect(component.getByTestId('remount-count')).toContainText('1');
});

View File

@ -17,9 +17,9 @@ import { useLayoutEffect, useRef, useState } from "react"
_remountCount++;
}
}, [])
return <div onClick={() => props.onClick?.('hello')}>
<div data-testid="props">{ props.count }</div>
<div data-testid="remount-count">{ remountCount }</div>
return <button onClick={() => props.onClick?.('hello')}>
<span data-testid="props">{ props.count }</span>
<span data-testid="remount-count">{ remountCount }</span>
{ props.children }
</div>
</button>
}

View File

@ -1,4 +1,3 @@
type MultipleChildrenProps = {
children?: [any, any, any];
}

View File

@ -1,5 +1,6 @@
import { test, expect } from '@playwright/experimental-ct-react17';
import Counter from '@/components/Counter';
import DefaultChildren from '@/components/DefaultChildren';
test('update props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />);
@ -12,6 +13,17 @@ test('update props without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update child props without remounting', async ({ mount }) => {
const component = await mount(<DefaultChildren><Counter count={9001} /></DefaultChildren>);
await expect(component.getByTestId('props')).toContainText('9001');
await component.update(<DefaultChildren><Counter count={1337} /></DefaultChildren>);
await expect(component).not.toContainText('9001');
await expect(component.getByTestId('props')).toContainText('1337');
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update callbacks without remounting', async ({ mount }) => {
const component = await mount(<Counter />);
@ -29,7 +41,26 @@ test('update callbacks without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update slots without remounting', async ({ mount }) => {
test('update child callbacks without remounting', async ({ mount }) => {
const component = await mount(<DefaultChildren><Counter /></DefaultChildren>);
const messages: string[] = [];
await component.update(
<DefaultChildren>
<Counter
onClick={(message) => {
messages.push(message);
}}
/>
</DefaultChildren>
);
await component.getByRole('button').click();
expect(messages).toEqual(['hello']);
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update children without remounting', async ({ mount }) => {
const component = await mount(<Counter>Default Slot</Counter>);
await expect(component).toContainText('Default Slot');
@ -39,3 +70,22 @@ test('update slots without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update grandchild without remounting', async ({ mount }) => {
const component = await mount(
<DefaultChildren>
<Counter>Default Slot</Counter>
</DefaultChildren>
);
await expect(component.getByRole('button')).toContainText('Default Slot');
await component.update(
<DefaultChildren>
<Counter>Test Slot</Counter>
</DefaultChildren>
);
await expect(component.getByRole('button')).not.toContainText('Default Slot');
await expect(component.getByRole('button')).toContainText('Test Slot');
await expect(component.getByTestId('remount-count')).toContainText('1');
});

View File

@ -10,10 +10,10 @@ import { createSignal } from "solid-js";
export default function Counter(props: CounterProps) {
const [remountCount, setRemountCount] = createSignal(_remountCount++);
return <div onClick={() => props.onClick?.('hello')}>
<div data-testid="props">{props.count}</div>
<div data-testid="remount-count">{remountCount()}</div>
return <button onClick={() => props.onClick?.('hello')}>
<span data-testid="props">{props.count}</span>
<span data-testid="remount-count">{remountCount()}</span>
{ props.children }
</div>
</button>
}

View File

@ -1,5 +1,6 @@
import { test, expect } from '@playwright/experimental-ct-solid';
import Counter from '@/components/Counter';
import DefaultChildren from '@/components/DefaultChildren';
test('update props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />);
@ -16,13 +17,13 @@ test('update props without remounting', async ({ mount }) => {
await expect(component.getByTestId('remount-count')).toContainText('2');
});
test('update slots without remounting', async ({ mount }) => {
const component = await mount(<Counter>Default Slot</Counter>);
await expect(component).toContainText('Default Slot');
test('update child props without remounting', async ({ mount }) => {
const component = await mount(<DefaultChildren><Counter count={9001} /></DefaultChildren>);
await expect(component.getByTestId('props')).toContainText('9001');
await component.update(<Counter>Test Slot</Counter>);
await expect(component).not.toContainText('Default Slot');
await expect(component).toContainText('Test Slot');
await component.update(<DefaultChildren><Counter count={1337} /></DefaultChildren>);
await expect(component).not.toContainText('9001');
await expect(component.getByTestId('props')).toContainText('1337');
/**
* Ideally toContainText('2') should be toContainText('1')
@ -51,3 +52,64 @@ test('update callbacks without remounting', async ({ mount }) => {
*/
await expect(component.getByTestId('remount-count')).toContainText('2');
});
test('update child callbacks without remounting', async ({ mount }) => {
const component = await mount(<DefaultChildren><Counter /></DefaultChildren>);
const messages: string[] = [];
await component.update(
<DefaultChildren>
<Counter
onClick={(message) => {
messages.push(message);
}}
/>
</DefaultChildren>
);
await component.getByRole('button').click();
expect(messages).toEqual(['hello']);
/**
* Ideally toContainText('2') should be toContainText('1')
* However it seems impossible to update the props, slots or events of a rendered component
*/
await expect(component.getByTestId('remount-count')).toContainText('2');
});
test('update children without remounting', async ({ mount }) => {
const component = await mount(<Counter>Default Slot</Counter>);
await expect(component).toContainText('Default Slot');
await component.update(<Counter>Test Slot</Counter>);
await expect(component).not.toContainText('Default Slot');
await expect(component).toContainText('Test Slot');
/**
* Ideally toContainText('2') should be toContainText('1')
* However it seems impossible to update the props, slots or events of a rendered component
*/
await expect(component.getByTestId('remount-count')).toContainText('2');
});
test('update grandchild without remounting', async ({ mount }) => {
const component = await mount(
<DefaultChildren>
<Counter>Default Slot</Counter>
</DefaultChildren>
);
await expect(component.getByRole('button')).toContainText('Default Slot');
await component.update(
<DefaultChildren>
<Counter>Test Slot</Counter>
</DefaultChildren>
);
await expect(component.getByRole('button')).not.toContainText('Default Slot');
await expect(component.getByRole('button')).toContainText('Test Slot');
/**
* Ideally toContainText('2') should be toContainText('1')
* However it seems impossible to update the props, slots or events of a rendered component
*/
await expect(component.getByTestId('remount-count')).toContainText('2');
});

View File

@ -6,9 +6,9 @@ const dispatch = createEventDispatcher();
update();
</script>
<div on:click={() => dispatch('submit', 'hello')}>
<div data-testid="props">{count}</div>
<div data-testid="remount-count">{remountCount}</div>
<button on:click={() => dispatch('submit', 'hello')}>
<span data-testid="props">{count}</span>
<span data-testid="remount-count">{remountCount}</span>
<slot name="main" />
<slot />
</div>
</button>

View File

@ -6,9 +6,9 @@ const dispatch = createEventDispatcher();
update();
</script>
<div on:click={() => dispatch('submit', 'hello')}>
<div data-testid="props">{count}</div>
<div data-testid="remount-count">{remountCount}</div>
<button on:click={() => dispatch('submit', 'hello')}>
<span data-testid="props">{count}</span>
<span data-testid="remount-count">{remountCount}</span>
<slot name="main" />
<slot />
</div>
</button>

View File

@ -1,8 +1,10 @@
<template>
<div>
<button @click="$emit('submit', 'hello')">
<span data-testid="props">{{ count }}</span>
<span data-testid="remount-count">{{ remountCount }}</span>
<span data-testid="rerender-count">{{ count }}</span>
</div>
<slot name="main" />
<slot />
</button>
</template>
<script lang="ts">

View File

@ -1,19 +1,47 @@
import { test, expect } from '@playwright/experimental-ct-vue';
import Counter from '@/components/Counter.vue';
test('renderer and keep the component instance intact', async ({ mount }) => {
const component = await mount<{ count: number }>(Counter, {
props: {
count: 9001,
},
test('update props without remounting', async ({ mount }) => {
const component = await mount(Counter, {
props: { count: 9001 },
});
await expect(component.getByTestId('rerender-count')).toContainText('9001');
await expect(component.getByTestId('props')).toContainText('9001');
await component.update({ props: { count: 1337 } });
await expect(component.getByTestId('rerender-count')).toContainText('1337');
await component.update({ props: { count: 42 } });
await expect(component.getByTestId('rerender-count')).toContainText('42');
await component.update({
props: { count: 1337 },
});
await expect(component).not.toContainText('9001');
await expect(component.getByTestId('props')).toContainText('1337');
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update event listeners without remounting', async ({ mount }) => {
const component = await mount(Counter);
const messages: string[] = [];
await component.update({
on: {
submit: (count: string) => messages.push(count),
},
});
await component.click();
expect(messages).toEqual(['hello']);
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update slots without remounting', async ({ mount }) => {
const component = await mount(Counter, {
slots: { default: 'Default Slot' },
});
await expect(component).toContainText('Default Slot');
await component.update({
slots: { main: 'Test Slot' },
});
await expect(component).not.toContainText('Default Slot');
await expect(component).toContainText('Test Slot');
await expect(component.getByTestId('remount-count')).toContainText('1');
});

View File

@ -1,15 +1,45 @@
import { test, expect } from '@playwright/experimental-ct-vue';
import Counter from '@/components/Counter.vue';
test('renderer and keep the component instance intact', async ({ mount }) => {
test('update props without remounting', async ({ mount }) => {
const component = await mount(<Counter count={9001} />);
await expect(component.getByTestId('rerender-count')).toContainText('9001');
await expect(component.getByTestId('props')).toContainText('9001');
await component.update(<Counter count={1337} />);
await expect(component.getByTestId('rerender-count')).toContainText('1337');
await expect(component).not.toContainText('9001');
await expect(component.getByTestId('props')).toContainText('1337');
await component.update(<Counter count={42} />);
await expect(component.getByTestId('rerender-count')).toContainText('42');
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update event listeners without remounting', async ({ mount }) => {
const component = await mount(<Counter />);
const messages: string[] = [];
await component.update(
<Counter
v-on:submit={(count: string) => {
messages.push(count);
}}
/>
);
await component.click();
expect(messages).toEqual(['hello']);
await expect(component.getByTestId('remount-count')).toContainText('1');
});
test('update slots without remounting', async ({ mount }) => {
const component = await mount(<Counter>Default Slot</Counter>);
await expect(component).toContainText('Default Slot');
await component.update(
<Counter>
<template v-slot:main>Test Slot</template>
</Counter>
);
await expect(component).not.toContainText('Default Slot');
await expect(component).toContainText('Test Slot');
await expect(component.getByTestId('remount-count')).toContainText('1');
});

View File

@ -1,10 +1,10 @@
<template>
<div @click="$emit('submit', 'hello')">
<div data-testid="props">{{ count }}</div>
<div data-testid="remount-count">{{ remountCount }}</div>
<button @click="$emit('submit', 'hello')">
<span data-testid="props">{{ count }}</span>
<span data-testid="remount-count">{{ remountCount }}</span>
<slot name="main" />
<slot />
</div>
</button>
</template>
<script lang="ts">

View File

@ -1,10 +1,10 @@
<template>
<div @click="$emit('submit', 'hello')">
<div data-testid="props">{{ count }}</div>
<div data-testid="remount-count">{{ remountCount }}</div>
<button @click="$emit('submit', 'hello')">
<span data-testid="props">{{ count }}</span>
<span data-testid="remount-count">{{ remountCount }}</span>
<slot name="main" />
<slot />
</div>
</button>
</template>
<script lang="ts">