Skip to content

Stabilize cross-platform CI after preview E2E rollout - #4386

Merged
wwwillchen merged 1 commit into
mainfrom
fix/ci-32979318031
Aug 27, 2026
Merged

Stabilize cross-platform CI after preview E2E rollout#4386
wwwillchen merged 1 commit into
mainfrom
fix/ci-32979318031

Conversation

@keppo-bot

@keppo-bot keppo-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix the cross-platform unit and E2E failures exposed by the main CI run after isolated preview testing landed. The changes make the affected tests observe the repository/runtime coordination boundaries that production already enforces and remove Windows-only text/path assumptions.

  • Wait for generated-app preview readiness before the GitHub publish flow. The retained Windows traces showed pnpm install holding the app operation slot for 65–70 seconds, so repository creation stayed queued until the original 60-second assertion timed out.
  • Fence hybrid retry assertions on renderer IPC settlement before probing Git cleanliness or making direct commits, preventing a late Git finalizer from racing the test with .git/index.lock.
  • Give the Git collaboration continuation assertion an explicit loaded-runner timeout while retaining the success UI as the authoritative completion signal.
  • Normalize recorded eval fixture newlines before replay and accept either platform separator in the preview artifact-path assertion. Production behavior is unchanged.
  • Document the generated-app Git sequencing contract for future E2E coverage.

#skip-bugbot

Review in cubic

@keppo-bot
keppo-bot Bot requested a review from a team August 26, 2026 16:13

@chatgpt-codex-connector chatgpt-codex-connector 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.

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faf91bd6e2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


async function waitForCleanGit(cwd: string) {
async function waitForCleanGit(harness: HybridChatHarness) {
await harness.bridge.settleInFlight();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use the full Git-finalization timeout

On loaded Windows runners where the chat end event precedes Git finalization by 5–15 seconds, this new call throws after settleInFlight()'s default 5,000 ms, so the existing 15-second Git-status wait below is never reached. This reduces the helper's prior waiting budget and can fail precisely the late-finalizer cases being addressed; pass an explicit timeout of at least 15 seconds or coordinate both checks under one shared deadline. rules/hybrid-testing.mdL162-L165

Useful? React with πŸ‘Β / πŸ‘Ž.

@dyad-assistant dyad-assistant Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Claude review: 3 inline finding(s).

}

async function waitForCleanGit(cwd: string) {
async function waitForCleanGit(harness: HybridChatHarness) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟑 MEDIUM

settleInFlight default 5s timeout throws instead of retrying

waitForCleanGit now calls harness.bridge.settleInFlight() with no timeout argument. The bridge default is 5000ms and it THROWS on expiry ("settleInFlight timed out ... A hung handler at teardown is a real bug") rather than returning. This call sits outside the waitFor below, so it is not retried: on a loaded Windows runner where a real git commit/finalizer invoke takes longer than 5s, the helper fails hard with a misleading teardown-flavoured error instead of waiting out the finalizer. That is a new non-retryable failure vector in the same helper this PR is trying to make more tolerant of slow runners, and it is used at seven call sites in the slowest tests in the file.

πŸ’‘ Suggestion: Pass an explicit budget aligned with the surrounding waitFor, e.g. await harness.bridge.settleInFlight(15_000), or move the settle inside the waitFor callback so it is retried.

),
).toBeTruthy();
},
{ timeout: 30_000 },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟑 MEDIUM

Assertion timeout raised to 30s without raising the 90s test timeout

The push-success assertion timeout goes from 20_000 to 30_000, but the enclosing it(...) still has a 90_000 budget (line 399). The waits already in this test before this point are 30s (conflict resolution) + 15s (Conflicts resolved) + 15s (Continue to Sync), on top of real setupLinkedApp clone/push work. With the new 30s the worst-case in-test waiting alone exceeds the 90s test timeout, so on exactly the loaded runner this change targets the vitest timeout fires first and the extra 10s is never usable - and the failure surfaces as a generic test timeout rather than the specific assertion.

πŸ’‘ Suggestion: Raise the it(...) timeout (e.g. to 120_000) alongside the assertion timeout so the new budget can actually be consumed.

const CALLS_DIR = resolve(__dirname, "recorded_calls");
const FIXTURES_DIR = resolve(__dirname, "fixtures");

function normalizeNewlines(content: string): string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟑 MEDIUM

Read-time newline normalization masks CRLF handling instead of pinning fixtures

The Windows failure comes from git checkout converting the recorded fixtures and call files to CRLF (the repo-wide '* text=auto' in .gitattributes). Normalizing at read time makes the replay green, but it also means the recordings are no longer byte-identical to what was captured, and the search/replace parser and processor are never exercised with CRLF input from this suite - so a genuine \r handling gap in parseSearchReplaceBlocks/applySearchReplace would stay invisible. The repo already solves this exact problem the other way for e2e snapshots ('e2e-tests/snapshots/** text eol=lf'), so this also diverges from the established convention.

