The board settings sheet — setup leaves the popover for a home a stray click can't dismiss
The popover/sheet split lands: a board-scoped, titled, sectioned sheet on the board window hosts everything setup-shaped, opened from the popover's Board Settings… row and the new Board ▸ Board Settings… menu row. The three existing setup controls relocate — add-git (whose noteFormVisible lines now make the sheet the form-anchored failure surface), branch creation (a standing field; create-and-switch runs the identical settle sequence), and the commit-identity fields (the 2s visibility-scoped poll rides with them). The popover keeps the daily face and its postures; its Pro/mode-none section becomes header + door (.addGit renamed .noRepository). Availability is derived from the section inventory (Pro + mode none or git), so pro-m2's sections can't drift from the doors; the sheet's fields join the caret-chord disable set. The audit suite pins what the free fixture can reach; the sheet's own audit is manual until a tier override is ruled. Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -5,12 +5,24 @@ import XCTest
|
||||
///
|
||||
/// > **Automated audits are test failures**: Xcode's accessibility audit (`performAccessibilityAudit`)
|
||||
/// > runs in UI tests over every surface — board (trash shown and hidden), card window (Preview, Edit,
|
||||
/// > raw source), welcome, template chooser, board popover.
|
||||
/// > raw source), welcome, template chooser, board popover, board settings sheet.
|
||||
///
|
||||
/// Eight surfaces, eight tests, one audit call each. `performAccessibilityAudit` audits **the app's
|
||||
/// One test per surface, one audit call each. `performAccessibilityAudit` audits **the app's
|
||||
/// currently displayed UI** rather than a subtree, so each test's job is entirely navigation: get the
|
||||
/// surface on screen, then let the audit look at whatever is there.
|
||||
///
|
||||
/// ### The one surface this suite cannot reach, and why it is not fixable here
|
||||
///
|
||||
/// The **board settings sheet** is Pro-only (03-board-ui.md ▸ Board settings sheet;
|
||||
/// `BoardSettingsAvailability`), and the fixture launch has no tier control: `AppModel.currentTier`
|
||||
/// reads `ProEntitlement`, which reads StoreKit, and there is deliberately **no launch argument that
|
||||
/// grants Pro**. Adding one would be worse than the gap it closed — `UITestLaunch` is compiled into
|
||||
/// the shipping binary on purpose ("the thing being audited must be the app that ships"), so a
|
||||
/// `--ui-test-pro` flag would be a subscription bypass anyone could type into Terminal. So the sheet's
|
||||
/// own audit is **deferred to the manual VoiceOver pass** (`AccessibilityVerification.md`), and what
|
||||
/// is automated here instead is the posture that *is* reachable: the free tier's, where the row exists
|
||||
/// and is disabled. See `testBoardSettingsRowIsPresentAndDisabledOnTheFreeFixture`.
|
||||
///
|
||||
/// ### No waiving
|
||||
///
|
||||
/// The audit's issue handler is where a false positive would be excused, and every test here passes
|
||||
@@ -188,4 +200,46 @@ final class AccessibilityAuditTests: XCTestCase {
|
||||
)
|
||||
try app.performAccessibilityAudit()
|
||||
}
|
||||
|
||||
// MARK: - The board settings sheet
|
||||
|
||||
/// **The reachable half of the settings sheet's audit** — the free tier's, which is the tier the
|
||||
/// fixture launch runs in (see this file's header for why there is no Pro fixture and why adding
|
||||
/// one would be a subscription bypass).
|
||||
///
|
||||
/// What it pins is the design's deliberate asymmetry between the sheet's two doors
|
||||
/// (`BoardSettingsAvailability`): the **menu row stays visible and disabled** where the sheet
|
||||
/// cannot exist — standard menu validation, and 11-command-nexus.md's "a command absent here
|
||||
/// doesn't exist" read in the other direction — while the popover's row is *absent* there instead.
|
||||
/// A row that vanished from the menu on the free tier would be the app hiding its own inventory;
|
||||
/// one that was enabled would present an empty sheet.
|
||||
///
|
||||
/// The audit call is the board's, taken with the Board menu closed again: the sheet is what this
|
||||
/// test cannot open, so auditing the surface that *is* on screen keeps the test honest about what
|
||||
/// it checked.
|
||||
@MainActor
|
||||
func testBoardSettingsRowIsPresentAndDisabledOnTheFreeFixture() throws {
|
||||
let app = XCUIApplication.launchedWithFixtureBoard()
|
||||
|
||||
let bar = app.menuBars.firstMatch
|
||||
let boardMenu = bar.menuBarItems["Board"]
|
||||
XCTAssertTrue(
|
||||
boardMenu.waitForExistence(timeout: XCUIApplication.uiTimeout),
|
||||
"the Board menu is missing from the menu bar"
|
||||
)
|
||||
boardMenu.click()
|
||||
|
||||
let row = bar.menuItems["Board Settings…"]
|
||||
XCTAssertTrue(
|
||||
row.waitForExistence(timeout: XCUIApplication.uiTimeout),
|
||||
"Board ▸ Board Settings… is missing — the row ships whether or not this board can open it"
|
||||
)
|
||||
XCTAssertFalse(
|
||||
row.isEnabled,
|
||||
"the free tier has no board settings sheet, so the row must be disabled rather than open an empty one"
|
||||
)
|
||||
app.typeKey(.escape, modifierFlags: [])
|
||||
|
||||
try app.performAccessibilityAudit()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user