Skip to content

Commit

Permalink
Migrate detox driver (#82)
Browse files Browse the repository at this point in the history
* chore: add an example application for mobile pilot testing

The app contains 3 screens: emoji game, colors game, assertions screen

* feat & test: create Detox driver and add suitable tests

- "Import" the driver from the Detox project
- Add Detox id injection
- Remove native matchers and clarify the importance of using "by id"
- Add prompt handler to the package
- Add Pilot tests for each screen

* chore: code review changes

* chore: delete redundant file promptHandler.js

* fix: resolve package-lock conflict

* fix: add lint configuration to detox package

* fix: lint fix

* fix: tsconfig fix

* refactor: remove rendundant ExampleApp duplication

* fix: make linter happy.

* fix: add type-check script to detox package.json
  • Loading branch information
LironMShemen authored Feb 18, 2025
1 parent f56d922 commit b754536
Show file tree
Hide file tree
Showing 74 changed files with 25,332 additions and 2,059 deletions.
2 changes: 2 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6,421 changes: 4,362 additions & 2,059 deletions package-lock.json

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions packages/drivers/detox/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
plugins: ['@typescript-eslint'],
env: {
node: true,
jest: true,
es6: true,
},
parserOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-console': 'off',
},
ignorePatterns: ['dist/', 'node_modules/', '*.js', 'ExampleApp/'],
};
2 changes: 2 additions & 0 deletions packages/drivers/detox/ExampleApp/.bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
83 changes: 83 additions & 0 deletions packages/drivers/detox/ExampleApp/.detoxrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/** @type {Detox.DetoxConfig} */
module.exports = {
testRunner: {
args: {
'$0': 'jest',
config: 'e2e/jest.config.js'
},
jest: {
setupTimeout: 120000
}
},
apps: {
'ios.debug': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/ExampleApp.app',
build: 'xcodebuild -workspace ios/ExampleApp.xcworkspace -scheme ExampleApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build'
},
'ios.release': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/ExampleApp.app',
build: 'xcodebuild -workspace ios/ExampleApp.xcworkspace -scheme ExampleApp -configuration Release -sdk iphonesimulator -derivedDataPath ios/build'
},
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
build: 'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
reversePorts: [
8081
]
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
build: 'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release'
}
},
devices: {
simulator: {
type: 'ios.simulator',
device: {
type: 'iPhone 15'
}
},
attached: {
type: 'android.attached',
device: {
adbName: '.*'
}
},
emulator: {
type: 'android.emulator',
device: {
avdName: 'Pixel_3a_API_30_x86'
}
}
},
configurations: {
'ios.sim.debug': {
device: 'simulator',
app: 'ios.debug'
},
'ios.sim.release': {
device: 'simulator',
app: 'ios.release'
},
'android.att.debug': {
device: 'attached',
app: 'android.debug'
},
'android.att.release': {
device: 'attached',
app: 'android.release'
},
'android.emu.debug': {
device: 'emulator',
app: 'android.debug'
},
'android.emu.release': {
device: 'emulator',
app: 'android.release'
}
}
};
4 changes: 4 additions & 0 deletions packages/drivers/detox/ExampleApp/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: '@react-native',
};
74 changes: 74 additions & 0 deletions packages/drivers/detox/ExampleApp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# OSX
#
.DS_Store

# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
**/.xcode.env.local

# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore

# node.js
#
node_modules/
npm-debug.log
yarn-error.log

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/

**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/screenshots
**/fastlane/test_output

# Bundle artifact
*.jsbundle

# Ruby / CocoaPods
**/Pods/
/vendor/bundle/

# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*

# testing
/coverage

# Yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
7 changes: 7 additions & 0 deletions packages/drivers/detox/ExampleApp/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
arrowParens: 'avoid',
bracketSameLine: true,
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
};
1 change: 1 addition & 0 deletions packages/drivers/detox/ExampleApp/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
51 changes: 51 additions & 0 deletions packages/drivers/detox/ExampleApp/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import { Pressable } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import EmojiGameScreen from './screens/EmojiGameScreen.tsx';
import ColorGameScreen from './screens/ColorGameScreen.tsx';
import AssertionsScreen from './screens/AssertionsScreen.tsx';
import { Home, Palette, TextQuote } from 'lucide-react-native';

const Tab = createBottomTabNavigator();

const App: React.FC = () => {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="EmojiGame"
component={EmojiGameScreen}
options={{
tabBarIcon: ({ color, size }) => <Home color={color} size={size} />,
title: 'Emoji Game',
tabBarButton: (props) => (
<Pressable {...props} testID="emoji-game-tab" />
)
}}
/>
<Tab.Screen
name="ColorGame"
component={ColorGameScreen}
options={{
tabBarIcon: ({ color, size }) => <Palette color={color} size={size} />,
title: 'Color Game'
}}
/>
<Tab.Screen
name="Assertions"
component={AssertionsScreen}
options={{
tabBarIcon: ({ color, size }) => <TextQuote color={color} size={size} />,
title: 'Assertions',
tabBarButton: (props) => (
<Pressable {...props} testID="assertions-tab" />
)
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
};

export default App;
9 changes: 9 additions & 0 deletions packages/drivers/detox/ExampleApp/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source 'https://rubygems.org'

# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"

# Exclude problematic versions of cocoapods and activesupport that causes build failures.
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
gem 'xcodeproj', '< 1.26.0'
79 changes: 79 additions & 0 deletions packages/drivers/detox/ExampleApp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).

# Getting Started

>**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding.
## Step 1: Start the Metro Server

First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native.

To start Metro, run the following command from the _root_ of your React Native project:

```bash
# using npm
npm start

# OR using Yarn
yarn start
```

## Step 2: Start your Application

Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app:

### For Android

```bash
# using npm
npm run android

# OR using Yarn
yarn android
```

### For iOS

```bash
# using npm
npm run ios

# OR using Yarn
yarn ios
```

If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly.

This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively.

## Step 3: Modifying your App

Now that you have successfully run the app, let's modify it.

1. Open `App.tsx` in your text editor of choice and edit some lines.
2. For **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Developer Menu** (<kbd>Ctrl</kbd> + <kbd>M</kbd> (on Window and Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (on macOS)) to see your changes!

For **iOS**: Hit <kbd>Cmd ⌘</kbd> + <kbd>R</kbd> in your iOS Simulator to reload the app and see your changes!

## Congratulations! :tada:

You've successfully run and modified your React Native App. :partying_face:

### Now what?

- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started).

# Troubleshooting

If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.

# Learn More

To learn more about React Native, take a look at the following resources:

- [React Native Website](https://reactnative.dev) - learn more about React Native.
- [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment.
- [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**.
- [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts.
- [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native.
17 changes: 17 additions & 0 deletions packages/drivers/detox/ExampleApp/__tests__/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @format
*/

import 'react-native';
import React from 'react';
import App from '../App';

// Note: import explicitly to use the types shipped with jest.
import {it} from '@jest/globals';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
renderer.create(<App />);
});
Loading

0 comments on commit b754536

Please sign in to comment.