From 4b7f12a74239a5f9dd627a4ee02ac613dcb515ee Mon Sep 17 00:00:00 2001 From: Paul Annesley Date: Tue, 25 Aug 2026 13:09:18 +0930 Subject: [PATCH] Add a green Swift XCUITest example Add a minimal iOS app and passing UI test target that loads the Swift Test Engine collector. The shared scheme and lexical test plan make the fixture deterministic, while the runner command retains an xcresult bundle for comparison and injects Buildkite metadata into the Xcode test process. Run the example on the Open Source cluster's macos queue. Keep this first slice free of runner crashes and retries so it establishes a normal green collector integration before a stacked change exercises process loss. Amp-Thread-ID: https://ampcode.com/threads/T-01a036f0-4e44-73ab-a085-68af2e00b5cb Co-authored-by: Amp --- .buildkite/pipeline.yml | 15 + swift-xcuitest/.gitignore | 1 + swift-xcuitest/ExampleApp/ExampleApp.swift | 12 + .../ExampleAppUITests/ExampleAppUITests.swift | 24 + swift-xcuitest/README.md | 15 + .../SwiftXCUITest.xcodeproj/project.pbxproj | 438 ++++++++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 15 + .../xcschemes/SwiftXCUITest.xcscheme | 96 ++++ swift-xcuitest/SwiftXCUITest.xctestplan | 23 + swift-xcuitest/bin/test | 67 +++ 10 files changed, 706 insertions(+) create mode 100644 swift-xcuitest/.gitignore create mode 100644 swift-xcuitest/ExampleApp/ExampleApp.swift create mode 100644 swift-xcuitest/ExampleAppUITests/ExampleAppUITests.swift create mode 100644 swift-xcuitest/README.md create mode 100644 swift-xcuitest/SwiftXCUITest.xcodeproj/project.pbxproj create mode 100644 swift-xcuitest/SwiftXCUITest.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 swift-xcuitest/SwiftXCUITest.xcodeproj/xcshareddata/xcschemes/SwiftXCUITest.xcscheme create mode 100644 swift-xcuitest/SwiftXCUITest.xctestplan create mode 100755 swift-xcuitest/bin/test diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index d710d88..ea2edea 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -224,6 +224,21 @@ steps: - BUILDKITE_ANALYTICS_TAGS - BUILDKITE_ANALYTICS_DEBUG_ENABLED + - label: ":swift: Swift: XCUITest (test-collector-swift)" + command: swift-xcuitest/bin/test + agents: + queue: macos + artifact_paths: + - swift-xcuitest/artifacts/SwiftXCUITest.xcresult/**/* + env: + BUILDKITE_ANALYTICS_TAGS: '{"test.framework.name":"xcuitest","language.name":"swift","custom.tag.from":"upload"}' + plugins: + - tests#v1.0.0: + test-runner: custom + suite-slug: test-engine-client-examples + upload-results: false + install-client: false + - label: ":android: Android" commands: - cd android diff --git a/swift-xcuitest/.gitignore b/swift-xcuitest/.gitignore new file mode 100644 index 0000000..d4f588e --- /dev/null +++ b/swift-xcuitest/.gitignore @@ -0,0 +1 @@ +artifacts/ diff --git a/swift-xcuitest/ExampleApp/ExampleApp.swift b/swift-xcuitest/ExampleApp/ExampleApp.swift new file mode 100644 index 0000000..9d0a04a --- /dev/null +++ b/swift-xcuitest/ExampleApp/ExampleApp.swift @@ -0,0 +1,12 @@ +import SwiftUI + +@main +struct ExampleApp: App { + var body: some Scene { + WindowGroup { + Text("Swift XCUITest example") + .accessibilityIdentifier("status") + .padding() + } + } +} diff --git a/swift-xcuitest/ExampleAppUITests/ExampleAppUITests.swift b/swift-xcuitest/ExampleAppUITests/ExampleAppUITests.swift new file mode 100644 index 0000000..500ebcf --- /dev/null +++ b/swift-xcuitest/ExampleAppUITests/ExampleAppUITests.swift @@ -0,0 +1,24 @@ +import Core +import XCTest + +final class ExampleAppUITests: XCTestCase { + override func setUpWithError() throws { + continueAfterFailure = false + } + + func test01AppLaunches() { + let app = XCUIApplication() + app.launch() + + XCTAssertTrue(app.staticTexts["status"].waitForExistence(timeout: 5)) + } + + func test02ExecutionTag() { + tagExecution("custom.tag.from", "execution") + + let app = XCUIApplication() + app.launch() + + XCTAssertEqual(app.staticTexts["status"].label, "Swift XCUITest example") + } +} diff --git a/swift-xcuitest/README.md b/swift-xcuitest/README.md new file mode 100644 index 0000000..be7ffb4 --- /dev/null +++ b/swift-xcuitest/README.md @@ -0,0 +1,15 @@ +# Swift XCUITest example + +This example runs passing UI tests against a minimal iOS app and uploads the +results with [`test-collector-swift`](https://github.com/buildkite/test-collector-swift). +It uses a shared scheme, a lexical test plan, and an explicit `.xcresult` +bundle so the same command works locally and on a macOS Buildkite agent. + +Run it with: + +```sh +bin/test +``` + +The script selects the first available iPhone Simulator. Set +`XCUITEST_DESTINATION` to pass a different `xcodebuild` destination. diff --git a/swift-xcuitest/SwiftXCUITest.xcodeproj/project.pbxproj b/swift-xcuitest/SwiftXCUITest.xcodeproj/project.pbxproj new file mode 100644 index 0000000..65a3cd5 --- /dev/null +++ b/swift-xcuitest/SwiftXCUITest.xcodeproj/project.pbxproj @@ -0,0 +1,438 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1EDCF6E03305FFA646EC4A27 /* ExampleAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7D16EF86AE46B2D45CD4B1 /* ExampleAppUITests.swift */; }; + 625357C9D57FEB694CD0B65D /* ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF276F55237E8755355E193 /* ExampleApp.swift */; }; + 8776A32F56208B01F099D452 /* BuildkiteTestCollector in Frameworks */ = {isa = PBXBuildFile; productRef = DB07F6513929E915435499BA /* BuildkiteTestCollector */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 9D461E396542A35BBC7F9E7D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 60D6D53EE4BE8B31C7F8437F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1B1BA0F4764BE5BC96BC792B; + remoteInfo = ExampleApp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0A7D16EF86AE46B2D45CD4B1 /* ExampleAppUITests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ExampleAppUITests.swift; sourceTree = ""; }; + 8A9D399FC1D693D87B900BE7 /* ExampleAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9AF276F55237E8755355E193 /* ExampleApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ExampleApp.swift; sourceTree = ""; }; + F37BE348888EE455E9EBCCB2 /* ExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 269ABC61BD849F40E89B2BE1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 37B992968C501FD8E23AAA13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8776A32F56208B01F099D452 /* BuildkiteTestCollector in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 02E50034CFB138D127A41EFA /* ExampleApp */ = { + isa = PBXGroup; + children = ( + 9AF276F55237E8755355E193 /* ExampleApp.swift */, + ); + name = ExampleApp; + path = ExampleApp; + sourceTree = ""; + }; + 15771E3CC944F418353D1657 = { + isa = PBXGroup; + children = ( + 55AE842CDC491C8FB4A68112 /* Products */, + 02E50034CFB138D127A41EFA /* ExampleApp */, + 991F452F6D58ED02EC4D346A /* ExampleAppUITests */, + ); + sourceTree = ""; + }; + 55AE842CDC491C8FB4A68112 /* Products */ = { + isa = PBXGroup; + children = ( + F37BE348888EE455E9EBCCB2 /* ExampleApp.app */, + 8A9D399FC1D693D87B900BE7 /* ExampleAppUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 991F452F6D58ED02EC4D346A /* ExampleAppUITests */ = { + isa = PBXGroup; + children = ( + 0A7D16EF86AE46B2D45CD4B1 /* ExampleAppUITests.swift */, + ); + name = ExampleAppUITests; + path = ExampleAppUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1B1BA0F4764BE5BC96BC792B /* ExampleApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5959CF0AE1EAF684326025C3 /* Build configuration list for PBXNativeTarget "ExampleApp" */; + buildPhases = ( + C01C891A9F9ADE12236135ED /* Sources */, + 269ABC61BD849F40E89B2BE1 /* Frameworks */, + DC1D7BB654B2C78D844248AB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ExampleApp; + productName = ExampleApp; + productReference = F37BE348888EE455E9EBCCB2 /* ExampleApp.app */; + productType = "com.apple.product-type.application"; + }; + 736F5421D3126D489F8E0CFB /* ExampleAppUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 68BE85C41B31CC3145E2130C /* Build configuration list for PBXNativeTarget "ExampleAppUITests" */; + buildPhases = ( + D8B2953515B18A82F71E6136 /* Sources */, + 37B992968C501FD8E23AAA13 /* Frameworks */, + F5702B9A5A569247045C49A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D1FF02D96AB7478A65199220 /* PBXTargetDependency */, + ); + name = ExampleAppUITests; + packageProductDependencies = ( + DB07F6513929E915435499BA /* BuildkiteTestCollector */, + ); + productName = ExampleAppUITests; + productReference = 8A9D399FC1D693D87B900BE7 /* ExampleAppUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 60D6D53EE4BE8B31C7F8437F /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1600; + LastUpgradeCheck = 1600; + }; + buildConfigurationList = 89F91903A12BB944C8023215 /* Build configuration list for PBXProject "SwiftXCUITest" */; + compatibilityVersion = "Xcode 15.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 15771E3CC944F418353D1657; + minimizedProjectReferenceProxies = 0; + packageReferences = ( + 0F260402842AAB649211B9B2 /* XCRemoteSwiftPackageReference "test-collector-swift" */, + ); + preferredProjectObjectVersion = 100; + productRefGroup = 55AE842CDC491C8FB4A68112 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1B1BA0F4764BE5BC96BC792B /* ExampleApp */, + 736F5421D3126D489F8E0CFB /* ExampleAppUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DC1D7BB654B2C78D844248AB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F5702B9A5A569247045C49A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + C01C891A9F9ADE12236135ED /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 625357C9D57FEB694CD0B65D /* ExampleApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D8B2953515B18A82F71E6136 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1EDCF6E03305FFA646EC4A27 /* ExampleAppUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + D1FF02D96AB7478A65199220 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ExampleApp; + target = 1B1BA0F4764BE5BC96BC792B /* ExampleApp */; + targetProxy = 9D461E396542A35BBC7F9E7D /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 4EEDD9730A9C76C5689AACE9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.buildkite.test-engine-client-examples.swift-xcuitest-tests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + TEST_TARGET_NAME = ExampleApp; + }; + name = Debug; + }; + 6FDDB98CF6EDF035B91E6163 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.buildkite.test-engine-client-examples.swift-xcuitest-tests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + TEST_TARGET_NAME = ExampleApp; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7AB3AD7D3562FBA97D97F311 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + D0E117B7946D3555B2C08B06 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + D24A842A868E3CFC27AC6E2F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.buildkite.test-engine-client-examples.swift-xcuitest"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + F4A572DFDB752041A299BEEE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.buildkite.test-engine-client-examples.swift-xcuitest"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5959CF0AE1EAF684326025C3 /* Build configuration list for PBXNativeTarget "ExampleApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F4A572DFDB752041A299BEEE /* Release */, + D24A842A868E3CFC27AC6E2F /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 68BE85C41B31CC3145E2130C /* Build configuration list for PBXNativeTarget "ExampleAppUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6FDDB98CF6EDF035B91E6163 /* Release */, + 4EEDD9730A9C76C5689AACE9 /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 89F91903A12BB944C8023215 /* Build configuration list for PBXProject "SwiftXCUITest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7AB3AD7D3562FBA97D97F311 /* Debug */, + D0E117B7946D3555B2C08B06 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 0F260402842AAB649211B9B2 /* XCRemoteSwiftPackageReference "test-collector-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/buildkite/test-collector-swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.6.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + DB07F6513929E915435499BA /* BuildkiteTestCollector */ = { + isa = XCSwiftPackageProductDependency; + package = 0F260402842AAB649211B9B2 /* XCRemoteSwiftPackageReference "test-collector-swift" */; + productName = BuildkiteTestCollector; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 60D6D53EE4BE8B31C7F8437F /* Project object */; +} diff --git a/swift-xcuitest/SwiftXCUITest.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/swift-xcuitest/SwiftXCUITest.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..cef9935 --- /dev/null +++ b/swift-xcuitest/SwiftXCUITest.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "f28a54e288718485642adbe7b780a05abf05f95f0f435b3f87b6d3684b95d268", + "pins" : [ + { + "identity" : "test-collector-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/buildkite/test-collector-swift", + "state" : { + "revision" : "dbb0f13987c3f9f54611aaf0ac0dc1085ebb5ea6", + "version" : "0.6.0" + } + } + ], + "version" : 3 +} diff --git a/swift-xcuitest/SwiftXCUITest.xcodeproj/xcshareddata/xcschemes/SwiftXCUITest.xcscheme b/swift-xcuitest/SwiftXCUITest.xcodeproj/xcshareddata/xcschemes/SwiftXCUITest.xcscheme new file mode 100644 index 0000000..df66d57 --- /dev/null +++ b/swift-xcuitest/SwiftXCUITest.xcodeproj/xcshareddata/xcschemes/SwiftXCUITest.xcscheme @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/swift-xcuitest/SwiftXCUITest.xctestplan b/swift-xcuitest/SwiftXCUITest.xctestplan new file mode 100644 index 0000000..2533a2a --- /dev/null +++ b/swift-xcuitest/SwiftXCUITest.xctestplan @@ -0,0 +1,23 @@ +{ + "configurations" : [ + { + "name" : "Default", + "options" : { + "testExecutionOrdering" : "lexical" + } + } + ], + "defaultOptions" : { + "codeCoverage" : false + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:SwiftXCUITest.xcodeproj", + "identifier" : "736F5421D3126D489F8E0CFB", + "name" : "ExampleAppUITests" + } + } + ], + "version" : 1 +} diff --git a/swift-xcuitest/bin/test b/swift-xcuitest/bin/test new file mode 100755 index 0000000..c33db23 --- /dev/null +++ b/swift-xcuitest/bin/test @@ -0,0 +1,67 @@ +#!/bin/bash + +set -euo pipefail + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +artifacts_dir="${XCUITEST_ARTIFACTS_DIR:-$root/artifacts}" +result_bundle="$artifacts_dir/SwiftXCUITest.xcresult" + +for name in \ + BUILDKITE_ANALYTICS_BASE_URL \ + BUILDKITE_ANALYTICS_BRANCH \ + BUILDKITE_ANALYTICS_DEBUG_ENABLED \ + BUILDKITE_ANALYTICS_ENABLED \ + BUILDKITE_ANALYTICS_ENVIRONMENT \ + BUILDKITE_ANALYTICS_EXECUTION_NAME_PREFIX \ + BUILDKITE_ANALYTICS_EXECUTION_NAME_SUFFIX \ + BUILDKITE_ANALYTICS_JOB_ID \ + BUILDKITE_ANALYTICS_MESSAGE \ + BUILDKITE_ANALYTICS_NUMBER \ + BUILDKITE_ANALYTICS_SHA \ + BUILDKITE_ANALYTICS_TAGS \ + BUILDKITE_ANALYTICS_TOKEN \ + BUILDKITE_ANALYTICS_URL \ + BUILDKITE_BRANCH \ + BUILDKITE_BUILD_ID \ + BUILDKITE_BUILD_NUMBER \ + BUILDKITE_BUILD_URL \ + BUILDKITE_COMMIT \ + BUILDKITE_JOB_ID \ + BUILDKITE_MESSAGE +do + if [[ -n "${!name:-}" ]]; then + export "TEST_RUNNER_${name}=${!name}" + fi +done + +destination="${XCUITEST_DESTINATION:-}" +if [[ -z "$destination" ]]; then + device_id="$({ + xcrun simctl list devices available \ + | sed -nE '/iPhone/s/^.*\(([[:xdigit:]-]{36})\).*$/\1/p' + } | sed -n '1p')" + + if [[ -z "$device_id" ]]; then + echo "No available iPhone Simulator found; set XCUITEST_DESTINATION" >&2 + exit 1 + fi + + destination="platform=iOS Simulator,id=$device_id" +fi + +rm -rf "$result_bundle" +mkdir -p "$artifacts_dir" + +xcodebuild \ + -project "$root/SwiftXCUITest.xcodeproj" \ + -scheme SwiftXCUITest \ + -resolvePackageDependencies + +xcodebuild \ + -project "$root/SwiftXCUITest.xcodeproj" \ + -scheme SwiftXCUITest \ + -testPlan SwiftXCUITest \ + -destination "$destination" \ + -derivedDataPath "$artifacts_dir/DerivedData" \ + -resultBundlePath "$result_bundle" \ + test