From f335c7db61c4cde4d3f8fd30813ab834c673997f Mon Sep 17 00:00:00 2001 From: robonen Date: Mon, 8 Jun 2026 17:20:40 +0700 Subject: [PATCH] test(editor): wait for async selectionchange in cross-block selection test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit selectionchange is dispatched on a macrotask, so awaiting nextTick (microtasks) didn't wait for the editor to sync the native selection into the model — the assertion saw the initial selection. Poll with vi.waitFor instead. (Surfaced now that per-package CI runs editor's browser tests, which the root vitest projects list omitted.) --- .../src/view/__test__/editor.browser.test.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/vue/editor/src/view/__test__/editor.browser.test.ts b/vue/editor/src/view/__test__/editor.browser.test.ts index 1ac96d9..d01e865 100644 --- a/vue/editor/src/view/__test__/editor.browser.test.ts +++ b/vue/editor/src/view/__test__/editor.browser.test.ts @@ -1,5 +1,5 @@ import { render } from 'vitest-browser-vue'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { nextTick } from 'vue'; import { createDoc, createNode, textSelection } from '../../model'; import { createDefaultRegistry } from '../../preset'; @@ -49,17 +49,20 @@ describe('EditorRoot (single contenteditable)', () => { const bText = hosts[1]!.firstChild!; // text node "world" selectNative({ node: aText, offset: 1 }, { node: bText, offset: 3 }); - await nextTick(); - await nextTick(); - const sel = editor.state.selection; - expect(sel.kind).toBe('text'); - if (sel.kind === 'text') { - expect(sel.anchor.blockId).toBe('a'); - expect(sel.anchor.offset).toBe(1); - expect(sel.focus.blockId).toBe('b'); - expect(sel.focus.offset).toBe(3); - } + // `selectionchange` is dispatched on a macrotask, so awaiting microtasks + // (nextTick) isn't enough — poll until the editor has synced the model. + const sel = await vi.waitFor(() => { + const s = editor.state.selection; + if (s.kind !== 'text' || s.anchor.offset !== 1) + throw new Error('selection not synced yet'); + return s; + }); + + expect(sel.anchor.blockId).toBe('a'); + expect(sel.anchor.offset).toBe(1); + expect(sel.focus.blockId).toBe('b'); + expect(sel.focus.offset).toBe(3); }); it('writes a cross-block model selection back to a native range spanning blocks', async () => {