In the below code formEl is mounted in normal mode and inside portal, playwright can access when its mounted normal mode, but its unable to in portal mode.
function App() {
const [todos, setTodos] = useState<Todo[]>([{id: 1, title: "Buy Milk"}])
const [formMode, setFormMode] = useState<"portal" | 'normal' | 'none'>('none')
const formEl = <div className={'form'}>
<form onSubmit={e => {
e.preventDefault()
setFormMode('none')
const data = e.currentTarget.elements.todo.value;
setTodos(prevVal => [...prevVal, {id: Date.now(), title: data}])
}}>
<input name={'todo'} placeholder={'Enter Todo'}/>
<button type={'submit'}>Submit</button>
</form>
</div>;
return (
<div>
<div className={'btn-group'}>
<button onClick={() => setFormMode('portal')}>Add Todo via Portal</button>
<button onClick={() => setFormMode('normal')}>Add Todo Normal Mode</button>
</div>
<div className={'todos'}>
{todos.map((todo) => (<div className={'todo-item'} key={todo.id}>
{todo.title}
</div>))}
</div>
{formMode === 'portal' && createPortal(
formEl,
document.body
)}
{formMode === 'normal' && formEl}
</div>
)
}
Test Code
test('normal mode', async ({ mount }) => {
const component = await mount(<App />);
await component.getByRole('button', { name: 'Add Todo Normal Mode' }).click();
await expect(component.getByPlaceholder('Enter Todo')).toBeVisible()
await component.getByPlaceholder('Enter Todo').fill("Learn Playwright")
await component.getByRole('button', {name: 'submit'}).click()
await expect(component.getByText("Learn Playwright")).toBeVisible()
});
test('portal mode', async ({ mount }) => {
const component = await mount(<App />);
await component.getByRole('button', { name: 'Add Todo via Portal' }).click();
await expect(component.getByPlaceholder('Enter Todo')).toBeVisible()
await component.getByPlaceholder('Enter Todo').fill("Learn Playwright")
await component.getByRole('button', {name: 'submit'}).click()
await expect(component.getByText("Learn Playwright")).toBeVisible()
});
You can use the
page.evaluteHandlemethod to get the element handle from inside the browser context: