test(web): write folder queries with per-key gestures

Directly after a chip deletion, fill()'s single-task select-all +
insertText lands on a Lexical selection that has not absorbed the DOM
selection yet and is dropped, leaving the previous draft in place. Real
keystrokes leave room for selectionchange between keys, matching what a
user's typing does.
This commit is contained in:
Yichen Jiang 2026-08-25 10:42:40 +08:00
parent 0a247137f0
commit e71688c1fe

View file

@ -110,6 +110,22 @@ function targetSessionFixture(): string {
].join('\n')
}
/**
* Replace the draft through per-key gestures. `fill()` issues select-all and
* insertText inside one task; directly after a chip deletion Lexical's internal
* selection has not yet absorbed the DOM selection, and the batched insertText
* lands on a null selection and is dropped. Real keystrokes leave room for
* `selectionchange` between keys, which is also what a user's typing does.
* @param page - the page under test.
* @param input - the composer surface locator.
* @param text - the replacement draft.
*/
async function writeDraft(page: Page, input: ReturnType<Page['locator']>, text: string): Promise<void> {
await input.click()
await page.keyboard.press('ControlOrMeta+A')
await page.keyboard.type(text)
}
describe.skipIf(MODE === 'record')('web e2e: file and session references through the real host', () => {
let scaffold: WebScaffold
let browser: Browser
@ -248,7 +264,7 @@ describe.skipIf(MODE === 'record')('web e2e: file and session references through
// Settle: Enter on the highlighted folder row resolves the folder itself
// as an atomic chip — folder glyph, no trigger character, one unit.
await input.fill('@folderx')
await writeDraft(page, input, '@folderx')
// First folder query on this page: allow the Host index a cold start.
await menu.getByRole('option', { name: /Folder · folderx\// }).waitFor({ timeout: 60_000 })
await page.keyboard.press('Enter')
@ -259,14 +275,14 @@ describe.skipIf(MODE === 'record')('web e2e: file and session references through
// Tab drills: the literal descent text stays editable and the open menu
// lists the folder's children.
await input.fill('@folderx')
await writeDraft(page, input, '@folderx')
await menu.getByRole('option', { name: /Folder · folderx\// }).waitFor()
await page.keyboard.press('Tab')
await expect.poll(() => input.textContent()).toBe('@folderx/')
await menu.getByRole('option', { name: /File · child\.txt/ }).waitFor()
// The row chevron drills the same way by pointer.
await input.fill('@folderx')
await writeDraft(page, input, '@folderx')
const row = menu.getByRole('option', { name: /Folder · folderx\// })
await row.waitFor()
await row.getByRole('button', { name: 'Browse folder' }).click()