feat: expand XCUITest coverage to 54 QA scenarios with accessibility IDs and fix test failures

Add 22 new UI tests across 8 test files covering Home, Schedule, Progress,
Settings, TabNavigation, TripSaving, and TripOptions. Add accessibility
identifiers to 11 view files for test element discovery. Fix sport chip
assertion logic (all sports start selected, tap deselects), scroll container
issues on iOS 26 nested ScrollViews, toggle interaction, and delete trip flow.
Update QA coverage map from 32 to 54 automated test cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-16 19:44:22 -06:00
parent d53f222489
commit dc142bd14b
25 changed files with 1637 additions and 102 deletions

View File

@@ -212,6 +212,7 @@ struct SportProgressButton: View {
.accessibilityValue(isSelected ? "Selected" : "Not selected")
.accessibilityAddTraits(.isButton)
.accessibilityAddTraits(isSelected ? .isSelected : [])
.accessibilityIdentifier("progress.sport.\(sport.rawValue.lowercased())")
.simultaneousGesture(
DragGesture(minimumDistance: 0)
.onChanged { _ in

View File

@@ -45,6 +45,7 @@ struct HomeView: View {
.foregroundStyle(Theme.warmOrange)
}
.accessibilityLabel("Create new trip")
.accessibilityIdentifier("home.createNewTripButton")
}
}
}
@@ -648,6 +649,7 @@ struct SavedTripsListView: View {
SavedTripListRow(trip: trip)
}
.buttonStyle(.plain)
.accessibilityIdentifier("myTrips.trip.\(index)")
.staggeredAnimation(index: index)
}
}

View File

