Skip to content

Commit 3945676

Browse files
feat: add harness tests for turbo module
1 parent 9f36982 commit 3945676

21 files changed

Lines changed: 2482 additions & 30 deletions

.github/CI_DOCUMENTATION.md

Lines changed: 490 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/build-android.yml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ jobs:
2727
- name: Install NDK
2828
run: echo "y" | ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install "ndk;27.3.13750724"
2929

30+
- name: Cache Gradle
31+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
32+
with:
33+
path: |
34+
~/.gradle/caches
35+
~/.gradle/wrapper
36+
example/android/.gradle
37+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
38+
restore-keys: |
39+
${{ runner.os }}-gradle-
40+
3041
- name: Build with Gradle
3142
run: ./gradlew assembleDebug
32-
working-directory: example/android
43+
working-directory: example/android
44+
45+
- name: Upload APK artifact
46+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
47+
with:
48+
name: android-apk
49+
path: example/android/app/build/outputs/apk/debug/app-debug.apk
50+
retention-days: 1

.github/workflows/build-ios.yml

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@ jobs:
2323
with:
2424
ruby-version: '3.2'
2525
bundler-cache: true
26-
working-directory: example/ios
26+
working-directory: example
27+
28+
- name: Cache iOS build artifacts
29+
id: cache-ios-app
30+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
31+
with:
32+
path: example/ios/build/Build/Products/Debug-iphonesimulator/MendixNativeExample.app
33+
key: ios-app-${{ runner.os }}-${{ hashFiles('example/ios/Podfile.lock', 'example/ios/**/*.pbxproj', 'ios/**/*.swift', 'ios/**/*.h', 'ios/**/*.m', 'ios/**/*.mm') }}
2734

2835
- name: Cache CocoaPods
36+
if: steps.cache-ios-app.outputs.cache-hit != 'true'
2937
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
3038
with:
3139
path: |
@@ -37,12 +45,14 @@ jobs:
3745
${{ runner.os }}-pods-
3846
3947
- name: Install CocoaPods
40-
working-directory: example/ios
48+
if: steps.cache-ios-app.outputs.cache-hit != 'true'
49+
working-directory: example
4150
run: |
4251
bundle install
43-
bundle exec pod install
52+
cd ios && bundle exec pod install
4453
4554
- name: Build iOS example for simulator
55+
if: steps.cache-ios-app.outputs.cache-hit != 'true'
4656
working-directory: example/ios
4757
run: |
4858
xcodebuild \
@@ -52,6 +62,11 @@ jobs:
5262
-sdk iphonesimulator \
5363
-destination 'platform=iOS Simulator,name=iPhone 17,OS=latest' \
5464
-derivedDataPath build \
55-
CODE_SIGNING_ALLOWED=NO \
56-
CODE_SIGNING_REQUIRED=NO \
5765
build
66+
67+
- name: Upload iOS app artifact
68+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
69+
with:
70+
name: ios-app
71+
path: example/ios/build/Build/Products/Debug-iphonesimulator/MendixNativeExample.app
72+
retention-days: 1

.github/workflows/ci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,13 @@ jobs:
1717
name: Build iOS
1818
needs: lint
1919
uses: ./.github/workflows/build-ios.yml
20+
21+
test-android-harness:
22+
name: Test Android Harness
23+
needs: build-android
24+
uses: ./.github/workflows/test-android-harness.yml
25+
26+
test-ios-harness:
27+
name: Test iOS Harness
28+
needs: build-ios
29+
uses: ./.github/workflows/test-ios-harness.yml
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Test Android Harness
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
test-android-harness:
8+
name: Test Android Harness
9+
runs-on: ubuntu-latest
10+
timeout-minutes: 60
11+
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
15+
16+
- name: Setup Project
17+
uses: ./.github/actions/setup-node-yarn
18+
19+
- name: Setup Java
20+
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e
21+
with:
22+
distribution: 'zulu'
23+
java-version: '17'
24+
25+
- name: Setup Android SDK
26+
uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407
27+
28+
# Download pre-built APK from build job
29+
- name: Download APK artifact
30+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
31+
with:
32+
name: android-apk
33+
path: example/android/app/build/outputs/apk/debug/
34+
35+
# Use official React Native Harness action
36+
- name: Run React Native Harness Tests
37+
uses: callstackincubator/react-native-harness/actions/android@7c8f2d8da0b3e191fbdea4017d8532e47e7e9e65
38+
with:
39+
app: example/android/app/build/outputs/apk/debug/app-debug.apk
40+
runner: android
41+
projectRoot: example
42+
43+
- name: Upload Android test results
44+
if: always()
45+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
46+
with:
47+
name: android-harness-test-results
48+
path: |
49+
example/test-results/
50+
example/coverage/
51+
retention-days: 7
52+
53+
- name: Upload Android test logs
54+
if: failure()
55+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
56+
with:
57+
name: android-test-logs
58+
path: |
59+
example/android/app/build/outputs/logs/
60+
retention-days: 7
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Test iOS Harness
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
test-ios-harness:
8+
name: Test iOS Harness
9+
runs-on: macos-latest
10+
timeout-minutes: 60
11+
env:
12+
DEVELOPER_DIR: /Applications/Xcode_26.1.app/Contents/Developer
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
17+
18+
- name: Setup Project
19+
uses: ./.github/actions/setup-node-yarn
20+
21+
# Download pre-built iOS app from build job
22+
- name: Download iOS app artifact
23+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
24+
with:
25+
name: ios-app
26+
path: example/ios/build/Build/Products/Debug-iphonesimulator/
27+
28+
# Use official React Native Harness action
29+
- name: Run React Native Harness Tests
30+
uses: callstackincubator/react-native-harness/actions/ios@7c8f2d8da0b3e191fbdea4017d8532e47e7e9e65
31+
with:
32+
app: example/ios/build/Build/Products/Debug-iphonesimulator/MendixNativeExample.app
33+
runner: ios
34+
projectRoot: example
35+
36+
- name: Upload iOS test results
37+
if: always()
38+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
39+
with:
40+
name: ios-harness-test-results
41+
path: |
42+
example/test-results/
43+
example/coverage/
44+
retention-days: 7
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { describe, test, expect, beforeEach } from 'react-native-harness';
2+
import { NativeCookie } from 'mendix-native';
3+
4+
describe('NativeCookie', () => {
5+
describe('API surface', () => {
6+
test('should expose clearAll method', () => {
7+
expect(typeof NativeCookie.clearAll).toBe('function');
8+
});
9+
});
10+
11+
describe('clearAll', () => {
12+
test('should call clearAll without throwing', async () => {
13+
await expect(NativeCookie.clearAll()).resolves.not.toThrow();
14+
});
15+
16+
test('should return a Promise', () => {
17+
const result = NativeCookie.clearAll();
18+
expect(result).toBeInstanceOf(Promise);
19+
});
20+
21+
test('should resolve to undefined', async () => {
22+
const result = await NativeCookie.clearAll();
23+
expect(result).toBeOneOf([undefined, null]);
24+
});
25+
26+
test('should be callable multiple times', async () => {
27+
await NativeCookie.clearAll();
28+
await NativeCookie.clearAll();
29+
await NativeCookie.clearAll();
30+
31+
// Should not throw
32+
expect(true).toBe(true);
33+
});
34+
35+
test('should handle concurrent clearAll calls', async () => {
36+
const promises = [
37+
NativeCookie.clearAll(),
38+
NativeCookie.clearAll(),
39+
NativeCookie.clearAll(),
40+
];
41+
42+
await expect(Promise.all(promises)).resolves.not.toThrow();
43+
});
44+
});
45+
46+
describe('integration scenarios', () => {
47+
beforeEach(async () => {
48+
// Clear cookies before each test
49+
await NativeCookie.clearAll();
50+
});
51+
52+
test('should clear all cookies when called', async () => {
53+
// This test verifies that clearAll can be called successfully
54+
// The actual cookie clearing behavior would need to be tested
55+
// in an integration test with a real web view
56+
await expect(NativeCookie.clearAll()).resolves.not.toThrow();
57+
});
58+
59+
test('should work when no cookies exist', async () => {
60+
// Calling clearAll when there are no cookies should succeed
61+
await NativeCookie.clearAll();
62+
await expect(NativeCookie.clearAll()).resolves.not.toThrow();
63+
});
64+
});
65+
});

0 commit comments

Comments
 (0)