Complete accessibility identifier coverage across all 152 project files
Exhaustive file-by-file audit of every Swift file in the project (iOS app, Watch app, Widget extension). Every interactive UI element — buttons, toggles, pickers, links, menus, tap gestures, text editors, color pickers, photo pickers — now has an accessibilityIdentifier for XCUITest automation. 46 files changed across Shared/, Onboarding/, Watch App/, and Widget targets. Added ~100 new ID definitions covering settings debug controls, export/photo views, sharing templates, customization subviews, onboarding flows, tip modals, widget voting buttons, and watch mood buttons.
This commit is contained in:
@@ -54,6 +54,7 @@ struct DebugAnimationSettingsView: View {
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.animationDoneButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,6 +218,7 @@ struct AnimationCard: View {
|
||||
)
|
||||
.scaleEffect(isPressed ? 0.95 : (isSelected ? 1.02 : 1.0))
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.animationCard(type.rawValue))
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.onLongPressGesture(minimumDuration: .infinity, pressing: { pressing in
|
||||
withAnimation(.easeInOut(duration: 0.15)) {
|
||||
@@ -336,6 +338,7 @@ struct DebugVotingContentView: View {
|
||||
.fill(mood.color.opacity(0.15))
|
||||
)
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.debugMoodButton(mood.strValue))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ struct LiveActivityPreviewView: View {
|
||||
.background(Color.gray.opacity(0.2))
|
||||
.cornerRadius(12)
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.liveActivityResetButton)
|
||||
|
||||
Button(action: toggleAnimation) {
|
||||
Label(isAnimating ? "Pause" : "Start", systemImage: isAnimating ? "pause.fill" : "play.fill")
|
||||
@@ -68,6 +69,7 @@ struct LiveActivityPreviewView: View {
|
||||
.foregroundColor(.white)
|
||||
.cornerRadius(12)
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.liveActivityToggleButton)
|
||||
}
|
||||
|
||||
Button(action: { showRecordingMode = true }) {
|
||||
@@ -79,6 +81,7 @@ struct LiveActivityPreviewView: View {
|
||||
.foregroundColor(.white)
|
||||
.cornerRadius(12)
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.liveActivityRecordButton)
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.bottom, 40)
|
||||
@@ -264,6 +267,7 @@ struct LiveActivityRecordingView: View {
|
||||
.background(Color.orange)
|
||||
.foregroundColor(.white)
|
||||
.cornerRadius(12)
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.liveActivityDismissButton)
|
||||
} else if isExporting {
|
||||
Text("Exporting frames...")
|
||||
.font(.title2.bold())
|
||||
@@ -282,6 +286,7 @@ struct LiveActivityRecordingView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.liveActivityExportButton)
|
||||
.onTapGesture {
|
||||
if !isExporting && !exportComplete {
|
||||
startExport()
|
||||
|
||||
@@ -35,6 +35,7 @@ struct PaywallPreviewSettingsView: View {
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.paywallPreviewDoneButton)
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showFullPreview) {
|
||||
@@ -160,6 +161,7 @@ struct PaywallPreviewSettingsView: View {
|
||||
.foregroundColor(.white)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 14))
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.viewFullPaywallButton)
|
||||
}
|
||||
|
||||
private var gradientColors: [Color] {
|
||||
@@ -241,6 +243,7 @@ struct StyleOptionRow: View {
|
||||
.stroke(isSelected ? Color.accentColor : Color.clear, lineWidth: 2)
|
||||
)
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Debug.paywallStyleOption(style.displayName))
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
|
||||
@@ -255,6 +255,7 @@ struct WhyUpgradeView: View {
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.doneButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ struct SettingsContentView: View {
|
||||
}
|
||||
.padding()
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.reminderTimeButton)
|
||||
.accessibilityLabel(String(localized: "Reminder Time"))
|
||||
.accessibilityValue(formattedReminderTime)
|
||||
.accessibilityHint(String(localized: "Opens time picker to change reminder time"))
|
||||
@@ -269,6 +270,7 @@ struct SettingsContentView: View {
|
||||
showTrialDatePicker = true
|
||||
}
|
||||
.font(.subheadline.weight(.medium))
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.changeTrialDateButton)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
@@ -283,6 +285,7 @@ struct SettingsContentView: View {
|
||||
displayedComponents: .date
|
||||
)
|
||||
.datePickerStyle(.graphical)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.trialDatePicker)
|
||||
.padding()
|
||||
.navigationTitle("Set Trial Start Date")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -295,6 +298,7 @@ struct SettingsContentView: View {
|
||||
await iapManager.checkSubscriptionStatus()
|
||||
}
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.trialDatePickerDoneButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,6 +342,7 @@ struct SettingsContentView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.paywallPreviewButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -381,6 +386,7 @@ struct SettingsContentView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.tipsPreviewButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -418,6 +424,7 @@ struct SettingsContentView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.testNotificationsButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -470,6 +477,7 @@ struct SettingsContentView: View {
|
||||
.padding()
|
||||
}
|
||||
.disabled(isExportingWidgets)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportWidgetsButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -522,6 +530,7 @@ struct SettingsContentView: View {
|
||||
.padding()
|
||||
}
|
||||
.disabled(isExportingVotingLayouts)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportVotingLayoutsButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -574,6 +583,7 @@ struct SettingsContentView: View {
|
||||
.padding()
|
||||
}
|
||||
.disabled(isExportingWatchViews)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportWatchViewsButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -632,6 +642,7 @@ struct SettingsContentView: View {
|
||||
.padding()
|
||||
}
|
||||
.disabled(isExportingInsights)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportInsightsButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -691,6 +702,7 @@ struct SettingsContentView: View {
|
||||
.padding()
|
||||
}
|
||||
.disabled(isGeneratingScreenshots)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.generateScreenshotsButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -741,6 +753,7 @@ struct SettingsContentView: View {
|
||||
.padding()
|
||||
}
|
||||
.disabled(isDeletingHealthKitData)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.deleteHealthKitButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -852,11 +865,12 @@ struct SettingsContentView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.addTestDataButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
}
|
||||
|
||||
|
||||
private var healthKitToggle: some View {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 12) {
|
||||
@@ -1048,7 +1062,9 @@ struct SettingsContentView: View {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.locationAlertOpenSettingsButton)
|
||||
Button(String(localized: "Cancel"), role: .cancel) {}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.locationAlertCancelButton)
|
||||
} message: {
|
||||
Text("Reflect needs location access to show weather. You can enable it in Settings.")
|
||||
}
|
||||
@@ -1084,6 +1100,7 @@ struct SettingsContentView: View {
|
||||
}
|
||||
.padding()
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportDataButton)
|
||||
.accessibilityLabel(String(localized: "Export Data"))
|
||||
.accessibilityHint(String(localized: "Export your mood data as CSV or PDF"))
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
@@ -1382,6 +1399,7 @@ struct SettingsView: View {
|
||||
Divider()
|
||||
Text("Test builds only")
|
||||
Toggle("Bypass Subscription", isOn: $iapManager.bypassSubscription)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.bypassSubscriptionToggle)
|
||||
addTestDataCell
|
||||
clearDB
|
||||
// fixWeekday
|
||||
@@ -1745,7 +1763,9 @@ struct SettingsView: View {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.locationAlertOpenSettingsButton)
|
||||
Button(String(localized: "Cancel"), role: .cancel) {}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.locationAlertCancelButton)
|
||||
} message: {
|
||||
Text("Reflect needs location access to show weather. You can enable it in Settings.")
|
||||
}
|
||||
@@ -1781,6 +1801,7 @@ struct SettingsView: View {
|
||||
}
|
||||
.padding()
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportDataButton)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
@@ -1797,6 +1818,7 @@ struct SettingsView: View {
|
||||
.font(.body)
|
||||
.foregroundColor(Color(UIColor.systemBlue))
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.closeButton)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1811,17 +1833,20 @@ struct SettingsView: View {
|
||||
Text(String(localized: "settings_view_special_thanks_to_title"))
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.specialThanksButton)
|
||||
.padding()
|
||||
|
||||
if showSpecialThanks {
|
||||
Divider()
|
||||
Link("Font Awesome", destination: URL(string: "https://fontawesome.com")!)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.fontAwesomeLink)
|
||||
.accentColor(textColor)
|
||||
.padding(.bottom)
|
||||
|
||||
Divider()
|
||||
|
||||
Link("Charts", destination: URL(string: "https://github.com/danielgindi/Charts")!)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.chartsLink)
|
||||
.accentColor(textColor)
|
||||
.padding(.bottom)
|
||||
}
|
||||
@@ -1838,6 +1863,7 @@ struct SettingsView: View {
|
||||
Text("Add test data")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.addTestDataButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
@@ -1867,6 +1893,7 @@ struct SettingsView: View {
|
||||
showTrialDatePicker = true
|
||||
}
|
||||
.font(.subheadline.weight(.medium))
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.changeTrialDateButton)
|
||||
}
|
||||
.padding()
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
@@ -1880,6 +1907,7 @@ struct SettingsView: View {
|
||||
displayedComponents: .date
|
||||
)
|
||||
.datePickerStyle(.graphical)
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.trialDatePicker)
|
||||
.padding()
|
||||
.navigationTitle("Set Trial Start Date")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -1892,6 +1920,7 @@ struct SettingsView: View {
|
||||
await iapManager.checkSubscriptionStatus()
|
||||
}
|
||||
}
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.trialDatePickerDoneButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1909,6 +1938,7 @@ struct SettingsView: View {
|
||||
Text("Reset luanch date to current date")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.resetLaunchDateButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
@@ -1923,6 +1953,7 @@ struct SettingsView: View {
|
||||
Text("Clear DB")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.clearDataButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
@@ -1937,6 +1968,7 @@ struct SettingsView: View {
|
||||
Text("Fix Weekday")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.fixWeekdayButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
@@ -1954,6 +1986,7 @@ struct SettingsView: View {
|
||||
Text(String(localized: "settings_view_why_bg_mode_title"))
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.whyBackgroundModeButton)
|
||||
.padding()
|
||||
if showWhyBGMode {
|
||||
Text(String(localized: "settings_view_why_bg_mode_body"))
|
||||
@@ -2110,13 +2143,14 @@ struct SettingsView: View {
|
||||
Text("Export")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.exportLegacyButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
}
|
||||
|
||||
|
||||
private var importData: some View {
|
||||
Button(action: {
|
||||
showingImporter.toggle()
|
||||
@@ -2125,13 +2159,14 @@ struct SettingsView: View {
|
||||
Text("Import")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.importButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
|
||||
}
|
||||
|
||||
|
||||
private var randomIcons: some View {
|
||||
Button(action: {
|
||||
var iconViews = [UIImage]()
|
||||
@@ -2255,6 +2290,7 @@ struct SettingsView: View {
|
||||
Text("Create random icons")
|
||||
.foregroundColor(textColor)
|
||||
})
|
||||
.accessibilityIdentifier(AccessibilityID.Settings.randomIconsButton)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(theme.currentTheme.secondaryBGColor)
|
||||
|
||||
Reference in New Issue
Block a user