LearnNewsExamplesServices
Frontmatter
id16128
titleHeaded E2E defaults to a non-presenting browser profile
stateClosed
labels
bugaitesting
assigneesneo-gpt-emmy
createdAtJul 29, 2026, 12:36 PM
updatedAtJul 29, 2026, 11:55 PM
githubUrlhttps://github.com/neomjs/neo/issues/16128
authorneo-gpt-emmy
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 29, 2026, 11:55 PM

Headed E2E defaults to a non-presenting browser profile

Closed Backlog/active-chunk-10 bugaitesting
neo-gpt-emmy
neo-gpt-emmy commented on Jul 29, 2026, 12:36 PM

Context

Repeated headed Workstation runs opened native Chrome windows whose App Worker, DOM, Canvas Worker, and Neural Link state were live while the physical windows presented no application frames. The operator has now caught this same mistake more than twenty times across agent sessions: a maintainer launches the default E2E profile, sees green semantic assertions, and only later learns that every visible window was empty.

The current source makes that recurrence the default:

activeLaunchArgs() with no environment sentinel
→ E2E_LAUNCH_ARGS
→ includes --disable-frame-rate-limit plus GPU-intent flags

Resolved ticket #15912 already established the relevant host behavior: this profile keeps engine truth live but suppresses headed compositor frames, while the same launch base without --disable-frame-rate-limit presents real pixels. A current #16117 run reproduced the split: the default profile passed semantic assertions behind empty native windows; the identical actual-pointer run with presenting launch arguments showed real Workstation content and passed.

This replaces this ticket's original prescription. Preserving a known non-presenting profile as the default was wrong: it encoded a recurring human/agent failure into the launcher and relied on perfect sentinel recall to avoid it.

The Problem

A headed UI test has one unsurprising baseline contract: unless the caller explicitly asks for a specialized mode, its native windows must present the application.

Today that contract is inverted. Pixel-bearing compositing requires remembering NEO_FILM_TAKE=1, even when the run is not a film take. Compaction, handoff, copied commands, and ordinary shell use therefore fall into a profile that is semantically live but visually empty. The failure is especially damaging for docking work because the operator can see multiple empty OS windows while the harness reports that popup content and proxies exist.

The root problem is the default selector, not missing documentation. A warning cannot make a known non-presenting headed profile a safe default.

The Architectural Reality

  • test/playwright/e2e/utils/gpuIntent.mjs is the single launch-argument authority.
  • test/playwright/playwright.config.e2e.mjs gives activeLaunchArgs() to both the GL probe and the Chromium project; changing the selector changes the actual browser and its proportional boot assertion together.
  • test/playwright/e2e/gl.setup.mjs correctly demands accelerated GL only when the selected arguments claim it. The presenting default makes no benchmark-grade GPU claim.
  • NEO_FILM_TAKE is also consumed by Workstation specs for recording, pacing, and take shape. Those semantics remain useful, but visible compositing must not depend on that sentinel.
  • Some engine/OffscreenCanvas or benchmark investigations may deliberately require --disable-frame-rate-limit. That is a specialized, non-presenting profile and must be explicit.

The Fix

  1. Make the presenting launch list the unconditional default returned by activeLaunchArgs().
  2. Add exact-sentinel opt-in NEO_E2E_ENGINE_PROFILE=1 for the existing frame-limit-disabled/GPU-intent argument list.
  3. Keep NEO_FILM_TAKE=1 as the recording/pacing selector used by Workstation specs; it no longer changes the browser from invisible to visible.
  4. Update launcher JSDoc and affected E2E comments so no public example or code comment describes the non-presenting profile as ordinary/default.
  5. Pin the inversion with unit tests for unset, false-like, arbitrary, film, and explicit engine values, then run a headed Workstation popup witness with no presentation sentinel.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
activeLaunchArgs() default test/playwright/e2e/utils/gpuIntent.mjs Return the pixel-bearing presenting arguments None; presentation is the default Owner JSDoc + config comments Unit matrix + headed Workstation witness
NEO_E2E_ENGINE_PROFILE=1 gpuIntent.mjs:isEngineProfile() Select the existing frame-limit-disabled/GPU-intent arguments only for the exact sentinel Any other value uses presenting arguments Owner JSDoc Exact-sentinel unit matrix
NEO_FILM_TAKE=1 gpuIntent.mjs:isFilmTake() and Workstation specs Continue selecting film pacing/recording behavior; browser presentation is already the default Unset retains normal test shape with visible windows Existing spec JSDoc/comments Existing film-mode tests + launch-selector unit matrix
GL boot demand test/playwright/e2e/gl.setup.mjs Continue deriving the demand from the arguments actually selected No GPU-intent flag means no acceleration claim Existing probe output Unit matrix + boot probe

Acceptance Criteria

  • With NEO_E2E_ENGINE_PROFILE unset, activeLaunchArgs() excludes --disable-frame-rate-limit and returns the presenting profile.
  • Values 0, false, and arbitrary non-empty strings still select the presenting profile; only exact 1 selects the engine profile.
  • NEO_FILM_TAKE=1 remains a film-shape signal but is not required to obtain compositor frames.
  • NEO_E2E_ENGINE_PROFILE=1 selects the existing GPU-intent arguments including --disable-frame-rate-limit.
  • The GL probe evaluates the same selected list as the Chromium project and keeps its proportional claim behavior.
  • A headed Workstation popup test launched without a presentation sentinel visibly renders application content and passes its retained assertions.
  • No touched JSDoc, test comment, or runner example calls the non-presenting profile the ordinary/default profile.

Out of Scope

  • Removing the explicit engine/benchmark profile.
  • Weakening engine/OffscreenCanvas assertions inside tests that explicitly select that profile.
  • Product-side docking changes from #16117.
  • Reopening resolved #15912; its compositing bisect remains valid authority.
  • Solving the original mid-suite GPU-process-decay investigation. If that still reproduces under the explicit engine profile after this default repair, it gets a new successor ticket.

Related

  • #15912 — resolved compositing bisect and presenting launch profile.
  • #16117 — popup-over-popup witness that exposed the repeated default misuse.

Decision Record impact: none.

Origin Session ID: 019fac4d-7844-7422-9486-7f73ccf308f5

Retrieval Hint: "headed E2E default empty windows presenting launch args explicit engine profile"

tobiu referenced in commit 34621e0 - "fix(test): make headed E2E presenting by default (#16128) (#16138) on Jul 29, 2026, 11:55 PM
tobiu closed this issue on Jul 29, 2026, 11:55 PM