docs/solutions/test-failures/2026-05-18-slate-read-only-selection-tests-need-selector-owned-dom-selection.md
A two-pane Slate example made the public comment pane read-only, while the document pane stayed editable. The browser test used the shared example harness to select text, but that helper targeted the contenteditable document pane.
Add comment on selection stayed disabled until the test timed out.#review-comments-selection showed selection:none.selection:0.0:0|0.0:24, proving the helper selected
the wrong editor.editor.selection.select(...) to
editor.selection.selectDOM(...).
The helper still starts from the harness root, and the harness root resolves
to the editable surface, not the read-only viewer.For read-only panes, select through the pane's own DOM selector and dispatch
selectionchange from that document.
await page.locator('#review-comments').evaluate((root) => {
const document = root.ownerDocument
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)
const textNode = walker.nextNode()
if (!textNode?.textContent) {
throw new Error('Comment text node was not found')
}
const range = document.createRange()
range.setStart(textNode, 0)
range.setEnd(textNode, 24)
const selection = document.defaultView?.getSelection()
if (!selection) {
throw new Error('Window selection is unavailable')
}
selection.removeAllRanges()
selection.addRange(range)
document.dispatchEvent(new Event('selectionchange'))
})
For stress rows that only need comment data, seed the comment through the example control instead of pretending selection transport is part of the overlay contract.
{
kind: 'clickSelector',
label: 'seed-review-comment',
selector: 'button:has-text("Seed example comment")',
}
openExample(...).selection.selectDOM(...) is a good default for editable
examples because the harness owns a contenteditable root. A read-only pane is
not contenteditable, so the test has to identify the exact viewer DOM before it
can prove that Slate imports the browser selection for that viewer.
Splitting stress setup from read-only selection also keeps the test honest: one integration row proves selecting in the read-only pane, and the stress rows focus on annotation and widget invalidation.