@@ -170,6 +170,7 @@ struct HomeContent_Classic: View {
}
}
}
.accessibilityIdentifier("home.featuredTripsSection")
} else if let error = suggestedTripsGenerator.error {
// Error state
VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
@@ -238,6 +239,7 @@ struct HomeContent_Classic: View {
}
}
}
.accessibilityIdentifier("home.recentTripsSection")
}
private func classicTripCard(savedTrip: SavedTrip, trip: Trip) -> some View {
@@ -319,6 +321,7 @@ struct HomeContent_Classic: View {
.stroke(Theme.surfaceGlow(colorScheme), lineWidth: 1)
}
}
.accessibilityIdentifier("home.tipsSection")
}
private func classicTipRow(icon: String, title: String, subtitle: String) -> some View {

View File

@@ -170,6 +170,7 @@ struct HomeContent_ClassicAnimated: View {
}
}
}
.accessibilityIdentifier("home.featuredTripsSection")
} else if let error = suggestedTripsGenerator.error {
// Error state
VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
@@ -238,6 +239,7 @@ struct HomeContent_ClassicAnimated: View {
}
}
}
.accessibilityIdentifier("home.recentTripsSection")
}
private func classicTripCard(savedTrip: SavedTrip, trip: Trip) -> some View {
@@ -319,6 +321,7 @@ struct HomeContent_ClassicAnimated: View {
.stroke(Theme.surfaceGlow(colorScheme), lineWidth: 1)
}
}
.accessibilityIdentifier("home.tipsSection")
}
private func classicTipRow(icon: String, title: String, subtitle: String) -> some View {

View File

@@ -30,6 +30,7 @@ struct PaywallView: View {
Text("Upgrade to Pro")
.font(.largeTitle.bold())
.foregroundStyle(Theme.textPrimary(colorScheme))
.accessibilityIdentifier("paywall.title")
Text("Unlock the full SportsTime experience")
.font(.body)

View File

@@ -27,6 +27,7 @@ struct PollsListView: View {
}
}
.navigationTitle("Group Polls")
.accessibilityIdentifier("polls.list")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {

View File

@@ -107,6 +107,7 @@ struct ProgressTabView: View {
VStack(spacing: Theme.Spacing.lg) {
// League Selector
leagueSelector
.accessibilityIdentifier("progress.sportSelector")
.staggeredAnimation(index: 0)
// Progress Summary Card
@@ -212,6 +213,7 @@ struct ProgressTabView: View {
Text("Stadium Quest")
.font(.subheadline)
.foregroundStyle(Theme.textSecondary(colorScheme))
.accessibilityIdentifier("progress.stadiumQuest")
if progress.isComplete {
HStack(spacing: 4) {
@@ -330,6 +332,7 @@ struct ProgressTabView: View {
Text("Achievements")
.font(.title2)
.foregroundStyle(Theme.textPrimary(colorScheme))
.accessibilityIdentifier("progress.achievementsTitle")
Spacer()
@@ -398,6 +401,7 @@ struct ProgressTabView: View {
Text("Recent Visits")
.font(.title2)
.foregroundStyle(Theme.textPrimary(colorScheme))
.accessibilityIdentifier("progress.recentVisitsTitle")
Spacer()

View File

@@ -147,8 +147,10 @@ struct ScheduleListView: View {
viewModel.resetFilters()
}
.buttonStyle(.bordered)
.accessibilityIdentifier("schedule.resetFiltersButton")
}
}
.accessibilityIdentifier("schedule.emptyState")
}
// MARK: - Loading State
@@ -221,6 +223,7 @@ struct SportFilterChip: View {
.clipShape(Capsule())
}
.buttonStyle(.plain)
.accessibilityIdentifier("schedule.sport.\(sport.rawValue.lowercased())")
.accessibilityValue(isSelected ? "Selected" : "Not selected")
.accessibilityAddTraits(isSelected ? .isSelected : [])
}

View File

@@ -138,6 +138,7 @@ struct SettingsView: View {
}
.buttonStyle(.plain)
.accessibilityAddTraits(AppearanceManager.shared.currentMode == mode ? .isSelected : [])
.accessibilityIdentifier("settings.appearance.\(mode.rawValue)")
}
} header: {
Text("Appearance")
@@ -228,6 +229,7 @@ struct SettingsView: View {
.accessibilityHidden(true)
}
}
.accessibilityIdentifier("settings.animationsToggle")
} header: {
Text("Home Screen")
}
@@ -414,6 +416,7 @@ struct SettingsView: View {
.accessibilityHidden(true)
}
}
.accessibilityIdentifier("settings.resetButton")
}
.listRowBackground(Theme.cardBackground(colorScheme))
}
@@ -495,6 +498,7 @@ struct SettingsView: View {
Label("Sync Now", systemImage: "arrow.triangle.2.circlepath")
}
.disabled(isSyncActionInProgress)
.accessibilityIdentifier("settings.syncNowButton")
Button {
showSyncLogs = true
@@ -784,6 +788,7 @@ struct SettingsView: View {
}
}
.buttonStyle(.plain)
.accessibilityIdentifier("settings.upgradeProButton")
Button {
Task {
@@ -792,6 +797,7 @@ struct SettingsView: View {
} label: {
Label("Restore Purchases", systemImage: "arrow.clockwise")
}
.accessibilityIdentifier("settings.restorePurchasesButton")
}
} header: {
Text("Subscription")

View File

@@ -170,6 +170,7 @@ struct TripDetailView: View {
.foregroundStyle(Theme.warmOrange)
}
.accessibilityLabel("Export trip as PDF")
.accessibilityIdentifier("tripDetail.pdfExportButton")
}
}
@@ -472,6 +473,7 @@ struct TripDetailView: View {
StatPill(icon: "car", value: trip.formattedTotalDriving)
}
}
.accessibilityIdentifier("tripDetail.statsRow")
}
// MARK: - Score Card

View File

@@ -68,6 +68,7 @@ struct ReviewStep: View {
.font(.caption)
.foregroundStyle(Theme.textMuted(colorScheme))
}
.accessibilityIdentifier("wizard.missingFieldsWarning")
}
Button(action: onPlan) {