Files
orca/tests/e2e/terminal-ime-preedit-continuity.spec.ts
Neil 85a3ba6d42 fix(terminal): align CJK IME preedit spacing (#19367)
* fix(terminal): align IME preedit to terminal cell grid

* fix(terminal): preserve native shaping and reuse IME preedit on repaint

* fix(terminal): preserve native shaping with bounded IME spacing runs

* test(terminal): account for inline preedit subpixel rounding

* test(terminal): keep the IME grid fixture wide at every DPI

* chore: regenerate xterm patch after rebase

* test(terminal): remove IME assertion lint findings

* test(terminal): avoid reflective IME fixture access

* test(e2e): run IME renderer matrix with WebGL available

* fix(ci): restore editor line budget
2026-09-19 16:44:38 -07:00

74 lines
2.8 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test } from './helpers/orca-app'
import { closeTerminalImePaneArena, openTerminalImePaneArena } from './terminal-ime-pane-arena'
import { setImeComposition } from './terminal-ime-cdp-composition'
import { writeToActiveTerminal } from './terminal-ime-midline-occlusion-probe'
test('keeps the CJK prefix in place across mixed text and the layout budget', async ({
orcaPage
}, testInfo) => {
const arena = await openTerminalImePaneArena(orcaPage)
let completed = false
try {
await orcaPage.evaluate(() => {
const state = window.__store!.getState()
const terminal = window.__paneManagers!.get(state.activeTabId!)!.getActivePane()!.terminal
terminal.options.fontSize = 13
terminal.options.fontFamily = 'monospace'
})
await writeToActiveTerminal(orcaPage, '\x1b[2J\x1b[H')
const prefix = 'あ'.repeat(32)
let initial: number[] | undefined
for (const suffix of [
'',
'a',
'',
'😀',
'سلام',
'क्षि',
' あ',
...[125, 126, 127, 128, 129, 130, 256].map((count) => 'aあ'.repeat(count)),
`${'aあ'.repeat(256)}\u3099`,
'',
'a'
]) {
await setImeComposition(arena.session, prefix + suffix)
const preedit = orcaPage.locator('.composition-view.active .xterm-composition-preedit')
await expect(preedit).toHaveText(`‎${prefix + suffix}‎`)
const sample = await preedit.evaluate((element) => {
const bounds = element.getBoundingClientRect()
const starts: number[] = []
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT)
let node: Node | null
while ((node = walker.nextNode()) && starts.length < 32) {
const text = node.textContent ?? ''
for (let offset = 0; offset < text.length && starts.length < 32; offset++) {
if (text[offset] !== 'あ') {
continue
}
const range = document.createRange()
range.setStart(node, offset)
range.setEnd(node, offset + 1)
starts.push(range.getBoundingClientRect().left - bounds.left)
}
}
const caret = element.parentElement!.querySelector('.xterm-composition-caret')!
return {
starts,
width: bounds.width,
caretRight: caret.getBoundingClientRect().right - bounds.left
}
})
initial ??= sample.starts
expect(sample.starts).toHaveLength(32)
for (const [index, start] of sample.starts.entries()) {
expect(start).toBeCloseTo(initial[index], 1)
}
expect(sample.caretRight).toBeCloseTo(sample.width, 1)
}
await setImeComposition(arena.session, '')
completed = true
} finally {
await closeTerminalImePaneArena(arena, testInfo, 'preedit-continuity', !completed)
}
})