fix: pass key attribute from jsx to component test (#30426)

When using the `key` attribute in jsx inside the test modules, it is not
serialised and passed to the browser in component test
This commit is contained in:
Tan Li Hau 2024-04-27 00:49:44 +08:00 committed by GitHub
parent 3643fd456b
commit 194479d90e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 2 deletions

View File

@ -40,7 +40,10 @@ function __pwRender(value) {
if (isJsxComponent(v)) {
const component = v;
const props = component.props ? __pwRender(component.props) : {};
const key = component.key ? __pwRender(component.key) : undefined;
const { children, ...propsWithoutChildren } = props;
if (key)
propsWithoutChildren.key = key;
const createElementArguments = [propsWithoutChildren];
if (children)
createElementArguments.push(children);

View File

@ -40,7 +40,10 @@ function __pwRender(value) {
if (isJsxComponent(v)) {
const component = v;
const props = component.props ? __pwRender(component.props) : {};
const key = component.key ? __pwRender(component.key) : undefined;
const { children, ...propsWithoutChildren } = props;
if (key)
propsWithoutChildren.key = key;
const createElementArguments = [propsWithoutChildren];
if (children)
createElementArguments.push(children);

View File

@ -14,19 +14,21 @@
* limitations under the License.
*/
function jsx(type, props) {
function jsx(type, props, key) {
return {
__pw_type: 'jsx',
type,
props,
key,
};
}
function jsxs(type, props) {
function jsxs(type, props, key) {
return {
__pw_type: 'jsx',
type,
props,
key,
};
}

View File

@ -250,6 +250,57 @@ test('should work with JSX in variable', async ({ runInlineTest }) => {
expect(result.passed).toBe(1);
});
test('should pass "key" attribute from JSX in variable', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': playwrightCtConfigText,
'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': `
`,
'src/container.jsx': `
import { useState } from 'react';
export function Container({ children }) {
const [index, setIndex] = useState(0);
return (
<div onClick={() => setIndex((index + 1) % children.length)}>
{children[index]}
</div>
);
}
`,
'src/button.jsx': `
import { useState } from 'react';
export function Button({ value }) {
const [state, setState] = useState(value);
return <button onClick={() => setState(state + 1)}>{state}</button>;
}
`,
'src/index.test.jsx': `
import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button';
import { Container } from './container';
test('key should tear down and recreate component', async ({ mount }) => {
const component = await mount(
<Container>
<Button key='a' value={1} />
<Button key='b' value={10} />
</Container>
);
const button = component.getByRole('button');
expect(button).toHaveText("1");
await button.click();
expect(button).toHaveText("10");
});
`,
}, { workers: 1 });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1);
});
test('should return root locator for fragments', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': playwrightCtConfigText,