Files
AFFiNE-Mirror/tests/blocksuite/e2e/cross-platform/inline/firefox-beforeinput.spec.ts
DarkSky 7d47cc52b6 fix: firefox input (#14315)
fix #14296 
fix #14289

#### PR Dependency Tree


* **PR #14315** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved inline editor stability for selection edge cases and
beforeinput handling, with better recovery and native-input protection.
* Fixed potential crashes when deleting with selections outside the
editor bounds, including Firefox-specific scenarios.

* **Tests**
* Added unit tests covering beforeinput behavior and added Firefox
end-to-end regression tests.

* **Chores**
  * Reduced CI test parallelism to streamline pipeline.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-27 00:54:21 +08:00

88 lines
2.5 KiB
TypeScript

import { expect } from '@playwright/test';
import {
dragBetweenIndices,
enterPlaygroundRoom,
focusRichText,
getIndexCoordinate,
initEmptyParagraphState,
initThreeParagraphs,
pressForwardDelete,
type,
waitNextFrame,
} from '../../utils/actions/index.js';
import { assertRichTexts, assertTextContain } from '../../utils/asserts.js';
import { test } from '../../utils/playwright.js';
test('should not crash when deleting with selection dragged outside note (firefox)', async ({
page,
browserName,
}) => {
test.skip(browserName !== 'firefox', 'Firefox-only regression');
await enterPlaygroundRoom(page);
await initEmptyParagraphState(page);
await initThreeParagraphs(page);
await assertRichTexts(page, ['123', '456', '789']);
const outside = await page.evaluate(() => {
const note = document.querySelector('affine-note');
if (!note) {
throw new Error('affine-note not found');
}
const rect = note.getBoundingClientRect();
return { x: rect.left + rect.width / 2, y: rect.bottom + 50 };
});
// Drag starting from the end of the last paragraph to outside the note.
// Previously Firefox could perform native `contenteditable` deletion here and
// crash Lit updates with `ChildPart has no parentNode`.
await dragBetweenIndices(
page,
[2, 3],
[2, 3],
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{
steps: 20,
async beforeMouseUp() {
await page.mouse.move(outside.x, outside.y);
},
}
);
await pressForwardDelete(page);
await waitNextFrame(page);
await type(page, 'a');
await waitNextFrame(page);
await assertTextContain(page, 'a', 2);
});
test('should not crash when replacing the first word by double click (firefox)', async ({
page,
browserName,
}) => {
test.skip(browserName !== 'firefox', 'Firefox-only regression');
await enterPlaygroundRoom(page);
await initEmptyParagraphState(page);
await focusRichText(page, 0);
await type(page, 'hello world');
await waitNextFrame(page);
const coord = await getIndexCoordinate(page, [0, 1]);
await page.mouse.click(coord.x, coord.y, { clickCount: 2 });
await type(page, 'x');
await waitNextFrame(page);
const text = await page.evaluate(() => {
const editorHost = document.querySelector('editor-host');
const richText = editorHost?.querySelector('rich-text') as any;
return richText?.inlineEditor?.yText?.toString?.() ?? '';
});
expect(text.startsWith('x')).toBe(true);
expect(text.includes('world')).toBe(true);
});