Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2934349
refactor: update test imports and assertions to use react-native-harness
chrispader Mar 19, 2026
8c50b48
Merge branch 'main' into feat/harness-tests
chrispader Jul 1, 2026
19de80a
chore: update bun.lock
chrispader Jul 1, 2026
1546cc8
Merge branch 'main' into feat/harness-tests
chrispader Jul 1, 2026
631c5aa
fix: workflows
chrispader Jul 1, 2026
23c0227
fix: ios workflow simulator device not found
chrispader Jul 1, 2026
b2c4ee0
fix: ios harness workflow
chrispader Jul 1, 2026
f4e3f59
fix: increase harness bridge timeout
chrispader Jul 1, 2026
1ee0620
fix: typeorm harness test
chrispader Jul 1, 2026
6adea18
chore: explicitly add `react-native-quick-base64` dependency
chrispader Jul 1, 2026
efa5a48
Merge branch 'main' into feat/harness-tests
chrispader Jul 1, 2026
6a9b789
Update bun.lock
chrispader Jul 1, 2026
789b001
feat: re-enable typeorm tests
chrispader Jul 1, 2026
d23390e
Update Podfile.lock
chrispader Jul 1, 2026
8aa023e
chore: bump `react-native-buffer`
chrispader Jul 2, 2026
db247cf
fix: add `rn-harness.config.mjs` to `tsconfig.js`
chrispader Jul 2, 2026
12aef6b
refactor: move test files and allow harness alongside mocha
chrispader Jul 2, 2026
0722448
Merge branch 'main' into feat/harness-tests
chrispader Jul 2, 2026
1afa297
chore: add new aliases to babel config
chrispader Jul 2, 2026
a5af1c5
fix: lint
chrispader Jul 2, 2026
893a9eb
chore: update harness sim iOS version
chrispader Jul 2, 2026
7ac430e
chore: add RNQuickCrypto
chrispader Jul 2, 2026
eaf5c8e
refactor: move harness tests into sub folder
chrispader Jul 2, 2026
5595105
fix: workflow file triggers test folder
chrispader Jul 2, 2026
a904af7
chore: add babel polyfills for RNQuickCrypto
chrispader Jul 2, 2026
a4fb941
fix: init quickcrypto in harness tests
chrispader Jul 2, 2026
9837845
chore: simplify harness workflows by using official gh action
chrispader Jul 2, 2026
6c88ff9
refactor: remove unused code in `metro.config.js`
chrispader Jul 2, 2026
b9a1a78
chore: update harness
chrispader Jul 2, 2026
b161c09
chore: downgrade android avd version
chrispader Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/test-harness-android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Test Harness Android

on:
pull_request:
paths:
- ".github/workflows/test-harness-android.yml"
- "example/android/**"
- "example/src/tests/**"
- "example/tests/**"
- "example/rn-harness.config.mjs"
- "example/jest.config.js"
- "package/cpp/**"
- "package/android/**"
- "**/bun.lock"
- "**/react-native.config.js"
- "**/nitro.json"

env:
TARGET_ANDROID_ARCH: x86_64

jobs:
test:
name: Harness Tests (Android)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2

- name: Setup JDK 17
uses: actions/setup-java@v5
with:
distribution: "zulu"
java-version: 17

- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Install dependencies (bun)
run: bun install

- name: Build Android app
working-directory: example/android
run: >-
./gradlew :app:assembleDebug --no-daemon
-PreactNativeArchitectures=${{ env.TARGET_ANDROID_ARCH }}

- name: Run react-native-harness on Android
uses: callstackincubator/react-native-harness@v1.2.0
with:
app: android/app/build/outputs/apk/debug/app-debug.apk
runner: android
projectRoot: example
packageManager: bun
cacheAvd: false
71 changes: 71 additions & 0 deletions .github/workflows/test-harness-ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Test Harness iOS

on:
pull_request:
paths:
- ".github/workflows/test-harness-ios.yml"
- "example/ios/**"
- "example/src/tests/**"
- "example/tests/**"
- "example/rn-harness.config.mjs"
- "example/jest.config.js"
- "package/cpp/**"
- "package/ios/**"
- "**/Podfile.lock"
- "**/*.podspec"
- "**/react-native.config.js"
- "**/nitro.json"
- "**/bun.lock"

jobs:
test:
name: Harness Tests (iOS)
runs-on: macOS-26
env:
IOS_SIMULATOR_NAME: iPhone 17 Pro
IOS_SIMULATOR_OS: "26.2"

steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2

- name: Install dependencies (bun)
run: bun install

- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.0
bundler-cache: true
working-directory: example

