diff --git a/e2e/freight/cypress/e2e/flows/onboarding.cy.ts b/e2e/freight/cypress/e2e/flows/onboarding.cy.ts index bb077df6b..437c0e92e 100644 --- a/e2e/freight/cypress/e2e/flows/onboarding.cy.ts +++ b/e2e/freight/cypress/e2e/flows/onboarding.cy.ts @@ -42,21 +42,44 @@ function latestOnboardJourney() { }); } -/** Fill a labelled Mantine input (label[for] → input id). */ +/** + * Fill a labelled Mantine input (label[for] → input id). + * + * The input is resolved fresh for every action rather than captured once. + * Each wizard step persists and re-seeds asynchronously, and when a field + * remounts Mantine mints a NEW generated id — so both a subject and an id + * captured a command earlier can be stale by the time the next command runs. + * Going label → for → element each time always addresses what's on the page + * now. + */ function fill(label: string | RegExp, value: string) { - cy.contains("label", label) - .invoke("attr", "for") - .then((id) => { - cy.get(`[id="${id}"]`).clear({ force: true }).type(value, { force: true }); - }); + const input = () => + cy + .contains("label", label) + .invoke("attr", "for") + .then((id) => cy.get(`[id="${id}"]`)); + + input().clear({ force: true }); + input().type(value, { force: true }); +} + +/** + * Fill an input that has no