Skip to content

Feat/design system compliance - #114

Merged
MyNameIsEdi merged 11 commits into
mainfrom
feat/design-system-compliance
May 24, 2026
Merged

Feat/design system compliance#114
MyNameIsEdi merged 11 commits into
mainfrom
feat/design-system-compliance

Conversation

@MyNameIsEdi

@MyNameIsEdi MyNameIsEdi commented May 24, 2026

Copy link
Copy Markdown
Owner

Description

Fixes # (issue number)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

Release Notes

  • New Features

    • Real-time streaming of Playwright run summaries now displayed in team chat with detailed pass/fail metrics.
  • Style

    • Updated Playwright Dashboard color palette for improved visual consistency and semantic status indicators.
  • Documentation

    • Enhanced README with expanded feature descriptions for Multi-Agent Collaboration and Dashboard capabilities.
    • Fixed Troubleshooting documentation formatting.

Review Change Stack

MyNameIsEdi and others added 8 commits May 23, 2026 22:44
…for every run, UI polish

Three production fixes plus a feature upgrade for the Playwright Dashboard
and the QA Office chat panel:

- **Multi-agent collaboration** in /api/qa-agent: primary → critic → primary
  refine → Edi M synthesis. Auto-triggered when 2+ agents are tagged or the
  manager is mentioned. New SSE turn_start/turn_done/turn_verdict events
  produce a threaded conversation in chat, with colour-coded role pills.
- **Run logs persisted** alongside each archived run; clicking an old run
  re-hydrates the dashboard log panel. archiveRun() now logs success/failure
  to the server console so silent archive failures are visible.
- **Edi M summary now streams to chat for every Run Tests**, not just
  agent-generated dynamic runs. Phase 2 streamSummary() helper shared by
  /api/playwright/run and /api/run-dynamic-test.
- **Dashboard UI/UX polish**: KPI hero with progress ring + verdict, pill
  subtitle row, history-chart hover tooltip + moving-average trend line,
  sticky suite headers with smooth chevron rotation, copy-error button,
  cropped QA Office canvas (no more "blue void" above the office).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- server: drop unnecessary \- escape in runId sanitiser regex
- tests/sv-login: remove unused BASE_URL import
- PlaywrightDashboard: replace ternary-as-statement with explicit if/else
  in the multi-spec picker onChange (no-unused-expressions)
- OfficePage + PlaywrightDashboard: remove orphaned
  `eslint-disable-next-line react-hooks/exhaustive-deps` directives —
  the rule isn't registered in this project's ESLint config so the
  directive itself was reported as an error
- PlaywrightDashboard: drop two unused `// eslint-disable-line`
  trailing comments flagged by no-unused-disable
- README: mention multi-agent collab + persistent run history features
  so the docs-check script sees a docs update alongside the code change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-format 115 files with Prettier to fix the failing format:check
workflow step. Also removes the temporary PR_BODY.md file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, summary snapshot, types)

- CHANGELOG: remove duplicate bullets (two entries appeared under both the
  unreleased ### Changed block and an orphaned second block)
- runCollabTurn: accept and forward history + imageAttachments into
  startChat/sendMessageStream so collaborative turns preserve context and vision
- capturedLog: switch from oldest-first cap to a sliding window (push + shift)
  so archiveRun and AI summaries always see the newest 5 000 lines
- streamSummary: accept runId in SummaryCreds; reads the per-run immutable
  archive instead of the shared RESULTS_PATH to prevent concurrent-run clobbering
- Both route close-handlers now capture archiveRun return value and pass runId
  to streamSummary
- PlaywrightDashboard: define RunRequest and SummaryEvent types; runWithSSE
  typed as (body: RunRequest); evt typed as SummaryEvent | Record<string,unknown>;
  fetchResults always calls setRunLog (clears to [] when not an archived run)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-and-ui-upgrades

# Conflicts:
#	CHANGELOG.md
#	server/index.ts
#	ui/src/pages/PlaywrightDashboard.tsx
Satisfies the docs-validation CI check that requires README.md to be
updated alongside any server/ or ui/src/ changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rewrote all nine documentation sections in DocsPage to reflect the
current project state. Replaced every Anthropic/Claude reference with
Gemini/Ollama, updated the directory tree, rewrote the env-var section
with dual-provider setup instructions, corrected the tech stack table,
added FAQ entries for provider switching and multi-agent collaboration,
and updated the roadmap to mark completed features as done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace all off-spec color usage across PlaywrightDashboard.tsx:
- Primary brand blue: #2563eb (Tailwind blue-600) → #1a3a8f (DESIGN primary)
  applied to all interactive elements — buttons, toggles, active file border,
  selected-bar outline, badges, latest/viewing chips, send button.
- Success semantic: #10b981 (emerald-500) → #34C759 / #16A34A (DESIGN success)
  applied to StatusIcon, StatusBadge, KPI bar, chart bars, inline counts.
- Warning semantic: #fbbf24 (amber-400) → #E8A728 / #D97706 (DESIGN warning)
  applied to StatusIcon, StatusBadge, chart bars, duration gradient, KPI bar.
- Tooltip background: #1e1e2e → #2D2823 (DESIGN tooltip spec).
- StatusBadge: removed `uppercase` text-transform (DESIGN: no uppercase chips).
- rgba tints updated from Tailwind blue to brand primary rgba(26,58,143,…).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bbbf8078-89c0-4c56-9ecc-b445d40df883

📥 Commits

Reviewing files that changed from the base of the PR and between e9899a2 and 967cad0.

📒 Files selected for processing (2)
  • ui/src/pages/DocsPage.tsx
  • ui/src/pages/PlaywrightDashboard.tsx

📝 Walkthrough

Walkthrough

PlaywrightDashboard gains structured SSE event handling for AI summary streaming, archived run log restoration, and a comprehensive design system color refresh. Documentation updated for Gemini/Ollama stack. CHANGELOG and README revised to reflect these changes.

Changes

Dashboard & Documentation Updates

Layer / File(s) Summary
Documentation and changelog updates
CHANGELOG.md, README.md, ui/src/pages/DocsPage.tsx
CHANGELOG adds entries for PlaywrightDashboard design system pass and DocsPage rewrite; README features table reformatted with expanded multi-agent collaboration and design token descriptions; DocsPage troubleshooting apostrophe escaped.
SSE summary event typing and QA summary streaming
ui/src/pages/PlaywrightDashboard.tsx
runWithSSE and runDynamicTest parse structured JSON SSE events (summary_start/chunk/done) and stream QA summary chunks into a dedicated team-manager chat message; fetchResults restores runLog for archived runs and clears it when returning to latest.
Dashboard design system color palette refresh
ui/src/pages/PlaywrightDashboard.tsx
Systematic color palette update across all dashboard UI: run history charts/tables, status icons/badges, KPI visualizations, timeline, editor controls, chat, header, settings, and filter pills adopt new hex-based accents (#1a3a8f, #34C759, #EF4444, #E8A728, #D97706, #16A34A).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • MyNameIsEdi/open-qa#109: Overlaps in SSE parsing for /api/run-dynamic-test endpoint and runDynamicTest summary event handling (summary_start/chunk/done phases).
  • MyNameIsEdi/open-qa#111: Both modify PlaywrightDashboard SSE event handling for Phase 2 AI summary and archived run runLog rehydration.
  • MyNameIsEdi/open-qa#113: Overlaps in PlaywrightDashboard SSE typing, summary event handling, and archived-run log restoration logic.

Poem

🐰 A spectrum blooms across the dash so bright,
New blues and greens and ambers paint the flight,
Each summary streams in chunks of wisdom true,
While archived runs remember all they knew,
Design and function dance—a perfect pair!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely template boilerplate with no actual content filled in—no summary, no issue reference, no type of change selected, and no checklist items completed. Fill in the Description section with a summary of changes, link any related issue, select the appropriate Type of change, and check off completed checklist items to accurately document the PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feat/design system compliance' is directly related to the main changes in the PR, which broadly involve design system updates across multiple files including color/token updates and documentation adjustments.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/design-system-compliance

Comment @coderabbitai help to get the list of available commands and usage tips.

… feature row

Satisfies check-docs-updated.sh CI requirement — README.md must be in
the diff whenever ui/src/ files change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/src/pages/DocsPage.tsx (1)

35-308: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Localize Docs content instead of hardcoded English blocks

Most newly added user-facing strings are hardcoded in sections (for example Line 37, Line 78, Line 230, Line 268), so they cannot be translated through react-i18next. This makes the Docs page effectively English-only and hard to maintain as content evolves. Please move these strings into translation resources and reference them via t(...) (or structured translation objects) for each block.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/pages/DocsPage.tsx` around lines 35 - 308, The docs content is
hardcoded in the sections/blocks array (the constant named sections in
DocsPage.tsx) so it must be replaced with translation keys; extract each
user-facing string (paragraph text, list items, code labels, table headers/rows,
FAQ q/a, roadmap entries) into your i18n resource files (e.g. under
docs.sections.*) and update the sections data to reference
t('docs.sections.<key>') or structured translation objects (e.g.
t('docs.sections.env-vars.blocks.0.text', { returnObjects: true })) using the
useTranslation hook (t) in DocsPage.tsx so every block reads content via t(...)
instead of literal English strings. Ensure code block labels and table rows also
use translation keys and keep existing block type shape so UI rendering (blocks
map) continues to work.
🧹 Nitpick comments (1)
ui/src/pages/PlaywrightDashboard.tsx (1)

4807-4812: ⚡ Quick win

Keep the SSE payload parser strictly typed.

Falling back to Record<string, unknown> turns these API responses back into a generic bag, so any JSON object with an evt field is accepted and skipped out of the plain-log path. A small isSummaryEvent() guard would keep this aligned with the declared SummaryEvent contract in both parsers.

Possible fix
+ function isSummaryEvent(value: unknown): value is SummaryEvent {
+   if (!value || typeof value !== 'object' || !('evt' in value)) return false;
+   const evt = (value as { evt?: unknown }).evt;
+   return evt === 'summary_start' || evt === 'summary_chunk' || evt === 'summary_done';
+ }
+
  // First try to parse as a structured event object
- let evt: SummaryEvent | Record<string, unknown> | null = null;
+ let evt: SummaryEvent | null = null;
  try {
-   const parsed = JSON.parse(raw);
-   if (parsed && typeof parsed === 'object' && 'evt' in parsed) {
-     evt = parsed as SummaryEvent | Record<string, unknown>;
-   }
+   const parsed: unknown = JSON.parse(raw);
+   if (isSummaryEvent(parsed)) evt = parsed;
  } catch {
    /* not JSON — fall through to plain string */
  }

As per coding guidelines, **/*.{ts,tsx}: Use strict TypeScript interfaces/types for all test data, API responses, and parameters. No any types. Ever.

Also applies to: 4960-4965

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/pages/PlaywrightDashboard.tsx` around lines 4807 - 4812, The SSE
payload parser currently falls back to a loose Record<string, unknown> (in the
block that assigns evt from JSON.parse(raw)), which weakens typing; add a strict
type guard function isSummaryEvent(obj: unknown): obj is SummaryEvent and use it
when validating parsed so evt is only set when isSummaryEvent(parsed) is true
(remove the Record<string, unknown> fallback), update both locations referenced
(the current parse at the evt assignment and the similar block at the other
occurrence around lines 4960-4965), and ensure downstream code expects
SummaryEvent or null so the compiler enforces the contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ui/src/pages/PlaywrightDashboard.tsx`:
- Around line 4636-4637: The current call to setRunLog unconditionally replaces
the live log and trims it to 999 lines; change it so the run log is only
replaced when viewing an archived run (i.e. when runId is truthy and data.runLog
is an array) and preserved on latest-run refreshes (do nothing / keep previous
state when runId is falsy). In the archived-run branch (where you still update),
stop trimming to 999 and either remove the slice or use the server window size
(e.g., 5000) so you don't truncate server-kept history; update the logic around
setRunLog, runId and data.runLog (the fetchResults post-stream refresh path)
accordingly.

---

Outside diff comments:
In `@ui/src/pages/DocsPage.tsx`:
- Around line 35-308: The docs content is hardcoded in the sections/blocks array
(the constant named sections in DocsPage.tsx) so it must be replaced with
translation keys; extract each user-facing string (paragraph text, list items,
code labels, table headers/rows, FAQ q/a, roadmap entries) into your i18n
resource files (e.g. under docs.sections.*) and update the sections data to
reference t('docs.sections.<key>') or structured translation objects (e.g.
t('docs.sections.env-vars.blocks.0.text', { returnObjects: true })) using the
useTranslation hook (t) in DocsPage.tsx so every block reads content via t(...)
instead of literal English strings. Ensure code block labels and table rows also
use translation keys and keep existing block type shape so UI rendering (blocks
map) continues to work.

---

Nitpick comments:
In `@ui/src/pages/PlaywrightDashboard.tsx`:
- Around line 4807-4812: The SSE payload parser currently falls back to a loose
Record<string, unknown> (in the block that assigns evt from JSON.parse(raw)),
which weakens typing; add a strict type guard function isSummaryEvent(obj:
unknown): obj is SummaryEvent and use it when validating parsed so evt is only
set when isSummaryEvent(parsed) is true (remove the Record<string, unknown>
fallback), update both locations referenced (the current parse at the evt
assignment and the similar block at the other occurrence around lines
4960-4965), and ensure downstream code expects SummaryEvent or null so the
compiler enforces the contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 400f344f-e2e8-4953-94a6-7cd91aa10b3a

📥 Commits

Reviewing files that changed from the base of the PR and between b7e4a42 and afdab98.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • README.md
  • server/index.ts
  • ui/src/pages/DocsPage.tsx
  • ui/src/pages/PlaywrightDashboard.tsx

Comment on lines +4636 to +4637
// Restore the archived stdout when viewing an old run; clear when switching to latest.
setRunLog(runId && Array.isArray(data.runLog) ? data.runLog.slice(-999) : []);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't wipe the run log during the post-run refresh.

Both SSE runners call fetchResults() as soon as streaming finishes, so this latest-run branch clears the just-streamed output and makes the Run Output panel disappear right after a successful run. It also trims archived snapshots back to 999 lines even though the server now keeps a 5000-line window. Preserve the current log on latest refreshes, and only replace it when you actually hydrate an archived run.

Possible fix
- const fetchResults = useCallback(async (runId?: string) => {
+ const fetchResults = useCallback(async (runId?: string, opts?: { preserveRunLog?: boolean }) => {
    setIsLoading(true);
    try {
      const url = runId
        ? `${API_BASE}/api/playwright/results/${runId}`
        : `${API_BASE}/api/playwright/results`;
      const res = await fetch(url);
      // ...
      setExpandedSuites(Object.fromEntries(data.suites.map((s) => [s.id, true])));
-     setRunLog(runId && Array.isArray(data.runLog) ? data.runLog.slice(-999) : []);
+     const hydratedLog = Array.isArray(data.runLog) ? data.runLog.slice(-5000) : [];
+     if (runId) {
+       setRunLog(hydratedLog);
+       setShowLog(hydratedLog.length > 0);
+     } else if (!opts?.preserveRunLog) {
+       setRunLog([]);
+     }
    } catch {
      setServerOnline(false);
      setDemoMode(true);
    } finally {
      setIsLoading(false);
    }
  }, []);

And keep the live log after streaming completes:

- await fetchResults();
+ await fetchResults(undefined, { preserveRunLog: true });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/pages/PlaywrightDashboard.tsx` around lines 4636 - 4637, The current
call to setRunLog unconditionally replaces the live log and trims it to 999
lines; change it so the run log is only replaced when viewing an archived run
(i.e. when runId is truthy and data.runLog is an array) and preserved on
latest-run refreshes (do nothing / keep previous state when runId is falsy). In
the archived-run branch (where you still update), stop trimming to 999 and
either remove the slice or use the server window size (e.g., 5000) so you don't
truncate server-kept history; update the logic around setRunLog, runId and
data.runLog (the fetchResults post-stream refresh path) accordingly.

MyNameIsEdi and others added 2 commits May 24, 2026 03:16
…mpliance

# Conflicts:
#	CHANGELOG.md
#	README.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant