From 38723030eb0db58a9d62a45c7725861901309a05 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Mon, 20 Jul 2026 17:21:03 -0500 Subject: feat(a11y): add accessibility audit harness (#21 phase 0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 0 of the accessibility pass: a regression guard that must exist before any of the remedial phases, so their acceptance criteria are enforced rather than asserted once by hand. - Fix the project-level IPHONEOS_DEPLOYMENT_TARGET, which was 26.2 while all three targets are 17.6. It was shadowed everywhere today, but any target added later would silently inherit it and drop iOS 17.6 support with no error. - Add a DomainDigUITests target running performAccessibilityAudit on the six primary screens, plus a sweep of every root screen at AccessibilityXXXL. Uses the existing DOMAIN_DIG_FORCE_PRO_PLUS debug argument so Pro-gated screens are reachable. - Findings are reported, not failed. The audit surfaces violations that exist today, so gating on them would block unrelated PRs until the whole pass lands. Enforcement is a committed constant, AccessibilityAuditHarness.enforcedAuditTypes, widened per audit type as each phase clears a category. - CI now runs xcodebuild test across two simulators. Audit coverage is not nested between OS versions: on Tracked Domains, iOS 18.6 reported 2 findings and iOS 27.0 reported 6 (including contrast and element-detection issues 18.6 never raised), while at accessibility text sizes the Dashboard produced a hit-region finding on 18.6 that 27.0 did not. - Simulator selection is now dynamic and floor-aware. The previous selector took the first iPhone from any runtime, which can resolve to a simulator below the deployment target where the app cannot install. Baseline on iOS 18.6: 15 findings across 7 tests — text clipping on every screen, contrast on Inspect and Settings, and a hit-region failure on the Dashboard at accessibility text sizes. --- DomainDig.xcodeproj/project.pbxproj | 120 ++++++++++++++++++++- .../xcshareddata/xcschemes/DomainDig.xcscheme | 12 +++ 2 files changed, 130 insertions(+), 2 deletions(-) (limited to 'DomainDig.xcodeproj') diff --git a/DomainDig.xcodeproj/project.pbxproj b/DomainDig.xcodeproj/project.pbxproj index 8889f33..6b4c25c 100644 --- a/DomainDig.xcodeproj/project.pbxproj +++ b/DomainDig.xcodeproj/project.pbxproj @@ -33,6 +33,13 @@ remoteGlobalIDString = 8BDB00010000000000000006; remoteInfo = DomainDigShareExtension; }; + 8BDC00010000000000000003 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8B7800612F6090E300933221 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8B7800682F6090E300933221; + remoteInfo = DomainDig; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -61,6 +68,7 @@ 8BCA3CBD2F9C8D57004B742C /* LocalAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAPIService.swift; sourceTree = ""; }; 8BDA00010000000000000001 /* DomainDigWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = DomainDigWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 8BDB00010000000000000001 /* DomainDigShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = DomainDigShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 8BDC00010000000000000001 /* DomainDigUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DomainDigUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 8BF9DA842F9B13FB00EF41D5 /* DomainDataPortabilityService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainDataPortabilityService.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -120,6 +128,11 @@ path = DomainDigShareExtension; sourceTree = ""; }; + 8BDC0001000000000000000E /* DomainDigUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = DomainDigUITests; + sourceTree = ""; + }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ @@ -144,6 +157,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8BDC00010000000000000008 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -155,6 +175,7 @@ 8BDA0001000000000000000D /* Shared */, 8BDA0001000000000000000E /* DomainDigWidget */, 8BDB0001000000000000000E /* DomainDigShareExtension */, + 8BDC0001000000000000000E /* DomainDigUITests */, 8B78006A2F6090E300933221 /* Products */, 8BBFEF062F9874AE00E8E144 /* LookupSnapshot.swift */, 8BBFEF042F9874AE00E8E144 /* DomainReportBuilder.swift */, @@ -172,6 +193,7 @@ 8B7800692F6090E300933221 /* DomainDig.app */, 8BDA00010000000000000001 /* DomainDigWidgetExtension.appex */, 8BDB00010000000000000001 /* DomainDigShareExtension.appex */, + 8BDC00010000000000000001 /* DomainDigUITests.xctest */, ); name = Products; sourceTree = ""; @@ -251,6 +273,29 @@ productReference = 8BDB00010000000000000001 /* DomainDigShareExtension.appex */; productType = "com.apple.product-type.app-extension"; }; + 8BDC00010000000000000006 /* DomainDigUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8BDC0001000000000000000A /* Build configuration list for PBXNativeTarget "DomainDigUITests" */; + buildPhases = ( + 8BDC00010000000000000007 /* Sources */, + 8BDC00010000000000000008 /* Frameworks */, + 8BDC00010000000000000009 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8BDC00010000000000000004 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 8BDC0001000000000000000E /* DomainDigUITests */, + ); + name = DomainDigUITests; + packageProductDependencies = ( + ); + productName = DomainDigUITests; + productReference = 8BDC00010000000000000001 /* DomainDigUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -275,6 +320,10 @@ 8BDB00010000000000000006 = { CreatedOnToolsVersion = 26.3; }; + 8BDC00010000000000000006 = { + CreatedOnToolsVersion = 27.0; + TestTargetID = 8B7800682F6090E300933221; + }; }; }; buildConfigurationList = 8B7800642F6090E300933221 /* Build configuration list for PBXProject "DomainDig" */; @@ -294,6 +343,7 @@ 8B7800682F6090E300933221 /* DomainDig */, 8BDA00010000000000000006 /* DomainDigWidgetExtension */, 8BDB00010000000000000006 /* DomainDigShareExtension */, + 8BDC00010000000000000006 /* DomainDigUITests */, ); }; /* End PBXProject section */ @@ -320,6 +370,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8BDC00010000000000000009 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -351,6 +408,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8BDC00010000000000000007 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -364,6 +428,11 @@ target = 8BDB00010000000000000006 /* DomainDigShareExtension */; targetProxy = 8BDB00010000000000000003 /* PBXContainerItemProxy */; }; + 8BDC00010000000000000004 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8B7800682F6090E300933221 /* DomainDig */; + targetProxy = 8BDC00010000000000000003 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -420,7 +489,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 26.2; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -479,7 +548,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 26.2; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -680,6 +749,44 @@ }; name = Release; }; + 8BDC0001000000000000000B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 43; + DEVELOPMENT_TEAM = ZCNAX3VL9D; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; + MARKETING_VERSION = 4.8.3; + PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.DomainDigUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = DomainDig; + }; + name = Debug; + }; + 8BDC0001000000000000000C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 43; + DEVELOPMENT_TEAM = ZCNAX3VL9D; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; + MARKETING_VERSION = 4.8.3; + PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.DomainDigUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = DomainDig; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -719,6 +826,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 8BDC0001000000000000000A /* Build configuration list for PBXNativeTarget "DomainDigUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8BDC0001000000000000000B /* Debug */, + 8BDC0001000000000000000C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 8B7800612F6090E300933221 /* Project object */; diff --git a/DomainDig.xcodeproj/xcshareddata/xcschemes/DomainDig.xcscheme b/DomainDig.xcodeproj/xcshareddata/xcschemes/DomainDig.xcscheme index 8f733d7..5b0bc8e 100644 --- a/DomainDig.xcodeproj/xcshareddata/xcschemes/DomainDig.xcscheme +++ b/DomainDig.xcodeproj/xcshareddata/xcschemes/DomainDig.xcscheme @@ -29,6 +29,18 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES" shouldAutocreateTestPlan = "YES"> + + + + + +