diff --git a/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/VendorConfiguration.kt b/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/VendorConfiguration.kt index 173610643..58f86d2bf 100644 --- a/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/VendorConfiguration.kt +++ b/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/VendorConfiguration.kt @@ -21,6 +21,7 @@ import com.malinskiy.marathon.config.vendor.apple.ios.SigningConfiguration import com.malinskiy.marathon.config.vendor.apple.SshConfiguration import com.malinskiy.marathon.config.vendor.apple.TimeoutConfiguration as AppleTimeoutConfiguration import com.malinskiy.marathon.config.vendor.apple.ios.XcresultConfiguration +import com.malinskiy.marathon.config.vendor.apple.ios.XctestrunEnvConfiguration import java.io.File import com.malinskiy.marathon.config.vendor.android.TimeoutConfiguration as AndroidTimeoutConfiguration import com.malinskiy.marathon.config.vendor.apple.TestParserConfiguration as AppleTestParserConfiguration @@ -159,7 +160,7 @@ sealed class VendorConfiguration { @JsonProperty("xcresult") val xcresult: XcresultConfiguration = XcresultConfiguration(), @JsonProperty("screenRecordConfiguration") val screenRecordConfiguration: IosScreenRecordConfiguration = IosScreenRecordConfiguration(), - @JsonProperty("xctestrunEnv") val xctestrunEnv: Map = emptyMap(), + @JsonProperty("xctestrunEnv") val xctestrunEnv: XctestrunEnvConfiguration = XctestrunEnvConfiguration(), @JsonProperty("lifecycle") val lifecycleConfiguration: LifecycleConfiguration = LifecycleConfiguration(), @JsonProperty("permissions") val permissions: PermissionsConfiguration = PermissionsConfiguration(), @JsonProperty("timeoutConfiguration") val timeoutConfiguration: AppleTimeoutConfiguration = AppleTimeoutConfiguration(), @@ -188,7 +189,7 @@ sealed class VendorConfiguration { @JsonProperty("ssh") val ssh: SshConfiguration = SshConfiguration(), @JsonProperty("xcresult") val xcresult: XcresultConfiguration = XcresultConfiguration(), - @JsonProperty("xctestrunEnv") val xctestrunEnv: Map = emptyMap(), + @JsonProperty("xctestrunEnv") val xctestrunEnv: XctestrunEnvConfiguration = XctestrunEnvConfiguration(), @JsonProperty("timeoutConfiguration") val timeoutConfiguration: AppleTimeoutConfiguration = AppleTimeoutConfiguration(), @JsonProperty("threadingConfiguration") val threadingConfiguration: AppleThreadingConfiguration = AppleThreadingConfiguration(), @JsonProperty("hideRunnerOutput") val hideRunnerOutput: Boolean = false, diff --git a/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/apple/ios/XctestrunEnvConfiguration.kt b/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/apple/ios/XctestrunEnvConfiguration.kt new file mode 100644 index 000000000..f89de2e57 --- /dev/null +++ b/configuration/src/main/kotlin/com/malinskiy/marathon/config/vendor/apple/ios/XctestrunEnvConfiguration.kt @@ -0,0 +1,8 @@ +package com.malinskiy.marathon.config.vendor.apple.ios + +import com.fasterxml.jackson.annotation.JsonProperty + +data class XctestrunEnvConfiguration( + @JsonProperty("app") val appEnvs: Map = emptyMap(), + @JsonProperty("test") val testEnvs: Map = emptyMap(), +) diff --git a/docs/runner/apple/configure/ios.md b/docs/runner/apple/configure/ios.md index 4bdd0fc8b..bd67912ad 100644 --- a/docs/runner/apple/configure/ios.md +++ b/docs/runner/apple/configure/ios.md @@ -299,17 +299,21 @@ The `display` and `mask` fields have the same options as the video recorder. The `type` specifies the format of a single frame and is advised not to be changes. The `delay` field specifies the minimal delay between frames using [ISO 8601][3] notation. -### xctestrun environment variables +### xctestrun Environment and TestingEnvironment variables -You specify additional environment variables for your test run: +You can specify additional Environment and TestingEnvironment variables for your test run: ```yaml xctestrunEnv: - MY_ENV_VAR_1: A - MY_ENV_VAR_2: B + app: # EnvironmentVariables + MY_ENV_VAR_1: A + MY_ENV_VAR_2: B + test: # TestingEnvironmentVariables + MY_TEST_ENV_VAR_1: AA + MY_TEST_ENV_VAR_2: BB ``` -These will be placed in the generated xctestrun property list file under the `TestingEnvironmentVariables` key. +These will be placed in the generated xctestrun property list file under the `EnvironmentVariables` and `TestingEnvironmentVariables` keys. :::info diff --git a/docs/runner/apple/configure/macos.md b/docs/runner/apple/configure/macos.md index 92454b995..ed907be06 100644 --- a/docs/runner/apple/configure/macos.md +++ b/docs/runner/apple/configure/macos.md @@ -184,19 +184,25 @@ deleted on success and user attachments will always be kept in the xcresult, but Possible values for the lifetime are `KEEP_ALWAYS`, `DELETE_ON_SUCCESS` and `KEEP_NEVER`. -### xctestrun environment variables -You specify additional environment variables for your test run: +### xctestrun Environment and TestingEnvironment variables + +You can specify additional Environment and TestingEnvironment variables for your test run: + ```yaml xctestrunEnv: - MY_ENV_VAR_1: A - MY_ENV_VAR_2: B + app: # EnvironmentVariables + MY_ENV_VAR_1: A + MY_ENV_VAR_2: B + test: # TestingEnvironmentVariables + MY_TEST_ENV_VAR_1: AA + MY_TEST_ENV_VAR_2: BB ``` -These will be placed in the generated xctestrun property list file under the `TestingEnvironmentVariables` key. +These will be placed in the generated xctestrun property list file under the `EnvironmentVariables` and `TestingEnvironmentVariables` keys. :::info -Marathon generates required values for `DYLD_FRAMEWORK_PATH`, `DYLD_LIBRARY_PATH` and `DYLD_INSERT_LIBRARIES` for test environment. +Marathon generates required values for `DYLD_FRAMEWORK_PATH`, `DYLD_LIBRARY_PATH` and `DYLD_INSERT_LIBRARIES` for test environment. If you specify custom ones then your values will be placed as a lower priority path elements at the end of the specified envvar. ::: diff --git a/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/extensions/ConfigurationExtensions.kt b/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/extensions/ConfigurationExtensions.kt index 20b2bc5c9..275348552 100644 --- a/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/extensions/ConfigurationExtensions.kt +++ b/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/extensions/ConfigurationExtensions.kt @@ -3,6 +3,7 @@ package com.malinskiy.marathon.apple.extensions import com.malinskiy.marathon.config.vendor.VendorConfiguration import com.malinskiy.marathon.config.vendor.apple.AppleTestBundleConfiguration import com.malinskiy.marathon.config.vendor.apple.ios.XcresultConfiguration +import com.malinskiy.marathon.config.vendor.apple.ios.XctestrunEnvConfiguration fun VendorConfiguration.bundleConfiguration(): AppleTestBundleConfiguration? { return when (this) { @@ -18,7 +19,7 @@ fun VendorConfiguration.bundleConfiguration(): AppleTestBundleConfiguration? { } } -fun VendorConfiguration.xctestrunEnv(): Map? { +fun VendorConfiguration.xctestrunEnv(): XctestrunEnvConfiguration? { return when (this) { is VendorConfiguration.IOSConfiguration -> { this.xctestrunEnv diff --git a/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/xctestrun/TestRootFactory.kt b/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/xctestrun/TestRootFactory.kt index 28d1ef4dc..b46da7fb7 100644 --- a/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/xctestrun/TestRootFactory.kt +++ b/vendor/vendor-apple/base/src/main/kotlin/com/malinskiy/marathon/apple/xctestrun/TestRootFactory.kt @@ -15,6 +15,7 @@ import com.malinskiy.marathon.apple.xctestrun.v2.Xctestrun import com.malinskiy.marathon.config.exceptions.ConfigurationException import com.malinskiy.marathon.config.vendor.apple.TestType import com.malinskiy.marathon.config.vendor.apple.ios.XcresultConfiguration +import com.malinskiy.marathon.config.vendor.apple.ios.XctestrunEnvConfiguration import com.malinskiy.marathon.exceptions.DeviceSetupException import com.malinskiy.marathon.exceptions.IncompatibleDeviceException import com.malinskiy.marathon.exceptions.TransferException @@ -27,7 +28,7 @@ import com.malinskiy.marathon.apple.xctestrun.v2.Metadata as Metadata class TestRootFactory( private val device: AppleDevice, - private val xctestrunEnv: Map, + private val xctestrunEnv: XctestrunEnvConfiguration, private val xcresultConfiguration: XcresultConfiguration, ) { suspend fun generate(testType: TestType, bundle: AppleTestBundle, useXctestParser: Boolean) { @@ -135,10 +136,11 @@ class TestRootFactory( val privateFrameworks = remoteFileManager.joinPath(developerPath, "Library", "PrivateFrameworks") val usrLib = remoteFileManager.joinPath(developerPath, "usr", "lib") + val xctestrunTestEnv = xctestrunEnv.testEnvs val userFrameworkPath = - xctestrunEnv["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() - val userLibraryPath = xctestrunEnv["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() - val userInsertLibraries = xctestrunEnv["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() + xctestrunTestEnv["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() + val userLibraryPath = xctestrunTestEnv["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() + val userInsertLibraries = xctestrunTestEnv["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() val dyldFrameworks = mutableListOf().apply { add("__TESTROOT__") @@ -194,7 +196,7 @@ class TestRootFactory( "DYLD_LIBRARY_PATH" to dyldLibraries.joinToString(":"), "DYLD_INSERT_LIBRARIES" to dyldInsertLibraries.joinToString(":") ).apply { - xctestrunEnv + xctestrunTestEnv .filterKeys { !setOf("DYLD_FRAMEWORK_PATH", "DYLD_LIBRARY_PATH", "DYLD_INSERT_LIBRARIES").contains(it) } .forEach { put(it.key, it.value) @@ -209,6 +211,7 @@ class TestRootFactory( arrayOf( TestTarget.withArtifactReinstall( name = bundle.testBundleId, + environmentVariables = xctestrunEnv.appEnvs.ifEmpty { null }, testingEnvironmentVariables = testEnv, productModuleName = bundle.testBundleId, systemAttachmentLifetime = xcresultConfiguration.attachments.systemAttachmentLifetime.value, @@ -265,11 +268,12 @@ class TestRootFactory( val privateFrameworks = remoteFileManager.joinPath(developerPath, "Library", "PrivateFrameworks") val usrLib = remoteFileManager.joinPath(developerPath, "usr", "lib") + val xctestrunTestEnvs = xctestrunEnv.testEnvs val userFrameworkPath = - xctestrunEnv["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() - val userLibraryPath = xctestrunEnv["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() + xctestrunTestEnvs["DYLD_FRAMEWORK_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() + val userLibraryPath = xctestrunTestEnvs["DYLD_LIBRARY_PATH"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() val userInsertLibraries = - xctestrunEnv["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() + xctestrunTestEnvs["DYLD_INSERT_LIBRARIES"]?.split(":")?.filter { it.isNotBlank() } ?: emptySet() val dyldFrameworks = mutableListOf("__TESTROOT__", frameworks, privateFrameworks, *userFrameworkPath.toTypedArray()) /** @@ -293,7 +297,7 @@ class TestRootFactory( "DYLD_LIBRARY_PATH" to dyldLibraries.joinToString(":"), "XCInjectBundleInto" to "__TESTHOST__/${remoteFileManager.appUnderTestFileName()}" ).apply { - xctestrunEnv + xctestrunTestEnvs .filterKeys { !setOf("DYLD_FRAMEWORK_PATH", "DYLD_INSERT_LIBRARIES", "DYLD_LIBRARY_PATH").contains(it) } .forEach { put(it.key, it.value) @@ -308,6 +312,7 @@ class TestRootFactory( arrayOf( TestTarget.withArtifactReinstall( name = bundle.testBundleId, + environmentVariables = xctestrunEnv.appEnvs.ifEmpty { null }, testingEnvironmentVariables = testEnv, productModuleName = bundle.testBundleId, systemAttachmentLifetime = xcresultConfiguration.attachments.systemAttachmentLifetime.value,