πŸ’‘ Suggestion: Prefer a .gitattributes entry pinning src/tests/evals/fixtures/** and src/tests/evals/recorded_calls/** to 'text eol=lf' so the recordings stay verbatim; if read-time normalization is kept, add a case that replays CRLF input end-to-end.

@dyad-assistant

Copy link
Copy Markdown
Contributor

πŸ” Dyadbot Code Review Summary

Verdict: πŸ€” NOT SURE - Potential issues
Recommendation: ready

Test- and docs-only PR (no production code paths, no IPC surface, schema, or UI primitives touched), so the Electron boundary, DyadError, Base UI, and migration rules are not in play here. The diff is complete (not truncated). The three sequencing fixes are directionally right β€” waiting for preview-iframe-element before Git work matches the coordinator contract the PR documents in rules/e2e-testing.md, and the new waitForCleanGit(harness) signature correctly fences on renderer IPC settlement before touching .git. I verified the referenced helpers exist and behave as assumed: PreviewPanel.expectPreviewIframeIsVisible(timeout), Timeout.EXTRA_LONG (120s on CI), HybridChatHarness.appDir/.bridge, and RendererIpcBridge.settleInFlight. app_screenshot.spec.ts already asserts preview-iframe visibility right after sendPrompt without opening the panel, so the new github.spec.ts wait is consistent with existing usage.

The issues below are about timeout budgeting and about one fix masking rather than pinning the underlying condition. None of them are merge blockers.

Issues Summary

Severity File Issue
🟑 MEDIUM src/ipc/handlers/__tests__/retry.integration.test.ts:47 settleInFlight default 5s timeout throws instead of retrying
🟑 MEDIUM src/ipc/handlers/__tests__/git_collaboration.integration.test.tsx:388 Assertion timeout raised to 30s without raising the 90s test timeout
🟑 MEDIUM src/__tests__/evals/recorded_calls.spec.ts:31 Read-time newline normalization masks CRLF handling instead of pinning fixtures

settleInFlight budget. harness.bridge.settleInFlight() defaults to 5000ms and throws on expiry (the error text even asserts "a hung handler at teardown is a real bug"). It sits outside the waitFor, so it is not retried, while the git-cleanliness assertion right below it gets 15s. On the loaded Windows runner this PR is written for, a git finalizer that needs more than 5s turns into a hard, confusingly-worded failure at seven call sites.

Git collaboration timeout. Raising only the inner assertion to 30s leaves the it(...) budget at 90s while the pre-existing waits in that test already sum to 60s plus real clone/push work. The extra 10s is unlikely to ever be reachable before the vitest timeout fires.

Eval fixture newlines. The root cause is * text=auto converting the recorded fixtures/calls on Windows checkout. .gitattributes already pins e2e-tests/snapshots/** to eol=lf for precisely this reason; extending that to the eval fixture directories keeps the recordings byte-identical to what was captured, whereas normalizing at read time also removes the suite's only CRLF exposure.

🟒 Low Priority Notes (5 items)
  • EXTRA_LONG eats most of the E2E budget - Timeout.EXTRA_LONG is 120s on CI against a 180s Playwright test timeout, and this is one of the longest specs in the suite (branch create/rename/merge/delete, sync, clone, pull, reconnect). Wall-clock is probably not additive, since the publish flow was queued behind the same install anyway, but a preview that never appears now burns 120s before the real assertions start. Timeout.LONG may be enough. (e2e-tests/github.spec.ts)
  • The IPC fence is partial - settleInFlight drains invokes that are already in flight plus follow-ups scheduled within the same event-loop drain. A finalizer whose invoke has not been dispatched yet when the helper runs can still start after the git assertions pass. This narrows the race rather than closing it; worth a comment so a future reader does not treat it as a hard barrier. (src/ipc/handlers/__tests__/retry.integration.test.ts)
  • Separator assertion is now platform-agnostic in both directions - /^--output=.*0001[\\/]artifacts$/ accepts a backslash on Linux/macOS too, so a genuinely wrong separator would pass there. Building the expected suffix with path.join would keep the assertion exact per platform. (src/ipc/handlers/tests_handlers.preview.test.ts)
  • New unit test is tautological - "normalizes platform line endings before replay" only asserts the local regex helper against two literals; it does not assert that the replay itself survives CRLF input, which is the behavior that actually broke. (src/__tests__/evals/recorded_calls.spec.ts)
  • findByText β†’ waitFor + getByText is churn - The only material change is 20s β†’ 30s; findByText already accepted the timeout in its third argument. The rewrite does gain one thing (getByTestId is re-resolved on each retry, so a remount is tolerated) β€” if that was the intent, a short comment would make it durable. (src/ipc/handlers/__tests__/git_collaboration.integration.test.tsx)

Generated by Dyadbot persona-based code review

@github-actions

Copy link
Copy Markdown
Contributor

🎭 Playwright Test Results

βœ… All tests passed!

OS Passed Flaky Skipped
🍎 macOS 294 0 12

Total: 294 tests passed (12 skipped)

πŸ“Š View full report

@github-actions github-actions Bot added the needs-human:review-issue ai agent flagged an issue that requires human review label Aug 26, 2026
@wwwillchen
wwwillchen merged commit 880012a into main Aug 27, 2026
24 of 25 checks passed
@wwwillchen
wwwillchen deleted the fix/ci-32979318031 branch August 27, 2026 04:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human:review-issue ai agent flagged an issue that requires human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant