Add onboarding Next buttons and fix accessibility for paged TabView
App-side changes: - Added "Get Started" / "Continue" next buttons to all onboarding pages (Welcome, Day, Time, Style) with onboarding_next_button accessibility ID - Added onNext callback plumbing from OnboardingMain to each page - OnboardingMain now uses TabView(selection:) for programmatic page navigation - Added .accessibilityElement(children: .contain) to all onboarding pages to fix iOS 26 paged TabView not exposing child elements - Added settings_segmented_picker accessibility ID to Settings Picker - Reduced padding on onboarding pages to keep buttons in visible area Test-side changes: - OnboardingScreen: replaced unreliable swipeToNext() with tapNext() that taps the accessibility-identified next button - OnboardingScreen: multi-strategy skip button detection for subscription page - SettingsScreen: scoped segment tap to picker element to avoid tab bar collision - CustomizeScreen: simplified horizontal scroll to plain app.swipeLeft() - OnboardingVotingTests: uses tapNext() to advance to Day page Passing: OnboardingTests.CompleteFlow, OnboardingVotingTests Remaining: OnboardingTests.DoesNotRepeat (session state issue), Settings scroll (deep elements), Customize horizontal pickers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,7 +42,7 @@ struct CustomizeScreen {
|
||||
// MARK: - Actions
|
||||
|
||||
/// Select a button in a horizontal picker. Scrolls vertically to reveal
|
||||
/// the section, then scrolls horizontally within the picker to find the button.
|
||||
/// the section, then scrolls horizontally to find the button.
|
||||
private func selectHorizontalPickerButton(
|
||||
_ button: XCUIElement,
|
||||
file: StaticString = #filePath,
|
||||
@@ -55,31 +55,23 @@ struct CustomizeScreen {
|
||||
}
|
||||
|
||||
// Phase 1: Scroll settings page vertically to reveal the section
|
||||
let mainScroll = app.scrollViews.firstMatch
|
||||
for _ in 0..<5 {
|
||||
if button.exists && button.isHittable {
|
||||
button.forceTap(file: file, line: line)
|
||||
return
|
||||
}
|
||||
mainScroll.swipeUp()
|
||||
app.swipeUp()
|
||||
}
|
||||
|
||||
// Phase 2: Button is in hierarchy but off-screen in horizontal scroll.
|
||||
// Find the horizontal scroll view containing the button and swipe within it.
|
||||
// Phase 2: Button exists in tree but is off-screen in a horizontal ScrollView.
|
||||
// Simple left swipes on the app to scroll horizontally.
|
||||
if button.exists {
|
||||
// Swipe left on the button's parent region to scroll the horizontal picker
|
||||
for _ in 0..<8 {
|
||||
if button.isHittable {
|
||||
button.forceTap(file: file, line: line)
|
||||
return
|
||||
}
|
||||
// Swipe left at the button's Y position to scroll the horizontal picker
|
||||
let buttonFrame = button.frame
|
||||
let startPoint = app.coordinate(withNormalizedOffset: CGVector(dx: 0.8, dy: 0))
|
||||
.withOffset(CGVector(dx: 0, dy: buttonFrame.midY))
|
||||
let endPoint = app.coordinate(withNormalizedOffset: CGVector(dx: 0.2, dy: 0))
|
||||
.withOffset(CGVector(dx: 0, dy: buttonFrame.midY))
|
||||
startPoint.press(forDuration: 0.05, thenDragTo: endPoint)
|
||||
app.swipeLeft()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +81,7 @@ struct CustomizeScreen {
|
||||
button.forceTap(file: file, line: line)
|
||||
return
|
||||
}
|
||||
mainScroll.swipeRight()
|
||||
app.swipeRight()
|
||||
}
|
||||
|
||||
XCTFail("Could not find or tap button: \(button)", file: file, line: line)
|
||||
|
||||
Reference in New Issue
Block a user