mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(ct): empty slots or children (#28225)
closes: https://github.com/microsoft/playwright/issues/28212
This commit is contained in:
parent
96ce1a8f88
commit
f58c1f37eb
@ -121,12 +121,15 @@ export default declare((api: BabelAPI) => {
|
|||||||
children.push(t.spreadElement(child.expression));
|
children.push(t.spreadElement(child.expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
path.replaceWith(t.objectExpression([
|
const component = [
|
||||||
t.objectProperty(t.identifier('kind'), t.stringLiteral('jsx')),
|
t.objectProperty(t.identifier('kind'), t.stringLiteral('jsx')),
|
||||||
t.objectProperty(t.identifier('type'), t.stringLiteral(componentName)),
|
t.objectProperty(t.identifier('type'), t.stringLiteral(componentName)),
|
||||||
t.objectProperty(t.identifier('props'), t.objectExpression(props)),
|
t.objectProperty(t.identifier('props'), t.objectExpression(props)),
|
||||||
t.objectProperty(t.identifier('children'), t.arrayExpression(children)),
|
];
|
||||||
]));
|
if (children.length)
|
||||||
|
component.push(t.objectProperty(t.identifier('children'), t.arrayExpression(children)));
|
||||||
|
|
||||||
|
path.replaceWith(t.objectExpression(component));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export type JsxComponent = {
|
|||||||
kind: 'jsx',
|
kind: 'jsx',
|
||||||
type: string,
|
type: string,
|
||||||
props: Record<string, any>,
|
props: Record<string, any>,
|
||||||
children: JsxComponentChild[],
|
children?: JsxComponentChild[],
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MountOptions = {
|
export type MountOptions = {
|
||||||
|
|||||||
@ -71,7 +71,7 @@ async function __pwResolveComponent(component) {
|
|||||||
if (componentFactory)
|
if (componentFactory)
|
||||||
__pwRegistry.set(component.type, await componentFactory());
|
__pwRegistry.set(component.type, await componentFactory());
|
||||||
|
|
||||||
if ('children' in component)
|
if (component.children?.length)
|
||||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ function __renderChild(child) {
|
|||||||
*/
|
*/
|
||||||
function __pwRender(component) {
|
function __pwRender(component) {
|
||||||
const componentFunc = __pwRegistry.get(component.type);
|
const componentFunc = __pwRegistry.get(component.type);
|
||||||
const children = component.children.map(child => __renderChild(child)).filter(child => {
|
const children = component.children?.map(child => __renderChild(child)).filter(child => {
|
||||||
if (typeof child === 'string')
|
if (typeof child === 'string')
|
||||||
return !!child.trim();
|
return !!child.trim();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -70,7 +70,7 @@ async function __pwResolveComponent(component) {
|
|||||||
if (componentFactory)
|
if (componentFactory)
|
||||||
__pwRegistry.set(component.type, await componentFactory());
|
__pwRegistry.set(component.type, await componentFactory());
|
||||||
|
|
||||||
if ('children' in component)
|
if (component.children?.length)
|
||||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ function __renderChild(child) {
|
|||||||
*/
|
*/
|
||||||
function __pwRender(component) {
|
function __pwRender(component) {
|
||||||
const componentFunc = __pwRegistry.get(component.type);
|
const componentFunc = __pwRegistry.get(component.type);
|
||||||
const children = component.children.map(child => __renderChild(child)).filter(child => {
|
const children = component.children?.map(child => __renderChild(child)).filter(child => {
|
||||||
if (typeof child === 'string')
|
if (typeof child === 'string')
|
||||||
return !!child.trim();
|
return !!child.trim();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -69,7 +69,7 @@ async function __pwResolveComponent(component) {
|
|||||||
if (componentFactory)
|
if (componentFactory)
|
||||||
__pwRegistry.set(component.type, await componentFactory());
|
__pwRegistry.set(component.type, await componentFactory());
|
||||||
|
|
||||||
if ('children' in component)
|
if (component.children?.length)
|
||||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ function __pwCreateChild(child) {
|
|||||||
*/
|
*/
|
||||||
function __pwCreateComponent(component) {
|
function __pwCreateComponent(component) {
|
||||||
const componentFunc = __pwRegistry.get(component.type);
|
const componentFunc = __pwRegistry.get(component.type);
|
||||||
const children = component.children.map(child => __pwCreateChild(child)).filter(child => {
|
const children = component.children?.map(child => __pwCreateChild(child)).filter(child => {
|
||||||
if (typeof child === 'string')
|
if (typeof child === 'string')
|
||||||
return !!child.trim();
|
return !!child.trim();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -72,7 +72,7 @@ async function __pwResolveComponent(component) {
|
|||||||
if (componentFactory)
|
if (componentFactory)
|
||||||
__pwRegistry.set(component.type, await componentFactory());
|
__pwRegistry.set(component.type, await componentFactory());
|
||||||
|
|
||||||
if ('children' in component)
|
if ('children' in component && component.children?.length)
|
||||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ function __pwCreateComponent(component) {
|
|||||||
if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') {
|
if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') {
|
||||||
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
||||||
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
||||||
slots[slot] = child.children.map(__pwCreateChild);
|
slots[slot] = child.children?.map(__pwCreateChild);
|
||||||
} else {
|
} else {
|
||||||
children.push(__pwCreateChild(child));
|
children.push(__pwCreateChild(child));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@ async function __pwResolveComponent(component) {
|
|||||||
if (componentFactory)
|
if (componentFactory)
|
||||||
__pwRegistry.set(component.type, await componentFactory());
|
__pwRegistry.set(component.type, await componentFactory());
|
||||||
|
|
||||||
if ('children' in component)
|
if ('children' in component && component.children?.length)
|
||||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
await Promise.all(component.children.map(child => __pwResolveComponent(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ function __pwCreateComponent(component) {
|
|||||||
if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') {
|
if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') {
|
||||||
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:'));
|
||||||
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default';
|
||||||
nodeData.scopedSlots[slot] = () => child.children.map(c => __pwCreateChild(c));
|
nodeData.scopedSlots[slot] = () => child.children?.map(c => __pwCreateChild(c));
|
||||||
} else {
|
} else {
|
||||||
children.push(__pwCreateChild(child));
|
children.push(__pwCreateChild(child));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export default function EmptyFragment() {
|
export default function EmptyFragment(props: unknown) {
|
||||||
|
Object.assign(window, { props });
|
||||||
return <>{[]}</>;
|
return <>{[]}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,9 @@ test('render attributes', async ({ mount }) => {
|
|||||||
await expect(component).toHaveClass('primary');
|
await expect(component).toHaveClass('primary');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get textContent of the empty fragment', async ({ mount }) => {
|
test('render an empty component', async ({ mount, page }) => {
|
||||||
const component = await mount(<EmptyFragment />);
|
const component = await mount(<EmptyFragment />);
|
||||||
|
expect(await page.evaluate(() => 'props' in window && window.props)).toEqual({});
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
expect(await component.allTextContents()).toEqual(['']);
|
||||||
expect(await component.textContent()).toBe('');
|
expect(await component.textContent()).toBe('');
|
||||||
await expect(component).toHaveText('');
|
await expect(component).toHaveText('');
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export default function EmptyFragment() {
|
export default function EmptyFragment(props: unknown) {
|
||||||
|
Object.assign(window, { props });
|
||||||
return <>{[]}</>;
|
return <>{[]}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,8 +20,9 @@ test('render delayed data', async ({ mount }) => {
|
|||||||
await expect(component).toHaveText('complete');
|
await expect(component).toHaveText('complete');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get textContent of the empty fragment', async ({ mount }) => {
|
test('render an empty component', async ({ mount, page }) => {
|
||||||
const component = await mount(<EmptyFragment />);
|
const component = await mount(<EmptyFragment />);
|
||||||
|
expect(await page.evaluate(() => 'props' in window && window.props)).toEqual({});
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
expect(await component.allTextContents()).toEqual(['']);
|
||||||
expect(await component.textContent()).toBe('');
|
expect(await component.textContent()).toBe('');
|
||||||
await expect(component).toHaveText('');
|
await expect(component).toHaveText('');
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export default function EmptyFragment() {
|
export default function EmptyFragment(props: unknown) {
|
||||||
|
Object.assign(window, { props });
|
||||||
return <>{[]}</>;
|
return <>{[]}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,9 @@ test('render attributes', async ({ mount }) => {
|
|||||||
await expect(component).toHaveClass('primary');
|
await expect(component).toHaveClass('primary');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get textContent of the empty fragment', async ({ mount }) => {
|
test('render an empty component', async ({ mount, page }) => {
|
||||||
const component = await mount(<EmptyFragment />);
|
const component = await mount(<EmptyFragment />);
|
||||||
|
expect(await page.evaluate(() => 'props' in window && window.props)).toEqual({});
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
expect(await component.allTextContents()).toEqual(['']);
|
||||||
expect(await component.textContent()).toBe('');
|
expect(await component.textContent()).toBe('');
|
||||||
await expect(component).toHaveText('');
|
await expect(component).toHaveText('');
|
||||||
|
|||||||
@ -1,2 +1,8 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useSlots } from 'vue';
|
||||||
|
const slots = useSlots();
|
||||||
|
Object.assign(window, { slots });
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,9 @@ test('render props', async ({ mount }) => {
|
|||||||
await expect(component).toContainText('Submit');
|
await expect(component).toContainText('Submit');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get textContent of the empty template', async ({ mount }) => {
|
test('render an empty component', async ({ page, mount }) => {
|
||||||
const component = await mount(<EmptyTemplate />);
|
const component = await mount(<EmptyTemplate />);
|
||||||
|
expect(await page.evaluate(() => 'slots' in window && window.slots)).toEqual({});
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
expect(await component.allTextContents()).toEqual(['']);
|
||||||
expect(await component.textContent()).toBe('');
|
expect(await component.textContent()).toBe('');
|
||||||
await expect(component).toHaveText('');
|
await expect(component).toHaveText('');
|
||||||
|
|||||||
@ -1,2 +1,7 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useSlots } from 'vue';
|
||||||
|
const slots = useSlots();
|
||||||
|
Object.assign(window, { slots });
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -12,8 +12,9 @@ test('render attributes', async ({ mount }) => {
|
|||||||
await expect(component).toHaveClass('primary');
|
await expect(component).toHaveClass('primary');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get textContent of the empty template', async ({ mount }) => {
|
test('render an empty component', async ({ page, mount }) => {
|
||||||
const component = await mount(<EmptyTemplate />);
|
const component = await mount(<EmptyTemplate />);
|
||||||
|
expect(await page.evaluate(() => 'slots' in window && window.slots)).toEqual({});
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
expect(await component.allTextContents()).toEqual(['']);
|
||||||
expect(await component.textContent()).toBe('');
|
expect(await component.textContent()).toBe('');
|
||||||
await expect(component).toHaveText('');
|
await expect(component).toHaveText('');
|
||||||
|
|||||||
@ -1,2 +1,8 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useSlots } from 'vue';
|
||||||
|
const slots = useSlots();
|
||||||
|
Object.assign(window, { slots });
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,9 @@ test('render attributes', async ({ mount }) => {
|
|||||||
await expect(component).toHaveClass('primary');
|
await expect(component).toHaveClass('primary');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('get textContent of the empty template', async ({ mount }) => {
|
test('render an empty component', async ({ page, mount }) => {
|
||||||
const component = await mount(<EmptyTemplate />);
|
const component = await mount(<EmptyTemplate />);
|
||||||
|
expect(await page.evaluate(() => 'slots' in window && window.slots)).toEqual({});
|
||||||
expect(await component.allTextContents()).toEqual(['']);
|
expect(await component.allTextContents()).toEqual(['']);
|
||||||
expect(await component.textContent()).toBe('');
|
expect(await component.textContent()).toBe('');
|
||||||
await expect(component).toHaveText('');
|
await expect(component).toHaveText('');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user