diff --git a/packages/playwright-ct-solid/registerSource.mjs b/packages/playwright-ct-solid/registerSource.mjs index 4ea8ca2fdb..0e9741830a 100644 --- a/packages/playwright-ct-solid/registerSource.mjs +++ b/packages/playwright-ct-solid/registerSource.mjs @@ -17,7 +17,8 @@ // @ts-check // This file is injected into the registry as text, no dependencies are allowed. -import { render as solidRender, createComponent } from 'solid-js/web'; +import { render as solidRender, createComponent as solidCreateComponent } from 'solid-js/web'; +import h from 'solid-js/h'; /** @typedef {import('../playwright-test/types/component').Component} Component */ /** @typedef {() => import('solid-js').JSX.Element} FrameworkComponent */ @@ -33,40 +34,54 @@ export function register(components) { registry.set(name, value); } +function createChild(child) { + return typeof child === 'string' ? child : createComponent(child); +} + /** * @param {Component} component */ -function render(component) { - let componentFunc = registry.get(component.type); - if (!componentFunc) { +function createComponent(component) { + if (typeof component === 'string') + return component; + + let Component = registry.get(component.type); + if (!Component) { // Lookup by shorthand. for (const [name, value] of registry) { if (component.type.endsWith(`_${name}`)) { - componentFunc = value; + Component = value; break; } } } - if (!componentFunc) + if (!Component && component.type[0].toUpperCase() === component.type[0]) throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); if (component.kind !== 'jsx') throw new Error('Object mount notation is not supported'); - return createComponent(componentFunc, { - children: component.children, - ...component.props - }); + const children = component.children.reduce((/** @type {any[]} */ children, current) => { + const child = createChild(current); + if (typeof child !== 'string' || !!child.trim()) + children.push(child); + return children; + }, []); + + if (!Component) + return h(component.type, component.props, children); + + return solidCreateComponent(Component, { ...component.props, children }); } -const unmountKey = Symbol('disposeKey'); +const unmountKey = Symbol('unmountKey'); window.playwrightMount = async (component, rootElement, hooksConfig) => { for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) await hook({ hooksConfig }); - const unmount = solidRender(() => render(component), rootElement); + const unmount = solidRender(() => createComponent(component), rootElement); rootElement[unmountKey] = unmount; for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || []) diff --git a/tests/components/ct-solid/src/components/MultipleChildren.tsx b/tests/components/ct-solid/src/components/MultipleChildren.tsx new file mode 100644 index 0000000000..283f88a189 --- /dev/null +++ b/tests/components/ct-solid/src/components/MultipleChildren.tsx @@ -0,0 +1,17 @@ +type MultipleChildrenProps = { + children?: [any, any, any]; +} + +export default function MultipleChildren(props: MultipleChildrenProps) { + return
+
+ {props.children?.at(0)} +
+
+ {props.children?.at(1)} +
+ +
+} diff --git a/tests/components/ct-solid/src/tests.spec.tsx b/tests/components/ct-solid/src/tests.spec.tsx index 24dc0f67cc..00804374f3 100644 --- a/tests/components/ct-solid/src/tests.spec.tsx +++ b/tests/components/ct-solid/src/tests.spec.tsx @@ -1,6 +1,7 @@ -import { test, expect } from '@playwright/experimental-ct-solid' +import { test, expect } from '@playwright/experimental-ct-solid'; import Button from './components/Button'; import DefaultChildren from './components/DefaultChildren'; +import MultipleChildren from './components/MultipleChildren'; import MultiRoot from './components/MultiRoot'; import EmptyFragment from './components/EmptyFragment'; @@ -12,46 +13,86 @@ test('render props', async ({ mount }) => { }); test('execute callback when the button is clicked', async ({ mount }) => { - const messages: string[] = [] - const component = await mount() - await component.click() - expect(messages).toEqual(['hello']) -}) + const messages: string[] = []; + const component = await mount( +