Teach the live sign-up test about the age gate
The gate landed on 2026-08-29 and `canSubmit` has required a year of birth ever since. The test was never taught to pick one, so it failed on "submit stayed disabled" — and the live sign-up path, the one thing that proves a new person can actually get in, went unverified from then until now. The app was fine the whole time; the check was not. Two things it got wrong on the way, both worth keeping in the comments: the picker's options are not buttons in every OS version, so the year is matched by label across element types; and the list runs 1900…this year in reverse, about 127 entries, of which a menu renders only what is on screen — a year thirty rows down is not in the accessibility tree at all, and the failure reads as "the list never opened". It now picks the youngest year the gate accepts, which is near the top of the list and is also the boundary worth exercising. Verified against production: passes, creating a real account through the real UI and ending signed in. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9534e273df
commit
237a0f6460
@@ -110,8 +110,40 @@ final class LiveSignUpUITests: XCTestCase {
|
||||
+ "the strong-password panel ate the input")
|
||||
}
|
||||
|
||||
// 🔴 **The age gate, which this test did not know about.** It landed on
|
||||
// 2026-08-29 and `canSubmit` has required a year ever since; the test
|
||||
// was never taught to pick one, so it failed on "submit stayed
|
||||
// disabled" and the live sign-up path went unverified from then until
|
||||
// 2026-08-30. The app was fine the whole time — a person sees the
|
||||
// picker and uses it. What was broken was the check.
|
||||
//
|
||||
// ⚠️ A menu picker, so this is tap-to-open then tap-the-option, not a
|
||||
// wheel to spin. The option is titled with the bare year.
|
||||
// ⚠️ **The youngest year the gate accepts, because it is near the top of
|
||||
// the list.** The picker offers 1900…this year in reverse, which is
|
||||
// about 127 entries, and a menu renders only the slice on screen — a
|
||||
// year thirty rows down is simply not in the accessibility tree, and
|
||||
// the failure reads as "the list never opened". This also puts the test
|
||||
// exactly on the boundary the gate allows, which is the value worth
|
||||
// exercising anyway.
|
||||
let year = Calendar.current.component(.year, from: Date()) - 14
|
||||
let picker = app.buttons["signup.birthyear"]
|
||||
XCTAssertTrue(picker.waitForExistence(timeout: 10),
|
||||
"no year-of-birth control — the age gate changed shape")
|
||||
picker.tap()
|
||||
// ⚠️ Matched by label across every element type, not as a button. A
|
||||
// SwiftUI menu picker's options are not buttons in the accessibility
|
||||
// tree on every OS version, and a query that assumes one type fails
|
||||
// with "the year list never opened" when the list opened fine.
|
||||
let option = app.descendants(matching: .any)
|
||||
.matching(NSPredicate(format: "label == %@", String(year))).firstMatch
|
||||
XCTAssertTrue(option.waitForExistence(timeout: 10),
|
||||
"no option labelled \(year) after opening the picker. "
|
||||
+ "Hierarchy:\n\(app.debugDescription)")
|
||||
option.tap()
|
||||
|
||||
let submit = app.buttons["signup.submit"]
|
||||
XCTAssertTrue(submit.isEnabled,
|
||||
XCTAssertTrue(submit.waitForExistence(timeout: 5) && submit.isEnabled,
|
||||
"submit stayed disabled — the form is still demanding a field it cannot use")
|
||||
submit.tap()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user