Skip to content

test(e2e): finish an interrupted deploy end-to-end (pubspec pushed, class not re-provisioned) - #116

Merged
sgardoll merged 1 commit into
hardening/deploy-resiliencefrom
hardening/finish-deploy-e2e
Oct 4, 2026
Merged

sgardoll merged 1 commit into
hardening/deploy-resiliencefrom
hardening/finish-deploy-e2e

Conversation

@sgardoll

@sgardoll sgardoll commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

What

Adds e2e/finish-deploy-e2e.spec.js, browser proof of the last P0: an interrupted deploy that outlives the browser bound now finishes rather than being left as a re-read estimate.

The "step-2 timeout ends with classes AND pubspec both present" criterion was previously proven only at the unit level (isDeployFinishable, buildFinishPushFileMap in src/flutterFlowCodeFileProvisioning.js), never through the handler that actually performs the push. This spec drives the real code:

  1. The runner provision request stalls past a shortened UI bound while the class it was writing has landed in the project export.
  2. The reconcile re-read reports every class landed, so the unconfirmed terminal offers Finish deploy (armed via window.showCommitUnconfirmedModal with the finish context merged exactly as mergeFinishDeployContext does — the same dispatch production uses).
  3. Running the action (window.finishProvisionedDeploy behind the on-screen button) runs step 3 only.

Assertions that matter

  • The intercepted syncCustomCodeChanges request body carries serialized_yaml containing the merged dependency (http: ^1.2.0) — the pubspec was really pushed, not just presumed.
  • No second request reaches /deployCustomClasses after the finish action (provision count stays at 1), and the push file_map carries no entry for the landed class — it is not re-provisioned.
  • The terminal ends in a finished success state (#success-message = "Deploy finished…"), not still-unknown.

Scope

Only e2e/finish-deploy-e2e.spec.js. No change to app.js, src/**, or playwright.config.js. The test starts the flow through the existing __CCC_PROVISION_CUSTOM_CLASSES__ transport hook (app.js exports it explicitly "for the browser suite"); the real confirm-deploy entry point is unreachable without a full generate→review→confirm journey, consistent with how stu380-deploy.spec.js and deploy-timeout-reconcile.spec.js already drive this transport.

Verification

CCC_TEST_PORT=3109 npx playwright test e2e/finish-deploy-e2e.spec.js → 1 passed. Unit baseline (node --test src/*.test.js) → 402 pass, 0 fail.


Devin Review

…al step-3 push

The "step-2 timeout ends with classes AND pubspec both present" criterion was
only proven at the unit level (isDeployFinishable, buildFinishPushFileMap).
This drives the real handlers: provision stalls past a shortened UI bound
while the class has landed, reconcile arms the "Finish deploy" terminal, and
running that action pushes the merged pubspec (asserted on the intercepted
syncCustomCodeChanges request body), issues no second /deployCustomClasses
request, and ends the terminal in a finished state.
@greptile-apps

greptile-apps Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

This PR does not match any of the 1 configured review trigger rule.

@devin-ai-integration devin-ai-integration 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.

Devin Review found 2 potential issues.

Devin Review

Comment on lines +78 to +82
zip.file("pubspec.yaml", mergedPubspec);
zip.file(
"lib/custom_code/gauge_widget.dart",
attemptedClass["gauge_widget.dart"].content,
);

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.

🔍 Export already contains the target dependency

The export contains http: ^1.2.0 before the finish action runs. The request assertion proves the dependency was sent, but not that finishing added it to the project.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +134 to +160
// Mirror app.js mergeFinishDeployContext: gives the finished terminal the
// identity and the "Deploy finished" message a normal deploy would show.
const merged = {
...fd,
result: {
targetIdentity: identity,
metadata: {
artifactType: identity.artifactType,
artifactName: identity.artifactName,
fileName: identity.fileName,
projectId: identity.projectId,
},
message: `Deploy finished: ${identity.artifactName || "custom classes"} and their dependencies are now in FlutterFlow.`,
addedDependencies: [],
unverified: [],
approximate: [],
warnings: [],
elapsedTime: 0,
},
};
window.showCommitUnconfirmedModal({
success: false,
unconfirmed: true,
targetIdentity: identity,
error: error.message,
finishDeploy: merged,
});

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.

🔍 Manual terminal setup leaves deploy wiring untested

The test builds the finish context and opens the modal itself. A broken production handoff through mergeFinishDeployContext or renderCommitTerminal can leave this test passing.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@sgardoll
sgardoll merged commit 17aa55a into hardening/deploy-resilience Oct 4, 2026
1 of 2 checks passed
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