ci(editor): enable cross platform test (#11566)

This commit is contained in:
Saul-Mirone
2025-04-10 16:52:15 +00:00
parent 823bf40a57
commit a2f879066f
3 changed files with 190 additions and 112 deletions

View File

@@ -218,7 +218,43 @@ jobs:
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: test-results-e2e-legacy-bs-${{ matrix.shard }} name: test-results-e2e-bs-${{ matrix.shard }}
path: ./test-results
if-no-files-found: ignore
e2e-blocksuite-cross-browser-test:
name: E2E BlockSuite Cross Browser Test
runs-on: ubuntu-latest
needs: optimize_ci
if: needs.optimize_ci.outputs.skip == 'false'
strategy:
fail-fast: false
matrix:
shard: [1, 2]
browser: ['chromium', 'firefox', 'webkit']
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
playwright-install: true
playwright-platform: ${{ matrix.browser }}
electron-install: false
full-cache: true
- name: Run playground build
run: yarn workspace @blocksuite/playground build
- name: Run playwright tests
env:
BROWSER: ${{ matrix.browser }}
run: yarn workspace @affine-test/blocksuite test "inline-editor.spec.ts" --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-e2e-bs-cross-browser-${{ matrix.browser }}-${{ matrix.shard }}
path: ./test-results path: ./test-results
if-no-files-found: ignore if-no-files-found: ignore
@@ -1141,6 +1177,7 @@ jobs:
- check-yarn-binary - check-yarn-binary
- e2e-test - e2e-test
- e2e-blocksuite-test - e2e-blocksuite-test
- e2e-blocksuite-cross-browser-test
- e2e-mobile-test - e2e-mobile-test
- unit-test - unit-test
- build-native - build-native

View File

@@ -227,6 +227,13 @@ export class CustomToolbar extends ShadowlessElement {
} }
`; `;
override connectedCallback() {
super.connectedCallback();
this.addEventListener('pointerdown', e => {
e.preventDefault();
});
}
override firstUpdated() { override firstUpdated() {
const boldButton = this.querySelector('.bold'); const boldButton = this.querySelector('.bold');
const italicButton = this.querySelector('.italic'); const italicButton = this.querySelector('.italic');

View File

@@ -2,7 +2,13 @@ import type { InlineEditor, InlineRange } from '@blocksuite/affine/std/inline';
import type { DeltaInsert } from '@blocksuite/affine/store'; import type { DeltaInsert } from '@blocksuite/affine/store';
import { expect, type Page, test } from '@playwright/test'; import { expect, type Page, test } from '@playwright/test';
import { pressArrowLeft, pressEnter } from '../utils/actions/keyboard.js'; import { press } from '../database/actions.js';
import {
pressArrowLeft,
pressBackspace,
pressEnter,
type,
} from '../utils/actions/keyboard.js';
import { import {
enterPlaygroundRoom, enterPlaygroundRoom,
focusRichText, focusRichText,
@@ -15,15 +21,6 @@ const defaultPlaygroundURL = new URL(
`http://localhost:${process.env.CI ? 4173 : 5173}/` `http://localhost:${process.env.CI ? 4173 : 5173}/`
); );
async function type(page: Page, content: string) {
await page.keyboard.type(content, { delay: 50 });
}
async function press(page: Page, content: string) {
await page.keyboard.press(content, { delay: 50 });
await page.waitForTimeout(50);
}
async function enterInlineEditorPlayground(page: Page) { async function enterInlineEditorPlayground(page: Page) {
const url = new URL('examples/inline/index.html', defaultPlaygroundURL); const url = new URL('examples/inline/index.html', defaultPlaygroundURL);
await page.goto(url.toString()); await page.goto(url.toString());
@@ -158,7 +155,7 @@ async function assertSelection(
expect(actual).toEqual({ index: rangeIndex, length: rangeLength }); expect(actual).toEqual({ index: rangeIndex, length: rangeLength });
} }
test('basic input', async ({ page }) => { test('basic input', async ({ page, browserName }) => {
await enterInlineEditorPlayground(page); await enterInlineEditorPlayground(page);
await focusInlineRichText(page); await focusInlineRichText(page);
@@ -168,43 +165,43 @@ test('basic input', async ({ page }) => {
const editorAUndo = page.getByText('undo').nth(0); const editorAUndo = page.getByText('undo').nth(0);
const editorARedo = page.getByText('redo').nth(0); const editorARedo = page.getByText('redo').nth(0);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abcd😃efg👨👨👧👦hj'); await type(page, 'abcd😃efg👨👨👧👦hj');
expect(await editorA.innerText()).toBe('abcd😃efg👨👨👧👦hj'); await expect(editorA).toHaveText('abcd😃efg👨👨👧👦hj');
expect(await editorB.innerText()).toBe('abcd😃efg👨👨👧👦hj'); await expect(editorB).toHaveText('abcd😃efg👨👨👧👦hj');
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abcd😃efg👨👨👧👦hj'); await expect(editorA).toHaveText('abcd😃efg👨👨👧👦hj');
expect(await editorB.innerText()).toBe('abcd😃efg👨👨👧👦hj'); await expect(editorB).toHaveText('abcd😃efg👨👨👧👦hj');
await focusInlineRichText(page); await focusInlineRichText(page);
await press(page, 'Backspace'); await pressBackspace(page, 2); // remove j and h
await press(page, 'Backspace'); // see https://github.com/microsoft/vscode/issues/99629#issuecomment-831565509
await press(page, 'Backspace'); await pressBackspace(page, browserName === 'firefox' ? 5 : 1);
expect(await editorA.innerText()).toBe('abcd😃efg'); await expect(editorA).toHaveText('abcd😃efg');
expect(await editorB.innerText()).toBe('abcd😃efg'); await expect(editorB).toHaveText('abcd😃efg');
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe('abcd😃efg👨👨👧👦hj'); await expect(editorA).toHaveText('abcd😃efg👨👨👧👦hj');
expect(await editorB.innerText()).toBe('abcd😃efg👨👨👧👦hj'); await expect(editorB).toHaveText('abcd😃efg👨👨👧👦hj');
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abcd😃efg'); await expect(editorA).toHaveText('abcd😃efg');
expect(await editorB.innerText()).toBe('abcd😃efg'); await expect(editorB).toHaveText('abcd😃efg');
await focusInlineRichText(page); await focusInlineRichText(page);
await press(page, 'ArrowLeft'); await press(page, 'ArrowLeft');
@@ -216,8 +213,8 @@ test('basic input', async ({ page }) => {
await press(page, 'Delete'); await press(page, 'Delete');
await type(page, '🥰👨‍👨‍👧‍👦'); await type(page, '🥰👨‍👨‍👧‍👦');
expect(await editorA.innerText()).toBe('abc🥰👨👨👧👦efg'); await expect(editorA).toHaveText('abc🥰👨👨👧👦efg');
expect(await editorB.innerText()).toBe('abc🥰👨👨👧👦efg'); await expect(editorB).toHaveText('abc🥰👨👨👧👦efg');
await setInlineRichTextRange(page, { await setInlineRichTextRange(page, {
index: 3, index: 3,
@@ -226,18 +223,18 @@ test('basic input', async ({ page }) => {
await page.waitForTimeout(100); await page.waitForTimeout(100);
await press(page, 'Delete'); await press(page, 'Delete');
expect(await editorA.innerText()).toBe('abc'); await expect(editorA).toHaveText('abc');
expect(await editorA.innerText()).toBe('abc'); await expect(editorB).toHaveText('abc');
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe('abcd😃efg'); await expect(editorA).toHaveText('abcd😃efg');
expect(await editorB.innerText()).toBe('abcd😃efg'); await expect(editorB).toHaveText('abcd😃efg');
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abc'); await expect(editorA).toHaveText('abc');
expect(await editorB.innerText()).toBe('abc'); await expect(editorB).toHaveText('abc');
await focusInlineRichText(page); await focusInlineRichText(page);
await page.waitForTimeout(100); await page.waitForTimeout(100);
@@ -247,38 +244,47 @@ test('basic input', async ({ page }) => {
await page.waitForTimeout(100); await page.waitForTimeout(100);
expect(await editorA.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nbbb'); await expect(editorA).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nbbb', {
expect(await editorB.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nbbb'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nbbb', {
useInnerText: true, // for multi-line text
});
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe('abc'); await expect(editorA).toHaveText('abc');
expect(await editorB.innerText()).toBe('abc'); await expect(editorB).toHaveText('abc');
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nbbb'); await expect(editorA).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nbbb', {
expect(await editorB.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nbbb'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nbbb', {
useInnerText: true, // for multi-line text
});
await focusInlineRichText(page); await focusInlineRichText(page);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await press(page, 'Backspace'); await pressBackspace(page, 5);
await press(page, 'Backspace');
await press(page, 'Backspace');
await press(page, 'Backspace');
await press(page, 'Backspace');
expect(await editorA.innerText()).toBe('abc'); await expect(editorA).toHaveText('abc');
expect(await editorB.innerText()).toBe('abc'); await expect(editorB).toHaveText('abc');
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nbbb'); await expect(editorA).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nbbb', {
expect(await editorB.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nbbb'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nbbb', {
useInnerText: true, // for multi-line text
});
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abc'); await expect(editorA).toHaveText('abc');
await expect(editorB).toHaveText('abc');
await focusInlineRichText(page); await focusInlineRichText(page);
await page.waitForTimeout(100); await page.waitForTimeout(100);
@@ -289,17 +295,17 @@ test('basic input', async ({ page }) => {
await press(page, 'ArrowRight'); await press(page, 'ArrowRight');
await type(page, 'dd'); await type(page, 'dd');
expect(await editorA.innerText()).toBe('abbbcdd'); await expect(editorA).toHaveText('abbbcdd');
expect(await editorB.innerText()).toBe('abbbcdd'); await expect(editorB).toHaveText('abbbcdd');
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe('abc'); await expect(editorA).toHaveText('abc');
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abbbcdd'); await expect(editorA).toHaveText('abbbcdd');
expect(await editorB.innerText()).toBe('abbbcdd'); await expect(editorB).toHaveText('abbbcdd');
await focusInlineRichText(page); await focusInlineRichText(page);
await page.waitForTimeout(100); await page.waitForTimeout(100);
@@ -308,29 +314,42 @@ test('basic input', async ({ page }) => {
await press(page, 'Enter'); await press(page, 'Enter');
await press(page, 'Enter'); await press(page, 'Enter');
expect(await editorA.innerText()).toBe('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd'); await expect(editorA).toHaveText('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd', {
expect(await editorB.innerText()).toBe('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd', {
useInnerText: true, // for multi-line text
});
await editorAUndo.click(); await editorAUndo.click();
expect(await editorA.innerText()).toBe('abbbcdd'); await expect(editorA).toHaveText('abbbcdd');
expect(await editorB.innerText()).toBe('abbbcdd'); await expect(editorB).toHaveText('abbbcdd');
await editorARedo.click(); await editorARedo.click();
expect(await editorA.innerText()).toBe('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd'); await expect(editorA).toHaveText('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd', {
expect(await editorB.innerText()).toBe('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abbbc\n' + ZERO_WIDTH_SPACE + '\ndd', {
useInnerText: true, // for multi-line text
});
}); });
test('chinese input', async ({ page }) => { test('chinese input', async ({ page, browserName }) => {
test.skip(
browserName !== 'chromium',
'CDPSession is only supported in chromium'
);
await enterInlineEditorPlayground(page); await enterInlineEditorPlayground(page);
await focusInlineRichText(page); await focusInlineRichText(page);
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorB = page.locator('[data-v-root="true"]').nth(1); const editorB = page.locator('[data-v-root="true"]').nth(1);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
const client = await page.context().newCDPSession(page); const client = await page.context().newCDPSession(page);
@@ -347,8 +366,8 @@ test('chinese input', async ({ page }) => {
await client.send('Input.insertText', { await client.send('Input.insertText', {
text: '你', text: '你',
}); });
expect(await editorA.innerText()).toBe('你'); await expect(editorA).toHaveText('你');
expect(await editorB.innerText()).toBe('你'); await expect(editorB).toHaveText('你');
}); });
test('type many times in one moment', async ({ page }) => { test('type many times in one moment', async ({ page }) => {
@@ -377,15 +396,15 @@ test('readonly mode', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorB = page.locator('[data-v-root="true"]').nth(1); const editorB = page.locator('[data-v-root="true"]').nth(1);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abcdefg'); await type(page, 'abcdefg');
expect(await editorA.innerText()).toBe('abcdefg'); await expect(editorA).toHaveText('abcdefg');
expect(await editorB.innerText()).toBe('abcdefg'); await expect(editorB).toHaveText('abcdefg');
await page.evaluate(() => { await page.evaluate(() => {
const richTextA = document const richTextA = document
@@ -402,8 +421,8 @@ test('readonly mode', async ({ page }) => {
await type(page, 'aaaa'); await type(page, 'aaaa');
expect(await editorA.innerText()).toBe('abcdefg'); await expect(editorA).toHaveText('abcdefg');
expect(await editorB.innerText()).toBe('abcdefg'); await expect(editorB).toHaveText('abcdefg');
}); });
test('basic styles', async ({ page }) => { test('basic styles', async ({ page }) => {
@@ -422,18 +441,18 @@ test('basic styles', async ({ page }) => {
const editorAUndo = page.getByText('undo').nth(0); const editorAUndo = page.getByText('undo').nth(0);
const editorARedo = page.getByText('redo').nth(0); const editorARedo = page.getByText('redo').nth(0);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abcdefg'); await type(page, 'abcdefg');
expect(await editorA.innerText()).toBe('abcdefg'); await expect(editorA).toHaveText('abcdefg');
expect(await editorB.innerText()).toBe('abcdefg'); await expect(editorB).toHaveText('abcdefg');
let delta = await getDeltaFromInlineRichText(page); let delta = await getDeltaFromInlineRichText(page);
expect(delta).toEqual([ await expect(delta).toEqual([
{ {
insert: 'abcdefg', insert: 'abcdefg',
}, },
@@ -677,15 +696,15 @@ test('overlapping styles', async ({ page }) => {
const editorAUndo = page.getByText('undo').nth(0); const editorAUndo = page.getByText('undo').nth(0);
const editorARedo = page.getByText('redo').nth(0); const editorARedo = page.getByText('redo').nth(0);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abcdefghijk'); await type(page, 'abcdefghijk');
expect(await editorA.innerText()).toBe('abcdefghijk'); await expect(editorA).toHaveText('abcdefghijk');
expect(await editorB.innerText()).toBe('abcdefghijk'); await expect(editorB).toHaveText('abcdefghijk');
let delta = await getDeltaFromInlineRichText(page); let delta = await getDeltaFromInlineRichText(page);
expect(delta).toEqual([ expect(delta).toEqual([
@@ -849,15 +868,15 @@ test('input continuous spaces', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorB = page.locator('[data-v-root="true"]').nth(1); const editorB = page.locator('[data-v-root="true"]').nth(1);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abc def'); await type(page, 'abc def');
expect(await editorA.innerText()).toBe('abc def'); await expect(editorA).toHaveText('abc def');
expect(await editorB.innerText()).toBe('abc def'); await expect(editorB).toHaveText('abc def');
await focusInlineRichText(page); await focusInlineRichText(page);
await page.waitForTimeout(100); await page.waitForTimeout(100);
@@ -868,8 +887,12 @@ test('input continuous spaces', async ({ page }) => {
await press(page, 'Enter'); await press(page, 'Enter');
expect(await editorA.innerText()).toBe('abc \n' + ' def'); await expect(editorA).toHaveText('abc \n' + ' def', {
expect(await editorB.innerText()).toBe('abc \n' + ' def'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abc \n' + ' def', {
useInnerText: true, // for multi-line text
});
}); });
test('select from the start of line using shift+arrow', async ({ page }) => { test('select from the start of line using shift+arrow', async ({ page }) => {
@@ -879,8 +902,8 @@ test('select from the start of line using shift+arrow', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorB = page.locator('[data-v-root="true"]').nth(1); const editorB = page.locator('[data-v-root="true"]').nth(1);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
@@ -890,8 +913,12 @@ test('select from the start of line using shift+arrow', async ({ page }) => {
await press(page, 'Enter'); await press(page, 'Enter');
await type(page, 'ghi'); await type(page, 'ghi');
expect(await editorA.innerText()).toBe('abc\ndef\nghi'); await expect(editorB).toHaveText('abc\ndef\nghi', {
expect(await editorB.innerText()).toBe('abc\ndef\nghi'); useInnerText: true, // for multi-line text
});
await expect(editorA).toHaveText('abc\ndef\nghi', {
useInnerText: true, // for multi-line text
});
/** /**
* abc * abc
@@ -920,11 +947,11 @@ test('select from the start of line using shift+arrow', async ({ page }) => {
*/ */
await press(page, 'ArrowRight'); await press(page, 'ArrowRight');
await assertSelection(page, 0, 1, 7); await assertSelection(page, 0, 1, 7);
await press(page, 'Backspace'); await pressBackspace(page);
await page.waitForTimeout(100); await page.waitForTimeout(100);
expect(await editorA.innerText()).toBe('aghi'); await expect(editorA).toHaveText('aghi');
expect(await editorB.innerText()).toBe('aghi'); await expect(editorB).toHaveText('aghi');
}); });
test('getLine', async ({ page }) => { test('getLine', async ({ page }) => {
@@ -934,15 +961,19 @@ test('getLine', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorB = page.locator('[data-v-root="true"]').nth(1); const editorB = page.locator('[data-v-root="true"]').nth(1);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorB.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorB).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abc\ndef\nghi'); await type(page, 'abc\ndef\nghi');
expect(await editorA.innerText()).toBe('abc\ndef\nghi'); await expect(editorA).toHaveText('abc\ndef\nghi', {
expect(await editorB.innerText()).toBe('abc\ndef\nghi'); useInnerText: true, // for multi-line text
});
await expect(editorB).toHaveText('abc\ndef\nghi', {
useInnerText: true, // for multi-line text
});
const [line1, offset1] = await getInlineRichTextLine(page, 0); const [line1, offset1] = await getInlineRichTextLine(page, 0);
const [line2, offset2] = await getInlineRichTextLine(page, 1); const [line2, offset2] = await getInlineRichTextLine(page, 1);
@@ -1001,14 +1032,13 @@ test('embed', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorAEmbed = page.getByText('embed').nth(0); const editorAEmbed = page.getByText('embed').nth(0);
await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abcde'); await type(page, 'abcde');
expect(await editorA.innerText()).toBe('abcde'); await expect(editorA).toHaveText('abcde');
await press(page, 'ArrowLeft'); await press(page, 'ArrowLeft');
await page.waitForTimeout(100); await page.waitForTimeout(100);
@@ -1022,7 +1052,7 @@ test('embed', async ({ page }) => {
await editorAEmbed.click(); await editorAEmbed.click();
const embedCount = await page.locator('[data-v-embed="true"]').count(); const embedCount = await page.locator('[data-v-embed="true"]').count();
expect(embedCount).toBe(3); await expect(embedCount).toBe(3);
// try to update cursor position using arrow keys // try to update cursor position using arrow keys
await assertSelection(page, 0, 1, 3); await assertSelection(page, 0, 1, 3);
@@ -1071,10 +1101,10 @@ test('delete embed when pressing backspace after embed', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
const editorAEmbed = page.getByText('embed').nth(0); const editorAEmbed = page.getByText('embed').nth(0);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'ab'); await type(page, 'ab');
expect(await editorA.innerText()).toBe('ab'); await expect(editorA).toHaveText('ab');
await page.keyboard.down('Shift'); await page.keyboard.down('Shift');
await press(page, 'ArrowLeft'); await press(page, 'ArrowLeft');
@@ -1100,7 +1130,7 @@ test('delete embed when pressing backspace after embed', async ({ page }) => {
// use click to select right side of the embed instead of use arrow key // use click to select right side of the embed instead of use arrow key
await page.mouse.click(rect.x + 3, rect.y); await page.mouse.click(rect.x + 3, rect.y);
await assertSelection(page, 0, 2, 0); await assertSelection(page, 0, 2, 0);
await press(page, 'Backspace'); await pressBackspace(page);
delta = await getDeltaFromInlineRichText(page); delta = await getDeltaFromInlineRichText(page);
expect(delta).toEqual([ expect(delta).toEqual([
@@ -1116,11 +1146,13 @@ test('triple click to select line', async ({ page }) => {
const editorA = page.locator('[data-v-root="true"]').nth(0); const editorA = page.locator('[data-v-root="true"]').nth(0);
expect(await editorA.innerText()).toBe(ZERO_WIDTH_SPACE); await expect(editorA).toHaveText(ZERO_WIDTH_SPACE);
await page.waitForTimeout(100); await page.waitForTimeout(100);
await type(page, 'abc\nabc abc abc\nabc'); await type(page, 'abc\nabc abc abc\nabc');
expect(await editorA.innerText()).toBe('abc\nabc abc abc\nabc'); await expect(editorA).toHaveText('abc\nabc abc abc\nabc', {
useInnerText: true, // for multi-line text
});
const rect = await getInlineRangeIndexRect(page, [0, 10]); const rect = await getInlineRangeIndexRect(page, [0, 10]);
await page.mouse.click(rect.x, rect.y, { await page.mouse.click(rect.x, rect.y, {
@@ -1128,8 +1160,10 @@ test('triple click to select line', async ({ page }) => {
}); });
await assertSelection(page, 0, 4, 11); await assertSelection(page, 0, 4, 11);
await press(page, 'Backspace'); await pressBackspace(page);
expect(await editorA.innerText()).toBe('abc\n' + ZERO_WIDTH_SPACE + '\nabc'); await expect(editorA).toHaveText('abc\n' + ZERO_WIDTH_SPACE + '\nabc', {
useInnerText: true, // for multi-line text
});
}); });
test('caret should move correctly when inline elements are exist', async ({ test('caret should move correctly when inline elements are exist', async ({