LibreChat/e2e/setup
Marco Beretta 8da51562f5
🧜 feat: Open Mermaid Diagrams as Artifacts with SVG/PNG Export (#14713)
* feat: open Mermaid diagrams in the artifact panel with SVG and PNG export

Mermaid diagrams previously rendered inline only, and the artifact panel
routed every artifact through Sandpack even when no bundler was needed.

- Route Mermaid artifacts to a direct renderer in ArtifactTabs, moving the
  Sandpack path into a lazily loaded SandboxArtifactTabs so opening a
  diagram no longer pulls in the bundler chrome or the startup config.
- Add an inline artifact card that opens the diagram in the panel instead
  of rendering the same diagram twice.
- Add SVG and PNG export from both the inline diagram and the panel
  header, with size-capped canvas scaling and background compositing.
- Lazy-load the artifact panel in Presentation and ShareArtifacts.
- Accessibility: label the panel as a dialog on mobile with a focus trap,
  make the mobile resize handle keyboard operable, restore focus to the
  opener on close, and honor prefers-reduced-motion.
- Fix the generated Sandpack wrapper to serialize diagram source instead
  of interpolating it into a template literal.
- Cover the new paths with unit tests and a cross-browser Playwright spec.

* fix: keep Mermaid artifact identity and render state per diagram

Addresses three review findings on the Mermaid artifact panel.

Mermaid fences do not consume a code-block index, so every diagram in a
message received the same `mermaid-${blockIndex}` and therefore the same
Recoil artifact key: expanding one overwrote the other, and both cards
read as selected. Mermaid fences now carry their own index sequence,
seeded per markdown block the same way the code and artifact counters
are, so the id stays stable across streamed tokens.

The panel renderer is keyed by artifact id, so switching directly
between two diagrams can no longer carry the previous render, its
dimensions, or its export payload across the boundary while the new
source debounces. Editing an open diagram still does not remount.

The preview Refresh action drives the Sandpack client, which a Mermaid
preview never populates, so it only covered the panel with a spinner.
It is hidden for Mermaid, which offers its own retry on render failure.

Also drops com_ui_mermaid_export_preparing and com_ui_mermaid_source,
which no longer have call sites, fixing the unused-i18n-keys check.

* fix: bind Mermaid preview and export to the artifact on screen

Three further review findings, all on state outliving what it describes.

The editor reset in ArtifactTabs only lands after commit, so the render
that switched artifacts still passed the previous artifact's editor text
to the freshly keyed renderer, which mounted showing (and exporting) the
diagram just navigated away from. Editor text is now ignored until the
reset catches up. SandboxArtifactTabs carried the same pattern and gets
the same guard.

Switching to the code tab unmounts the preview, but the export payload
survived it, so the toolbar kept exporting a diagram that was no longer
on screen and no longer matched an edited source. The renderer now
withdraws its payload on unmount, and the export action is scoped to the
preview tab.

The diagram canvas mounts only once there is a diagram to show, so the
ResizeObserver ran against a null ref while the placeholder was up and
never saw the real element. Wide diagrams were fitted to the default
700px and clipped in narrower panels. Observation now re-runs when the
canvas appears.

* fix: scope Mermaid artifact ids to the content part

Each content part renders its own markdown tree, so the per-message
Mermaid counter restarts at zero in every part. Diagrams sitting either
side of a tool call therefore both resolved to
`mermaid-artifact-${messageId}-mermaid-0`: one registration overwrote
the other and both cards shared a selection state. The part index the
message context already carries now takes part in the scope.

* fix: keep the Mermaid export menu reachable in fullscreen

The artifact panel gained a fullscreen mode on dev, which re-roots the
panel into the fullscreen element and portals the copy and version
popovers there so they stay visible. The Mermaid export menu portals to
the body, so once these branches met it opened outside the fullscreen
element and rendered invisible. It now takes the same portal target.

* fix: heal Mermaid registrations and cap PNG canvases after rounding

Two findings from the latest review pass.

Closing the panel unmounts Artifacts, whose useArtifacts cleanup wipes
artifactsState while the inline cards stay on screen. The Mermaid card
never observed that, so reopening one card restored only itself and any
other expanded diagram vanished from the version navigator until it was
clicked again. It now subscribes to its own slice and re-registers when
the entry goes missing, matching the self-heal ToolArtifactCard already
documents. The write is a no-op when the entry matches, so it settles.

Rounding each PNG side independently could carry the product back over
the 16.7M pixel budget the scale was picked to satisfy: 3129x50000
resolved to 1025x16374, which is 16,783,350 pixels and enough for a
browser enforcing the area limit to reject toBlob outright. Rounding
down cannot exceed the budget, since the bounding scale is derived from
it.
2026-08-09 09:02:42 -04:00
..
authenticate.ts 🧭 ci: Use System Chrome for Mock E2E (#13481) 2026-06-02 22:07:10 -04:00
cleanupUser.ts 📦 chore: bump @librechat/agents to v3.4.2 and npm audit (#14702) 2026-08-08 12:24:06 -04:00
dynamic-mcp-tools.js 📡 fix: Refresh MCP Tools After List-Changed Notifications (#14686) 2026-08-08 13:50:21 -04:00
env.ts 📡 fix: Refresh MCP Tools After List-Changed Notifications (#14686) 2026-08-08 13:50:21 -04:00
fake-label-server.js 🏷️ feat: Activity Groups With Fast-Model Headers (#14391) 2026-07-29 14:05:47 -04:00
fake-mcp-dynamic-network-server.js 📡 fix: Refresh MCP Tools After List-Changed Notifications (#14686) 2026-08-08 13:50:21 -04:00
fake-mcp-http-server.js 🔐 fix: Honor Admin-Panel MCP Allowlist Overrides Without Restart (#13814) 2026-06-17 20:14:53 -04:00
fake-mcp-server.js 📡 fix: Refresh MCP Tools After List-Changed Notifications (#14686) 2026-08-08 13:50:21 -04:00
fake-model.js 🧜 feat: Open Mermaid Diagrams as Artifacts with SVG/PNG Export (#14713) 2026-08-09 09:02:42 -04:00
global-setup.local.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
global-setup.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
global-teardown.local.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
global-teardown.mock.ts 🎭 feat: Add Credential-Free Playwright Smoke Suite with a Local Mock LLM (#13472) 2026-06-02 16:36:39 -04:00
global-teardown.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
record.js 🎭 test: Run Mock E2E Suite Through createRun With In-Process Fake Model (#13508) 2026-06-04 08:33:28 -04:00
runtimeEnv.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
start-server-cluster.js 📡 fix: Refresh MCP Tools After List-Changed Notifications (#14686) 2026-08-08 13:50:21 -04:00
start-server.js 🧪 test: Run mock E2E against Redis in shards (#14551) 2026-07-31 12:10:43 -04:00
tool-approval-hook.js 🛂 test: Cover Tool Approval Workflows End to End (#14427) 2026-07-26 21:58:25 -04:00
user.ts 🛟 test: Restore Playwright Smoke E2E (#13020) 2026-05-14 09:49:26 -04:00
users.mock.ts 🎭 feat: Add Credential-Free Playwright Smoke Suite with a Local Mock LLM (#13472) 2026-06-02 16:36:39 -04:00