test(web): settle insertion before selecting composer text

This commit is contained in:
ZiyaZhang committed 2026-10-12 04:41:19 -07:00
1 parent 1d36cd5a3c
commit 5dec056c79
1 file changed
+11 -6
+11 -6
View File
@@ -47,19 +47,24 @@ function describeSelection(state: Awaited<ReturnType<typeof selectionState>>): s
async function exerciseComposer(page: Page): Promise<string[]> {
const input = page.locator('[data-composer-input][contenteditable="true"]')
await input.click()
// DOM selection changes precede Chromium's queued selectionchange event.
// Observe that event before testing restoration of the saved editor selection.
// Let the editor observe its insertText selection before native arrow moves;
// a coalesced first notification can otherwise be treated as its own update.
await input.evaluate((el) => {
const onSelectionChange = (): void => {
const selection = el.ownerDocument.getSelection()
if (selection?.toString() !== 'beta' || selection.anchorOffset !== 10 || selection.focusOffset !== 6
|| !el.contains(selection.anchorNode) || !el.contains(selection.focusNode)) return
el.dataset.selectionReady = 'true'
if (selection === null || !el.contains(selection.anchorNode) || !el.contains(selection.focusNode)) return
if (selection.isCollapsed && selection.anchorOffset === 16 && el.textContent === 'alpha beta gamma') {
el.dataset.selectionReady = 'inserted'
return
}
if (selection.toString() !== 'beta' || selection.anchorOffset !== 10 || selection.focusOffset !== 6) return
el.dataset.selectionReady = 'selected'
el.ownerDocument.removeEventListener('selectionchange', onSelectionChange)
}
el.ownerDocument.addEventListener('selectionchange', onSelectionChange)
})
await page.keyboard.insertText('alpha beta gamma')
await expect.poll(() => input.getAttribute('data-selection-ready')).toBe('inserted')
await page.keyboard.press('Home')
for (let index = 0; index < 10; index++) await page.keyboard.press('ArrowRight')
for (let index = 0; index < 4; index++) await page.keyboard.press('Shift+ArrowLeft')
@@ -88,7 +93,7 @@ async function exerciseComposer(page: Page): Promise<string[]> {
observations.push(`- ${point.name}: ${describeSelection(await selectionState(page))}`)
}
await expect.poll(() => input.getAttribute('data-selection-ready')).toBe('true')
await expect.poll(() => input.getAttribute('data-selection-ready')).toBe('selected')
await input.evaluate((el) => { delete el.dataset.selectionReady })
const top = points[0]!
const cardBox = await page.locator('[data-composer-card]').boundingBox()