test(e2e): say what the backup journey really touches, and pin it to promises

The file claimed it stayed inside its own account. "Backup now" enqueues the
pass for every account on the instance, so the header says that now, and says
what is confined instead: the restore's transaction, and the instance-wide
settings the dialog's opt-in leaves alone — which the journey asserts is clear
before it confirms, because a default that flipped would hand this file the
power to rewrite the document size cap for every spec sharing the server.

The run's own answer is asserted where it happens. Without it a missing worker
cost two minutes of polling and then blamed the backup pass for a 503 about
something else; the failure now names the endpoint in two seconds.

The rest are the assertions that pinned incidentals rather than promises: the
Argon2 cost comes from the constant the writer exports, so a legitimate cost
bump is not a red spec; the document is found by id rather than by position;
the poll compares the row against the row it saw before the click rather than
against the runner's clock; the non-admin bounce is pinned by pathname; the
empty-state CTA has its own test id, so nothing has to pick between two
buttons that share one; the deliberately corrupted copy is deleted when the
control is done with it instead of sitting in the console's list; and the
fixture orders by id after the timestamp so a tie cannot present as a change.
This commit is contained in:
Marc-André Bombeck committed 2026-09-10 05:48:18 +02:00
1 parent 6e4f3fb4c4
commit 343d6397a0
3 files changed
+113 -13

No files matched your search

+6 -1
View File
@@ -1017,6 +1017,11 @@ export function BackupsSection() {
// primitive. The header already exposes "Backup now" but a
// brand-new admin lands inside the card and benefits from a
// duplicate CTA right next to the explanation.
//
// Its own test id, because both buttons are in the tree while the list
// is empty and they do the same thing: one id on two elements forces
// every caller to pick one blind, and a third button would join the
// pick without anything failing.
<div>
<EmptyState
icon={<Database className="size-6" />}
@@ -1025,7 +1030,7 @@ export function BackupsSection() {
action={
<Button
size="sm"
data-testid="backup-run-now"
data-testid="backup-run-now-empty"
disabled={runBackup.isPending}
onClick={() => runBackup.mutate()}
className="min-h-11"