docs/solutions/developer-experience/2026-05-07-slate-browser-ime-proof-rows-need-honest-dom-composition.md
The Mobile/IME proof lane needed a row for composition inside marked text. Using Chromium CDP IME as the oracle for a mid-leaf mark boundary looked close, but it was not honest for this harness.
Input.imeSetComposition commit at
the end of bold rich, producing richすし instead of riすしch.replacementStart / replacementEnd experiment inserted after Th,
proving the offsets were not the Slate leaf offsets the test needed.packages/slate-browser/src/playwright/ime.ts did not change
Playwright behavior until packages/slate-browser was rebuilt, because tests
import slate-browser/playwright from dist.editor.selection.select(...) as enough for native CDP IME.editor.selection.selectDOM(...) as enough for native CDP IME.slate-browser source and rerunning Playwright without rebuilding
the package.For the mark-boundary row, use the same proof shape as ProseMirror's
webtest-composition.ts: set a real DOM range in the marked text node, dispatch
composition events, mutate the captured range, then let Slate import the DOM
change.
The landed row asserts the actual Slate contract:
rich at offset 2 produces riすしchWhen changing reusable slate-browser helpers, rebuild before expecting
Playwright to see the edit:
cd /Users/zbeyens/git/slate-v2/packages/slate-browser
bun run build
The proof row is about Slate importing a browser-owned composition mutation without corrupting marks or selection. A direct DOM composition mutation proves that contract. CDP IME is still useful for end-of-text native composition and trace rows, but this harness did not provide reliable mid-mark replacement semantics through CDP offsets.
slate-browser/playwright, remember it is using
built package output.