Skip to content

⚡ Bolt: Memoize filtered analyzed user messages to prevent O(N) re-filtering on every render#337

Open
daggerstuff wants to merge 9 commits intostagingfrom
perf/MentalHealthChatDemo-useMemo-id-5867982123106047137
Open

⚡ Bolt: Memoize filtered analyzed user messages to prevent O(N) re-filtering on every render#337
daggerstuff wants to merge 9 commits intostagingfrom
perf/MentalHealthChatDemo-useMemo-id-5867982123106047137

Conversation

@daggerstuff
Copy link
Copy Markdown
Owner

@daggerstuff daggerstuff commented Mar 31, 2026

💡 What: Memoize the filtering of messages for analyzedUserMessages using useMemo and replace inline filter and some calls with the memoized array.
🎯 Why: The component previously performed O(N) operations by iterating over the messages array inline on every render to find messages with mentalHealthAnalysis. This creates a rendering bottleneck as the chat session grows.
📊 Impact: Prevents unnecessary O(N) re-filtering and O(N) condition checks on every React render cycle.
🔬 Measurement: Profile the component rendering speed when the messages array becomes very large; the render time overhead from re-filtering will be eliminated.


PR created automatically by Jules for task 5867982123106047137 started by @daggerstuff

Summary by Sourcery

Enhancements:

  • Introduce a memoized collection of analyzed user messages and replace repeated inline filtering and existence checks with the shared memoized result to improve render performance.

Summary by cubic

Memoized filtering of analyzed user messages in MentalHealthChatDemo to avoid O(N) re-filtering on each render and keep the UI smooth. CI runs playwright with the shared config, publishes reports, and uses webServer for preview to avoid port collisions.

  • Refactors

    • Memoized analyzedUserMessages with useMemo and reused it for recent analysis and empty-state checks.
  • Bug Fixes

    • Run playwright with --config=config/playwright.config.ts; use the tests dir and let webServer handle build/preview to prevent port conflicts.
    • Publish Playwright reports to config/playwright-report and config/test-results for CI artifacts.

Written for commit 85f0d5c. Summary will update on new commits.

Summary by CodeRabbit

  • Refactor
    • Improved Insights panel performance by memoizing filtered analysis data for faster, more efficient rendering.
  • Tests
    • Updated browser test configuration and added automated test result reports to improve test execution and reporting.

…ltering on every render

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pixelated Ready Ready Preview, Comment Apr 1, 2026 10:13am

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 31, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Memoizes the filtered subset of user messages with mental health analysis and reuses it in render logic to avoid repeated O(N) filtering and condition checks on every render.

Sequence diagram for memoized analyzedUserMessages during React render

sequenceDiagram
  participant ReactRenderer
  participant MentalHealthChatDemo
  participant useMemo_analyzedUserMessages
  participant MessagesArray

  ReactRenderer->>MentalHealthChatDemo: render(messages)
  MentalHealthChatDemo->>useMemo_analyzedUserMessages: getAnalyzedUserMessages(messages)
  alt messages_reference_changed
    useMemo_analyzedUserMessages->>MessagesArray: filter(role === user && mentalHealthAnalysis && !isProcessing)
    MessagesArray-->>useMemo_analyzedUserMessages: analyzedUserMessages
    useMemo_analyzedUserMessages-->>MentalHealthChatDemo: new analyzedUserMessages
  else messages_reference_unchanged
    useMemo_analyzedUserMessages-->>MentalHealthChatDemo: cached analyzedUserMessages
  end

  MentalHealthChatDemo->>MentalHealthChatDemo: renderAnalyzedHistory(analyzedUserMessages.slice(-2))
  MentalHealthChatDemo->>MentalHealthChatDemo: renderEmptyStateIf(analyzedUserMessages.length === 0)
  MentalHealthChatDemo-->>ReactRenderer: rendered_output
Loading

Flow diagram for rendering logic using analyzedUserMessages

flowchart TD
  A_start[Start render] --> B_getAnalyzed[Use analyzedUserMessages from useMemo]
  B_getAnalyzed --> C_haveAnalyzed{analyzedUserMessages.length > 0}
  C_haveAnalyzed -->|Yes| D_slice[Take last two analyzedUserMessages]
  D_slice --> E_renderList[Render analysis cards for sliced messages]
  C_haveAnalyzed -->|No| F_renderEmpty[Render empty state Card]
  E_renderList --> G_end[End render]
  F_renderEmpty --> G_end[End render]
Loading

File-Level Changes

Change Details Files
Memoize analyzed user messages and reuse them instead of re-filtering the full messages list on each render.
  • Introduce a useMemo hook that precomputes the array of user messages with mentalHealthAnalysis that are not processing, derived from messages.
  • Replace the inline filter call used to render the last two analyzed user messages with the memoized analyzedUserMessages array.
  • Replace the inline some condition used to detect absence of analyzed user messages with a length check on the memoized analyzedUserMessages array.
src/components/MentalHealthChatDemo.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

Introduced a memoized analyzedUserMessages in the Mental Health chat component to avoid repeated per-render filters; updated Playwright test discovery and CI test invocation to use an explicit Playwright config; added test result/report files (JUnit XML and JSON).

Changes

Cohort / File(s) Summary
Chat UI component
src/components/MentalHealthChatDemo.tsx
Added useMemo to compute analyzedUserMessages (user messages with mentalHealthAnalysis and not processing). Replaced repeated messages.filter(...)/messages.some(...) checks in the Insights panel with the memoized value.
Playwright config
config/playwright.config.ts
Changed Playwright testDir from ./tests../tests (test discovery root adjusted).
CI workflow
.github/workflows/browser-tests.yml
Updated browser test step to run Playwright with explicit config (--config=config/playwright.config.ts) and removed workflow-managed build/preview-server/start-wait steps.
Test results / reports
config/test-results/junit.xml, config/test-results/results.json
Added Playwright/JUnit test report outputs: a JUnit XML with skipped tests and a JSON results snapshot capturing multi-project test metadata and skipped test entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • CharlieHelps

Poem

🐰 I hopped through the code,
Caught filters on the road,
Memoized my find—
Renderings feel kind,
Tests hum while reports gently glow. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly addresses the main change: memoizing filtered analyzed user messages using useMemo to prevent O(N) re-filtering on every render, which aligns with the primary modification in MentalHealthChatDemo.tsx.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 perf/MentalHealthChatDemo-useMemo-id-5867982123106047137

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

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

Memoizing the filtered messages is a good improvement, but it relies on messages being updated immutably (otherwise useMemo can return stale results). Also, getAnalysisHistory() still performs a separate filter/map pass over messages; now that analyzedUserMessages exists, you can centralize the criteria and avoid redundant work.

Additional notes (1)
  • Performance | src/components/MentalHealthChatDemo.tsx:386-394
    Now that analyzedUserMessages exists, you can likely eliminate an extra pass over messages by deriving analysis history from it (and potentially drop getAnalysisHistory entirely). This keeps the “what counts as analyzed” criteria centralized and avoids redundant filtering work when messages changes.
Summary of changes

Summary

  • Added a memoized analyzedUserMessages array via useMemo to cache messages.filter(...) results.
  • Updated the Live Analysis Results UI to use analyzedUserMessages instead of inline .filter(...) and replaced an inline .some(...) check with analyzedUserMessages.length === 0.

Key code paths touched

  • Memoization added near getAnalysisHistory() (useMemo(() => messages.filter(...), [messages])).
  • Rendering logic now slices/maps analyzedUserMessages (.slice(-2).map(...)) and uses it for the empty-state condition.

Comment on lines +386 to +390
const analyzedUserMessages = useMemo(() => {
return messages.filter(
(m) => m.role === 'user' && m.mentalHealthAnalysis && !m.isProcessing,
)
}, [messages])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

useMemo only helps if messages changes by reference when updated. If messages is ever mutated in-place (e.g., messages.push(...) followed by a state set with the same array), this memo can go stale and the UI will fail to update correctly.

Suggestion

Ensure all messages updates are immutable (create a new array each time). For example:

setMessages((prev) => [...prev, nextMessage])

Reply with "@CharlieHelps yes please" if you'd like me to add a commit that audits the messages update sites in this component to guarantee immutable updates.

…fig/playwright.config.ts

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Memoizes the subset of user messages that have completed mental health analysis to avoid repeated inline O(N) filtering/existence checks on each render, improving performance as chat histories grow.

Changes:

  • Added a useMemo-backed analyzedUserMessages derived from messages.
  • Replaced inline messages.filter(...) rendering logic with the memoized array.
  • Replaced inline messages.some(...) empty-state check with a length check on the memoized array.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
src/components/MentalHealthChatDemo.tsx Introduces memoized analyzedUserMessages and reuses it for rendering and empty-state logic to reduce render-time work.
.github/workflows/browser-tests.yml Adjusts workflow quoting/formatting and adds an explicit Playwright --config argument for browser tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…ltering on every render

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/browser-tests.yml">

<violation number="1">
P2: Removing the explicit `--config=config/playwright.config.ts` means Playwright will not load the intended config (there is no root `playwright.config.*`). This can cause the browser tests to run with incorrect defaults or fail to resolve settings from the config.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…ltering on every render

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
…n browser-tests.yml

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="config/test-results/results.json">

<violation number="1" location="config/test-results/results.json:1">
P2: Do not commit generated Playwright JSON results; this file is runtime test output and should be excluded from version control.</violation>
</file>

<file name="config/test-results/junit.xml">

<violation number="1" location="config/test-results/junit.xml:1">
P2: Do not commit generated JUnit test-result artifacts; they cause noisy diffs and can leave stale CI status data in version control.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
config/test-results/results.json (1)

1-467: Avoid checking in generated Playwright result snapshots.

This file is machine-generated and bakes in absolute paths, timestamps, and run-specific outcomes. Keeping it under version control will create noisy diffs and stale review signal; it is better kept as a CI artifact and ignored from git.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/test-results/results.json` around lines 1 - 467, The committed file
config/test-results/results.json is a generated Playwright test artifact (see
"json" reporter with "outputFile": "test-results/results.json") and should be
removed from source control; delete config/test-results/results.json from the
repo, add an appropriate ignore rule (e.g., config/test-results/ or
test-results/*.json) to .gitignore so future runs aren’t committed, and commit
the removal; optionally ensure CI uploads the Playwright report artifact instead
of checking it in.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/browser-tests.yml:
- Around line 59-66: The workflow step "Run browser tests" currently uses
config/playwright.config.ts which writes Playwright reporter outputs to
config/test-results/results.json, but the subsequent upload step still targets
public/test-results/ so the report job misses files; update the upload action to
include the config/test-results/ directory (or change the Playwright reporter
path to public/test-results/) so the artifacts produced by the Playwright
reporter are uploaded and available to the report job, making sure to reference
the Playwright config at config/playwright.config.ts and the upload step that
currently points to public/test-results/.
- Around line 59-66: The workflow's test-report parsing expects Mocha-style
.failures/.passes arrays but Playwright emits a JSON with a "stats" object;
update the report generation logic (the step that reads FAILED, PASSED, SKIPPED,
TOTAL_TESTS after the "Run browser tests" job) to produce Playwright JSON (add
--reporter=json, e.g. --reporter=json=playwright-report.json to the pnpm exec
playwright command) and replace any jq/grep reads of .failures and .passes with
reads of .stats.unexpected (FAILED), .stats.expected (PASSED), and
.stats.skipped (SKIPPED), then compute TOTAL_TESTS from those three fields;
ensure variable names FAILED, PASSED, SKIPPED, TOTAL_TESTS are used consistently
when rendering the final status.

In `@config/playwright.config.ts`:
- Around line 73-74: The testIgnore glob no longer matches because testDir is
set to '../tests'—update the testIgnore entry in the config (the testIgnore
array in playwright.config.ts) to match paths relative to the new test root;
replace 'tests/accessibility/**' with 'accessibility/**' (or use a more
defensive '**/accessibility/**') so accessibility tests are actually excluded
when testDir is '../tests'.

---

Nitpick comments:
In `@config/test-results/results.json`:
- Around line 1-467: The committed file config/test-results/results.json is a
generated Playwright test artifact (see "json" reporter with "outputFile":
"test-results/results.json") and should be removed from source control; delete
config/test-results/results.json from the repo, add an appropriate ignore rule
(e.g., config/test-results/ or test-results/*.json) to .gitignore so future runs
aren’t committed, and commit the removal; optionally ensure CI uploads the
Playwright report artifact instead of checking it in.
🪄 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

Run ID: dc6250e8-54f0-44c9-82b1-0b70acaa2609

📥 Commits

Reviewing files that changed from the base of the PR and between 328e6a7 and 2e0760c.

📒 Files selected for processing (5)
  • .github/workflows/browser-tests.yml
  • config/playwright-report/index.html
  • config/playwright.config.ts
  • config/test-results/junit.xml
  • config/test-results/results.json
✅ Files skipped from review due to trivial changes (1)
  • config/test-results/junit.xml

Comment on lines +59 to +66
- name: Run browser tests
run: |
export NODE_ENV=test
export DISABLE_AUTH=true
export DISABLE_WEB_FONTS=true
export SKIP_MSW=true
export BASE_URL=http://localhost:4323
pnpm exec playwright test tests/browser/auth.spec.ts tests/browser/cross-browser-compatibility.spec.ts --project=chromium --max-failures=10 --workers=1
pnpm exec playwright test tests/browser/auth.spec.ts tests/browser/cross-browser-compatibility.spec.ts --config=config/playwright.config.ts --project=chromium --max-failures=10 --workers=1
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

Upload config/test-results/ or the report job will miss the reporter output.

Line 66 now activates config/playwright.config.ts, and this PR already shows the JSON reporter writing to config/test-results/results.json. Lines 74-78 still upload public/test-results/, so the downstream report job never receives the Playwright JSON/JUnit files it is supposed to summarize.

📦 Minimal fix
       - name: Upload test results
         if: always()
         uses: actions/upload-artifact@v7.0.0
         with:
           name: browser-test-results-${{ github.run_id }}
           path: |
             playwright-report/
+            config/test-results/
             public/test-results/

Also applies to: 70-79

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/browser-tests.yml around lines 59 - 66, The workflow step
"Run browser tests" currently uses config/playwright.config.ts which writes
Playwright reporter outputs to config/test-results/results.json, but the
subsequent upload step still targets public/test-results/ so the report job
misses files; update the upload action to include the config/test-results/
directory (or change the Playwright reporter path to public/test-results/) so
the artifacts produced by the Playwright reporter are uploaded and available to
the report job, making sure to reference the Playwright config at
config/playwright.config.ts and the upload step that currently points to
public/test-results/.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

jq '{
  has_passes: has("passes"),
  has_failures: has("failures"),
  stats: .stats
}' config/test-results/results.json

Repository: daggerstuff/pixelated

Length of output: 288


🏁 Script executed:

cat -n .github/workflows/browser-tests.yml | sed -n '139,181p'

Repository: daggerstuff/pixelated

Length of output: 2765


🏁 Script executed:

cat -n .github/workflows/browser-tests.yml | sed -n '59,66p'

Repository: daggerstuff/pixelated

Length of output: 551


Update Playwright JSON parsing in test report generation.

Line 66 uses Playwright's test runner, which outputs results to a JSON schema with .stats.expected, .stats.unexpected, and .stats.skipped, but lines 147–148 still parse Mocha-style .failures and .passes arrays that don't exist in the Playwright output. With the current code, FAILED and PASSED both become 0, making TOTAL_TESTS 0, and lines 177–180 incorrectly render "All Tests Passed" even when tests were skipped or the test run produced no parseable results.

Replace the jq and grep parsing with Playwright's actual schema:

Suggested fix
-                      FAILED=$(jq -r 'try (.failures // []) | length' "$json_file" 2>/dev/null || echo "0")
-                      PASSED=$(jq -r 'try (.passes // []) | length' "$json_file" 2>/dev/null || echo "0")
+                      FAILED=$(jq -r 'try (.stats.unexpected // 0)' "$json_file" 2>/dev/null || echo "0")
+                      PASSED=$(jq -r 'try (.stats.expected // 0)' "$json_file" 2>/dev/null || echo "0")
+                      SKIPPED=$(jq -r 'try (.stats.skipped // 0)' "$json_file" 2>/dev/null || echo "0")
                   else
-                      FAILED=$(grep -o '"failures":\s*\[[^]]*\]' "$json_file" 2>/dev/null | wc -l || echo "0")
-                      PASSED=$(grep -o '"passes":\s*\[[^]]*\]' "$json_file" 2>/dev/null | wc -l || echo "0")
+                      FAILED=$(grep -o '"unexpected":\s*[0-9]\+' "$json_file" 2>/dev/null | grep -o '[0-9]\+' | head -1 || echo "0")
+                      PASSED=$(grep -o '"expected":\s*[0-9]\+' "$json_file" 2>/dev/null | grep -o '[0-9]\+' | head -1 || echo "0")
+                      SKIPPED=$(grep -o '"skipped":\s*[0-9]\+' "$json_file" 2>/dev/null | grep -o '[0-9]\+' | head -1 || echo "0")
                   fi

                   ISSUE_COUNT=$((ISSUE_COUNT + FAILED))
                   PASSED_TESTS=$((PASSED_TESTS + PASSED))
-                  TOTAL_TESTS=$((TOTAL_TESTS + FAILED + PASSED))
+                  TOTAL_TESTS=$((TOTAL_TESTS + FAILED + PASSED + SKIPPED))
               done
...
-          if [ "$ISSUE_COUNT" -gt 0 ]; then
+          if [ "$TOTAL_TESTS" -eq 0 ]; then
+              echo '<div class="summary">' >> report.html
+              echo '<h2>⚠️ No Executed Tests</h2>' >> report.html
+              echo '<p>Playwright produced no runnable test results.</p>' >> report.html
+              echo '</div>' >> report.html
+          elif [ "$ISSUE_COUNT" -gt 0 ]; then
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/browser-tests.yml around lines 59 - 66, The workflow's
test-report parsing expects Mocha-style .failures/.passes arrays but Playwright
emits a JSON with a "stats" object; update the report generation logic (the step
that reads FAILED, PASSED, SKIPPED, TOTAL_TESTS after the "Run browser tests"
job) to produce Playwright JSON (add --reporter=json, e.g.
--reporter=json=playwright-report.json to the pnpm exec playwright command) and
replace any jq/grep reads of .failures and .passes with reads of
.stats.unexpected (FAILED), .stats.expected (PASSED), and .stats.skipped
(SKIPPED), then compute TOTAL_TESTS from those three fields; ensure variable
names FAILED, PASSED, SKIPPED, TOTAL_TESTS are used consistently when rendering
the final status.

Comment on lines 73 to 74
testDir: '../tests',
testIgnore: ['tests/accessibility/**'],
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 | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

In Playwright config, how are testIgnoreglob patterns resolved whentestDiris set? IftestDiris../tests, will testIgnore: ['tests/accessibility/']still ignoretests/accessibility/accessibility-audit.spec.ts, or should the pattern be accessibility///accessibility/ instead?

💡 Result:

In Playwright config, testIgnore glob patterns are matched against the absolute file path of candidate test files discovered by recursively scanning the testDir directory. The patterns are standard glob patterns (using minimatch), where matches any number of directories, * matches filenames without path separator, etc. For testDir: '../tests', the absolute path of tests/accessibility/accessibility-audit.spec.ts (assuming config at root and tests sibling) is something like /path/to/project/tests/accessibility/accessibility-audit.spec.ts. - testIgnore: ['tests/accessibility/'] will NOT match because it expects a subpath starting with tests/ directly under root, but the path from testDir starts with accessibility/. - Use testIgnore: ['accessibility/'] to match paths under tests/accessibility/. - /accessibility/ would also work, matching anywhere under testDir. Official docs confirm: "Matching is performed against the absolute file path. Strings are treated as glob patterns. For example, '/test-assets/' will ignore any files in the test-assets directory." Examples use patterns like *test-assets or /test-assets/ that work regardless of testDir because they use or simple *. Secondary source notes patterns are "relative to the project's testDir", meaning they effectively match the subpath under testDir when using non-anchored globs, but technically against full absolute path.

Citations:


Update testIgnore glob for the new test directory.

Line 73 sets testDir: '../tests', but Line 74 uses testIgnore: ['tests/accessibility/**']. Playwright matches testIgnore patterns against the absolute path of discovered test files. With the new test root, paths will start from accessibility/, not tests/accessibility/, so the current pattern won't exclude accessibility tests as intended.

♻️ Minimal fix
-  testIgnore: ['tests/accessibility/**'],
+  testIgnore: ['accessibility/**'],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
testDir: '../tests',
testIgnore: ['tests/accessibility/**'],
testDir: '../tests',
testIgnore: ['accessibility/**'],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/playwright.config.ts` around lines 73 - 74, The testIgnore glob no
longer matches because testDir is set to '../tests'—update the testIgnore entry
in the config (the testIgnore array in playwright.config.ts) to match paths
relative to the new test root; replace 'tests/accessibility/**' with
'accessibility/**' (or use a more defensive '**/accessibility/**') so
accessibility tests are actually excluded when testDir is '../tests'.

…ltering on every render

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.com>
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="config/playwright.config.ts">

<violation number="1">
P1: `testDir` now points to `config/tests`, so Playwright will miss the repository’s actual test suite under top-level `tests/`.</violation>
</file>

<file name=".github/workflows/browser-tests.yml">

<violation number="1">
P1: The Playwright run no longer points to the repo’s main config file, so CI skips the intended shared test configuration.</violation>

<violation number="2">
P2: Using `sleep 15` for server readiness is flaky; replace it with an actual health check loop before running tests.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…ltering on every render

Co-authored-by: daggerstuff <261005129+daggerstuff@users.noreply.github.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.

2 participants