Skip to content

Commit c3c9d36

Browse files
niklasberglundbuggmagnet
authored andcommitted
GitHub actions workflow for iOS end to end tests
1 parent c28989c commit c3c9d36

File tree

7 files changed

+158
-5
lines changed

7 files changed

+158
-5
lines changed
+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
name: iOS end-to-end tests
3+
permissions:
4+
contents: read
5+
issues: write
6+
pull-requests: write
7+
on:
8+
pull_request:
9+
types:
10+
- closed
11+
branches:
12+
- main
13+
workflow_dispatch:
14+
jobs:
15+
test:
16+
if: github.event.pull_request.merged || github.event_name == 'workflow_dispatch'
17+
name: End to end tests
18+
runs-on: [self-hosted, macOS, ios-test]
19+
env:
20+
IOS_DEVICE_PIN_CODE: ${{ secrets.IOS_DEVICE_PIN_CODE }}
21+
TEST_DEVICE_IDENTIFIER_UUID: ${{ secrets.IOS_TEST_DEVICE_IDENTIFIER_UUID }}
22+
TEST_DEVICE_UDID: ${{ secrets.IOS_TEST_DEVICE_UDID }}
23+
HAS_TIME_ACCOUNT_NUMBER: ${{ secrets.IOS_HAS_TIME_ACCOUNT_NUMBER }}
24+
NO_TIME_ACCOUNT_NUMBER: ${{ secrets.IOS_NO_TIME_ACCOUNT_NUMBER }}
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
29+
- name: Configure Rust
30+
run: rustup target install aarch64-apple-ios aarch64-apple-ios-sim
31+
32+
- name: Configure Xcode project
33+
run: |
34+
for file in *.xcconfig.template ; do cp $file ${file//.template/} ; done
35+
sed -i "" \
36+
"/MULLVAD_IOS_DEVICE_PIN_CODE =/ s/= .*/= $IOS_DEVICE_PIN_CODE/" \
37+
UITests.xcconfig
38+
sed -i "" \
39+
"/MULLVAD_TEST_DEVICE_IDENTIFIER_UUID =/ s/= .*/= $TEST_DEVICE_IDENTIFIER_UUID/" \
40+
UITests.xcconfig
41+
sed -i "" \
42+
"/MULLVAD_HAS_TIME_ACCOUNT_NUMBER =/ s/= .*/= $HAS_TIME_ACCOUNT_NUMBER/" \
43+
UITests.xcconfig
44+
sed -i "" \
45+
"/MULLVAD_NO_TIME_ACCOUNT_NUMBER =/ s/= .*/= $NO_TIME_ACCOUNT_NUMBER/" \
46+
UITests.xcconfig
47+
working-directory: ios/Configurations
48+
49+
- name: Run end-to-end-tests
50+
run: |
51+
set -o pipefail && env NSUnbufferedIO=YES xcodebuild \
52+
-project MullvadVPN.xcodeproj \
53+
-scheme MullvadVPNUITests \
54+
-testPlan MullvadVPNUITestsSmoke \
55+
-destination "platform=iOS,id=$TEST_DEVICE_UDID" \
56+
test 2>&1 | xcbeautify --report junit --report-path test-report
57+
working-directory: ios/
58+
59+
- name: Comment PR on test failure
60+
if: failure() && github.event_name != 'workflow_dispatch'
61+
uses: actions/github-script@v7
62+
with:
63+
github-token: ${{secrets.GITHUB_TOKEN}}
64+
script: |
65+
const issue_number = context.issue.number;
66+
const run_id = context.runId;
67+
const run_url = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${run_id}`;
68+
github.rest.issues.createComment({
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
issue_number: issue_number,
72+
body: `🚨 End to end tests failed. Please check the [failed workflow run](${run_url}).`
73+
});
74+
75+
- name: Store test report artifact
76+
if: always()
77+
uses: actions/upload-artifact@v4
78+
with:
79+
name: test-report
80+
path: ios/test-report/junit.xml

ios/MullvadVPN.xcodeproj/project.pbxproj

+4-2
Original file line numberDiff line numberDiff line change
@@ -1810,14 +1810,15 @@
18101810
7AF9BE8F2A39F26000DBFEDB /* Collection+Sorting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Sorting.swift"; sourceTree = "<group>"; };
18111811
7AF9BE942A40461100DBFEDB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; };
18121812
7AF9BE962A41C71F00DBFEDB /* RelayFilterChipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterChipView.swift; sourceTree = "<group>"; };
1813+
85006A8E2B73EF67004AD8FB /* MullvadVPNUITestsSmoke.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MullvadVPNUITestsSmoke.xctestplan; sourceTree = "<group>"; };
18131814
850201DA2B503D7700EF8C96 /* RelayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayTests.swift; sourceTree = "<group>"; };
18141815
850201DC2B503D8C00EF8C96 /* SelectLocationPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationPage.swift; sourceTree = "<group>"; };
18151816
850201DE2B5040A500EF8C96 /* TunnelControlPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelControlPage.swift; sourceTree = "<group>"; };
18161817
850201E22B51A93C00EF8C96 /* SettingsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsPage.swift; sourceTree = "<group>"; };
18171818
8518F6372B60157E009EB113 /* LoggedInWithoutTimeUITestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedInWithoutTimeUITestCase.swift; sourceTree = "<group>"; };
18181819
852969252B4D9C1F007EAD4C /* MullvadVPNUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MullvadVPNUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
18191820
852969272B4D9C1F007EAD4C /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = "<group>"; };
1820-
852969302B4D9E70007EAD4C /* MullvadVPNUITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MullvadVPNUITests.xctestplan; sourceTree = "<group>"; };
1821+
852969302B4D9E70007EAD4C /* MullvadVPNUITestsAll.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MullvadVPNUITestsAll.xctestplan; sourceTree = "<group>"; };
18211822
852969322B4E9232007EAD4C /* Page.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Page.swift; sourceTree = "<group>"; };
18221823
852969342B4E9270007EAD4C /* LoginPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginPage.swift; sourceTree = "<group>"; };
18231824
852969372B4ED20E007EAD4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
@@ -3443,7 +3444,8 @@
34433444
7A83C3FC2A55B39500DFB83A /* TestPlans */ = {
34443445
isa = PBXGroup;
34453446
children = (
3446-
852969302B4D9E70007EAD4C /* MullvadVPNUITests.xctestplan */,
3447+
852969302B4D9E70007EAD4C /* MullvadVPNUITestsAll.xctestplan */,
3448+
85006A8E2B73EF67004AD8FB /* MullvadVPNUITestsSmoke.xctestplan */,
34473449
7A83C3FE2A55B72E00DFB83A /* MullvadVPNApp.xctestplan */,
34483450
7A83C4002A55B81A00DFB83A /* MullvadVPNCI.xctestplan */,
34493451
7A02D4EA2A9CEC7A00C19E31 /* MullvadVPNScreenshots.xctestplan */,

ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNUITests.xcscheme

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
shouldUseLaunchSchemeArgsEnv = "YES">
1414
<TestPlans>
1515
<TestPlanReference
16-
reference = "container:TestPlans/MullvadVPNUITests.xctestplan"
16+
reference = "container:TestPlans/MullvadVPNUITestsAll.xctestplan"
1717
default = "YES">
1818
</TestPlanReference>
19+
<TestPlanReference
20+
reference = "container:TestPlans/MullvadVPNUITestsSmoke.xctestplan">
21+
</TestPlanReference>
1922
</TestPlans>
2023
<Testables>
2124
<TestableReference

ios/MullvadVPNUITests/README.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Integration tests
2+
3+
## iOS device setup
4+
1. Make sure device is added to provisioning profiles
5+
2. Disable passcode in iOS settings - otherwise tests cannot be started without manually entering passcode
6+
3. Make sure device is configured in GitHub secrets(see *GitHub setup* below)
7+
8+
## Set up of runner environment
9+
1. Install Xcode
10+
2. Sign in with Apple id in Xcode
11+
3. Download manual provisioning profiles in Xcode
12+
4. Install Xcode command line tools `xcode-select --install`
13+
5. Install yeetd
14+
- `wget https://github.com/biscuitehh/yeetd/releases/download/1.0/yeetd-normal.pkg`
15+
- `sudo installer -pkg yeetd-normal.pkg -target yeetd`
16+
6. Install Homebrew and dependencies
17+
- `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
18+
- `brew install xcbeautify wget swiftlint`
19+
7. Install Ruby
20+
- `\curl -sSL https://get.rvm.io | bash`
21+
8. Install Rust and add iOS targets
22+
- `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
23+
- `rustup target install aarch64-apple-ios aarch64-apple-ios-sim`
24+
9. Install Go 1.19
25+
- `brew install go@1.19`
26+
27+
## GitHub runner setup
28+
1. Ask GitHub admin for new runner token and set it up according to the steps presented, pass `--labels ios-test` to `config.sh` when running it. By default it will also have the labels `self-hosted` and `macOS` which are required as well.
29+
2. Make sure GitHub actions secrets for the repository are correctly set up:
30+
- `IOS_DEVICE_PIN_CODE` - Device passcode if the device require it, otherwise leave blank. Devices used with CI should not require passcode.
31+
- `IOS_HAS_TIME_ACCOUNT_NUMBER` - Production server account without time left
32+
- `IOS_NO_TIME_ACCOUNT_NUMBER` - Production server account with time added to it
33+
- `IOS_TEST_DEVICE_IDENTIFIER_UUID` - unique identifier for the test device. Create new identifier with `uuidgen`.
34+
- `IOS_TEST_DEVICE_UDID` - the iOS device's UDID.

ios/MullvadVPNUITests/Test base classes/BaseUITestCase.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ class BaseUITestCase: XCTestCase {
3535
alertAllowButton.tap()
3636
}
3737

38-
_ = springboard.buttons["1"].waitForExistence(timeout: Self.defaultTimeout)
39-
springboard.typeText(iOSDevicePinCode)
38+
if iOSDevicePinCode.isEmpty == false {
39+
_ = springboard.buttons["1"].waitForExistence(timeout: Self.defaultTimeout)
40+
springboard.typeText(iOSDevicePinCode)
41+
}
4042
}
4143

4244
// MARK: - Setup & teardown

ios/TestPlans/MullvadVPNUITests.xctestplan ios/TestPlans/MullvadVPNUITestsAll.xctestplan

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
},
1818
"testTargets" : [
1919
{
20+
"selectedTests" : [
21+
"AccountTests\/testLogin()",
22+
"AccountTests\/testLoginWithIncorrectAccountNumber()"
23+
],
2024
"target" : {
2125
"containerPath" : "container:MullvadVPN.xcodeproj",
2226
"identifier" : "852969242B4D9C1F007EAD4C",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"configurations" : [
3+
{
4+
"id" : "3BCBAC52-59BD-45E8-BC9D-1AF65D1B15B7",
5+
"name" : "Configuration 1",
6+
"options" : {
7+
8+
}
9+
}
10+
],
11+
"defaultOptions" : {
12+
13+
},
14+
"testTargets" : [
15+
{
16+
"selectedTests" : [
17+
"AccountTests\/testLogin()",
18+
"AccountTests\/testLoginWithIncorrectAccountNumber()"
19+
],
20+
"target" : {
21+
"containerPath" : "container:MullvadVPN.xcodeproj",
22+
"identifier" : "852969242B4D9C1F007EAD4C",
23+
"name" : "MullvadVPNUITests"
24+
}
25+
}
26+
],
27+
"version" : 1
28+
}

0 commit comments

Comments
 (0)