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:
2026-08-01 12:07:12 -04:00
parent 988a7245a3
commit 8345378972
12 changed files with 1168 additions and 321 deletions
+56 -2
View File
@@ -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()
}
}