LibreChat/e2e
Danny Avila 9a0a8d1c15 feat: dedicated escalation arrow + shortcut, menu split into actions and preferences
The escalation was still half-hidden: the bubble only offered it inside
the overflow menu, and the tooltip taught the composer chord, which does
a different thing (interrupts with typed text, not this chip). Three
changes make it a first-class command:

- A shared EscalateNowButton (circular arrow, ghost-bordered like the
  composer's interrupt control) is always visible on BOTH surfaces:
  beside each queued row's Steer primary and on every waiting steer
  bubble next to its menu. It disappears once a steer is interrupting.
- A dedicated registry shortcut, escalateSteer (Cmd/Ctrl+Shift+.),
  editing-allowed and rebindable like every other action. Deliberately
  NOT an Enter chord: the composer owns every Enter chord, and the
  yield design rests on no default binding using Enter besides submit.
  Its handler clicks the newest enabled arrow control (bubbles beat
  queued rows), so the shortcut can never diverge from the button, and
  the arrow's tooltip teaches THIS command via the registry display.
- The overflow menus separate one-off actions from sticky behavior
  changes: Edit, Cancel, Queue, then a smaller "Preferences" section
  holding the queueing and always-interrupt toggles, each with the
  standard InfoHoverCard reusing the Settings panel's descriptions.
  "Interrupt & steer now" leaves the menu entirely.

386 client tests green, including a menu-structure test locking the
order and the absence of the escalation entry; bubble escalation tests
drive the visible arrow. The e2e spec's bubble test now clicks the
arrow, and a fourth test drives the dedicated shortcut end to end
through a real mid-stream seal.
2026-07-30 18:44:32 -04:00
..
benchmarks perf: Reduce Agent Chat Startup Latency (#14423) 2026-07-25 07:58:20 -04:00
benchmarks-reasoning 🧪 test: Reasoning-Stream Render Perf Benchmark via react-scan (#14494) 2026-07-28 22:18:24 -04:00
config 🎯 feat: Tool Intent Label Capability (tool_intents) (#14499) 2026-07-29 15:40:52 -04:00
fixtures/deployment-skills/e2e-deployment-skill 🗂️ feat: Add Deployment Skill Directory (#13523) 2026-06-05 10:24:28 -04:00
recordings 🎭 feat: Add Credential-Free Playwright Smoke Suite with a Local Mock LLM (#13472) 2026-06-02 16:36:39 -04:00
setup 🏷️ feat: Activity Groups With Fast-Model Headers (#14391) 2026-07-29 14:05:47 -04:00
specs feat: dedicated escalation arrow + shortcut, menu split into actions and preferences 2026-07-30 18:44:32 -04:00
config.local.example.ts 🤲 feat(a11y): Initial a11y improvements, added linters, tests; fix: close sidebars in mobile view (#3536) 2024-08-04 20:39:52 -04:00
jestSetup.js v0.8.7 (#13907) 2026-06-24 14:49:32 -04:00
playwright.config.a11y.ts ⚖️ feat: Add Violation Scores (#8304) 2025-07-07 17:08:40 -04:00
playwright.config.benchmark.ts perf: Reduce Agent Chat Startup Latency (#14423) 2026-07-25 07:58:20 -04:00
playwright.config.local.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
playwright.config.mock.ts 🏷️ feat: Activity Groups With Fast-Model Headers (#14391) 2026-07-29 14:05:47 -04:00
playwright.config.real.ts 🎯 feat: Tool Intent Label Capability (tool_intents) (#14499) 2026-07-29 15:40:52 -04:00
playwright.config.reasoning-perf.ts 🧪 test: Reasoning-Stream Render Perf Benchmark via react-scan (#14494) 2026-07-28 22:18:24 -04:00
playwright.config.ts 🎭 feat: Add Credential-Free Playwright Smoke Suite with a Local Mock LLM (#13472) 2026-06-02 16:36:39 -04:00
README.md 🎭 test: Run Mock E2E Suite Through createRun With In-Process Fake Model (#13508) 2026-06-04 08:33:28 -04:00
types.ts 🤲 feat(a11y): Initial a11y improvements, added linters, tests; fix: close sidebars in mobile view (#3536) 2024-08-04 20:39:52 -04:00

LibreChat e2e

The mock e2e profile is the safest default for generated tests. It starts LibreChat with e2e/config/librechat.e2e.yaml, injects an in-process fake LLM (via LIBRECHAT_TEST_RUN_HOOK), creates an authenticated e2e user, and avoids real provider credentials.

Recording Tests

Use Playwright codegen when you want to turn an exploratory browser session into a draft test:

npm run e2e:record

That command builds the app, starts the LibreChat test server (with an in-process fake LLM) when needed, writes e2e/storageState.json, and opens Playwright codegen at /c/new. The npm script uses http://localhost:3333 so it does not collide with a normal dev server on 3080. Raw recordings are written to e2e/recordings/ and ignored by git.

For a real local LibreChat config instead of the mock profile:

npm run e2e:record:local

Useful direct options:

node e2e/setup/record.js --url=http://localhost:3080/c/new
node e2e/setup/record.js --profile=local --no-output
node e2e/setup/record.js --auth-only
node e2e/setup/record.js --output=e2e/recordings/settings-draft.spec.ts

LLM-Assisted Loop

  1. Start npm run e2e:record.
  2. Let the LLM use Computer Use to operate the headed Playwright browser.
  3. Stop codegen after the workflow is captured.
  4. Move the useful parts from e2e/recordings/ into a committed spec under e2e/specs/mock/.
  5. Replace brittle generated selectors with role, label, text, or data-testid locators.
  6. Add assertions that prove the behavior, not just the clicked path.
  7. Run the finished spec with npm run e2e:mock -- <spec name>.

Generated recordings are a draft, not the final test. The committed version should use the shared helpers in e2e/specs/mock/helpers.ts where possible, wait on network or visible UI state instead of fixed sleeps, and keep test data deterministic.