Skip to content

[Desktop E2E] transcript-scroll history test races initial tail positioning #4618

Description

@Sun-GLiang

What happened

The Desktop E2E test below fails intermittently under concurrent CI load:

apps/desktop/e2e/transcript-scroll.spec.ts

history asked for at the very top of the scroller still lands above the reader

The assertion waiting for the first resident turn to change times out after 20 seconds. In the observed CI failure, the first resident turn remained turn-prompt-rail-111.

Expected behavior: the test should deterministically wait for the transcript's initial tail positioning to finish, scroll to the top, request earlier history, and verify that the loaded history lands above the reader.

Observed behavior: the test can execute root.scrollTop = 0 while the scroller is already at 0. That assignment is a no-op, so Chromium emits no reader scroll event and requestEarlier / loadEarlier is never triggered.

This appears to be a test-readiness race rather than a product behavior defect.

How to reproduce

From apps/desktop:

  1. Build the Desktop app and workspace dependencies.

  2. Run the affected test repeatedly with four Playwright workers:

    npm run build:with-deps
    npx playwright test \
      --config e2e/playwright.config.ts \
      e2e/transcript-scroll.spec.ts \
      --grep "history asked for at the very top" \
      --repeat-each=12 \
      --workers=4
  3. Observe that some iterations time out while waiting for the first resident turn to change.

Reproduction results during investigation:

  • Single worker, five isolated runs: 5/5 passed.
  • Four workers, 12 repeated runs: 2 failures.
  • Four workers, 16 repeated runs with temporary read-only diagnostics: 1 failure.

The failing diagnostic sample, captured before the test assigned root.scrollTop = 0, was:

{
  "scrollTop": 0,
  "scrollHeight": 3246,
  "clientHeight": 780
}

Because the assignment is 0 -> 0, it does not emit the scroll event used by useChatScroll to request earlier history. The transcript scroll authority completes its initial tail pin only afterward.

Environment

Logs, screenshots, or additional context

Related PR: #4417

The failed CI job completed with:

  • 104 passed
  • 4 skipped
  • 1 failed

Lint, build, typecheck, and the observer E2E tests added by PR #4417 all passed.

Root cause

The promptRailWindow setup waits for the transcript DOM to appear, but the affected test does not wait for initial tail positioning to settle. Under concurrent/Xvfb load, the test can reach its top-of-scroller action before the initial tail pin.

Suggested fix

Before assigning root.scrollTop = 0, deterministically wait for a single scroll-metrics sample satisfying both:

  • scrollTop > 0
  • scrollHeight - scrollTop - clientHeight <= 4

Then perform the existing scroll-to-top action and history-load assertions.

A fixed delay or a larger 20-second assertion timeout would only mask the readiness race.

Validate the fix with:

  • The affected test using --repeat-each and --workers=4.
  • The complete transcript-scroll.spec.ts E2E file.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions