Skip to content

Commit 0fc02ed

Browse files
authored
Merge pull request #51 from passageidentity/PSG-4144
PSG-4144
2 parents 4a045b6 + cbdee0f commit 0fc02ed

13 files changed

+195
-57
lines changed
+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Integration Tests
2+
3+
on:
4+
pull_request:
5+
branches: [ "main" ]
6+
7+
jobs:
8+
web-tests:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Set up Flutter
15+
uses: subosito/flutter-action@v2
16+
with:
17+
flutter-version: '3.22.1'
18+
19+
- name: Install Node.js
20+
uses: actions/setup-node@v3
21+
with:
22+
node-version: '16'
23+
24+
- name: Install dependencies
25+
run: |
26+
cd proxy-server
27+
npm install
28+
cd ../..
29+
flutter pub get
30+
working-directory: ./integrationtestapp
31+
32+
- name: Set up Google Chrome and ChromeDriver
33+
uses: browser-actions/setup-chrome@v1
34+
with:
35+
chrome-version: 125
36+
install-chromedriver: true
37+
install-dependencies: true
38+
39+
- name: Start Xvfb
40+
run: |
41+
sudo apt-get install -y xvfb
42+
export DISPLAY=:99
43+
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
44+
45+
- name: Start ChromeDriver
46+
run: |
47+
nohup chromedriver --port=4444 &
48+
sleep 5
49+
50+
- name: Start Proxy Server
51+
run: |
52+
nohup node integrationtestapp/proxy-server/proxy_server.js &
53+
sleep 5
54+
env:
55+
MAILOSAUR_API_KEY: ${{ secrets.MAILOSAUR_API_KEY }}
56+
57+
- name: Run Web tests with XVFB
58+
run: |
59+
for test in integration_test/*.dart; do
60+
xvfb-run --auto-servernum --server-args="-screen 0 1280x1024x24" flutter drive --driver=test_driver/integration_test.dart --target=$test -d chrome --web-port=4200 --dart-define=MAILOSAUR_API_KEY=${{ secrets.MAILOSAUR_API_KEY }}
61+
done
62+
working-directory: ./integrationtestapp
63+
env:
64+
MAILOSAUR_API_KEY: ${{ secrets.MAILOSAUR_API_KEY }}
65+
66+
android-tests:
67+
runs-on: ubuntu-latest
68+
needs: web-tests
69+
70+
steps:
71+
- name: Checkout
72+
uses: actions/checkout@v4
73+
74+
- name: Set up Java
75+
uses: actions/setup-java@v3
76+
with:
77+
distribution: 'zulu'
78+
java-version: '11'
79+
80+
- name: Set up Flutter
81+
uses: subosito/flutter-action@v2
82+
with:
83+
flutter-version: '3.22.1'
84+
85+
- name: Enable KVM
86+
run: |
87+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
88+
sudo udevadm control --reload-rules
89+
sudo udevadm trigger --name-match=kvm
90+
91+
- name: Install dependencies
92+
run: flutter pub get
93+
working-directory: ./integrationtestapp
94+
95+
- name: Set environment variables
96+
env:
97+
MAILOSAUR_API_KEY: ${{ secrets.MAILOSAUR_API_KEY }}
98+
run: |
99+
echo "export MAILOSAUR_API_KEY=${{ secrets.MAILOSAUR_API_KEY }}" >> $GITHUB_ENV
100+
101+
- name: Start emulator and run tests
102+
uses: reactivecircus/android-emulator-runner@v2
103+
with:
104+
api-level: 34
105+
target: google_apis
106+
build-tools: 34.0.0
107+
arch: x86_64
108+
profile: Nexus 6
109+
working-directory: ./integrationtestapp
110+
script: flutter test integration_test/*.dart -d emulator-5554 --dart-define=MAILOSAUR_API_KEY=${{ secrets.MAILOSAUR_API_KEY }}
111+
112+
ios-tests:
113+
runs-on: macos-latest
114+
needs: android-tests
115+
116+
steps:
117+
- uses: actions/checkout@v4
118+
119+
- name: Set up Flutter
120+
uses: subosito/flutter-action@v2
121+
with:
122+
flutter-version: '3.22.1'
123+
124+
- name: Install dependencies
125+
run: flutter pub get
126+
working-directory: ./integrationtestapp
127+
128+
- name: Install CocoaPods
129+
run: pod install --project-directory=ios
130+
working-directory: ./integrationtestapp
131+
132+
- name: Install simulator
133+
uses: futureware-tech/simulator-action@v3
134+
with:
135+
model: 'iPhone 14'
136+
137+
- name: Run iOS tests
138+
run: flutter test integration_test/*.dart -d D9B9FD9F-A0A3-422F-8D9B-35F8CC886FF3 --dart-define=MAILOSAUR_API_KEY=${{ secrets.MAILOSAUR_API_KEY }}
139+
working-directory: ./integrationtestapp
140+
env:
141+
MAILOSAUR_API_KEY: ${{ secrets.MAILOSAUR_API_KEY }}

integrationtestapp/integration_test/change_user_info_test.dart

+19-28
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import 'package:flutter/foundation.dart';
22
import 'package:flutter_test/flutter_test.dart';
33
import 'package:passage_flutter/passage_flutter.dart';
44
import 'package:passage_flutter/passage_flutter_models/passage_error.dart';
5-
import 'integration_test_config.dart';
6-
import 'mailosaur_api_client.dart';
7-
import 'platform_helper/platform_helper.dart';
5+
import 'helper/integration_test_config.dart';
6+
import 'helper/mailosaur_api_client.dart';
7+
import 'helper/platform_helper.dart';
8+
import 'package:integration_test/integration_test.dart';
89

910
void main() {
10-
PassageFlutter passage =
11-
PassageFlutter(IntegrationTestConfig.appIdMagicLink);
11+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
12+
PassageFlutter passage = PassageFlutter(IntegrationTestConfig.appIdMagicLink);
1213

1314
setUp(() async {
1415
if (!kIsWeb) {
@@ -20,7 +21,7 @@ void main() {
2021
}
2122
});
2223

23-
tearDownAll(() async {
24+
tearDown(() async {
2425
try {
2526
await passage.signOut();
2627
} catch (e) {
@@ -29,19 +30,19 @@ void main() {
2930
});
3031

3132
Future<void> loginWithMagicLink() async {
32-
try {
33-
await passage.newLoginMagicLink(
34-
IntegrationTestConfig.existingUserEmailMagicLink);
35-
await Future.delayed(const Duration(
36-
milliseconds: IntegrationTestConfig.waitTimeMilliseconds));
37-
final magicLinkStr = await MailosaurAPIClient.getMostRecentMagicLink();
38-
if (magicLinkStr.isEmpty) {
39-
fail('Test failed: Magic link is empty');
40-
}
41-
await passage.magicLinkActivate(magicLinkStr);
42-
} catch (e) {
43-
fail('Expected to activate login magic link, but got an exception: $e');
33+
try {
34+
await passage
35+
.newLoginMagicLink(IntegrationTestConfig.existingUserEmailMagicLink);
36+
await Future.delayed(const Duration(
37+
milliseconds: IntegrationTestConfig.waitTimeMilliseconds));
38+
final magicLinkStr = await MailosaurAPIClient.getMostRecentMagicLink();
39+
if (magicLinkStr.isEmpty) {
40+
fail('Test failed: Magic link is empty');
4441
}
42+
await passage.magicLinkActivate(magicLinkStr);
43+
} catch (e) {
44+
fail('Expected to activate login magic link, but got an exception: $e');
45+
}
4546
}
4647

4748
group('ChangeContactTests', () {
@@ -73,16 +74,6 @@ void main() {
7374
}
7475
});
7576

76-
test('testChangePhone', () async {
77-
try {
78-
await loginWithMagicLink();
79-
final response = passage.changePhone('+14155552671');
80-
expect(response, isNotNull);
81-
} catch (e) {
82-
fail('Test failed due to unexpected exception: $e');
83-
}
84-
});
85-
8677
test('testChangePhoneInvalid', () async {
8778
try {
8879
await loginWithMagicLink();

integrationtestapp/integration_test/current_user_test.dart

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import 'package:flutter_test/flutter_test.dart';
22
import 'package:passage_flutter/passage_flutter.dart';
3-
import 'integration_test_config.dart';
4-
import 'mailosaur_api_client.dart';
3+
import 'helper/integration_test_config.dart';
4+
import 'helper/mailosaur_api_client.dart';
55
import 'package:flutter/foundation.dart';
6-
import 'platform_helper/platform_helper.dart';
6+
import 'helper/platform_helper.dart';
7+
import 'package:integration_test/integration_test.dart';
78

89
void main() {
9-
PassageFlutter passage =
10-
PassageFlutter(IntegrationTestConfig.appIdMagicLink);
10+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
11+
PassageFlutter passage = PassageFlutter(IntegrationTestConfig.appIdMagicLink);
1112

1213
setUp(() async {
1314
if (!kIsWeb) {
@@ -29,8 +30,8 @@ void main() {
2930

3031
Future<void> loginWithMagicLink() async {
3132
try {
32-
await passage.newLoginMagicLink(
33-
IntegrationTestConfig.existingUserEmailMagicLink);
33+
await passage
34+
.newLoginMagicLink(IntegrationTestConfig.existingUserEmailMagicLink);
3435
await Future.delayed(const Duration(
3536
milliseconds: IntegrationTestConfig.waitTimeMilliseconds));
3637
final magicLinkStr = await MailosaurAPIClient.getMostRecentMagicLink();

integrationtestapp/integration_test/mailosaur_api_client.dart integrationtestapp/integration_test/helper/mailosaur_api_client.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class GetMessageResponse {
121121
class MailosaurAPIClient {
122122
static const String serverId = 'ncor7c1m';
123123
static const String apiURL = 'https://mailosaur.com/api/messages';
124-
static const String mailosaurAPIKey = 'YOUR_API_KEY_HERE';
124+
static const String mailosaurAPIKey = "YOUR_MAILOSAUR_API_KEY";
125125

126126
static String appUrl(String path) {
127127
if (kIsWeb) {
@@ -131,7 +131,8 @@ class MailosaurAPIClient {
131131
}
132132

133133
static String get authHeader {
134-
const apiKey = 'api:$mailosaurAPIKey';
134+
const key = String.fromEnvironment("MAILOSAUR_API_KEY", defaultValue: mailosaurAPIKey);
135+
final apiKey = 'api:$key';
135136
final encodedApiKey = base64Encode(utf8.encode(apiKey));
136137
return 'Basic $encodedApiKey';
137138
}

integrationtestapp/integration_test/magic_link_test.dart

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import 'package:flutter/foundation.dart';
22
import 'package:flutter_test/flutter_test.dart';
33
import 'package:passage_flutter/passage_flutter.dart';
44
import 'package:passage_flutter/passage_flutter_models/passage_error.dart';
5-
import 'integration_test_config.dart';
6-
import 'mailosaur_api_client.dart';
7-
import 'platform_helper/platform_helper.dart';
5+
import 'helper/integration_test_config.dart';
6+
import 'helper/mailosaur_api_client.dart';
7+
import 'helper/platform_helper.dart';
8+
import 'package:integration_test/integration_test.dart';
89

910
void main() {
10-
PassageFlutter passage =
11-
PassageFlutter(IntegrationTestConfig.appIdMagicLink);
11+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
12+
PassageFlutter passage = PassageFlutter(IntegrationTestConfig.appIdMagicLink);
1213

13-
setUp(() async {
14+
setUpAll(() async {
1415
if (!kIsWeb) {
1516
String basePath = IntegrationTestConfig.apiBaseUrl;
1617
if (PlatformHelper.isAndroid) {
@@ -20,7 +21,7 @@ void main() {
2021
}
2122
});
2223

23-
tearDownAll(() async {
24+
tearDown(() async {
2425
try {
2526
await passage.signOut();
2627
} catch (e) {

integrationtestapp/integration_test/otp_test.dart

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import 'package:flutter/foundation.dart';
22
import 'package:flutter_test/flutter_test.dart';
33
import 'package:passage_flutter/passage_flutter.dart';
44
import 'package:passage_flutter/passage_flutter_models/passage_error.dart';
5-
import 'integration_test_config.dart';
6-
import 'mailosaur_api_client.dart';
7-
import 'platform_helper/platform_helper.dart';
5+
import 'helper/integration_test_config.dart';
6+
import 'helper/mailosaur_api_client.dart';
7+
import 'helper/platform_helper.dart';
8+
import 'package:integration_test/integration_test.dart';
89

910
void main() {
11+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
1012
PassageFlutter passage = PassageFlutter(IntegrationTestConfig.appIdOtp);
1113

1214
setUp(() async {
@@ -19,7 +21,7 @@ void main() {
1921
}
2022
});
2123

22-
tearDownAll(() async {
24+
tearDown(() async {
2325
try {
2426
await passage.signOut();
2527
} catch (e) {

integrationtestapp/integration_test/token_store_test.dart

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import 'package:flutter_test/flutter_test.dart';
22
import 'package:passage_flutter/passage_flutter.dart';
3-
import 'integration_test_config.dart';
4-
import 'mailosaur_api_client.dart';
3+
import 'helper/integration_test_config.dart';
4+
import 'helper/mailosaur_api_client.dart';
55
import 'package:flutter/foundation.dart';
6-
import 'platform_helper/platform_helper.dart';
6+
import 'helper/platform_helper.dart';
7+
import 'package:integration_test/integration_test.dart';
78

89
void main() {
9-
PassageFlutter passage =
10-
PassageFlutter(IntegrationTestConfig.appIdMagicLink);
10+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
11+
PassageFlutter passage = PassageFlutter(IntegrationTestConfig.appIdMagicLink);
1112

1213
setUp(() async {
1314
if (!kIsWeb) {
@@ -29,8 +30,8 @@ void main() {
2930

3031
Future<void> loginWithMagicLink() async {
3132
try {
32-
await passage.newLoginMagicLink(
33-
IntegrationTestConfig.existingUserEmailMagicLink);
33+
await passage
34+
.newLoginMagicLink(IntegrationTestConfig.existingUserEmailMagicLink);
3435
await Future.delayed(const Duration(
3536
milliseconds: IntegrationTestConfig.waitTimeMilliseconds));
3637
final magicLinkStr = await MailosaurAPIClient.getMostRecentMagicLink();

integrationtestapp/proxy-server/proxy_server.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ app.use((req, res, next) => {
1818
app.use(bodyParser.json());
1919
app.use(bodyParser.urlencoded({ extended: true }));
2020

21-
const mailosaurAPIKey = 'YOUR_API_KEY_HERE';
21+
const mailosaurAPIKey = process.env.MAILOSAUR_API_KEY || 'default_key';
2222

2323
// Proxy for Mailosaur API
2424
app.get('/api/messages', (req, res) => {
@@ -57,4 +57,4 @@ app.get('/api/messages/:id', (req, res) => {
5757

5858
app.listen(PORT, () => {
5959
console.log(`Proxy server running on http://localhost:${PORT}`);
60-
});
60+
});

0 commit comments

Comments
 (0)