- name: Select Xcode 26.2
run: sudo xcode-select -s "/Applications/Xcode_26.2.app/Contents/Developer"

- name: Install Pods
working-directory: example
run: bun pods

- name: Build debug app
working-directory: example/ios
run: |
set -euo pipefail

xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace NitroSQLiteExample.xcworkspace \
-scheme NitroSQLiteExample \
-sdk iphonesimulator \
-configuration Debug \
-destination "generic/platform=iOS Simulator" \
build \
CODE_SIGNING_ALLOWED=NO

- name: Run react-native-harness on iOS
uses: callstackincubator/react-native-harness@v1.2.0
with:
app: ios/build/Build/Products/Debug-iphonesimulator/NitroSQLiteExample.app
runner: ios
projectRoot: example
packageManager: bun
500 changes: 374 additions & 126 deletions bun.lock

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion example/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ module.exports = {
extensions: ['.tsx', '.ts', '.js', '.json'],
alias: {
[pak.name]: path.join(__dirname, '../package', pak.source),
'stream': 'stream-browserify',
'crypto': 'react-native-quick-crypto',
'stream': 'readable-stream',
'buffer': 'react-native-quick-crypto',
'react-native-sqlite-storage': 'react-native-nitro-sqlite',
'^@/(.+)': './src/\\1',
'^@tests/(.+)': './tests/\\1',
},
},
],
Expand Down
61 changes: 61 additions & 0 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ PODS:
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- OpenSSL-Universal (3.6.2000)
- QuickCrypto (1.1.5):
- hermes-engine
- NitroModules
- OpenSSL-Universal (~> 3.6.2000)
- RCTRequired
- RCTTypeSafety
- React-callinvoker
- React-Core
- React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- RCTDeprecation (0.85.0-rc.0)
- RCTRequired (0.85.0-rc.0)
- RCTSwiftUI (0.85.0-rc.0)
Expand Down Expand Up @@ -1384,6 +1410,28 @@ PODS:
- React-RCTFBReactNativeSpec
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- react-native-quick-base64 (3.0.0):
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- react-native-safe-area-context (5.6.2):
- hermes-engine
- RCTRequired
Expand Down Expand Up @@ -1936,6 +1984,7 @@ DEPENDENCIES:
- FBLazyVector (from `../../node_modules/react-native/Libraries/FBLazyVector`)
- hermes-engine (from `../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- NitroModules (from `../../node_modules/react-native-nitro-modules`)
- QuickCrypto (from `../../node_modules/react-native-quick-crypto`)
- RCTDeprecation (from `../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
- RCTRequired (from `../../node_modules/react-native/Libraries/Required`)
- RCTSwiftUI (from `../../node_modules/react-native/ReactApple/RCTSwiftUI`)
Expand Down Expand Up @@ -1973,6 +2022,7 @@ DEPENDENCIES:
- React-logger (from `../../node_modules/react-native/ReactCommon/logger`)
- React-Mapbuffer (from `../../node_modules/react-native/ReactCommon`)
- React-microtasksnativemodule (from `../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
- react-native-quick-base64 (from `../../node_modules/react-native-quick-base64`)
- react-native-safe-area-context (from `../../node_modules/react-native-safe-area-context`)
- React-NativeModulesApple (from `../../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-networking (from `../../node_modules/react-native/ReactCommon/react/networking`)
Expand Down Expand Up @@ -2013,6 +2063,10 @@ DEPENDENCIES:
- RNScreens (from `../../node_modules/react-native-screens`)
- Yoga (from `../../node_modules/react-native/ReactCommon/yoga`)

SPEC REPOS:
trunk:
- OpenSSL-Universal

EXTERNAL SOURCES:
FBLazyVector:
:path: "../../node_modules/react-native/Libraries/FBLazyVector"
Expand All @@ -2021,6 +2075,8 @@ EXTERNAL SOURCES:
:tag: hermes-v250829098.0.10
NitroModules:
:path: "../../node_modules/react-native-nitro-modules"
QuickCrypto:
:path: "../../node_modules/react-native-quick-crypto"
RCTDeprecation:
:path: "../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
RCTRequired:
Expand Down Expand Up @@ -2093,6 +2149,8 @@ EXTERNAL SOURCES:
:path: "../../node_modules/react-native/ReactCommon"
React-microtasksnativemodule:
:path: "../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
react-native-quick-base64:
:path: "../../node_modules/react-native-quick-base64"
react-native-safe-area-context:
:path: "../../node_modules/react-native-safe-area-context"
React-NativeModulesApple:
Expand Down Expand Up @@ -2176,6 +2234,8 @@ SPEC CHECKSUMS:
FBLazyVector: 4ee5f665093abe339f4b579fc3d59f65c8af196c
hermes-engine: 56e1f8e0c324283e1cc2c35f56dc6037c141f67d
NitroModules: 587af3c2bc93f5c9f9b39aec315eb29509a7c537
OpenSSL-Universal: ecee7b138fa75a74ecf00d7ffd248fb584739b9e
QuickCrypto: 790e6537bb81a11d036a24ce3248b51f66857ceb
RCTDeprecation: b73940ea69ab57c2c59f845b37b09e1d8b0d0588
RCTRequired: f3a52c914af5f19f04d02b2091d83e43cf71676c
RCTSwiftUI: 6dea7b613e8930a973b723c121aa8646374ee694
Expand Down Expand Up @@ -2212,6 +2272,7 @@ SPEC CHECKSUMS:
React-logger: dbf8f36688ca7ccdb14cd2c2a9a738162fa87fbd
React-Mapbuffer: 82c344b9a3dc807a40aefece0714587be25d7718
React-microtasksnativemodule: c6299f5e04ba84779dc08f884caf8f42f370e9da
react-native-quick-base64: 740f0799082262a4f0a0001647288840bc54a3c4
react-native-safe-area-context: 4b3960e27c8a3ca0c1523348f97513e27f8509b7
React-NativeModulesApple: f8da6e477ffca7ad38869d16d7fd0b4289771f6a
React-networking: 3b027fd335be928ee4ac5172937fe96729a6eb27
Expand Down
9 changes: 9 additions & 0 deletions example/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
projects: [
{
displayName: 'react-native-harness',
preset: 'react-native-harness',
testMatch: ['**/tests/**/*.harness.(js|jsx|ts|tsx)'],
},
],
}
29 changes: 0 additions & 29 deletions example/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
const fs = require('fs')
const path = require('path')
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
const pak = require('../package.json')

const root = path.resolve(__dirname, '..')
const modules = Object.keys({ ...pak.peerDependencies })

function getPackageNames(nodeModulesPath) {
if (!fs.existsSync(nodeModulesPath)) {
return []
}

const allFiles = fs.readdirSync(nodeModulesPath)

// Filter out only directories (package names)
const packageNames = allFiles.filter((file) => {
const filePath = path.join(nodeModulesPath, file)
return fs.statSync(filePath).isDirectory()
})

// Handle scoped packages (e.g., @scope/package)
const scopedPackages = packageNames
.filter((pkg) => pkg.startsWith('@'))
.flatMap((scope) => {
const scopePath = path.join(nodeModulesPath, scope)
const scopedFiles = fs.readdirSync(scopePath)
return scopedFiles.map((scopedFile) => `${scope}/${scopedFile}`)
})

// Return both regular and scoped package names
return packageNames
.filter((pkg) => !pkg.startsWith('@'))
.concat(scopedPackages)
}

const config = {
projectRoot: __dirname,
watchFolders: [root],
Expand Down
14 changes: 12 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
"pods": "cd ios && bundle exec pod install",
"typecheck": "tsc --noEmit",
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
"codegen": "bun react-native codegen"
"codegen": "bun react-native codegen",
"test:harness": "react-native-harness",
"test:harness:android": "react-native-harness --harnessRunner android",
"test:harness:ios": "react-native-harness --harnessRunner ios"
},
"dependencies": {
"@craftzdog/react-native-buffer": "^6.0.5",
"@craftzdog/react-native-buffer": "^6.1.2",
"@react-native-clipboard/clipboard": "^1.16.3",
"@react-navigation/native": "^7.1.19",
"@react-navigation/native-stack": "^7.6.2",
Expand All @@ -25,6 +28,8 @@
"react-native": "0.85.0-rc.0",
"react-native-nitro-modules": "*",
"react-native-nitro-sqlite": "9.6.0",
"react-native-quick-base64": "^3.0.0",
"react-native-quick-crypto": "^1.1.5",
"react-native-safe-area-context": "^5.5.2",
"react-native-screens": "^4.18.0",
"reflect-metadata": "^0.1.13",
Expand All @@ -50,6 +55,11 @@
"@types/node": "^22.7.4",
"@types/react": "^19.1.1",
"@types/react-test-renderer": "^19.1.0",
"@react-native-harness/cli": "1.2.0",
"@react-native-harness/jest": "1.2.0",
"@react-native-harness/platform-android": "1.2.0",
"@react-native-harness/platform-apple": "1.2.0",
"react-native-harness": "1.2.0",
"mocha": "^10.1.0",
"postinstall-postinstall": "^2.1.0",
"react-test-renderer": "19.1.1"
Expand Down
Loading
Loading