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:
parent
3643fd456b
commit
194479d90e
|
|
@ -40,7 +40,10 @@ function __pwRender(value) {
|
||||||
if (isJsxComponent(v)) {
|
if (isJsxComponent(v)) {
|
||||||
const component = v;
|
const component = v;
|
||||||
const props = component.props ? __pwRender(component.props) : {};
|
const props = component.props ? __pwRender(component.props) : {};
|
||||||
|
const key = component.key ? __pwRender(component.key) : undefined;
|
||||||
const { children, ...propsWithoutChildren } = props;
|
const { children, ...propsWithoutChildren } = props;
|
||||||
|
if (key)
|
||||||
|
propsWithoutChildren.key = key;
|
||||||
const createElementArguments = [propsWithoutChildren];
|
const createElementArguments = [propsWithoutChildren];
|
||||||
if (children)
|
if (children)
|
||||||
createElementArguments.push(children);
|
createElementArguments.push(children);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,10 @@ function __pwRender(value) {
|
||||||
if (isJsxComponent(v)) {
|
if (isJsxComponent(v)) {
|
||||||
const component = v;
|
const component = v;
|
||||||
const props = component.props ? __pwRender(component.props) : {};
|
const props = component.props ? __pwRender(component.props) : {};
|
||||||
|
const key = component.key ? __pwRender(component.key) : undefined;
|
||||||
const { children, ...propsWithoutChildren } = props;
|
const { children, ...propsWithoutChildren } = props;
|
||||||
|
if (key)
|
||||||
|
propsWithoutChildren.key = key;
|
||||||
const createElementArguments = [propsWithoutChildren];
|
const createElementArguments = [propsWithoutChildren];
|
||||||
if (children)
|
if (children)
|
||||||
createElementArguments.push(children);
|
createElementArguments.push(children);
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,21 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function jsx(type, props) {
|
function jsx(type, props, key) {
|
||||||
return {
|
return {
|
||||||
__pw_type: 'jsx',
|
__pw_type: 'jsx',
|
||||||
type,
|
type,
|
||||||
props,
|
props,
|
||||||
|
key,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsxs(type, props) {
|
function jsxs(type, props, key) {
|
||||||
return {
|
return {
|
||||||
__pw_type: 'jsx',
|
__pw_type: 'jsx',
|
||||||
type,
|
type,
|
||||||
props,
|
props,
|
||||||
|
key,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,57 @@ test('should work with JSX in variable', async ({ runInlineTest }) => {
|
||||||
expect(result.passed).toBe(1);
|
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 }) => {
|
test('should return root locator for fragments', async ({ runInlineTest }) => {
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
'playwright.config.ts': playwrightCtConfigText,
|
'playwright.config.ts': playwrightCtConfigText,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue