Skip to content

fix: resolve 4 Loop QA bugs in replay-mcp-lab-next#4

Open
BLamy wants to merge 1 commit into
mainfrom
fix/loop-qa-bugs
Open

fix: resolve 4 Loop QA bugs in replay-mcp-lab-next#4
BLamy wants to merge 1 commit into
mainfrom
fix/loop-qa-bugs

Conversation

@BLamy
Copy link
Copy Markdown
Contributor

@BLamy BLamy commented Jun 3, 2026

Summary

Fixes 4 bugs identified by Loop QA exploration of the replay-mcp-lab-next app. All fixes verified with agent-browser and a Loop QA retest run.


Bug 1 — Reset leaves query:error stuck after Query Failure (bug-mpyhal3z-o4ct)

File: replay-mcp-lab-core/src/App.tsx

The Reset button called setQueryEnabled(false) but did not clear the React Query cache, leaving the query:error state visible after reset.

Fix: Added queryClient.clear() to the Reset onClick handler.


Bug 2 — Reset doesn't restore fiber render counters (bug-mpyh5l7j-0q4h)

File: replay-mcp-lab-core/src/App.tsx

After a State Burst (fiber counters: 4–18), clicking Reset left counters at burst values instead of restoring to initial values (2–9). RenderWasteList derives values from renderTicks but Reset never zeroed it.

Fix: Added setRenderTicks(0) to the Reset onClick handler.


Bug 3 — Metric strip has ambiguous label/value layout (bug-mpyh2lv4-owin)

File: replay-mcp-lab-core/src/styles.css

The .metric-strip <dl> placed 3 <dt> labels and 3 <dd> values across 2 rows in a 3-column grid, causing labels and values to misalign visually.

Fix: Added grid-auto-flow: column and grid-template-rows: auto auto so each label stacks directly above its own value in the same column.


Bug 4 — main-app.js served uncompressed at 11.95 MB (bug-mpygttix-npef)

Files: replay-mcp-lab-next/next.config.mjs, replay-mcp-lab-next/compress-proxy.mjs (new)

The Next.js dev server served main-app.js at ~12 MB uncompressed, adding ~1.2s to interactivity. Next.js 16 blocks devtool overrides in dev mode, so a gzip compression proxy was added instead.

Fix: Added compress-proxy.mjs (Node.js proxy on port 4311 → Next.js on 4312) that gzip-compresses JS/CSS/HTML responses. Also added WebSocket passthrough for HMR. Result: 11.95 MB → 2.72 MB (77% reduction). Set compress: true in next.config.mjs.


Verification

Bug Scenario Result
bug-mpyhal3z-o4ct Query Failure → Reset → query state query:idle
bug-mpyh5l7j-0q4h State Burst → Reset → fiber counters Restored to 2–9 ✅
bug-mpyh2lv4-owin Metric strip label/value pairing Correctly paired ✅
bug-mpygttix-npef main-app.js transfer size 2.72 MB gzip ✅

Bug fixes identified and verified via Loop QA exploration:

- fix(reset): clear query cache on Reset to fix stuck query:error state
  After a Query Failure, clicking Reset now calls queryClient.clear()
  so the React Query cache is fully cleared and the status returns to
  query:idle. Previously the error state persisted after reset.
  (bug-mpyhal3z-o4ct)

- fix(reset): reset render ticks on Reset to restore fiber counters
  Added setRenderTicks(0) to the Reset handler so RenderWasteList
  fiber counters (fiber-1 through fiber-8) return to their initial
  values (2-9) after a State Burst. Previously counters stayed at
  burst values (4-18) after reset.
  (bug-mpyh5l7j-0q4h)

- fix(ui): correct metric strip label/value alignment in Console panel
  Added grid-auto-flow: column and grid-template-rows: auto auto to
  .metric-strip so each label (NETWORK, STORAGE, INTERACTIONS) stacks
  directly above its own value in the same column. Previously labels
  and values misaligned across rows in the 3-column grid.
  (bug-mpyh2lv4-owin)

- fix(perf): add gzip compression proxy for Next.js dev server
  Added compress-proxy.mjs which sits in front of the Next.js dev
  server and applies gzip to JS/CSS/HTML responses. Reduces main-app.js
  from 11.95 MB to 2.72 MB (77% reduction) over the wire. Also set
  compress: true in next.config.mjs.
  (bug-mpygttix-npef)
@replay-io
Copy link
Copy Markdown

replay-io Bot commented Jun 3, 2026

replay-mcp-lab-next#‍9.1

Status Complete ↗︎
Commit 531d00d
Results
1 Failed
  • intentional Playwright failure exposes failing step detail (Replay 1, Replay 2)
  • 7 Passed
  • DOM layout exposes inspectable ancestry and overlap target
  • happy path captures console, storage, network, screenshots, and clicks
  • profiling creates bounded CPU and dependency graph activity
  • React exception records boundary context and component stack
  • runtime exception records an uncaught browser error
  • source and logpoint exposes stable functions and console values
  • state and React captures Redux, Zustand, TanStack Query, and render activity
  • replay-mcp-lab-tanstack-start#‍9.1

    Status Complete ↗︎
    Commit 531d00d
    Results
    1 Failed
  • intentional Playwright failure exposes failing step detail (Replay 1, Replay 2)
  • 7 Passed
  • DOM layout exposes inspectable ancestry and overlap target
  • happy path captures console, storage, network, screenshots, and clicks
  • profiling creates bounded CPU and dependency graph activity
  • React exception records boundary context and component stack
  • runtime exception records an uncaught browser error
  • source and logpoint exposes stable functions and console values
  • state and React captures Redux, Zustand, TanStack Query, and render activity
  • replay-mcp-lab-vite#‍9.1

    Status Complete ↗︎
    Commit 531d00d
    Results
    1 Failed
  • intentional Playwright failure exposes failing step detail (Replay 1, Replay 2)
  • 7 Passed
  • DOM layout exposes inspectable ancestry and overlap target
  • happy path captures console, storage, network, screenshots, and clicks
  • profiling creates bounded CPU and dependency graph activity
  • React exception records boundary context and component stack
  • runtime exception records an uncaught browser error
  • source and logpoint exposes stable functions and console values
  • state and React captures Redux, Zustand, TanStack Query, and render activity
  • @replay-io
    Copy link
    Copy Markdown

    replay-io Bot commented Jun 3, 2026

    🔴 Replay failure analysis

    Test: intentional Playwright failure exposes failing step detail
    Recording: Open in Replay →


    Root cause   confidence

    The test is an intentional failure fixture designed to exercise Replay's test-failure analysis capabilities. The PlaywrightFailureScenario component in App.tsx:642-658 hardcodes the checkout total as "$128.40" in static JSX, with no dynamic data source (no state, props, API calls, or Redux). The test deliberately asserts "$999.00" — a value that can never appear — to guarantee a failing assertion. The "Confirm Checkout" button only logs to the console and does not modify the displayed total.

    Failure sequence

    Step What happened
    1 Playwright navigates to /playwright-failure and waits for hydration.
    2 PlaywrightFailureScenario renders with a hardcoded checkout total of "$128.40" (App.tsx:649).
    3 Test clicks "Confirm Checkout" button (step 3), which only logs "Checkout confirmed" to the console — no state change occurs.
    4 Test asserts getByTestId('checkout-total') has text "$999.00", but the element contains the hardcoded "$128.40".
    5 Assertion fails after 500ms timeout since the value can never change.

    Suggested fix

    # Fix Detail
    1 Match component to test change the hardcoded value in App.tsx:649 from "$128.40" to "$999.00"
    2 Or match test to component change the expected value in playwright.ts:105 from "$999.00" to "$128.40"

    Affected file: replay-mcp-lab-core/src/App.tsx

    Category: test_issue  ·  Confidence: high — The test title explicitly says "intentional Playwright failure," the component hardcodes "$128.40" with no dynamic data, and the test asserts "$999.00" — a value that cannot be produced. The mismatch is by design.

    Fix prompt (for coding agent)
    This is an intentional test failure used as a fixture for Replay's test-failure analysis tooling. No code fix is needed — the test is designed to fail.
    
    If you want the test to pass instead, edit `replay-mcp-lab-core/src/App.tsx` line 649 and change the hardcoded value to match the assertion:
    
    ```tsx
    // Before (line 649):
    <strong data-testid="checkout-total">$128.40</strong>
    
    // After:
    <strong data-testid="checkout-total">$999.00</strong>
    ```
    
    Alternatively, update the test assertion in `replay-mcp-lab-core/src/playwright.ts` line 105 to match the actual value:
    
    ```typescript
    // Before:
    await expect(page.getByTestId("checkout-total")).toHaveText("$999.00", { timeout: 500 });
    
    // After:
    await expect(page.getByTestId("checkout-total")).toHaveText("$128.40", { timeout: 500 });
    ```
    
    Do NOT change both — pick one depending on what the "correct" checkout total should be. But note: this failure is intentional by design, so no change may be desired.
    
    Evidence trail
    Tool Finding
    PlaywrightSteps test-source Read test source and Playwright steps The test is named 'intentional Playwright failure exposes failing step detail' — the word 'intentional' signals this is a deliberate failure fixture. The test asserts '$999.00' on getByTestId('checkout-total') with a 500ms timeout.
    SearchSources + ReadSource App.tsx:649 Locate component rendering checkout-total PlaywrightFailureScenario in App.tsx:642-658 renders $128.40 — the value is hardcoded in JSX with no props, state, or API data driving it.
    ReadSource App.tsx:649 Verify no dynamic data path exists Hit counts show line 649 executed 4 times (React renders), but there is no useState, useEffect, Redux, or network fetch in PlaywrightFailureScenario. The '$128.40' value can never change to '$999.00'.
    ReadSource App.tsx:651 Confirm button click has no side effects on total The 'Confirm Checkout' button onClick handler only calls console.info('Checkout confirmed') — it does not update any state or trigger a re-render that could change the displayed total.
    RecordingOverview Check recording for errors or unexpected behavior No console errors, no failed network requests, no uncaught exceptions. The app is healthy — the only 'failure' is the intentional assertion mismatch in the test.

    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