Add localization strings and iOS test infrastructure
- Expand Localizable.xcstrings with 426 new localization entries - Add xctestplan files (CI, Cleanup, Parallel, Seed) for structured test runs - Add run_ui_tests.sh script for UI test execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
24
.claude/settings.local.json
Normal file
24
.claude/settings.local.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(head:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(tail:*)",
|
||||
"Bash(xcodebuild:*)",
|
||||
"Bash(find:*)",
|
||||
"Bash(curl:*)",
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(git fetch:*)",
|
||||
"Bash(git checkout:*)",
|
||||
"Bash(git:*)",
|
||||
"Bash(python3:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(ps:*)",
|
||||
"Bash(stdbuf:*)",
|
||||
"Bash(sysctl:*)",
|
||||
"Bash(tee:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
417
03_14_26_uiresults.md
Normal file
417
03_14_26_uiresults.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# HoneyDue UI Test Results - March 14, 2026
|
||||
|
||||
**Branch:** `rename/honeydue`
|
||||
**Device:** iPhone 16 Simulator (iOS 26.2)
|
||||
**Parallel:** No (sequential execution)
|
||||
**Machine:** Apple M1, 8GB RAM
|
||||
|
||||
## Summary
|
||||
|
||||
| Status | Count |
|
||||
|--------|-------|
|
||||
| Passed | 71 |
|
||||
| Failed | 168 |
|
||||
| Skipped | 15 |
|
||||
| **Total** | **254** |
|
||||
|
||||
**Pass Rate: 28.0%**
|
||||
|
||||
---
|
||||
|
||||
## Results by Suite
|
||||
|
||||
| Suite | Passed | Failed | Skipped | Total | Pass Rate |
|
||||
|-------|--------|--------|---------|-------|-----------|
|
||||
| AccessibilityTests | 6 | 0 | 0 | 6 | 100% |
|
||||
| AppLaunchTests | 2 | 0 | 0 | 2 | 100% |
|
||||
| StabilityTests | 6 | 0 | 0 | 6 | 100% |
|
||||
| SimpleLoginTest | 2 | 0 | 0 | 2 | 100% |
|
||||
| Suite3_ResidenceRebuildTests | 9 | 0 | 0 | 9 | 100% |
|
||||
| Suite0_OnboardingRebuildTests | 2 | 0 | 3 | 5 | 100%* |
|
||||
| OnboardingTests | 10 | 3 | 0 | 13 | 77% |
|
||||
| Suite2_AuthenticationRebuildTests | 4 | 2 | 0 | 6 | 67% |
|
||||
| Suite2_AuthenticationTests | 4 | 2 | 0 | 6 | 67% |
|
||||
| AuthCriticalPathTests | 3 | 2 | 0 | 5 | 60% |
|
||||
| Suite1_RegistrationTests | 6 | 5 | 0 | 11 | 55% |
|
||||
| Suite9_IntegrationE2ETests | 2 | 5 | 0 | 7 | 29% |
|
||||
| SmokeTests | 1 | 4 | 0 | 5 | 20% |
|
||||
| Suite4_ComprehensiveResidenceTests | 2 | 16 | 0 | 18 | 11% |
|
||||
| Suite6_ComprehensiveTaskTests | 2 | 13 | 0 | 15 | 13% |
|
||||
| Suite10_ComprehensiveE2ETests | 1 | 8 | 0 | 9 | 11% |
|
||||
| Suite5_TaskTests | 1 | 9 | 0 | 10 | 10% |
|
||||
| Suite7_ContractorTests | 2 | 18 | 0 | 20 | 10% |
|
||||
| AuthenticationTests | 10 | 6 | 0 | 16 | 63% |
|
||||
| Suite1_RegistrationRebuildTests | 0 | 2 | 12 | 14 | 0%* |
|
||||
| ContractorIntegrationTests | 0 | 5 | 0 | 5 | 0% |
|
||||
| DataLayerTests | 0 | 10 | 0 | 10 | 0% |
|
||||
| DocumentIntegrationTests | 0 | 4 | 0 | 4 | 0% |
|
||||
| NavigationCriticalPathTests | 0 | 10 | 0 | 10 | 0% |
|
||||
| PasswordResetTests | 0 | 5 | 0 | 5 | 0% |
|
||||
| ResidenceIntegrationTests | 0 | 5 | 0 | 5 | 0% |
|
||||
| Suite0_OnboardingTests | 0 | 1 | 0 | 1 | 0% |
|
||||
| Suite3_ResidenceTests | 0 | 6 | 0 | 6 | 0% |
|
||||
| Suite8_DocumentWarrantyTests | 0 | 25 | 0 | 25 | 0% |
|
||||
| TaskIntegrationTests | 0 | 5 | 0 | 5 | 0% |
|
||||
|
||||
*Pass rate excludes skipped tests
|
||||
|
||||
---
|
||||
|
||||
## Fully Passing Suites (6)
|
||||
|
||||
- **AccessibilityTests** (6/6)
|
||||
- **AppLaunchTests** (2/2)
|
||||
- **StabilityTests** (6/6)
|
||||
- **SimpleLoginTest** (2/2)
|
||||
- **Suite3_ResidenceRebuildTests** (9/9)
|
||||
- **Suite0_OnboardingRebuildTests** (2/2 run, 3 skipped)
|
||||
|
||||
## Fully Failing Suites (10)
|
||||
|
||||
- **ContractorIntegrationTests** (0/5)
|
||||
- **DataLayerTests** (0/10)
|
||||
- **DocumentIntegrationTests** (0/4)
|
||||
- **NavigationCriticalPathTests** (0/10)
|
||||
- **PasswordResetTests** (0/5)
|
||||
- **ResidenceIntegrationTests** (0/5)
|
||||
- **Suite0_OnboardingTests** (0/1)
|
||||
- **Suite3_ResidenceTests** (0/6)
|
||||
- **Suite8_DocumentWarrantyTests** (0/25)
|
||||
- **TaskIntegrationTests** (0/5)
|
||||
|
||||
---
|
||||
|
||||
## Detailed Results
|
||||
|
||||
### AccessibilityTests (6 passed, 0 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testA001_OnboardingPrimaryControlsAreReachable | PASSED | 16.8s |
|
||||
| testA002_LoginControlsRemainOperable | PASSED | 26.9s |
|
||||
| testA003_CoreControlsExposeIdentifiers | PASSED | 15.8s |
|
||||
| testA004_ValuePropsScreenControlsAreReachable | PASSED | 14.8s |
|
||||
| testA005_NameResidenceScreenControlsAreReachable | PASSED | 20.0s |
|
||||
| testA006_CreateAccountScreenControlsAreReachable | PASSED | 23.0s |
|
||||
|
||||
### AppLaunchTests (2 passed, 0 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testF001_ColdLaunchShowsOnboardingWelcome | PASSED | 12.3s |
|
||||
| testF002_ColdLaunchShowsPrimaryOnboardingActions | PASSED | 9.7s |
|
||||
|
||||
### AuthCriticalPathTests (3 passed, 2 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testForgotPasswordButtonExists | PASSED | 21.6s |
|
||||
| testLoginWithInvalidCredentials | PASSED | 21.0s |
|
||||
| testLoginWithValidCredentials | FAILED | 31.4s |
|
||||
| testLogoutFlow | FAILED | 36.0s |
|
||||
| testSignUpButtonNavigatesToRegistration | PASSED | 21.0s |
|
||||
|
||||
### AuthenticationTests (10 passed, 6 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test08_invalidatedTokenRedirectsToLogin | FAILED | 54.5s |
|
||||
| testF201_OnboardingLoginEntryShowsLoginScreen | PASSED | 15.8s |
|
||||
| testF202_LoginScreenCanTogglePasswordVisibility | PASSED | 19.1s |
|
||||
| testF203_RegisterSheetCanOpenAndDismiss | FAILED | 23.4s |
|
||||
| testF204_RegisterFormAcceptsInput | FAILED | 23.7s |
|
||||
| testF205_LoginButtonDisabledWhenCredentialsAreEmpty | PASSED | 16.1s |
|
||||
| testF206_ForgotPasswordButtonIsAccessible | PASSED | 16.4s |
|
||||
| testF207_LoginScreenShowsAllExpectedElements | PASSED | 15.2s |
|
||||
| testF208_RegisterFormShowsAllRequiredFields | FAILED | 24.4s |
|
||||
| testF209_ForgotPasswordNavigatesToResetFlow | PASSED | 18.2s |
|
||||
|
||||
### ContractorIntegrationTests (0 passed, 5 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test20_toggleContractorFavorite | FAILED | 0.4s |
|
||||
| test21_contractorByResidenceFilter | FAILED | 0.3s |
|
||||
| testCON002_CreateContractorMinimalFields | FAILED | 0.2s |
|
||||
| testCON005_EditContractor | FAILED | 0.2s |
|
||||
| testCON006_DeleteContractor | FAILED | 0.2s |
|
||||
|
||||
### DataLayerTests (0 passed, 10 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test08_diskPersistencePreservesLookupsAfterRestart | FAILED | 0.2s |
|
||||
| test09_themePersistsAcrossRestart | FAILED | 0.2s |
|
||||
| test10_completionHistoryLoadsAndIsSorted | FAILED | 0.2s |
|
||||
| testDATA001_LookupsInitializeAfterLogin | FAILED | 0.2s |
|
||||
| testDATA002_ETagRefreshHandles304 | FAILED | 0.2s |
|
||||
| testDATA003_LegacyFallbackStillLoadsCoreLookups | FAILED | 0.2s |
|
||||
| testDATA004_CacheTimeoutAndForceRefresh | FAILED | 0.2s |
|
||||
| testDATA005_LogoutClearsUserDataButRetainsTheme | FAILED | 0.2s |
|
||||
| testDATA006_LookupsPersistAfterAppRestart | FAILED | 0.2s |
|
||||
| testDATA007_LookupMapListConsistency | FAILED | 0.2s |
|
||||
|
||||
### DocumentIntegrationTests (0 passed, 4 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test22_documentImageSectionExists | FAILED | 0.2s |
|
||||
| testDOC002_CreateDocumentWithRequiredFields | FAILED | 0.2s |
|
||||
| testDOC004_EditDocument | FAILED | 0.2s |
|
||||
| testDOC005_DeleteDocument | FAILED | 0.2s |
|
||||
|
||||
### NavigationCriticalPathTests (0 passed, 10 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testAllTabsExist | FAILED | 45.9s |
|
||||
| testContractorAddButtonExists | FAILED | 45.9s |
|
||||
| testDocumentAddButtonExists | FAILED | 45.9s |
|
||||
| testNavigateBackToResidencesTab | FAILED | 45.8s |
|
||||
| testNavigateToContractorsTab | FAILED | 46.2s |
|
||||
| testNavigateToDocumentsTab | FAILED | 45.6s |
|
||||
| testNavigateToTasksTab | FAILED | 45.8s |
|
||||
| testResidenceAddButtonExists | FAILED | 45.8s |
|
||||
| testSettingsButtonExists | FAILED | 45.5s |
|
||||
| testTaskAddButtonExists | FAILED | 45.8s |
|
||||
|
||||
### OnboardingTests (10 passed, 3 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testF101_StartFreshFlowReachesCreateAccount | PASSED | 20.2s |
|
||||
| testF102_JoinExistingFlowGoesToCreateAccount | PASSED | 11.6s |
|
||||
| testF103_BackNavigationFromNameResidenceReturnsToValueProps | PASSED | 16.2s |
|
||||
| testF104_SkipOnValuePropsMovesToNameResidence | PASSED | 13.9s |
|
||||
| testF105_JoinExistingFlowSkipsValuePropsAndNameResidence | PASSED | 11.2s |
|
||||
| testF106_NameResidenceFieldAcceptsInput | PASSED | 15.7s |
|
||||
| testF107_ProgressIndicatorVisibleDuringOnboarding | PASSED | 12.8s |
|
||||
| testF108_BackFromCreateAccountNavigatesToPreviousStep | PASSED | 22.5s |
|
||||
| testF110_startFreshCreatesResidenceAfterVerification | FAILED | 29.1s |
|
||||
| testF111_completedOnboardingBypassedOnRelaunch | FAILED | 52.9s |
|
||||
|
||||
### PasswordResetTests (0 passed, 5 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test03_verifyResetCodeSuccess | FAILED | 35.4s |
|
||||
| test04_resetPasswordSuccessAndLogin | FAILED | 35.4s |
|
||||
| testAUTH015_VerifyResetCodeSuccessPath | FAILED | 35.3s |
|
||||
| testAUTH016_ResetPasswordSuccess | FAILED | 36.1s |
|
||||
| testAUTH017_MismatchedPasswordBlocked | FAILED | 35.3s |
|
||||
|
||||
### ResidenceIntegrationTests (0 passed, 5 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test18_setPrimaryResidence | FAILED | 0.4s |
|
||||
| test19_doubleSubmitProtection | FAILED | 0.3s |
|
||||
| testRES_CreateResidenceAppearsInList | FAILED | 0.2s |
|
||||
| testRES_DeleteResidenceRemovesFromList | FAILED | 0.2s |
|
||||
| testRES_EditResidenceUpdatesInList | FAILED | 0.2s |
|
||||
|
||||
### SimpleLoginTest (2 passed, 0 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testAppLaunchesAndShowsLoginScreen | PASSED | 24.3s |
|
||||
| testCanTypeInLoginFields | PASSED | 27.9s |
|
||||
|
||||
### SmokeTests (1 passed, 4 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testAppLaunches | FAILED | 25.8s |
|
||||
| testLoginScreenElements | PASSED | 20.7s |
|
||||
| testLoginWithExistingCredentials | FAILED | 30.7s |
|
||||
| testMainTabsExistAfterLogin | FAILED | 35.6s |
|
||||
| testTabNavigation | FAILED | 35.4s |
|
||||
|
||||
### StabilityTests (6 passed, 0 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testP001_RapidOnboardingNavigationDoesNotCrash | PASSED | 31.6s |
|
||||
| testP002_RepeatedForwardNavigationRemainsResponsive | PASSED | 53.1s |
|
||||
| testP003_RapidDoubleTapOnValuePropsContinueLandsOnNameResidence | PASSED | 13.7s |
|
||||
| testP004_StartFreshThenBackToWelcomeThenJoinExistingDoesNotCorruptState | PASSED | 17.0s |
|
||||
| testP005_RepeatedLoginNavigationRemainsStable | PASSED | 41.4s |
|
||||
| testP010_retryButtonExistsOnErrorState | PASSED | 21.1s |
|
||||
|
||||
### Suite0_OnboardingRebuildTests (2 passed, 0 failed, 3 skipped)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testR001_onboardingWelcomeLoadsAndCanNavigateToLoginEntry | PASSED | 12.5s |
|
||||
| testR002_startFreshFlowReachesCreateAccount | PASSED | 19.0s |
|
||||
| testR003_createAccountExpandedFormFieldsAreInteractable | SKIPPED | 6.5s |
|
||||
| testR004_emailFieldCanFocusAndAcceptTyping | SKIPPED | 6.2s |
|
||||
| testR005_createAccountContinueOnlyAfterValidInputs | SKIPPED | 6.3s |
|
||||
|
||||
### Suite0_OnboardingTests (0 passed, 1 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test_onboarding | FAILED | 33.1s |
|
||||
|
||||
### Suite1_RegistrationRebuildTests (0 passed, 2 failed, 12 skipped)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testR101_registerFormCanOpenFromLogin | FAILED | 29.9s |
|
||||
| testR102_registerFormAcceptsValidInput | FAILED | 29.1s |
|
||||
| testR103-R114 (12 tests) | SKIPPED | ~5s each |
|
||||
|
||||
### Suite1_RegistrationTests (6 passed, 5 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01_registrationScreenElements | PASSED | 40.8s |
|
||||
| test02_cancelRegistration | PASSED | 46.7s |
|
||||
| test03_registrationWithEmptyFields | PASSED | 45.0s |
|
||||
| test04_registrationWithInvalidEmail | PASSED | 54.8s |
|
||||
| test05_registrationWithMismatchedPasswords | PASSED | 55.9s |
|
||||
| test06_registrationWithWeakPassword | PASSED | 55.4s |
|
||||
| test07_successfulRegistrationAndVerification | FAILED | 64.5s |
|
||||
| test09_registrationWithInvalidVerificationCode | FAILED | 95.4s |
|
||||
| test10_verificationCodeFieldValidation | FAILED | 95.6s |
|
||||
| test11_appRelaunchWithUnverifiedUser | FAILED | 96.5s |
|
||||
| test12_logoutFromVerificationScreen | FAILED | 96.6s |
|
||||
|
||||
### Suite2_AuthenticationRebuildTests (4 passed, 2 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testR201_loginScreenLoadsFromOnboardingEntry | PASSED | 29.9s |
|
||||
| testR202_validCredentialsSubmitFromLogin | PASSED | 33.4s |
|
||||
| testR203_validLoginTransitionsToMainAppRoot | PASSED | 38.9s |
|
||||
| testR204_mainAppHasExpectedPrimaryTabsAfterLogin | PASSED | 24.2s |
|
||||
| testR205_logoutFromMainAppReturnsToLoginRoot | FAILED | 46.4s |
|
||||
| testR206_postLogoutMainAppIsNoLongerAccessible | FAILED | 43.8s |
|
||||
|
||||
### Suite2_AuthenticationTests (4 passed, 2 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01_loginWithInvalidCredentials | PASSED | 22.8s |
|
||||
| test02_loginWithValidCredentials | FAILED | 30.8s |
|
||||
| test03_passwordVisibilityToggle | PASSED | 15.6s |
|
||||
| test04_navigationToSignUp | PASSED | 14.1s |
|
||||
| test05_forgotPasswordNavigation | PASSED | 14.0s |
|
||||
| test06_logout | FAILED | 29.7s |
|
||||
|
||||
### Suite3_ResidenceRebuildTests (9 passed, 0 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| testR301_authenticatedPreconditionCanReachMainApp | PASSED | 24.2s |
|
||||
| testR302_residencesTabIsPresentAndNavigable | PASSED | 21.9s |
|
||||
| testR303_residencesListLoadsAfterTabSelection | PASSED | 22.8s |
|
||||
| testR304_openAddResidenceFormFromResidencesList | PASSED | 25.1s |
|
||||
| testR305_cancelAddResidenceReturnsToResidenceList | PASSED | 26.9s |
|
||||
| testR306_createResidenceMinimalDataSubmitsSuccessfully | PASSED | 31.3s |
|
||||
| testR307_newResidenceAppearsInResidenceList | PASSED | 31.1s |
|
||||
| testR308_openResidenceDetailsFromResidenceList | PASSED | 32.6s |
|
||||
| testR309_navigationAcrossPrimaryTabsAndBackToResidences | PASSED | 25.5s |
|
||||
|
||||
### Suite3_ResidenceTests (0 passed, 6 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01_viewResidencesList | FAILED | 31.1s |
|
||||
| test02_navigateToAddResidence | FAILED | 31.0s |
|
||||
| test03_navigationBetweenTabs | FAILED | 31.5s |
|
||||
| test04_cancelResidenceCreation | FAILED | 31.9s |
|
||||
| test05_createResidenceWithMinimalData | FAILED | 31.1s |
|
||||
| test06_viewResidenceDetails | FAILED | 31.4s |
|
||||
|
||||
### Suite4_ComprehensiveResidenceTests (2 passed, 16 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01-16 (16 tests) | FAILED | ~36s each |
|
||||
| test17_residenceListPerformance | PASSED | 78.1s |
|
||||
| test18_residenceCreationPerformance | PASSED | 47.5s |
|
||||
|
||||
### Suite5_TaskTests (1 passed, 9 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01_cancelTaskCreation | FAILED | 50.8s |
|
||||
| test02_tasksTabExists | FAILED | 39.3s |
|
||||
| test03_viewTasksList | FAILED | 53.2s |
|
||||
| test04_addTaskButtonExists | FAILED | 50.4s |
|
||||
| test05_navigateToAddTask | FAILED | 50.5s |
|
||||
| test06_createBasicTask | FAILED | 50.7s |
|
||||
| test07_viewTaskDetails | PASSED | 52.6s |
|
||||
| test08_navigateToContractors | FAILED | 50.7s |
|
||||
| test09_navigateToDocuments | FAILED | 51.0s |
|
||||
| test10_navigateBetweenTabs | FAILED | 45.7s |
|
||||
|
||||
### Suite6_ComprehensiveTaskTests (2 passed, 13 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01-13 (13 tests) | FAILED | ~43-56s each |
|
||||
| test14_taskListPerformance | PASSED | 82.7s |
|
||||
| test15_taskCreationPerformance | PASSED | 52.7s |
|
||||
|
||||
### Suite7_ContractorTests (2 passed, 18 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01-18 (18 tests) | FAILED | ~36s each |
|
||||
| test19_contractorListPerformance | PASSED | 78.6s |
|
||||
| test20_contractorCreationPerformance | PASSED | 48.3s |
|
||||
|
||||
### Suite8_DocumentWarrantyTests (0 passed, 25 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01-25 (all 25 tests) | FAILED | ~46-50s each |
|
||||
|
||||
### Suite9_IntegrationE2ETests (2 passed, 5 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test01_authenticationFlow | FAILED | 42.8s |
|
||||
| test02_residenceCRUDFlow | FAILED | 40.9s |
|
||||
| test03_taskLifecycleFlow | FAILED | 57.5s |
|
||||
| test04_kanbanColumnDistribution | FAILED | 38.0s |
|
||||
| test05_crossUserAccessControl | FAILED | 37.7s |
|
||||
| test06_lookupDataAvailable | PASSED | 41.8s |
|
||||
| test07_residenceSharingUIElements | PASSED | 42.0s |
|
||||
|
||||
### TaskIntegrationTests (0 passed, 5 failed)
|
||||
|
||||
| Test | Result | Time |
|
||||
|------|--------|------|
|
||||
| test15_uncancelRestorescancelledTask | FAILED | 0.4s |
|
||||
| test16_createTaskFromTemplate | FAILED | 0.2s |
|
||||
| testTASK_CreateTaskAppearsInList | FAILED | 0.2s |
|
||||
| testTASK010_UncancelTaskFlow | FAILED | 0.2s |
|
||||
| testTASK012_DeleteTaskUpdatesViews | FAILED | 0.2s |
|
||||
|
||||
---
|
||||
|
||||
## Observations
|
||||
|
||||
### Patterns in Failures
|
||||
|
||||
1. **Integration tests fail instantly (~0.2s):** ContractorIntegrationTests, DataLayerTests, DocumentIntegrationTests, ResidenceIntegrationTests, TaskIntegrationTests all fail in < 0.5s, suggesting they crash on setup or have missing preconditions.
|
||||
|
||||
2. **NavigationCriticalPathTests all timeout at ~45s:** These require authenticated login but consistently fail at the same timeout, likely unable to complete login flow.
|
||||
|
||||
3. **Suite3-8 (authenticated CRUD tests) fail at ~36-50s:** All authenticated tests that use the older test patterns fail with similar timeouts, suggesting the login/auth flow in these older suites is broken.
|
||||
|
||||
4. **Rebuild suites pass where old suites fail:** `Suite3_ResidenceRebuildTests` passes 9/9 while `Suite3_ResidenceTests` fails 6/6. The rebuild suites use the updated `AuthenticatedTestCase` framework.
|
||||
|
||||
5. **Pre-auth tests pass reliably:** Onboarding, accessibility, stability, app launch, and simple login tests all pass because they don't require authentication.
|
||||
|
||||
6. **Logout tests consistently fail:** Both `testR205_logoutFromMainAppReturnsToLoginRoot` and `test06_logout` fail across multiple suites.
|
||||
|
||||
### Build Fix Applied
|
||||
|
||||
Fixed `TEST_HOST` casing mismatch in `project.pbxproj`: changed `HoneyDue.app/HoneyDue` to `honeyDue.app/honeyDue` to match the renamed product.
|
||||
|
||||
Fixed `SubscriptionGatingTests` compile error: added missing `tier`, `isActive`, `trialStart`, `trialEnd`, `trialActive`, `subscriptionSource` parameters to `SubscriptionStatus` constructor.
|
||||
32
iosApp/CITests.xctestplan
Normal file
32
iosApp/CITests.xctestplan
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"configurations" : [
|
||||
{
|
||||
"id" : "D4000004-CI00-4D4D-BFDC-000000000004",
|
||||
"name" : "CI Configuration",
|
||||
"options" : {
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
"testTimeoutsEnabled" : true,
|
||||
"defaultTestExecutionTimeAllowance" : 300,
|
||||
"maximumTestRepetitions" : 1,
|
||||
"targetForVariableExpansion" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "D4ADB376A7A4CFB73469E173",
|
||||
"name" : "HoneyDue"
|
||||
}
|
||||
},
|
||||
"testTargets" : [
|
||||
{
|
||||
"parallelizable" : true,
|
||||
"target" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "1CBF1BEC2ECD9768001BF56C",
|
||||
"name" : "HoneyDueUITests"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 1
|
||||
}
|
||||
31
iosApp/CleanupTests.xctestplan
Normal file
31
iosApp/CleanupTests.xctestplan
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"configurations" : [
|
||||
{
|
||||
"id" : "C3000003-CLEN-4C3C-BFDC-000000000003",
|
||||
"name" : "Cleanup Configuration",
|
||||
"options" : {
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
"targetForVariableExpansion" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "D4ADB376A7A4CFB73469E173",
|
||||
"name" : "HoneyDue"
|
||||
}
|
||||
},
|
||||
"testTargets" : [
|
||||
{
|
||||
"selectedTests" : [
|
||||
"SuiteZZ_CleanupTests"
|
||||
],
|
||||
"target" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "1CBF1BEC2ECD9768001BF56C",
|
||||
"name" : "HoneyDueUITests"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 1
|
||||
}
|
||||
46
iosApp/ParallelTests.xctestplan
Normal file
46
iosApp/ParallelTests.xctestplan
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"configurations" : [
|
||||
{
|
||||
"id" : "B2000002-PARA-4B2B-BFDC-000000000002",
|
||||
"name" : "Parallel Configuration",
|
||||
"options" : {
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
"targetForVariableExpansion" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "D4ADB376A7A4CFB73469E173",
|
||||
"name" : "HoneyDue"
|
||||
}
|
||||
},
|
||||
"testTargets" : [
|
||||
{
|
||||
"parallelizable" : true,
|
||||
"selectedTests" : [
|
||||
"AuthCriticalPathTests",
|
||||
"NavigationCriticalPathTests",
|
||||
"SmokeTests",
|
||||
"SimpleLoginTest",
|
||||
"Suite0_OnboardingTests",
|
||||
"Suite1_RegistrationTests",
|
||||
"Suite2_AuthenticationTests",
|
||||
"Suite3_ResidenceTests",
|
||||
"Suite4_ComprehensiveResidenceTests",
|
||||
"Suite5_TaskTests",
|
||||
"Suite6_ComprehensiveTaskTests",
|
||||
"Suite7_ContractorTests",
|
||||
"Suite8_DocumentWarrantyTests",
|
||||
"Suite9_IntegrationE2ETests",
|
||||
"Suite10_ComprehensiveE2ETests"
|
||||
],
|
||||
"target" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "1CBF1BEC2ECD9768001BF56C",
|
||||
"name" : "HoneyDueUITests"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 1
|
||||
}
|
||||
31
iosApp/SeedTests.xctestplan
Normal file
31
iosApp/SeedTests.xctestplan
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"configurations" : [
|
||||
{
|
||||
"id" : "A1000001-SEED-4A1A-BFDC-000000000001",
|
||||
"name" : "Seed Configuration",
|
||||
"options" : {
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
"targetForVariableExpansion" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "D4ADB376A7A4CFB73469E173",
|
||||
"name" : "HoneyDue"
|
||||
}
|
||||
},
|
||||
"testTargets" : [
|
||||
{
|
||||
"selectedTests" : [
|
||||
"AAA_SeedTests"
|
||||
],
|
||||
"target" : {
|
||||
"containerPath" : "container:honeyDue.xcodeproj",
|
||||
"identifier" : "1CBF1BEC2ECD9768001BF56C",
|
||||
"name" : "HoneyDueUITests"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 1
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
"strings" : {
|
||||
"" : {
|
||||
|
||||
},
|
||||
" %@" : {
|
||||
"comment" : "A chevron up and down symbol. The argument is the “chevron.up.chevron.down” symbol.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"*" : {
|
||||
|
||||
@@ -46,6 +50,42 @@
|
||||
"comment" : "A message displayed when a contractor is successfully imported to the user's contacts. The placeholder is replaced with the name of the imported contractor.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"%@ plan, %@%@%@" : {
|
||||
"comment" : "A label describing a subscription plan. The first argument is the plan title. The second argument is the price of the plan. The third argument is the billing period. The fourth argument is the savings information, if available.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "%1$@ plan, %2$@%3$@%4$@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"%@, %@" : {
|
||||
"comment" : "Accessibility label and value that describe the task and its selection state.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "%1$@, %2$@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"%@, %@%@" : {
|
||||
"comment" : "A button that displays the name of a product and its price.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "%1$@, %2$@%3$@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"%@: %@" : {
|
||||
"comment" : "An error message displayed when there was an issue loading tasks for a residence.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
@@ -58,6 +98,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"%@: Free: %@, Pro: %@" : {
|
||||
"comment" : "A label that describes a comparison between a free and a pro feature.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "%1$@: Free: %2$@, Pro: %3$@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"%d" : {
|
||||
"comment" : "A badge displaying the number of tasks in a category. The argument is the count of tasks in the category.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -92,12 +144,12 @@
|
||||
"%lld common tasks" : {
|
||||
|
||||
},
|
||||
"%lld/%lld tasks selected" : {
|
||||
"%lld task%@ selected" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "%1$lld/%2$lld tasks selected"
|
||||
"value" : "%1$lld task%2$@ selected"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,6 +201,10 @@
|
||||
"comment" : "A label for the actions menu in the task card.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Add %@ to favorites" : {
|
||||
"comment" : "A label for the favorite button. The argument is the name of the contractor.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Add %lld Task%@ & Continue" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -158,9 +214,28 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Add contractor" : {
|
||||
"comment" : "A label for the button that adds a new contractor.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Add document" : {
|
||||
|
||||
},
|
||||
"Add Most Popular" : {
|
||||
|
||||
},
|
||||
"Add new property" : {
|
||||
"comment" : "A label displayed as a button in the toolbar.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Add new task" : {
|
||||
"comment" : "A label for a button that adds a new task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Add task" : {
|
||||
"comment" : "A button that adds a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Add your first property to get started!" : {
|
||||
"comment" : "A description below the image in the \"No properties yet\" view, encouraging the user to add their first property.",
|
||||
@@ -169,6 +244,9 @@
|
||||
"Adds a subtle hexagonal grid overlay" : {
|
||||
"comment" : "A description of the Honeycomb Pattern feature.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"All optional -- helps us personalize your plan" : {
|
||||
|
||||
},
|
||||
"Already have an account?" : {
|
||||
|
||||
@@ -315,6 +393,10 @@
|
||||
"comment" : "The text of a button that archives a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Archive task" : {
|
||||
"comment" : "A label displayed as a button that archives a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Archive Task" : {
|
||||
"comment" : "A button that archives a task. The text \"Archive Task\" is a placeholder and should be replaced with the actual translation.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -333,6 +415,10 @@
|
||||
},
|
||||
"Are you sure you want to remove %@ from this residence?" : {
|
||||
|
||||
},
|
||||
"Attached photo" : {
|
||||
"comment" : "A label for an attached photo.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"auth_account_info" : {
|
||||
"extractionState" : "manual",
|
||||
@@ -4270,6 +4356,10 @@
|
||||
},
|
||||
"Back" : {
|
||||
|
||||
},
|
||||
"Back to all photos" : {
|
||||
"comment" : "A button that dismisses a sheet and returns to the previous screen.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Back to Login" : {
|
||||
"comment" : "A button label that takes the user back to the login screen.",
|
||||
@@ -4288,6 +4378,10 @@
|
||||
},
|
||||
"Cancel anytime in Settings • No commitment" : {
|
||||
|
||||
},
|
||||
"Cancel task" : {
|
||||
"comment" : "A button that cancels a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Cancel Task" : {
|
||||
|
||||
@@ -5330,6 +5424,10 @@
|
||||
"comment" : "A button label that indicates a task has been completed.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Complete task" : {
|
||||
"comment" : "A label displayed as a button that completes a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Complete Task" : {
|
||||
"comment" : "A button label that says \"Complete Task\".",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -5338,9 +5436,23 @@
|
||||
"comment" : "The title of the view.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Completion Animation, %@" : {
|
||||
|
||||
},
|
||||
"Completion history for %@" : {
|
||||
"comment" : "A sheet that shows a user's completions history for a task. The argument is the name of the task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Completion photo%@" : {
|
||||
"comment" : "A label for the photo view. The argument is the caption of the photo.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Completion Photos" : {
|
||||
"comment" : "The title for the view that shows a user's photo submissions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Completions (%lld)" : {
|
||||
|
||||
},
|
||||
"completions at %@" : {
|
||||
"comment" : "A subheading describing the content of the honeycomb view.",
|
||||
@@ -5354,6 +5466,10 @@
|
||||
},
|
||||
"Continue with Free" : {
|
||||
|
||||
},
|
||||
"Contractor actions" : {
|
||||
"comment" : "A label for the menu button that appears in the navigation bar.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Contractor Imported" : {
|
||||
|
||||
@@ -9002,6 +9118,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Copy share code" : {
|
||||
"comment" : "A button that copies the share code to the user's clipboard.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Cost: %@" : {
|
||||
"comment" : "A label displaying the cost of a task completion. The argument is the cost of the completion.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -9017,6 +9137,10 @@
|
||||
},
|
||||
"Creating Account..." : {
|
||||
|
||||
},
|
||||
"Delete property" : {
|
||||
"comment" : "A button that deletes a residence.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Didn't receive a code? Check your spam folder or re-register" : {
|
||||
"comment" : "A hint instructing the user to check their spam folder if they haven't received the verification code.",
|
||||
@@ -9030,6 +9154,10 @@
|
||||
"comment" : "A label displayed above the documents tab in the main tab view.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Document actions" : {
|
||||
"comment" : "A label for the menu button that appears in the navigation bar.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"documents_active" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -17032,6 +17160,63 @@
|
||||
"comment" : "A button that dismisses an image viewer sheet.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to %@ completions" : {
|
||||
|
||||
},
|
||||
"Double tap to archive this task" : {
|
||||
"comment" : "A hint for the user to double tap a task to archive it.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to cancel this task" : {
|
||||
"comment" : "A hint for the user to double tap a task to cancel it.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to complete this task" : {
|
||||
"comment" : "A hint for the user to double tap a task to complete it.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to continue to the next step" : {
|
||||
"comment" : "A hint that describes the action to be taken.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to create account" : {
|
||||
|
||||
},
|
||||
"Double tap to edit this task" : {
|
||||
"comment" : "A hint for the user to double tap a task to edit it.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to join an existing property with a share code" : {
|
||||
|
||||
},
|
||||
"Double tap to log in to your existing account" : {
|
||||
|
||||
},
|
||||
"Double tap to mark this task as in progress" : {
|
||||
"comment" : "A hint for the user to double tap a task to mark it as in progress.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to restore this task" : {
|
||||
"comment" : "A hint for the user to double tap a task to restore it.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to send a verification code to your email" : {
|
||||
|
||||
},
|
||||
"Double tap to sign in" : {
|
||||
|
||||
},
|
||||
"Double tap to start setting up your property" : {
|
||||
|
||||
},
|
||||
"Double tap to unarchive this task" : {
|
||||
"comment" : "A hint for unarchive task buttons.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Double tap to use this template" : {
|
||||
"comment" : "A hint for using a task template.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Downloading..." : {
|
||||
|
||||
},
|
||||
@@ -17043,6 +17228,14 @@
|
||||
"comment" : "A label for an edit action.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Edit property" : {
|
||||
"comment" : "A label for the edit button in the residences list.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Edit task" : {
|
||||
"comment" : "A label for a button that edits a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Edit Task" : {
|
||||
"comment" : "A label for an \"Edit Task\" button.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -17053,10 +17246,25 @@
|
||||
"Email Address" : {
|
||||
"comment" : "A label for the user to input their email address.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Enter 6-character share code" : {
|
||||
|
||||
},
|
||||
"Enter 6-digit code" : {
|
||||
"comment" : "A placeholder text for a text field where a user can enter a 6-digit code.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Enter 6-digit verification code" : {
|
||||
|
||||
},
|
||||
"Enter 6-digit verification code from your email" : {
|
||||
|
||||
},
|
||||
"Enter a password with at least 8 characters" : {
|
||||
|
||||
},
|
||||
"Enter a unique username" : {
|
||||
|
||||
},
|
||||
"Enter new password" : {
|
||||
|
||||
@@ -17072,13 +17280,31 @@
|
||||
"Enter the 6-digit code from your email" : {
|
||||
"comment" : "A footer label explaining that users should enter the 6-digit code they received in their email.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Enter the name of your property" : {
|
||||
|
||||
},
|
||||
"Enter the number of days between each occurrence" : {
|
||||
|
||||
},
|
||||
"Enter your account email address" : {
|
||||
|
||||
},
|
||||
"Enter your email address" : {
|
||||
|
||||
},
|
||||
"Enter your email address and we'll send you a verification code" : {
|
||||
"comment" : "A description below the email input field, instructing the user to enter their email address to receive a password reset code.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Enter your first name" : {
|
||||
|
||||
},
|
||||
"Enter your last name" : {
|
||||
|
||||
},
|
||||
"Enter your ZIP code" : {
|
||||
|
||||
},
|
||||
"Enter your ZIP code so we can suggest\nmaintenance tasks for your climate region." : {
|
||||
|
||||
@@ -17423,6 +17649,13 @@
|
||||
"Feature" : {
|
||||
"comment" : "The header for a feature in the feature comparison table.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Filter by specialty" : {
|
||||
"comment" : "A button that filters the list of contractors by specialty.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Filter documents" : {
|
||||
|
||||
},
|
||||
"Forgot Password?" : {
|
||||
"comment" : "A title for the \"Forgot Password?\" screen.",
|
||||
@@ -17439,17 +17672,56 @@
|
||||
"comment" : "A button label that generates a new invitation code.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Generate maintenance report" : {
|
||||
"comment" : "A button that generates a maintenance report.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Generate New Code" : {
|
||||
"comment" : "A button label that appears when a user wants to generate a new invitation code.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Generate new share code" : {
|
||||
"comment" : "A button that generates a new share code.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Generating suggestions..." : {
|
||||
"comment" : "Text displayed while the app is generating personalized task suggestions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Get notified when someone joins your property" : {
|
||||
|
||||
},
|
||||
"Get notified when tasks are assigned to you" : {
|
||||
|
||||
},
|
||||
"Get notified when tasks are completed by others" : {
|
||||
|
||||
},
|
||||
"Get notified when tasks are due soon" : {
|
||||
|
||||
},
|
||||
"Get notified when tasks are overdue" : {
|
||||
|
||||
},
|
||||
"Get notified when warranties are about to expire" : {
|
||||
|
||||
},
|
||||
"Go back" : {
|
||||
"comment" : "A label for the back button.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Good match" : {
|
||||
"comment" : "A label describing a task's relevance.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Google Sign-In Error" : {
|
||||
|
||||
},
|
||||
"Help improve honeyDue by sharing anonymous usage data" : {
|
||||
|
||||
"Great match" : {
|
||||
"comment" : "A label describing a high-relevance task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Here are tasks recommended for your area.\nPick the ones you'd like to track!" : {
|
||||
"Help improve honeyDue by sharing anonymous usage data" : {
|
||||
|
||||
},
|
||||
"Honeycomb Pattern" : {
|
||||
@@ -17475,6 +17747,10 @@
|
||||
"comment" : "A button label that indicates the user is ready to use honeyDue.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Image" : {
|
||||
"comment" : "A label describing an image.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Image %lld of %lld" : {
|
||||
"comment" : "A navigation title that shows the current image index and the total number of images.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
@@ -17503,6 +17779,10 @@
|
||||
"comment" : "A header that suggests inviting others to join the app.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Join a property" : {
|
||||
"comment" : "A button that opens a sheet for joining a residence.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Join a Residence" : {
|
||||
"comment" : "A button label that instructs the user to join an existing residence.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -17534,6 +17814,9 @@
|
||||
},
|
||||
"Let's give your place a name!" : {
|
||||
|
||||
},
|
||||
"Loading" : {
|
||||
|
||||
},
|
||||
"Loading..." : {
|
||||
"comment" : "A placeholder text indicating that content is loading.",
|
||||
@@ -17547,6 +17830,10 @@
|
||||
},
|
||||
"Manage at honeyDue.treytartt.com" : {
|
||||
|
||||
},
|
||||
"Manage users" : {
|
||||
"comment" : "A button that opens a sheet for managing users in a residence.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Manage your subscription at honeyDue.treytartt.com" : {
|
||||
"comment" : "A description of how to manage a subscription on a third-party platform.",
|
||||
@@ -17554,6 +17841,10 @@
|
||||
},
|
||||
"Manage your subscription on your Android device" : {
|
||||
|
||||
},
|
||||
"Mark as in progress" : {
|
||||
"comment" : "A hint for the user to mark a task as in progress.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Mark Task In Progress" : {
|
||||
"comment" : "A button label that says \"Mark Task In Progress\".",
|
||||
@@ -17571,6 +17862,10 @@
|
||||
},
|
||||
"No personal data is collected. Analytics are fully anonymous." : {
|
||||
|
||||
},
|
||||
"No personalized suggestions yet" : {
|
||||
"comment" : "A message displayed when the user has not yet been personalized.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"No properties yet" : {
|
||||
|
||||
@@ -17594,6 +17889,14 @@
|
||||
"comment" : "A message displayed when no task templates match a search query.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"None" : {
|
||||
"comment" : "A button that clears the selection.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"not selected" : {
|
||||
"comment" : "A label that describes the selection state of a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Notification Time" : {
|
||||
"comment" : "The title of the sheet where a user can select the time for receiving notifications.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -17610,9 +17913,16 @@
|
||||
"comment" : "A button that dismisses the success dialog.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Open %@ in Maps" : {
|
||||
"comment" : "A label for the accessibility element that opens the address in Maps.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Open honeyDue.treytartt.com" : {
|
||||
"comment" : "A button label that opens the user's subscription management page in a web browser.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Opens email to contact support" : {
|
||||
|
||||
},
|
||||
"or" : {
|
||||
|
||||
@@ -17632,10 +17942,18 @@
|
||||
"comment" : "A title for a view that displays a single photo.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Photo%@" : {
|
||||
"comment" : "A label for a photo. The argument is the caption of the photo.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Primary" : {
|
||||
"comment" : "A label indicating that a residence is the user's primary residence.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Primary property" : {
|
||||
"comment" : "A label for the star icon.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Privacy" : {
|
||||
|
||||
},
|
||||
@@ -21692,12 +22010,43 @@
|
||||
},
|
||||
"Quick Start" : {
|
||||
|
||||
},
|
||||
"Rated %@ out of 5" : {
|
||||
"comment" : "A label that describes the rating of a task completion. The argument is the rating.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Rated 4.9 stars by 10K+ homeowners" : {
|
||||
|
||||
},
|
||||
"Rating: %lld out of 5 stars" : {
|
||||
|
||||
},
|
||||
"Re-enter new password" : {
|
||||
|
||||
},
|
||||
"Re-enter your password to confirm" : {
|
||||
|
||||
},
|
||||
"Receive a daily summary of upcoming tasks" : {
|
||||
|
||||
},
|
||||
"Receive email notifications when tasks are completed" : {
|
||||
|
||||
},
|
||||
"Refresh tasks" : {
|
||||
"comment" : "A button that refreshes the tasks.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Remove" : {
|
||||
|
||||
},
|
||||
"Remove %@ from favorites" : {
|
||||
"comment" : "A label for the favorite button. The argument is the name of the contractor.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Remove %@ from property" : {
|
||||
"comment" : "A button that removes a user from a property. The argument is the username of the user to be removed.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Remove User" : {
|
||||
|
||||
@@ -24845,6 +25194,10 @@
|
||||
"comment" : "A button label that allows users to restore previous purchases.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Restore task" : {
|
||||
"comment" : "A button that restores a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Restore Task" : {
|
||||
"comment" : "A button that restores a cancelled or archived task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -24866,6 +25219,10 @@
|
||||
},
|
||||
"Save your home to your account" : {
|
||||
|
||||
},
|
||||
"Search task templates by name" : {
|
||||
"comment" : "A hint for the search bar in the task templates browser.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Search templates..." : {
|
||||
"comment" : "A placeholder text for a search bar in the task templates browser.",
|
||||
@@ -24875,6 +25232,14 @@
|
||||
"comment" : "A label displayed above the picker for selecting the notification time.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"selected" : {
|
||||
"comment" : "A label that describes the selection state of a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Selected" : {
|
||||
"comment" : "A label that describes a selected option.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Send a .honeydue file via Messages, Email, or AirDrop. They just tap to join." : {
|
||||
|
||||
},
|
||||
@@ -24899,6 +25264,10 @@
|
||||
},
|
||||
"Set New Password" : {
|
||||
|
||||
},
|
||||
"Settings" : {
|
||||
"comment" : "A button that opens a settings screen.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"settings_language" : {
|
||||
"extractionState" : "manual",
|
||||
@@ -25037,12 +25406,33 @@
|
||||
"comment" : "A label displayed above the share code section of the view.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Share code: %@" : {
|
||||
"comment" : "A label for the share code, with the share code as the value.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Share this 6-character code. They can enter it in the app to join." : {
|
||||
"comment" : "A description of how to share the invitation code with others.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Shared Users (%lld)" : {
|
||||
|
||||
},
|
||||
"Show active warranties only" : {
|
||||
|
||||
},
|
||||
"Show all contractors" : {
|
||||
"comment" : "A label for a button that shows all contractors.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Show all warranties" : {
|
||||
|
||||
},
|
||||
"Show favorites only" : {
|
||||
"comment" : "A label for a button that filters contractors to show only the ones that the user has marked as favorites.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Sign in with Apple" : {
|
||||
|
||||
},
|
||||
"Sign in with Google" : {
|
||||
|
||||
@@ -25072,6 +25462,10 @@
|
||||
"comment" : "A description below the title of the screen.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Step %lld of 5" : {
|
||||
"comment" : "A label that describes the current step in the onboarding flow. The argument is the step number.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Subscription Active" : {
|
||||
"comment" : "The title of an alert that appears when a user successfully upgrades to a premium subscription.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -25087,6 +25481,10 @@
|
||||
"comment" : "A description of an action a user can take to add a property.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Task actions" : {
|
||||
"comment" : "A label displayed as a button in the task card that opens a menu of task actions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Task Templates" : {
|
||||
"comment" : "The title of the view that lists all predefined task templates.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@@ -30193,6 +30591,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Tell us about your home" : {
|
||||
|
||||
},
|
||||
"Templates will appear here once loaded" : {
|
||||
"comment" : "A description text displayed when there are no task templates available.",
|
||||
@@ -30203,6 +30604,10 @@
|
||||
},
|
||||
"The Smith Residence" : {
|
||||
|
||||
},
|
||||
"Toggle password visibility" : {
|
||||
"comment" : "A button that toggles the visibility of a password.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Try a different search term" : {
|
||||
"comment" : "A description below the \"No Templates Found\" message in the search results section of the task templates browser.",
|
||||
@@ -30212,10 +30617,18 @@
|
||||
"comment" : "A button label that says \"Try Again\".",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Try the Browse tab to explore tasks by category,\nor add home details for better suggestions." : {
|
||||
"comment" : "A description of the benefits of using the",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Unarchive" : {
|
||||
"comment" : "A button that unarchives a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Unarchive task" : {
|
||||
"comment" : "A button that unarchives a task.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Unarchive Task" : {
|
||||
|
||||
},
|
||||
@@ -30249,6 +30662,14 @@
|
||||
"comment" : "A message displayed while waiting for the email verification process to complete.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"View %d completions" : {
|
||||
"comment" : "A label that describes the action of viewing the completions of a task. The argument is the number of completions.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"View %lld photos" : {
|
||||
"comment" : "A button that opens a new screen showing a list of photos. The number in parentheses is replaced with the actual number of photos.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"View Photos (%lld)" : {
|
||||
"comment" : "A button that, when tapped, opens a view displaying photos taken during a task completion. The number in parentheses is replaced with the actual number of photos.",
|
||||
"isCommentAutoGenerated" : true
|
||||
|
||||
174
iosApp/run_ui_tests.sh
Executable file
174
iosApp/run_ui_tests.sh
Executable file
@@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
# run_ui_tests.sh — Three-phase UI test runner with parallel middle phase
|
||||
#
|
||||
# Usage:
|
||||
# ./run_ui_tests.sh # Default: iPhone 17 Pro, 4 workers
|
||||
# ./run_ui_tests.sh "iPhone Air" 3 # Custom device and worker count
|
||||
# ./run_ui_tests.sh --skip-seed # Skip seeding (already done)
|
||||
# ./run_ui_tests.sh --skip-cleanup # Skip cleanup at end
|
||||
# ./run_ui_tests.sh --only-parallel # Only run parallel phase
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT="$SCRIPT_DIR/honeyDue.xcodeproj"
|
||||
SCHEME="HoneyDueUITests"
|
||||
DESTINATION="platform=iOS Simulator,name=iPhone 17 Pro"
|
||||
WORKERS=4
|
||||
|
||||
SKIP_SEED=false
|
||||
SKIP_CLEANUP=false
|
||||
ONLY_PARALLEL=false
|
||||
|
||||
# Parse flags (positional args for device/workers, flags for skip options)
|
||||
POSITIONAL_ARGS=()
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--skip-seed) SKIP_SEED=true ;;
|
||||
--skip-cleanup) SKIP_CLEANUP=true ;;
|
||||
--only-parallel) ONLY_PARALLEL=true; SKIP_SEED=true; SKIP_CLEANUP=true ;;
|
||||
*) POSITIONAL_ARGS+=("$arg") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ${#POSITIONAL_ARGS[@]} -ge 1 ]; then
|
||||
DESTINATION="platform=iOS Simulator,name=${POSITIONAL_ARGS[0]}"
|
||||
fi
|
||||
if [ ${#POSITIONAL_ARGS[@]} -ge 2 ]; then
|
||||
WORKERS="${POSITIONAL_ARGS[1]}"
|
||||
fi
|
||||
|
||||
RESULTS_DIR="$SCRIPT_DIR/build/test-results"
|
||||
DERIVED_DATA="$SCRIPT_DIR/build/DerivedData"
|
||||
mkdir -p "$RESULTS_DIR" "$DERIVED_DATA"
|
||||
|
||||
BOLD='\033[1m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[0;33m'
|
||||
RESET='\033[0m'
|
||||
|
||||
phase_header() {
|
||||
echo ""
|
||||
echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"
|
||||
echo -e "${BOLD} $1${RESET}"
|
||||
echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Seed tests — must run first, sequentially
|
||||
SEED_TESTS=(
|
||||
"-only-testing:HoneyDueUITests/AAA_SeedTests"
|
||||
)
|
||||
|
||||
# All parallelizable test classes
|
||||
PARALLEL_TESTS=(
|
||||
"-only-testing:HoneyDueUITests/AuthCriticalPathTests"
|
||||
"-only-testing:HoneyDueUITests/NavigationCriticalPathTests"
|
||||
"-only-testing:HoneyDueUITests/SmokeTests"
|
||||
"-only-testing:HoneyDueUITests/SimpleLoginTest"
|
||||
"-only-testing:HoneyDueUITests/Suite0_OnboardingTests"
|
||||
"-only-testing:HoneyDueUITests/Suite1_RegistrationTests"
|
||||
"-only-testing:HoneyDueUITests/Suite2_AuthenticationTests"
|
||||
"-only-testing:HoneyDueUITests/Suite3_ResidenceTests"
|
||||
"-only-testing:HoneyDueUITests/Suite4_ComprehensiveResidenceTests"
|
||||
"-only-testing:HoneyDueUITests/Suite5_TaskTests"
|
||||
"-only-testing:HoneyDueUITests/Suite6_ComprehensiveTaskTests"
|
||||
"-only-testing:HoneyDueUITests/Suite7_ContractorTests"
|
||||
"-only-testing:HoneyDueUITests/Suite8_DocumentWarrantyTests"
|
||||
"-only-testing:HoneyDueUITests/Suite9_IntegrationE2ETests"
|
||||
"-only-testing:HoneyDueUITests/Suite10_ComprehensiveE2ETests"
|
||||
)
|
||||
|
||||
# Cleanup tests — must run last, sequentially
|
||||
CLEANUP_TESTS=(
|
||||
"-only-testing:HoneyDueUITests/SuiteZZ_CleanupTests"
|
||||
)
|
||||
|
||||
run_phase() {
|
||||
local phase_name="$1"
|
||||
local result_path="$RESULTS_DIR/${phase_name}.xcresult"
|
||||
shift
|
||||
local extra_args=("$@")
|
||||
|
||||
rm -rf "$result_path"
|
||||
|
||||
xcodebuild test \
|
||||
-project "$PROJECT" \
|
||||
-scheme "$SCHEME" \
|
||||
-destination "$DESTINATION" \
|
||||
-derivedDataPath "$DERIVED_DATA" \
|
||||
-resultBundlePath "$result_path" \
|
||||
"${extra_args[@]}" \
|
||||
2>&1 | tail -30
|
||||
|
||||
return ${PIPESTATUS[0]}
|
||||
}
|
||||
|
||||
OVERALL_START=$(date +%s)
|
||||
|
||||
# ── Phase 1: Seed ──────────────────────────────────────────────
|
||||
if [ "$SKIP_SEED" = false ]; then
|
||||
phase_header "Phase 1/3: Seeding test data (sequential)"
|
||||
SEED_START=$(date +%s)
|
||||
|
||||
if run_phase "SeedTests" "${SEED_TESTS[@]}"; then
|
||||
SEED_END=$(date +%s)
|
||||
echo -e "\n${GREEN}✓ Seed phase passed ($(( SEED_END - SEED_START ))s)${RESET}"
|
||||
else
|
||||
SEED_END=$(date +%s)
|
||||
echo -e "\n${RED}✗ Seed phase FAILED ($(( SEED_END - SEED_START ))s)${RESET}"
|
||||
echo -e "${RED} Cannot proceed without seeded data. Aborting.${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Phase 2: Parallel Tests ───────────────────────────────────
|
||||
phase_header "Phase 2/3: Running tests in parallel ($WORKERS workers)"
|
||||
PARALLEL_START=$(date +%s)
|
||||
|
||||
if run_phase "ParallelTests" \
|
||||
-parallel-testing-enabled YES \
|
||||
-parallel-testing-worker-count "$WORKERS" \
|
||||
"${PARALLEL_TESTS[@]}"; then
|
||||
PARALLEL_END=$(date +%s)
|
||||
echo -e "\n${GREEN}✓ Parallel phase passed ($(( PARALLEL_END - PARALLEL_START ))s)${RESET}"
|
||||
PARALLEL_PASSED=true
|
||||
else
|
||||
PARALLEL_END=$(date +%s)
|
||||
echo -e "\n${RED}✗ Parallel phase FAILED ($(( PARALLEL_END - PARALLEL_START ))s)${RESET}"
|
||||
PARALLEL_PASSED=false
|
||||
fi
|
||||
|
||||
# ── Phase 3: Cleanup ──────────────────────────────────────────
|
||||
if [ "$SKIP_CLEANUP" = false ]; then
|
||||
phase_header "Phase 3/3: Cleaning up test data (sequential)"
|
||||
CLEANUP_START=$(date +%s)
|
||||
|
||||
if run_phase "CleanupTests" "${CLEANUP_TESTS[@]}"; then
|
||||
CLEANUP_END=$(date +%s)
|
||||
echo -e "\n${GREEN}✓ Cleanup phase passed ($(( CLEANUP_END - CLEANUP_START ))s)${RESET}"
|
||||
else
|
||||
CLEANUP_END=$(date +%s)
|
||||
echo -e "\n${YELLOW}⚠ Cleanup phase failed ($(( CLEANUP_END - CLEANUP_START ))s) — non-blocking${RESET}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Summary ───────────────────────────────────────────────────
|
||||
OVERALL_END=$(date +%s)
|
||||
TOTAL_TIME=$(( OVERALL_END - OVERALL_START ))
|
||||
|
||||
phase_header "Summary"
|
||||
echo " Total time: ${TOTAL_TIME}s"
|
||||
echo " Workers: $WORKERS"
|
||||
echo " Results: $RESULTS_DIR/"
|
||||
echo ""
|
||||
|
||||
if [ "$PARALLEL_PASSED" = true ]; then
|
||||
echo -e " ${GREEN}${BOLD}ALL TESTS PASSED${RESET}"
|
||||
exit 0
|
||||
else
|
||||
echo -e " ${RED}${BOLD}TESTS FAILED${RESET}"
|
||||
echo -e " Check results: open $RESULTS_DIR/ParallelTests.xcresult"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user