mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Add swift command for running UI tests
This commit is contained in:
committed by
Stefan Ceriu
parent
1d8639a11a
commit
d3cefb8e0b
@@ -28,28 +28,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 #v1.2.3
|
- uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 #v1.2.3
|
||||||
|
|
||||||
- uses: actions/cache@v5
|
|
||||||
with:
|
|
||||||
path: vendor/bundle
|
|
||||||
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-gems-
|
|
||||||
|
|
||||||
- name: Setup environment
|
- name: Setup environment
|
||||||
run: source ci_scripts/ci_common.sh && setup_github_actions_environment
|
run: source ci_scripts/ci_common.sh && setup_github_actions_environment
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
if [[ -z "${{ github.event.inputs.test_name }}" ]]; then
|
args=(--device-type "${{ matrix.device }}")
|
||||||
bundle exec fastlane ui_tests device:${{ matrix.device }}
|
if [[ -n "${{ github.event.inputs.test_name }}" ]]; then
|
||||||
else
|
args+=( --test-name "${{ github.event.inputs.test_name }}")
|
||||||
bundle exec fastlane ui_tests device:${{ matrix.device }} test_name:${{ github.event.inputs.test_name }}
|
|
||||||
fi
|
fi
|
||||||
|
swift run tools ci ui-tests "${args[@]}"
|
||||||
- name: Zip results # Faster uploads
|
|
||||||
if: failure()
|
|
||||||
working-directory: fastlane/test_output
|
|
||||||
run: zip -r UITests.xcresult.zip UITests.xcresult
|
|
||||||
|
|
||||||
- name: Archive artifacts
|
- name: Archive artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v7
|
||||||
@@ -57,32 +45,22 @@ jobs:
|
|||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.device }}
|
name: ${{ matrix.device }}
|
||||||
path: fastlane/test_output/UITests.xcresult.zip
|
path: test_output/UITests.xcresult.zip
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
||||||
- name: Collect coverage
|
|
||||||
# Skip if not successful and in forks
|
|
||||||
if: ${{ success() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
|
||||||
run: xcresultparser -q -o cobertura -t ElementX -p $(pwd) fastlane/test_output/UITests.xcresult > fastlane/test_output/ui-cobertura.xml
|
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
# Skip if not successful and in forks
|
# Skip if not successful and in forks
|
||||||
if: ${{ success() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
if: ${{ success() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
||||||
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||||
with:
|
with:
|
||||||
report_type: coverage
|
report_type: coverage
|
||||||
files: fastlane/test_output/ui-cobertura.xml
|
files: test_output/ui-cobertura.xml
|
||||||
disable_search: true
|
disable_search: true
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
flags: uitests
|
flags: uitests
|
||||||
|
|
||||||
- name: Collect test results
|
|
||||||
# Skip if cancelled and in forks
|
|
||||||
if: ${{ !cancelled() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
|
||||||
run: xcresultparser -q -o junit -p $(pwd) fastlane/test_output/UITests.xcresult > fastlane/test_output/ui-junit.xml
|
|
||||||
|
|
||||||
- name: Upload test results to Codecov
|
- name: Upload test results to Codecov
|
||||||
# Skip if cancelled and in forks
|
# Skip if cancelled and in forks
|
||||||
if: ${{ !cancelled() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
if: ${{ !cancelled() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
|
||||||
@@ -90,7 +68,7 @@ jobs:
|
|||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
report_type: test_results
|
report_type: test_results
|
||||||
files: fastlane/test_output/ui-junit.xml
|
files: test_output/ui-junit.xml
|
||||||
disable_search: true
|
disable_search: true
|
||||||
fail_ci_if_error: false
|
fail_ci_if_error: false
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ struct CI: ParsableCommand {
|
|||||||
subcommands: [
|
subcommands: [
|
||||||
AccessibilityTests.self,
|
AccessibilityTests.self,
|
||||||
UnitTests.self,
|
UnitTests.self,
|
||||||
|
UITests.self,
|
||||||
RunTests.self,
|
RunTests.self,
|
||||||
ConfigureNightly.self
|
ConfigureNightly.self
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import ArgumentParser
|
||||||
|
import CommandLineTools
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct UITests: AsyncParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(commandName: "ui-tests",
|
||||||
|
abstract: "Runs the UI test CI workflow for a specific device type.",
|
||||||
|
discussion: """
|
||||||
|
Examples:
|
||||||
|
swift run tools ci ui-tests --device-type iPhone
|
||||||
|
swift run tools ci ui-tests --device-type iPad
|
||||||
|
swift run tools ci ui-tests --device-type iPhone --test-name "ClassName/testName"
|
||||||
|
""")
|
||||||
|
|
||||||
|
enum DeviceType: String, CaseIterable, ExpressibleByArgument {
|
||||||
|
case iPhone
|
||||||
|
case iPad
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option(help: "The device type to test (iPhone or iPad).")
|
||||||
|
var deviceType: DeviceType
|
||||||
|
|
||||||
|
@Option(help: "iOS version for the simulator.")
|
||||||
|
var osVersion = "26.1"
|
||||||
|
|
||||||
|
@Option(help: "Run only a specific test (format: 'ClassName/testName').")
|
||||||
|
var testName: String?
|
||||||
|
|
||||||
|
private var simulatorName: String {
|
||||||
|
switch deviceType {
|
||||||
|
case .iPhone: "iPhone-\(osVersion)"
|
||||||
|
case .iPad: "iPad-\(osVersion)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var simulatorType: String {
|
||||||
|
switch deviceType {
|
||||||
|
case .iPhone: "com.apple.CoreSimulator.SimDeviceType.iPhone-17"
|
||||||
|
case .iPad: "com.apple.CoreSimulator.SimDeviceType.iPad-A16"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We used to run these simultaneously on iPhone and iPad but it is *really* slow on GitHub runners.
|
||||||
|
/// Presumably because launching 2 simulators uses more memory than the runner has available.
|
||||||
|
func run() async throws {
|
||||||
|
var args = [
|
||||||
|
"--scheme", "UITests",
|
||||||
|
"--device", simulatorName,
|
||||||
|
"--os-version", osVersion,
|
||||||
|
"--create-simulator-name", simulatorName,
|
||||||
|
"--create-simulator-type", simulatorType
|
||||||
|
]
|
||||||
|
|
||||||
|
if let testName {
|
||||||
|
args += ["--test-name", testName]
|
||||||
|
}
|
||||||
|
|
||||||
|
var testsFailed = false
|
||||||
|
do {
|
||||||
|
print("\n🧪 Running UI tests (\(deviceType.rawValue))…\n")
|
||||||
|
try await RunTests.parse(args).run()
|
||||||
|
} catch {
|
||||||
|
testsFailed = true
|
||||||
|
print("\n❌ UI tests (\(deviceType.rawValue)) failed.\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
await CI.zipResults(bundles: ["UITests.xcresult"],
|
||||||
|
outputName: "UITests.xcresult.zip")
|
||||||
|
|
||||||
|
await CI.collectCoverage(resultBundle: "UITests.xcresult", outputName: "ui-cobertura.xml")
|
||||||
|
await CI.collectTestResults(resultBundle: "UITests.xcresult", outputName: "ui-junit.xml")
|
||||||
|
|
||||||
|
if testsFailed {
|
||||||
|
throw ExitCode.failure
|
||||||
|
}
|
||||||
|
|
||||||
|
print("\n✅ UI tests (\(deviceType.rawValue)) passed.\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,49 +45,6 @@ lane :unit_tests do |options|
|
|||||||
# We use xcresultparser in the workflow to collect coverage from both result bundles.
|
# We use xcresultparser in the workflow to collect coverage from both result bundles.
|
||||||
end
|
end
|
||||||
|
|
||||||
lane :ui_tests do |options|
|
|
||||||
# We used to run these simultaneously on iPhone and iPad but it is *really* slow on GitHub runners.
|
|
||||||
# Presumably because launching 2 simulators uses more memory than the runner has available.
|
|
||||||
|
|
||||||
if options[:device] == "iPhone"
|
|
||||||
device = "iPhone-#{simulator_version}"
|
|
||||||
|
|
||||||
create_simulator_if_necessary(
|
|
||||||
name: "iPhone-#{simulator_version}",
|
|
||||||
type: "com.apple.CoreSimulator.SimDeviceType.iPhone-17"
|
|
||||||
)
|
|
||||||
elsif options[:device] == "iPad"
|
|
||||||
device = "iPad-#{simulator_version}"
|
|
||||||
|
|
||||||
create_simulator_if_necessary(
|
|
||||||
name: "iPad-#{simulator_version}",
|
|
||||||
type: "com.apple.CoreSimulator.SimDeviceType.iPad-A16"
|
|
||||||
)
|
|
||||||
else
|
|
||||||
UI.user_error!("Please supply a device argument as device:iPhone or device:iPad")
|
|
||||||
end
|
|
||||||
|
|
||||||
if options[:test_name]
|
|
||||||
test_to_run = ["UITests/#{options[:test_name]}"]
|
|
||||||
else
|
|
||||||
test_to_run = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
reset_simulator = ENV.key?('CI')
|
|
||||||
|
|
||||||
run_tests(
|
|
||||||
scheme: "UITests",
|
|
||||||
device: "#{device} (#{simulator_version})",
|
|
||||||
ensure_devices_found: true,
|
|
||||||
prelaunch_simulator: false,
|
|
||||||
result_bundle: true,
|
|
||||||
only_testing: test_to_run,
|
|
||||||
number_of_retries: 3,
|
|
||||||
reset_simulator: reset_simulator,
|
|
||||||
xcodebuild_formatter: "xcbeautify --quiet --is-ci --renderer github-actions"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
lane :integration_tests do
|
lane :integration_tests do
|
||||||
clear_derived_data()
|
clear_derived_data()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user