open-design/apps/web/tests/components/PreviewDrawOverlay.send-disabled.test.tsx
leessju cfde84b038
Some checks failed
visual-baseline / Capture visual baselines (push) Waiting to run
ci / Detect CI change scopes (push) Successful in 0s
landing-page-ci / Validate landing page (push) Failing after 3s
landing-page-staging / Deploy landing page to staging (push) Has been skipped
nix-check / build (push) Failing after 2s
ci / Validate Nix flake (push) Has been skipped
ci / Preflight (push) Failing after 1s
ci / Workspace unit tests (push) Failing after 2s
ci / Daemon workspace tests (push) Failing after 1s
ci / Web workspace tests (push) Failing after 2s
ci / Browser tests (push) Failing after 1s
ci / Build workspaces (push) Failing after 1s
ci / Validate workspace (push) Failing after 0s
ci / Runtime trace (push) Has been skipped
fix(web): make hand-off no-editors fallback perform a real reveal (#2494)
* fix(web): make hand-off no-editors fallback perform a real reveal

The Finder/Explorer/File Manager fallback button was only calling an
optional onRequestRevealInFinder prop that the actual caller never
passes, so the surface advertised an action it never performed.

finder, explorer, and file-manager are real entries in the daemon's
open-in catalogue (open / explorer / xdg-open), so route the fallback
through openProjectInEditor(projectId, fallbackId) for a genuine
reveal. Keep the renderer reveal bridge as a secondary fallback if
the daemon spawn fails, and disable the button while busy so a double
click can't queue two reveals.

Adjacent: PreviewDrawOverlay's Send-while-streaming behavior is
intentional (sending is queued downstream, not blocked), and the
button already carries sendDisabledReason as its tooltip. Cover that
contract with a regression test so a future change can't silently
re-disable the control or drop the localized reason.

Scope note: the i18n hand-off key migration that previously rode on
this branch landed on main via a different key set, so this PR is
narrowed to just the fallback wire-up and the two regression tests.

* fix(web): surface daemon spawn failure inline in zero-editors fallback

The zero-editors HandoffButton fallback called setError() on a rejected
openProjectInEditor but returned only the <button>, so the error never
rendered. Production callers (ProjectView) mount the component without
onRequestRevealInFinder, so a daemon spawn failure became a silent no-op
— exactly the failure mode the PR was meant to cover.

Wrap the solo button in a handoff-wrap container and render the error
inline next to it. Adds a regression test for the rejected-spawn path.

* fix(web): align preview draw send-disabled test

* fix(web): show handoff fallback for zero editors

---------

Co-authored-by: nicejames <nicejames@gmail.com>
Co-authored-by: mrcfps <mrc@powerformer.com>
2026-05-30 06:34:12 +00:00

36 lines
1.5 KiB
TypeScript

// @vitest-environment jsdom
// Regression for the streaming-state localization: while sending is disabled
// (e.g. a run is in flight), the Send control stays rendered with the
// localized reason as its tooltip so the message reaches the DOM instead of
// being dropped. Queue remains available for staging the note downstream.
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it } from 'vitest';
import { PreviewDrawOverlay } from '../../src/components/PreviewDrawOverlay';
afterEach(() => {
cleanup();
});
describe('PreviewDrawOverlay send disabled (streaming) localization', () => {
it('surfaces the localized reason on the Send tooltip while keeping Queue operable', () => {
render(
<PreviewDrawOverlay active sendDisabled sendDisabledReason="Task running">
<div data-testid="content" />
</PreviewDrawOverlay>,
);
const note = document.querySelector('.preview-draw-note-input') as HTMLInputElement;
fireEvent.change(note, { target: { value: 'looks good' } });
const send = screen.getByRole('button', { name: 'Send' });
const queue = screen.getByRole('button', { name: 'Queue' });
// The localized reason reaches the DOM as the button's tooltip...
expect(send.getAttribute('title')).toBe('Task running');
// ...and Queue stays operable so the mark can be staged for the next turn.
expect((send as HTMLButtonElement).disabled).toBe(true);
expect((queue as HTMLButtonElement).disabled).toBe(false);
});
});