Add standalone HoneyDueAPITests target for pure-API suites
Split the pure-API integration tests (no UI) out of the UITest target into a dedicated standalone unit-test target that runs in seconds without launching the simulator app. - HoneyDueAPITests target: standalone unit-test bundle (no TEST_HOST — touches no app code), shares the API client/seeder/cleaner support files from the UITest target via explicit references, with its own shared scheme. - MultiUserSharingTests -> HoneyDueAPITests/SharingAPITests.swift (18 tests). Runs in ~2.3s vs. ~40-140s per UI test. - run_ui_tests.sh: new Phase 1b runs the API target (fast) between Seed and the parallel UI phase; the helper now takes a scheme so each phase targets the right one; summary reports the API result. Both targets build green; SharingAPITests passes (18/18) against the live stack. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ import XCTest
|
|||||||
///
|
///
|
||||||
/// These tests run entirely via API (no app launch needed for most steps)
|
/// These tests run entirely via API (no app launch needed for most steps)
|
||||||
/// with a final UI verification that the shared residence and tasks appear.
|
/// with a final UI verification that the shared residence and tasks appear.
|
||||||
final class MultiUserSharingTests: XCTestCase {
|
final class SharingAPITests: XCTestCase {
|
||||||
|
|
||||||
private var userA: TestSession!
|
private var userA: TestSession!
|
||||||
private var userB: TestSession!
|
private var userB: TestSession!
|
||||||
@@ -16,6 +16,11 @@
|
|||||||
1C81F2892EE41BB6000739EA /* HoneyDueQLThumbnail.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1C81F2802EE41BB6000739EA /* HoneyDueQLThumbnail.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
1C81F2892EE41BB6000739EA /* HoneyDueQLThumbnail.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1C81F2802EE41BB6000739EA /* HoneyDueQLThumbnail.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
1C81F3902EE69AF1000739EA /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = 1C81F38F2EE69AF1000739EA /* PostHog */; };
|
1C81F3902EE69AF1000739EA /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = 1C81F38F2EE69AF1000739EA /* PostHog */; };
|
||||||
36A43DA6D19BA51568EC55A5 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 6424E7E39866AD706041F321 /* SnapshotTesting */; };
|
36A43DA6D19BA51568EC55A5 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 6424E7E39866AD706041F321 /* SnapshotTesting */; };
|
||||||
|
53469EBEDD37557816983B6D /* SharingAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF8E25041D46376FEC29BE2 /* SharingAPITests.swift */; };
|
||||||
|
59A92CA8C3A412D8A18338C7 /* TestAccountAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70FEF27FDF4EFFACCE83F54 /* TestAccountAPIClient.swift */; };
|
||||||
|
91A9D5E4A93A022693888B95 /* TestDataSeeder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51B2E73D6FB0BDB53123DDC /* TestDataSeeder.swift */; };
|
||||||
|
99FB08E574AA3B88AD73DEAC /* TestDataCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1579B80B44611651771CC51A /* TestDataCleaner.swift */; };
|
||||||
|
BEF62D0EDC3E9B922195C7ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12403969C38C7CB74B1EA820 /* Foundation.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -73,6 +78,8 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
12403969C38C7CB74B1EA820 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
|
1579B80B44611651771CC51A /* TestDataCleaner.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TestDataCleaner.swift; path = HoneyDueUITests/Framework/TestDataCleaner.swift; sourceTree = "<group>"; };
|
||||||
1C07893D2EBC218B00392B46 /* HoneyDueExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = HoneyDueExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
1C07893D2EBC218B00392B46 /* HoneyDueExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = HoneyDueExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
1C07893F2EBC218B00392B46 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
1C07893F2EBC218B00392B46 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||||
1C0789412EBC218B00392B46 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
1C0789412EBC218B00392B46 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||||
@@ -86,7 +93,11 @@
|
|||||||
1CBF1BED2ECD9768001BF56C /* HoneyDueUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HoneyDueUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
1CBF1BED2ECD9768001BF56C /* HoneyDueUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HoneyDueUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4B07E04F794A4C1CAA8CCD5D /* PhotoViewerSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoViewerSheet.swift; sourceTree = "<group>"; };
|
4B07E04F794A4C1CAA8CCD5D /* PhotoViewerSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoViewerSheet.swift; sourceTree = "<group>"; };
|
||||||
96A3DDC05E14B3F83E56282F /* honeyDue.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = honeyDue.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
96A3DDC05E14B3F83E56282F /* honeyDue.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = honeyDue.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
A52A91DEA0ECFB45CBAAE168 /* HoneyDueAPITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HoneyDueAPITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
AD6CD907CA1045CBBC845D91 /* CompletionCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionCardView.swift; sourceTree = "<group>"; };
|
AD6CD907CA1045CBBC845D91 /* CompletionCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionCardView.swift; sourceTree = "<group>"; };
|
||||||
|
C51B2E73D6FB0BDB53123DDC /* TestDataSeeder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TestDataSeeder.swift; path = HoneyDueUITests/Framework/TestDataSeeder.swift; sourceTree = "<group>"; };
|
||||||
|
D70FEF27FDF4EFFACCE83F54 /* TestAccountAPIClient.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TestAccountAPIClient.swift; path = HoneyDueUITests/Framework/TestAccountAPIClient.swift; sourceTree = "<group>"; };
|
||||||
|
ECF8E25041D46376FEC29BE2 /* SharingAPITests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SharingAPITests.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
@@ -268,6 +279,14 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
55A71EFD2C2AB71B02035D05 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
BEF62D0EDC3E9B922195C7ED /* Foundation.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
@@ -278,6 +297,7 @@
|
|||||||
1C0789412EBC218B00392B46 /* SwiftUI.framework */,
|
1C0789412EBC218B00392B46 /* SwiftUI.framework */,
|
||||||
1C81F26A2EE416EE000739EA /* QuickLook.framework */,
|
1C81F26A2EE416EE000739EA /* QuickLook.framework */,
|
||||||
1C81F2812EE41BB6000739EA /* QuickLookThumbnailing.framework */,
|
1C81F2812EE41BB6000739EA /* QuickLookThumbnailing.framework */,
|
||||||
|
F9901640A563803981701DD0 /* iOS */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -306,9 +326,30 @@
|
|||||||
1C07893E2EBC218B00392B46 /* Frameworks */,
|
1C07893E2EBC218B00392B46 /* Frameworks */,
|
||||||
FA6022B7B844191C54E57EB4 /* Products */,
|
FA6022B7B844191C54E57EB4 /* Products */,
|
||||||
1C078A1B2EC1820B00392B46 /* Recovered References */,
|
1C078A1B2EC1820B00392B46 /* Recovered References */,
|
||||||
|
E7D6E53AF0B8430440E6B3EE /* HoneyDueAPITests */,
|
||||||
|
D70FEF27FDF4EFFACCE83F54 /* TestAccountAPIClient.swift */,
|
||||||
|
C51B2E73D6FB0BDB53123DDC /* TestDataSeeder.swift */,
|
||||||
|
1579B80B44611651771CC51A /* TestDataCleaner.swift */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
E7D6E53AF0B8430440E6B3EE /* HoneyDueAPITests */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
ECF8E25041D46376FEC29BE2 /* SharingAPITests.swift */,
|
||||||
|
);
|
||||||
|
name = HoneyDueAPITests;
|
||||||
|
path = HoneyDueAPITests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
F9901640A563803981701DD0 /* iOS */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
12403969C38C7CB74B1EA820 /* Foundation.framework */,
|
||||||
|
);
|
||||||
|
name = iOS;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
FA6022B7B844191C54E57EB4 /* Products */ = {
|
FA6022B7B844191C54E57EB4 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -318,6 +359,7 @@
|
|||||||
1CBF1BED2ECD9768001BF56C /* HoneyDueUITests.xctest */,
|
1CBF1BED2ECD9768001BF56C /* HoneyDueUITests.xctest */,
|
||||||
1C81F2692EE416EE000739EA /* HoneyDueQLPreview.appex */,
|
1C81F2692EE416EE000739EA /* HoneyDueQLPreview.appex */,
|
||||||
1C81F2802EE41BB6000739EA /* HoneyDueQLThumbnail.appex */,
|
1C81F2802EE41BB6000739EA /* HoneyDueQLThumbnail.appex */,
|
||||||
|
A52A91DEA0ECFB45CBAAE168 /* HoneyDueAPITests.xctest */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -458,6 +500,23 @@
|
|||||||
productReference = 96A3DDC05E14B3F83E56282F /* honeyDue.app */;
|
productReference = 96A3DDC05E14B3F83E56282F /* honeyDue.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
E9D862A585C17DD92D22D303 /* HoneyDueAPITests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 8D660A43441A0D51114CC335 /* Build configuration list for PBXNativeTarget "HoneyDueAPITests" */;
|
||||||
|
buildPhases = (
|
||||||
|
836DD50B36C6061FE1C3D6E3 /* Sources */,
|
||||||
|
55A71EFD2C2AB71B02035D05 /* Frameworks */,
|
||||||
|
4100A8774ECB9CF390C44011 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = HoneyDueAPITests;
|
||||||
|
productName = HoneyDueAPITests;
|
||||||
|
productReference = A52A91DEA0ECFB45CBAAE168 /* HoneyDueAPITests.xctest */;
|
||||||
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
/* Begin PBXProject section */
|
||||||
@@ -514,6 +573,7 @@
|
|||||||
1CBF1BEC2ECD9768001BF56C /* HoneyDueUITests */,
|
1CBF1BEC2ECD9768001BF56C /* HoneyDueUITests */,
|
||||||
1C81F2682EE416EE000739EA /* HoneyDueQLPreview */,
|
1C81F2682EE416EE000739EA /* HoneyDueQLPreview */,
|
||||||
1C81F27F2EE41BB6000739EA /* HoneyDueQLThumbnail */,
|
1C81F27F2EE41BB6000739EA /* HoneyDueQLThumbnail */,
|
||||||
|
E9D862A585C17DD92D22D303 /* HoneyDueAPITests */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@@ -554,6 +614,13 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
4100A8774ECB9CF390C44011 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
50827B76877E1E3968917892 /* Resources */ = {
|
50827B76877E1E3968917892 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -627,6 +694,17 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
836DD50B36C6061FE1C3D6E3 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
53469EBEDD37557816983B6D /* SharingAPITests.swift in Sources */,
|
||||||
|
59A92CA8C3A412D8A18338C7 /* TestAccountAPIClient.swift in Sources */,
|
||||||
|
91A9D5E4A93A022693888B95 /* TestDataSeeder.swift in Sources */,
|
||||||
|
99FB08E574AA3B88AD73DEAC /* TestDataCleaner.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
@@ -1119,6 +1197,33 @@
|
|||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
8B9401AF773E28539812BEB4 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = NO;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 26.1;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.myhoneydue.HoneyDueAPITests;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
90CF3F8366EF59205F9444AC /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = NO;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 26.1;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.myhoneydue.HoneyDueAPITests;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
E767E942685C7832D51FF978 /* Debug */ = {
|
E767E942685C7832D51FF978 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
@@ -1212,6 +1317,15 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
8D660A43441A0D51114CC335 /* Build configuration list for PBXNativeTarget "HoneyDueAPITests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
90CF3F8366EF59205F9444AC /* Release */,
|
||||||
|
8B9401AF773E28539812BEB4 /* Debug */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
F25B3A5CCAC6BFCC21CD4636 /* Build configuration list for PBXProject "honeyDue" */ = {
|
F25B3A5CCAC6BFCC21CD4636 /* Build configuration list for PBXProject "honeyDue" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1600"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "E9D862A585C17DD92D22D303"
|
||||||
|
BuildableName = "HoneyDueAPITests.xctest"
|
||||||
|
BlueprintName = "HoneyDueAPITests"
|
||||||
|
ReferencedContainer = "container:honeyDue.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "E9D862A585C17DD92D22D303"
|
||||||
|
BuildableName = "HoneyDueAPITests.xctest"
|
||||||
|
BlueprintName = "HoneyDueAPITests"
|
||||||
|
ReferencedContainer = "container:honeyDue.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
+41
-24
@@ -1,17 +1,18 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# run_ui_tests.sh — Phased UI test runner.
|
# run_ui_tests.sh — Phased test runner for the HoneyDue iOS suites.
|
||||||
#
|
#
|
||||||
# Architecture: every test mints its OWN isolated Kratos account (see
|
# Architecture: every UI test mints its OWN isolated Kratos account (see
|
||||||
# Core/Fixtures/TestAccount.swift + AuthenticatedUITestCase), so suites are
|
# Core/Fixtures/TestAccount.swift + AuthenticatedUITestCase), so suites are
|
||||||
# fully independent and the parallel phase scales to many workers with no
|
# fully independent and the parallel phase scales to many workers with no
|
||||||
# cross-suite data races. There is no per-suite ordering and no Suite6
|
# cross-suite data races. Pure-API tests live in a separate standalone target
|
||||||
# special-casing anymore.
|
# (HoneyDueAPITests) that runs in seconds without launching the app.
|
||||||
#
|
#
|
||||||
# Phases:
|
# Phases:
|
||||||
# 0. Smoke gate — fast launch/login sanity. Abort the run if it fails.
|
# 0. Smoke gate — fast launch/login sanity. Abort the run if it fails.
|
||||||
# 1. Seed — ensure baseline accounts exist (AAA_SeedTests).
|
# 1. Seed — ensure baseline accounts exist (AAA_SeedTests).
|
||||||
# 2. Parallel — the WHOLE target minus the four phase-managed suites, via
|
# 1b. API — standalone HoneyDueAPITests (no app launch; ~seconds).
|
||||||
# -skip-testing. New suites are auto-included (no hand-
|
# 2. Parallel — the WHOLE UI target minus the four phase-managed suites,
|
||||||
|
# via -skip-testing. New suites are auto-included (no hand-
|
||||||
# maintained list to drift), run at $WORKERS workers.
|
# maintained list to drift), run at $WORKERS workers.
|
||||||
# 3. Sweep — clear-all-data + delete leaked uit_* Kratos identities
|
# 3. Sweep — clear-all-data + delete leaked uit_* Kratos identities
|
||||||
# (SuiteZZ_CleanupTests). Non-blocking.
|
# (SuiteZZ_CleanupTests). Non-blocking.
|
||||||
@@ -23,12 +24,14 @@
|
|||||||
# ./run_ui_tests.sh --skip-cleanup # skip phase 3
|
# ./run_ui_tests.sh --skip-cleanup # skip phase 3
|
||||||
# ./run_ui_tests.sh --only-parallel # only phase 2
|
# ./run_ui_tests.sh --only-parallel # only phase 2
|
||||||
# ./run_ui_tests.sh --smoke # only phase 0
|
# ./run_ui_tests.sh --smoke # only phase 0
|
||||||
|
# ./run_ui_tests.sh --only-api # only phase 1b
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
PROJECT="$SCRIPT_DIR/honeyDue.xcodeproj"
|
PROJECT="$SCRIPT_DIR/honeyDue.xcodeproj"
|
||||||
SCHEME="HoneyDueUITests"
|
SCHEME="HoneyDueUITests"
|
||||||
|
API_SCHEME="HoneyDueAPITests"
|
||||||
TARGET="HoneyDueUITests"
|
TARGET="HoneyDueUITests"
|
||||||
DESTINATION="platform=iOS Simulator,name=iPhone 17 Pro"
|
DESTINATION="platform=iOS Simulator,name=iPhone 17 Pro"
|
||||||
WORKERS=8
|
WORKERS=8
|
||||||
@@ -41,11 +44,7 @@ PHASE_MANAGED=(
|
|||||||
"$TARGET/AppLaunchUITests"
|
"$TARGET/AppLaunchUITests"
|
||||||
)
|
)
|
||||||
|
|
||||||
SKIP_SEED=false
|
SKIP_SEED=false; SKIP_CLEANUP=false; ONLY_PARALLEL=false; ONLY_SMOKE=false; ONLY_API=false
|
||||||
SKIP_CLEANUP=false
|
|
||||||
ONLY_PARALLEL=false
|
|
||||||
ONLY_SMOKE=false
|
|
||||||
|
|
||||||
POSITIONAL_ARGS=()
|
POSITIONAL_ARGS=()
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case $arg in
|
case $arg in
|
||||||
@@ -53,6 +52,7 @@ for arg in "$@"; do
|
|||||||
--skip-cleanup) SKIP_CLEANUP=true ;;
|
--skip-cleanup) SKIP_CLEANUP=true ;;
|
||||||
--only-parallel) ONLY_PARALLEL=true; SKIP_SEED=true; SKIP_CLEANUP=true ;;
|
--only-parallel) ONLY_PARALLEL=true; SKIP_SEED=true; SKIP_CLEANUP=true ;;
|
||||||
--smoke) ONLY_SMOKE=true ;;
|
--smoke) ONLY_SMOKE=true ;;
|
||||||
|
--only-api) ONLY_API=true ;;
|
||||||
*) POSITIONAL_ARGS+=("$arg") ;;
|
*) POSITIONAL_ARGS+=("$arg") ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
@@ -66,11 +66,12 @@ mkdir -p "$RESULTS_DIR" "$DERIVED_DATA"
|
|||||||
BOLD='\033[1m'; GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[0;33m'; RESET='\033[0m'
|
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 ""; }
|
phase_header() { echo ""; echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"; echo -e "${BOLD} $1${RESET}"; echo -e "${BOLD}════════════════════════════════════════════════════${RESET}"; echo ""; }
|
||||||
|
|
||||||
|
# run_xcodebuild <result-name> <scheme> [extra xcodebuild args...]
|
||||||
run_xcodebuild() {
|
run_xcodebuild() {
|
||||||
local result_path="$RESULTS_DIR/$1.xcresult"; shift
|
local result_path="$RESULTS_DIR/$1.xcresult"; local scheme="$2"; shift 2
|
||||||
rm -rf "$result_path"
|
rm -rf "$result_path"
|
||||||
xcodebuild test \
|
xcodebuild test \
|
||||||
-project "$PROJECT" -scheme "$SCHEME" -destination "$DESTINATION" \
|
-project "$PROJECT" -scheme "$scheme" -destination "$DESTINATION" \
|
||||||
-derivedDataPath "$DERIVED_DATA" -resultBundlePath "$result_path" \
|
-derivedDataPath "$DERIVED_DATA" -resultBundlePath "$result_path" \
|
||||||
"$@" 2>&1 | tail -40
|
"$@" 2>&1 | tail -40
|
||||||
return ${PIPESTATUS[0]}
|
return ${PIPESTATUS[0]}
|
||||||
@@ -78,16 +79,20 @@ run_xcodebuild() {
|
|||||||
|
|
||||||
OVERALL_START=$(date +%s)
|
OVERALL_START=$(date +%s)
|
||||||
|
|
||||||
|
# ── Phase 1b only ──────────────────────────────────────────────
|
||||||
|
if [ "$ONLY_API" = true ]; then
|
||||||
|
phase_header "API tests (standalone)"
|
||||||
|
run_xcodebuild "API" "$API_SCHEME" && exit 0 || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Phase 0: Smoke gate ────────────────────────────────────────
|
# ── Phase 0: Smoke gate ────────────────────────────────────────
|
||||||
if [ "$ONLY_PARALLEL" = false ]; then
|
if [ "$ONLY_PARALLEL" = false ]; then
|
||||||
phase_header "Phase 0: Smoke gate"
|
phase_header "Phase 0: Smoke gate"
|
||||||
if run_xcodebuild "Smoke" \
|
if run_xcodebuild "Smoke" "$SCHEME" \
|
||||||
-only-testing:"$TARGET/SmokeUITests" \
|
-only-testing:"$TARGET/SmokeUITests" -only-testing:"$TARGET/AppLaunchUITests"; then
|
||||||
-only-testing:"$TARGET/AppLaunchUITests"; then
|
|
||||||
echo -e "${GREEN}✓ Smoke passed${RESET}"
|
echo -e "${GREEN}✓ Smoke passed${RESET}"
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗ Smoke FAILED — aborting (app can't launch/log in).${RESET}"
|
echo -e "${RED}✗ Smoke FAILED — aborting (app can't launch/log in).${RESET}"; exit 1
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
[ "$ONLY_SMOKE" = true ] && exit 0
|
[ "$ONLY_SMOKE" = true ] && exit 0
|
||||||
fi
|
fi
|
||||||
@@ -95,19 +100,30 @@ fi
|
|||||||
# ── Phase 1: Seed ──────────────────────────────────────────────
|
# ── Phase 1: Seed ──────────────────────────────────────────────
|
||||||
if [ "$SKIP_SEED" = false ]; then
|
if [ "$SKIP_SEED" = false ]; then
|
||||||
phase_header "Phase 1: Seed baseline accounts"
|
phase_header "Phase 1: Seed baseline accounts"
|
||||||
if run_xcodebuild "Seed" -only-testing:"$TARGET/AAA_SeedTests"; then
|
if run_xcodebuild "Seed" "$SCHEME" -only-testing:"$TARGET/AAA_SeedTests"; then
|
||||||
echo -e "${GREEN}✓ Seed passed${RESET}"
|
echo -e "${GREEN}✓ Seed passed${RESET}"
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗ Seed FAILED — aborting.${RESET}"; exit 1
|
echo -e "${RED}✗ Seed FAILED — aborting.${RESET}"; exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Phase 2: Parallel (whole target minus phase-managed) ───────
|
# ── Phase 1b: API contract tests (fast, standalone) ────────────
|
||||||
phase_header "Phase 2: Parallel suite ($WORKERS workers)"
|
API_PASSED=true
|
||||||
|
if [ "$ONLY_PARALLEL" = false ]; then
|
||||||
|
phase_header "Phase 1b: API tests (standalone bundle, no app launch)"
|
||||||
|
if run_xcodebuild "API" "$API_SCHEME"; then
|
||||||
|
echo -e "${GREEN}✓ API tests passed${RESET}"
|
||||||
|
else
|
||||||
|
API_PASSED=false; echo -e "${RED}✗ API tests FAILED${RESET}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Phase 2: Parallel (whole UI target minus phase-managed) ────
|
||||||
|
phase_header "Phase 2: Parallel UI suite ($WORKERS workers)"
|
||||||
SKIP_ARGS=()
|
SKIP_ARGS=()
|
||||||
for t in "${PHASE_MANAGED[@]}"; do SKIP_ARGS+=( -skip-testing:"$t" ); done
|
for t in "${PHASE_MANAGED[@]}"; do SKIP_ARGS+=( -skip-testing:"$t" ); done
|
||||||
PARALLEL_START=$(date +%s)
|
PARALLEL_START=$(date +%s)
|
||||||
if run_xcodebuild "Parallel" \
|
if run_xcodebuild "Parallel" "$SCHEME" \
|
||||||
-only-testing:"$TARGET" "${SKIP_ARGS[@]}" \
|
-only-testing:"$TARGET" "${SKIP_ARGS[@]}" \
|
||||||
-parallel-testing-enabled YES -parallel-testing-worker-count "$WORKERS"; then
|
-parallel-testing-enabled YES -parallel-testing-worker-count "$WORKERS"; then
|
||||||
PARALLEL_PASSED=true; echo -e "${GREEN}✓ Parallel phase passed${RESET}"
|
PARALLEL_PASSED=true; echo -e "${GREEN}✓ Parallel phase passed${RESET}"
|
||||||
@@ -119,7 +135,7 @@ PARALLEL_END=$(date +%s)
|
|||||||
# ── Phase 3: Sweep ─────────────────────────────────────────────
|
# ── Phase 3: Sweep ─────────────────────────────────────────────
|
||||||
if [ "$SKIP_CLEANUP" = false ]; then
|
if [ "$SKIP_CLEANUP" = false ]; then
|
||||||
phase_header "Phase 3: Sweep leaked accounts + data"
|
phase_header "Phase 3: Sweep leaked accounts + data"
|
||||||
if run_xcodebuild "Sweep" -only-testing:"$TARGET/SuiteZZ_CleanupTests"; then
|
if run_xcodebuild "Sweep" "$SCHEME" -only-testing:"$TARGET/SuiteZZ_CleanupTests"; then
|
||||||
echo -e "${GREEN}✓ Sweep passed${RESET}"
|
echo -e "${GREEN}✓ Sweep passed${RESET}"
|
||||||
else
|
else
|
||||||
echo -e "${YELLOW}⚠ Sweep failed (non-blocking)${RESET}"
|
echo -e "${YELLOW}⚠ Sweep failed (non-blocking)${RESET}"
|
||||||
@@ -130,9 +146,10 @@ fi
|
|||||||
phase_header "Summary"
|
phase_header "Summary"
|
||||||
echo " Total time: $(( $(date +%s) - OVERALL_START ))s"
|
echo " Total time: $(( $(date +%s) - OVERALL_START ))s"
|
||||||
echo " Parallel: $(( PARALLEL_END - PARALLEL_START ))s @ $WORKERS workers"
|
echo " Parallel: $(( PARALLEL_END - PARALLEL_START ))s @ $WORKERS workers"
|
||||||
|
echo " API tests: $([ "$API_PASSED" = true ] && echo passed || echo FAILED)"
|
||||||
echo " Results: $RESULTS_DIR/"
|
echo " Results: $RESULTS_DIR/"
|
||||||
echo ""
|
echo ""
|
||||||
if [ "${PARALLEL_PASSED:-false}" = true ]; then
|
if [ "${PARALLEL_PASSED:-false}" = true ] && [ "$API_PASSED" = true ]; then
|
||||||
echo -e " ${GREEN}${BOLD}ALL TESTS PASSED${RESET}"; exit 0
|
echo -e " ${GREEN}${BOLD}ALL TESTS PASSED${RESET}"; exit 0
|
||||||
else
|
else
|
||||||
echo -e " ${RED}${BOLD}TESTS FAILED${RESET} — open $RESULTS_DIR/"; exit 1
|
echo -e " ${RED}${BOLD}TESTS FAILED${RESET} — open $RESULTS_DIR/"; exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user