How can I validate Cypress.io backup and restore integrity across environments?
0 reputation · 06 Jan 2021, 23:10 UTC
0 reputation · 06 Jan 2021, 23:10 UTC
When backing up a Cypress.io test suite and its associated data, the goal is to confirm that a restore operation reproduces the original state exactly. The challenge is to automate validation without manual inspection, especially when the test data set is large, spans multiple nodes, and includes environment‑specific configurations such as API endpoints or database credentials.
Key constraints include limited restore windows, potential schema changes between environments, and the need to verify both data content and test metadata. Current uncertainty lies in the most efficient way to compare pre‑backup and post‑restore snapshots, as well as how to capture failures in a reproducible manner.
What steps can reliably confirm that all test files, fixtures, and database records are intact after a restore? How can we programmatically compare the original and restored states to detect any discrepancies? What tooling or scripts can automate this comparison while handling environment differences?
35275 reputation · 07 Jan 2021, 02:30 UTC
To confirm that a Cypress backup and restore reproduces the original state, you need to compare two orthogonal dimensions:
Below is a practical, step‑by‑step workflow that works for both the Dashboard export/import APIs and a local file‑system backup. It assumes you have the cypress CLI and access to the Dashboard API token for the source and target projects.
# 1️⃣ Export via the Dashboard API
# Replace PROJECT_ID and API_KEY with your values
curl -X POST \
https://dashboard.cypress.io/api/v1/projects/PROJECT_ID/export \
-H "Authorization: Bearer API_KEY" \
-o source_export.zip
The payload includes runs.json, screenshots, videos, and a metadata.json file with run counts and status distributions.
# 2️⃣ Import into the destination
curl -X POST \
https://dashboard.cypress.io/api/v1/projects/DEST_PROJECT_ID/import \
-H "Authorization: Bearer DEST_API_KEY" \
-F "file=@source_export.zip"
After import, the target project will contain the same runs and artifacts.
Use the CLI to fetch run summaries from both environments and compare.
# List runs on source
cypress run:list --projectId=PROJECT_ID --token=API_KEY > source_runs.json
# List runs on target
cypress run:list --projectId=DEST_PROJECT_ID --token=DEST_API_KEY > target_runs.json
# Simple diff of run counts & status distribution
jq '.runs | length' source_runs.json > source_count.txt
jq '.runs | length' target_runs.json > target_count.txt
# Compare status counts
jq '.runs | group_by(.status) | map({status: .[0].status, count: length})' source_runs.json > source_status.json
jq '.runs | group_by(.status) | map({status: .[0].status, count: length})' target_runs.json > target_status.json
# If counts differ, the restore is incomplete
Compute checksums of screenshots and videos in the source export and compare them to the files that were uploaded to the target. The Dashboard stores artifacts in S3‑compatible storage, but you can download them via the API or by inspecting the source_export.zip.
# Extract checksums from the export
unzip -p source_export.zip metadata.json | jq -r '.artifacts[] | "\(.path) \\(.checksum)"' > source_artifacts.txt
# For each artifact, download from target and compute checksum
while read path checksum; do
curl -s -o /tmp/artifact "https://dashboard.cypress.io/api/v1/projects/DEST_PROJECT_ID/artifacts/${path}" \
-H "Authorization: Bearer DEST_API_KEY"
target_checksum=$(sha256sum /tmp/artifact | cut -d' ' -f1)
if [ "$checksum" != "$target_checksum" ]; then
echo "Checksum mismatch for $path"
fi
done < source_artifacts.txt
Dashboard export does not include project settings or environment variables. If those are critical, export them manually:
# Export env vars via the Dashboard UI or API (if available)
# Example: curl -X GET https://dashboard.cypress.io/api/v1/projects/PROJECT_ID/env
# Compare the JSON output between source and target.
As a final sanity check, execute the same test suite on the target environment and assert that the results match the imported runs. Use the cypress run:verify helper (custom script) that compares the new run’s status distribution to the expected counts.
# Run tests locally
cypress run --record --project DEST_PROJECT_ID --key DEST_API_KEY
# After completion, fetch the latest run and compare
latest_run=$(jq -r '.runs[0].id' target_runs.json)
# Compare status distribution
Confirmed facts (based on Cypress Dashboard API docs and community experience):
runs.json, metadata.json, and artifacts.cypress run:list with the project token.metadata.json.Likely explanation (needs confirmation for specific setups):
Do you export environment variables or other non‑artifact project settings as part of your backup process? If so, the comparison steps above need to include those files as well.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 07 Jan 2021, 01:22 UTC
One gap in the export/checksum workflow above: it verifies the backup artifacts, but not that the restore actually reverted application state. A cheap way to close that gap is a canary record:
If the restore silently no-ops or targets the wrong namespace, checksums of the archive still pass — the canary is what fails.
Two related cautions for cross-environment comparison: avoid asserting on auto-increment IDs, timestamps, or absolute file paths, since restore sequences and clocks legitimately differ between environments; compare on stable business identifiers instead. And don't poll restore completion with fixed cy.wait() delays — expose (or reuse) a status/health endpoint and poll it until the restore reports done, otherwise the suite becomes timing-dependent exactly when restore windows are tight.
Worth confirming against your Cypress version's current cy.intercept/cy.request behavior before relying on this in CI.