Skip to content

[lexical][lexical-extension][lexical-list][lexical-playground][lexical-selection][lexical-y] Chore: reduce redundant test work - #9530

Draft
etrepum wants to merge 5 commits into
meta:mainfrom
etrepum:codex/test-ci-audit
Draft

etrepum wants to merge 5 commits into
meta:mainfrom
etrepum:codex/test-ci-audit

Conversation

@etrepum

@etrepum etrepum commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator

Description

Reduce test setup and repeated work across the unit, browser and E2E suites.

  • Remove 12 redundant unit checks, including eight mutation cases already exercised by the browser suite with the same fixtures.
  • Correct three copied test inputs found by the duplicate audit; the before-and-after details are below.
  • Move 22 rich-text E2E cases and their plain-text variants into browser mode: character-limit overflow, max-length/paste boundaries, select-all deletion, clipboard/execCommand input and text mutations. Preserve native input, caret, DOM and editor-state assertions. Keep three playground integration checks. The Chromium E2E inventory drops from 687 to 665 cases.
  • Bound newline-splitting arguments explicitly instead of constructing 600,000 nodes to reach a native argument limit. Keep author, peer and fresh-reader content checks; the original stress input remains available with TEXT_NEWLINES_COUNT=300000.
  • Replace wall-clock sampling with a serialization-work bound for follow-ups in 10,000-block documents.
  • Avoid idle simulated-network rounds, reuse an already-checked fresh reader, and avoid repeated JSON snapshots/normalization in the fuzz harness. Preserve all fuzz seeds and delivery schedules.

Three commits separate duplicate cleanup, browser migrations and Yjs test optimization. All changed files are tests or test helpers.

The audit found three tests whose bodies duplicated another case despite having different names. These corrections restore the coverage their names advertised:

Test Previous input Corrected input
LexicalBuilder: peer-first Both peer-first and peer-last passed (ExtensionA, ConfigExtension). peer-first now passes (ConfigExtension, ExtensionA), so the two cases exercise opposite orders.
LexicalNode.insertAfter(): segmented Used setMode('token'), duplicating the token case. Uses setMode('segmented').
ListItemNode.insertNewAfter(): middle list item Inserted after listItemNode3, duplicating the last-item case. Inserts after listItemNode2; the expected DOM places the new item between “two” and “three”.

These three corrections improve coverage accuracy; the runtime savings come from the removals, migrations and harness optimizations.

Test plan

Before

The five original E2E files pass against a development build with the default action delay:

25 passed (16.9s)

They spend 58.24 seconds summed across test attempts.

A controlled single-worker invocation runs both base and updated versions of the three costly unit suites; all 2,312 checks pass:

Suite Base Updated
FollowUpCheckCost 13.751 s 4.357 s
NormalizationConvergence 36.512 s 25.272 s
TextNewlines 34.068 s 2.786 s
Total 84.331 s 32.415 s

These are local suite measurements, not a whole-CI latency claim.

Temporarily disabling batching and forcing whole-container follow-up reads makes the new checks fail for the intended reasons; the implementation was then restored:

AssertionError: expected 20002 to be less than or equal to 12
RangeError: too many splitText arguments
Test Files  2 failed (2)
     Tests  3 failed | 22 skipped (25)

After

  • pnpm run test-unit --maxWorkers=4 --reporter=json: 15,310 successful checks, including 16 expected failures; zero unexpected failures.
  • pnpm run test-browser --maxWorkers=4 --reporter=json: 1,098 Chromium checks pass; zero failures.
  • The five browser migration suites run 52 checks in 5.88 seconds elapsed, 7.05 seconds summed across suites.
  • Retained E2E integration checks pass in both rich and plain modes: 3 passed (3.8s) and 3 passed (3.1s).
  • The migrated cases and retained managed-line-break coverage pass in WebKit. A final mutation-state polling improvement also passes in both Chromium and WebKit.
  • A temporary 60-seed comparison confirms identical findings and metrics from the original and updated fuzz checkpoint logic.
  • TypeScript test checking, ESLint, formatting, package builds and the playground development build pass.

Local engines were Chromium 141 and WebKit 26. WebKit validation used its matching driver without changing repository dependencies. Firefox cannot create its content process in this sandbox; validation against the repository's exact browser revisions and the full platform matrix remains for CI.

…remove redundant unit coverage

## Description

Remove twelve repeated checks: duplicate block-conversion and extension-type assertions, editor-state parsing cases that serialize the same document, and eight jsdom mutation cases already exercised by the browser suite with the same fixtures.

Correct three copied cases to exercise their advertised inputs: peer-first extension ordering, insertion after the middle list item, and segmented text insertion. Keep cases whose identical bodies run against different highlighters, editor modes, or fixtures.

## Test plan

### Before

The baseline unit run passed; these redundant checks do not cause a correctness failure. The source audit compared parsed test bodies and their surrounding fixtures.

### After

`pnpm exec vitest run --project unit LexicalBuilder.test.ts LexicalListItemNode.test.ts LexicalSelection.test.tsx LexicalEditor.test.tsx LexicalExtensionCore.test.ts LexicalNode.test.ts ManagedLineBreakObservedRemoval.test.ts --maxWorkers=4`

```text
 Test Files  7 passed (7)
      Tests  577 passed (577)
```

The retained managed-line-break browser coverage passes in Chromium and WebKit. Firefox could not start a content process in the local sandbox. Browser validation used available Chromium 141 and WebKit 26 builds; the repository's Playwright dependency is unchanged.
…r tests

## Description

Move 22 rich-text E2E cases (and their plain-text variants) into Vitest browser mode: character-limit overflow, max-length boundaries and paste, select-all deletion, synthetic clipboard plus execCommand, and text mutation observers. Keep native keyboard input, DOM and editor-state checks, caret assertions, Unicode cases, and both editor modes. Wait for the editor state when observing external text mutations.

Keep three playground integration cases for the character-limit/autolink combination and the max-length setting. The Chromium E2E inventory falls from 687 to 665 cases. The browser migration group now runs 52 checks, including the existing character-limit cases and the new plain-text coverage.

## Test plan

### Before

Run the five original E2E files, copied from the base commit, against a development build with the default action delay:

```text
25 passed (16.9s)
```

The JSON report records 58.24 seconds summed across test attempts.

### After

`pnpm run test-browser --maxWorkers=4 --reporter=json`

The full Chromium JSON report records 1,098 passing checks and no failures. The five migration suites run 52 passing checks in 5.88 seconds elapsed (7.05 seconds summed across suites). The retained E2E checks pass in both modes:

```text
3 passed (3.8s)
3 passed (3.1s)
```

The migrated cases also pass in WebKit, including the final mutation-state polling change (4 checks across Chromium and WebKit). Local engines were Chromium 141 and WebKit 26; their matching Playwright driver was used for WebKit validation without changing repository dependencies. Firefox cannot create its content process in this sandbox, and validation against the repository's exact browser revisions remains for CI.

TypeScript test checking, ESLint, formatting, package builds, and the playground development build pass.
…ization

## Description

Check newline-splitting batches against an explicit argument limit with 8,193 line feeds instead of constructing 600,000 nodes to reach a machine-dependent native limit. Preserve author, peer and fresh-reader content checks and the original stress input through TEXT_NEWLINES_COUNT=300000.

Replace repeated wall-clock sampling of naming follow-ups with a bound on paragraphs serialized by each check. Keep 10,000-block documents, middle/end edits, repeated keystrokes and persisted block-id assertions.

Stop the simulated network once no updates remain after draining queued work; retain the existing follow-up delivery bound when work is pending. Reuse the fresh reader already checked by expectConverged in the normalization matrix. Take one JSON snapshot per fuzz peer per checkpoint and normalize only mismatches. All fuzz seeds, delivery schedules and checks remain.

## Test plan

### Before

A single-worker comparison of unchanged base tests and updated tests in the same invocation records:

| Suite | Base | Updated |
| --- | ---: | ---: |
| FollowUpCheckCost | 13.751 s | 4.357 s |
| NormalizationConvergence | 36.512 s | 25.272 s |
| TextNewlines | 34.068 s | 2.786 s |

All 2,312 before/after checks pass. These are local suite timings, not a claim about whole-workflow latency.

Temporarily disabling batching and forcing whole-container follow-up reads proves the replacements still detect those regressions:

```text
AssertionError: expected 20002 to be less than or equal to 12
RangeError: too many splitText arguments
Test Files  2 failed (2)
     Tests  3 failed | 22 skipped (25)
```

### After

Restore the implementation, then run `pnpm run test-unit --maxWorkers=4 --reporter=json`:

```text
{'numPassedTests': 15310, 'numFailedTests': 0, 'success': True}
```

The pass count includes 16 expected-failure checks. The @lexical/y subset independently passes 4,967 checks, and a temporary comparison confirms identical findings and metrics from the original and updated fuzz checkpoint logic for 60 seeds.

TypeScript test checking, ESLint and formatting pass. Published implementation files and Yjs 13 bindings are unchanged.
@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
lexical Ready Ready Preview Oct 29, 2026 6:55pm UTC
lexical-playground Ready Ready Preview Oct 29, 2026 6:55pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 29, 2026
@etrepum etrepum added the extended-tests Run extended e2e tests on a PR label Oct 29, 2026
@pkg-pr-new

pkg-pr-new Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
lexical

npm i https://pkg.pr.new/lexical@9530

