diff --git a/packages/playwright-ct-vue2/registerSource.mjs b/packages/playwright-ct-vue2/registerSource.mjs index f4ef0ee68c..c27981d8e5 100644 --- a/packages/playwright-ct-vue2/registerSource.mjs +++ b/packages/playwright-ct-vue2/registerSource.mjs @@ -42,6 +42,20 @@ function createChild(child, h) { return typeof child === 'string' ? child : createWrapper(child, h); } +/** + * Exists to support fallthrough attributes: + * https://vuejs.org/guide/components/attrs.html#fallthrough-attributes + * @param {any} Component + * @param {string} key + * @return {boolean} + */ +function componentHasKeyInProps(Component, key) { + if (Array.isArray(Component.props)) + return Component.props.includes(key); + + return Object.entries(Component.props).flat().includes(key); +} + /** * @param {Component} component * @param {import('vue').CreateElement} h @@ -96,7 +110,7 @@ function createComponent(component, h) { const event = key.substring('v-on:'.length); nodeData.on[event] = value; } else { - if (isVueComponent) + if (isVueComponent && componentHasKeyInProps(componentFunc, key)) nodeData.props[key] = value; else nodeData.attrs[key] = value; diff --git a/tests/components/ct-react-vite/index.html b/tests/components/ct-react-vite/index.html index 38f3861103..cf3a13303c 100644 --- a/tests/components/ct-react-vite/index.html +++ b/tests/components/ct-react-vite/index.html @@ -2,7 +2,7 @@ - + Vite App diff --git a/tests/components/ct-react-vite/src/App.tsx b/tests/components/ct-react-vite/src/App.tsx index 1a5c71390f..8a1bf0f964 100644 --- a/tests/components/ct-react-vite/src/App.tsx +++ b/tests/components/ct-react-vite/src/App.tsx @@ -1,5 +1,5 @@ import { useState } from 'react' -import logo from './components/logo.svg' +import logo from './assets/logo.svg' import './App.css' function App() { diff --git a/tests/components/ct-react-vite/src/components/Button.tsx b/tests/components/ct-react-vite/src/components/Button.tsx index 78b0a7791f..2b44784ac4 100644 --- a/tests/components/ct-react-vite/src/components/Button.tsx +++ b/tests/components/ct-react-vite/src/components/Button.tsx @@ -1,7 +1,13 @@ +import { ButtonHTMLAttributes } from "react"; + type ButtonProps = { title: string; onClick?(props: string): void; -} -export default function Button(props: ButtonProps) { - return + className?: string; +} & ButtonHTMLAttributes; + +export default function Button({ onClick, title, ...attributes }: ButtonProps) { + return } diff --git a/tests/components/ct-react-vite/src/tests.spec.tsx b/tests/components/ct-react-vite/src/tests.spec.tsx index 38b525ada1..987dcf5ed1 100644 --- a/tests/components/ct-react-vite/src/tests.spec.tsx +++ b/tests/components/ct-react-vite/src/tests.spec.tsx @@ -13,6 +13,11 @@ test('render props', async ({ mount }) => { await expect(component).toContainText('Submit'); }); +test('render attributes', async ({ mount }) => { + const component = await mount( + className?: string; +} & ButtonHTMLAttributes; + +export default function Button({ onClick, title, ...attributes }: ButtonProps) { + return } diff --git a/tests/components/ct-react/src/tests.spec.tsx b/tests/components/ct-react/src/tests.spec.tsx index 5a79c245c8..049581ac62 100644 --- a/tests/components/ct-react/src/tests.spec.tsx +++ b/tests/components/ct-react/src/tests.spec.tsx @@ -16,6 +16,11 @@ test('render props', async ({ mount }) => { await expect(component).toContainText('Submit'); }); +test('render attributes', async ({ mount }) => { + const component = await mount( + className?: string; +} & JSX.ButtonHTMLAttributes; + +export default function Button({ onClick, title, ...attributes }: ButtonProps) { + return } diff --git a/tests/components/ct-solid/src/tests.spec.tsx b/tests/components/ct-solid/src/tests.spec.tsx index 00804374f3..3542e3ef7b 100644 --- a/tests/components/ct-solid/src/tests.spec.tsx +++ b/tests/components/ct-solid/src/tests.spec.tsx @@ -12,6 +12,11 @@ test('render props', async ({ mount }) => { await expect(component).toContainText('Submit'); }); +test('render attributes', async ({ mount }) => { + const component = await mount(