Problem
In e2e tests, Playwright's fill() and pressSequentially() set the DOM textarea value but do NOT update Svelte 5's $state variable bound via bind:value. This means sendMessage() reads an empty string from the state variable even though the textarea visually contains text.
Reproduction
Component:
<script lang="ts">
let messageInput = $state("");
function sendMessage() {
console.log(messageInput); // Always "" after fill()
}
</script>
<textarea bind:value={messageInput}></textarea>
<button onclick={sendMessage}>Send</button>
Test:
await textarea.fill("Hello");
await page.locator("button").click();
// sendMessage logs "" instead of "Hello"
Root cause
Svelte 5 uses event delegation — bind:value handlers are attached at the document root, not directly on the element. Playwright's synthetic events may not properly trigger this delegation chain.
Workaround
Use bind:this to get a DOM ref and read .value directly:
let textareaEl: HTMLTextAreaElement | undefined = $state();
function sendMessage() {
const msg = (textareaEl?.value ?? messageInput).trim();
// ...
}
<textarea bind:this={textareaEl} bind:value={messageInput} />
Affected tests
e2e/specs/companion-mode.spec.ts — "companion channel accepts message input"
Problem
In e2e tests, Playwright's
fill()andpressSequentially()set the DOM textarea value but do NOT update Svelte 5's$statevariable bound viabind:value. This meanssendMessage()reads an empty string from the state variable even though the textarea visually contains text.Reproduction
Component:
Test:
Root cause
Svelte 5 uses event delegation —
bind:valuehandlers are attached at the document root, not directly on the element. Playwright's synthetic events may not properly trigger this delegation chain.Workaround
Use
bind:thisto get a DOM ref and read.valuedirectly:let textareaEl: HTMLTextAreaElement | undefined = $state(); function sendMessage() { const msg = (textareaEl?.value ?? messageInput).trim(); // ... } <textarea bind:this={textareaEl} bind:value={messageInput} />Affected tests
e2e/specs/companion-mode.spec.ts— "companion channel accepts message input"