@lexical/a11y

npm i https://pkg.pr.new/@lexical/a11y@9530

@lexical/clipboard

npm i https://pkg.pr.new/@lexical/clipboard@9530

@lexical/code

npm i https://pkg.pr.new/@lexical/code@9530

@lexical/code-core

npm i https://pkg.pr.new/@lexical/code-core@9530

@lexical/code-prism

npm i https://pkg.pr.new/@lexical/code-prism@9530

@lexical/code-shiki

npm i https://pkg.pr.new/@lexical/code-shiki@9530

@lexical/compiler

npm i https://pkg.pr.new/@lexical/compiler@9530

@lexical/devtools-core

npm i https://pkg.pr.new/@lexical/devtools-core@9530

@lexical/dragon

npm i https://pkg.pr.new/@lexical/dragon@9530

@lexical/eslint-plugin

npm i https://pkg.pr.new/@lexical/eslint-plugin@9530

@lexical/extension

npm i https://pkg.pr.new/@lexical/extension@9530

@lexical/fast-check

npm i https://pkg.pr.new/@lexical/fast-check@9530

@lexical/file

npm i https://pkg.pr.new/@lexical/file@9530

@lexical/hashtag

npm i https://pkg.pr.new/@lexical/hashtag@9530

@lexical/headless

npm i https://pkg.pr.new/@lexical/headless@9530

@lexical/history

npm i https://pkg.pr.new/@lexical/history@9530

@lexical/html

npm i https://pkg.pr.new/@lexical/html@9530

@lexical/internal

npm i https://pkg.pr.new/@lexical/internal@9530

@lexical/link

npm i https://pkg.pr.new/@lexical/link@9530

@lexical/list

npm i https://pkg.pr.new/@lexical/list@9530

@lexical/mark

npm i https://pkg.pr.new/@lexical/mark@9530

@lexical/markdown

npm i https://pkg.pr.new/@lexical/markdown@9530

@lexical/mdast

npm i https://pkg.pr.new/@lexical/mdast@9530

@lexical/offset

npm i https://pkg.pr.new/@lexical/offset@9530

@lexical/overflow

npm i https://pkg.pr.new/@lexical/overflow@9530

@lexical/plain-text

npm i https://pkg.pr.new/@lexical/plain-text@9530

@lexical/react

npm i https://pkg.pr.new/@lexical/react@9530

@lexical/rich-text

npm i https://pkg.pr.new/@lexical/rich-text@9530

@lexical/selection

npm i https://pkg.pr.new/@lexical/selection@9530

@lexical/table

npm i https://pkg.pr.new/@lexical/table@9530

@lexical/tailwind

npm i https://pkg.pr.new/@lexical/tailwind@9530

@lexical/text

npm i https://pkg.pr.new/@lexical/text@9530

@lexical/utils

npm i https://pkg.pr.new/@lexical/utils@9530

@lexical/y

npm i https://pkg.pr.new/@lexical/y@9530

@lexical/yjs

npm i https://pkg.pr.new/@lexical/yjs@9530

commit: 72290aa

## Description

The migrated MaxLength emoji-boundary test dropped the 100 ms native typing delay used by its E2E predecessor. Firefox then leaves a non-collapsed DOM/model selection at offset 29 after rejecting the non-BMP character, and both rich-text and plain-text cases fail their caret assertions.

Forward an optional delay through the native browser typing helper and restore that delay for the rejected emoji. Other input keeps the zero-delay default. Preserve the content, Unicode-boundary, and collapsed-caret assertions.

## Test plan

### Before

Reproduced with the repository's Playwright 1.63.0 and Firefox 155 on Linux:

`VITEST_BROWSER=firefox pnpm exec vitest run --project browser packages/lexical-playground/src/__tests__/browser/MaxLength.test.ts --maxWorkers=1 --reporter=verbose`

```text
Test Files  1 failed (1)
     Tests  2 failed | 8 passed (10)
```

Both failures report `isCollapsed: false` at offset 29 for the DOM and Lexical selections. Upstream CI shows the same failures on Linux, macOS, and Windows.

### After

Run the MaxLength and NativeTyping suites in Firefox 155:

```text
Test Files  2 passed (2)
     Tests  12 passed (12)
```

The native-input lifecycle tests still verify that typing stays with its requesting editor and stops if that editor is removed. Local Firefox requires its sandbox disabled to create content processes in this environment.

ESLint, Prettier, TypeScript test checking, TypeScript scripts checking, and git diff --check pass. The full browser and platform matrix is being verified separately in CI.

This branch was successfully deployed

2 active deployments
Preview – lexical — 72290aa9 Deployed Oct 29, 2026 by vercel[bot]
Preview – lexical-playground — 72290aa9 Deployed Oct 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant