feat(core): add react native to main repo (#6493)

This commit is contained in:
Emily Xiong 2021-08-25 15:54:23 -04:00 committed by GitHub
parent 5ff55ced15
commit 387af0cf3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
271 changed files with 11693 additions and 9 deletions

View File

@ -44,6 +44,7 @@ jobs:
- e2e-web - e2e-web
- e2e-storybook - e2e-storybook
- e2e-workspace - e2e-workspace
- e2e-react-native,e2e-detox
exclude: exclude:
- os: ubuntu-latest - os: ubuntu-latest
node_version: '14' node_version: '14'
@ -121,6 +122,13 @@ jobs:
with: with:
version: 6.9.1 version: 6.9.1
- name: Install applesimutils, reset ios simulators
if: ${{ matrix.os == 'macos-latest' }}
run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
brew install applesimutils
xcrun simctl shutdown all && xcrun simctl erase all
- name: Run e2e tests - name: Run e2e tests
run: yarn nx run-many --target=e2e --projects="${{ join(matrix.packages) }}" run: yarn nx run-many --target=e2e --projects="${{ join(matrix.packages) }}"
env: env:

2
.gitignore vendored
View File

@ -4,7 +4,7 @@ node_modules
dist dist
/build /build
/coverage /coverage
test ./test
.DS_Store .DS_Store
tmp tmp
*.log *.log

View File

@ -0,0 +1,23 @@
# @nrwl/detox:build
Run the command defined in build property of the specified configuration.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### configPath
Alias(es): cp
Type: `string`
Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or "detox" section in package.json
### detoxConfiguration
Alias(es): C
Type: `string`
Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it

View File

@ -0,0 +1,177 @@
# @nrwl/detox:test
Initiating your detox test suite.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### appLaunchArgs
Type: `number`
Custom arguments to pass (through) onto the app every time it is launched.
### artifactsLocation
Alias(es): a
Type: `string`
Artifacts (logs, screenshots, etc) root directory.
### captureViewHierarchy
Type: `string`
[iOS Only] Capture \*.uihierarchy snapshots on view action errors and device.captureViewHierarchy() calls.
### cleanup
Type: `boolean`
Shutdown simulator when test is over, useful for CI scripts, to make sure detox exists cleanly with no residue
### configPath
Alias(es): cp
Type: `string`
Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or "detox" section in package.json
### debugSynchronization
Alias(es): d
Type: `string`
Customize how long an action/expectation can take to complete before Detox starts querying the app why it is busy. By default, the app status will be printed if the action takes more than 10s to complete.
### detoxConfiguration
Alias(es): C
Type: `string`
Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it
### deviceLaunchArgs
Type: `string`
A list of passthrough-arguments to use when (if) devices (Android emulator / iOS simulator) are launched by Detox.
### deviceName
Alias(es): n
Type: `string`
Override the device name specified in a configuration. Useful for running a single build configuration on multiple devices.
### forceAdbInstall
Type: `boolean`
Due to problems with the adb install command on Android, Detox resorts to a different scheme for install APK's. Setting true will disable that and force usage of adb install, instead.
### gpu
Type: `boolean`
[Android Only] Launch Emulator with the specific -gpu [gpu mode] parameter.
### headless
Type: `boolean`
Android Only] Launch Emulator in headless mode. Useful when running on CI.
### inspectBrk
Type: `boolean`
Uses node's --inspect-brk flag to let users debug the jest/mocha test runner
### jestReportSpecs
Type: `boolean`
[Jest Only] Whether to output logs per each running spec, in real-time. By default, disabled with multiple workers.
### loglevel
Alias(es): l
Type: `string`
Log level: fatal, error, warn, info, verbose, trace
### noColor
Type: `boolean`
Disable colors in log output
### recordLogs
Type: `string`
Save logs during each test to artifacts directory. Pass "failing" to save logs of failing tests only.
### recordPerformance
Type: `string`
[iOS Only] Save Detox Instruments performance recordings of each test to artifacts directory.
### recordTimeline
Type: `string`
[Jest Only] Record tests and events timeline, for visual display on the chrome://tracing tool.
### recordVideos
Type: `string`
Save screen recordings of each test to artifacts directory. Pass "failing" to save recordings of failing tests only.
### retries
Type: `number`
[Jest Circus Only] Re-spawn the test runner for individual failing suite files until they pass, or <N> times at least.
### reuse
Type: `boolean`
Reuse existing installed app (do not delete + reinstall) for a faster run.
### runnerConfig
Alias(es): o
Type: `string`
Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest.
### takeScreenshots
Type: `string`
Save screenshots before and after each test to artifacts directory. Pass "failing" to save screenshots of failing tests only.
### useCustomLogger
Type: `boolean`
Use Detox' custom console-logging implementation, for logging Detox (non-device) logs. Disabling will fallback to node.js / test-runner's implementation (e.g. Jest / Mocha).
### workers
Type: `number`
Specifies number of workers the test runner should spawn, requires a test runner with parallel execution support (Detox CLI currently supports Jest).

View File

@ -0,0 +1,81 @@
# @nrwl/detox:application
Create a detox application
## Usage
```bash
nx generate application ...
```
```bash
nx g app ... # same
```
By default, Nx will search for `application` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/detox:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
## Options
### name (_**required**_)
Type: `string`
Name of the E2E Project
### project (_**required**_)
Type: `string`
The name of the frontend project to test.
### directory
Type: `string`
A directory where the project is placed
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`, `none`
The tool to use for running lint checks.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files

View File

@ -0,0 +1,13 @@
# @nrwl/react-native:build-android
Release Build for Android.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### apk
Type: `boolean`
Generate apk file(s) rather than a bundle (.aab).

View File

@ -0,0 +1,45 @@
# @nrwl/react-native:bundle
Builds the JS bundle.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### bundleOutput (_**required**_)
Type: `string`
The output path of the generated files.
### entryFile (_**required**_)
Type: `string`
The entry file relative to project root.
### platform (_**required**_)
Type: `string`
Platform to build for (ios, android).
### dev
Default: `true`
Type: `boolean`
Generate a development build.
### maxWorkers
Type: `number`
The number of workers we should parallelize the transformer on.
### sourceMap
Type: `boolean`
Whether source maps should be generated or not.

View File

@ -0,0 +1,5 @@
# @nrwl/react-native:ensure-symlink
Ensure workspace node_modules is symlink under app's node_modules folder.
Options can be configured in `angular.json` when defining the executor, or when invoking it.

View File

@ -0,0 +1,85 @@
# @nrwl/react-native:run-android
Runs Android application.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### appId
Type: `string`
Specify an applicationId to launch after build. If not specified, 'package' from AndroidManifest.xml will be used.
### appIdSuffix
Type: `string`
Specify an applicationIdSuffix to launch after build.
### deviceId
Type: `string`
Builds your app and starts it on a specific device/simulator with the given device id (listed by running "adb devices" on the command line).
### jetifier
Default: `true`
Type: `boolean`
Run jetifier the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don't support AndroidX yet.
### mainActivity
Default: `MainActivity`
Type: `string`
Name of the activity to start.
### packager
Default: `true`
Type: `boolean`
Starts the packager server
### port
Default: `8081`
Type: `number`
The port where the packager server is listening on.
### sync
Default: `true`
Type: `boolean`
Syncs npm dependencies to package.json (for React Native autolink).
### tasks
Type: `string`
Run custom gradle tasks. If this argument is provided, then --variant option is ignored. Example: yarn react-native run-android --tasks clean,installDebug.
### terminal
Type: `string`
Launches the Metro Bundler in a new window using the specified terminal path.
### variant
Default: `debug`
Type: `string`
Specify your app's build variant (e.g. debug, release).

View File

@ -0,0 +1,73 @@
# @nrwl/react-native:run-ios
Runs iOS application.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### device
Type: `string`
Explicitly set device to use by name. The value is not required if you have a single device connected.
### install
Default: `true`
Type: `boolean`
Runs 'pod install' for native modules before building iOS app.
### packager
Default: `true`
Type: `boolean`
Starts the packager server
### port
Default: `8081`
Type: `number`
The port where the packager server is listening on.
### scheme
Type: `string`
Explicitly set the Xcode scheme to use
### simulator
Default: `iPhone X`
Type: `string`
Explicitly set simulator to use. Optionally include iOS version between parenthesis at the end to match an exact version: "iPhone X (12.1)"
### sync
Default: `true`
Type: `boolean`
Syncs npm dependencies to package.json (for React Native autolink). Always true when --install is used.
### terminal
Type: `string`
Launches the Metro Bundler in a new window using the specified terminal path.
### xcodeConfiguration
Default: `Debug`
Type: `string`
Explicitly set the Xcode configuration to use

View File

@ -0,0 +1,23 @@
# @nrwl/react-native:start
Starts the dev server for JS bundle.
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### port
Default: `8081`
Type: `number`
The port to listen on.
### resetCache
Default: `false`
Type: `boolean`
Resets metro cache.

View File

@ -0,0 +1,13 @@
# @nrwl/react-native:sync-deps
Syncs dependencies to package.json (required for autolinking).
Options can be configured in `angular.json` when defining the executor, or when invoking it.
## Options
### include
Type: `string`
A comma-separated list of additional npm packages to include. e.g. 'nx sync-deps --include=react-native-gesture-handler,react-native-safe-area-context'

View File

@ -0,0 +1,125 @@
# @nrwl/react-native:application
Create an application
## Usage
```bash
nx generate application ...
```
```bash
nx g app ... # same
```
By default, Nx will search for `application` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
### Examples
Generate apps/nested/myapp:
```bash
nx g app myapp --directory=nested
```
Use class components instead of functional components:
```bash
nx g app myapp --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
The directory of the new application.
### displayName
Type: `string`
The display name to show in the application. Defaults to name.
### e2eTestRunner
Default: `detox`
Type: `string`
Possible values: `detox`, `none`
Adds the specified e2e test runner
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`
The tool to use for running lint checks.
### name
Type: `string`
The name of the application.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files
### tags
Alias(es): t
Type: `string`
Add tags to the application (used for linting)
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests

View File

@ -0,0 +1,119 @@
# @nrwl/react-native:component
Create a component
## Usage
```bash
nx generate component ...
```
```bash
nx g c ... # same
```
By default, Nx will search for `component` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:component ...
```
Show what will be generated without writing to disk:
```bash
nx g component ... --dry-run
```
### Examples
Generate a component in the mylib library:
```bash
nx g component my-component --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g component my-component --project=mylib --classComponent
```
## Options
### name (_**required**_)
Type: `string`
The name of the component.
### project (_**required**_)
Alias(es): p
Type: `string`
The name of the project.
### classComponent
Alias(es): C
Default: `false`
Type: `boolean`
Use class components instead of functional component.
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### pascalCaseFiles
Alias(es): P
Default: `false`
Type: `boolean`
Use pascal case component file name (e.g. App.tsx).
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.

View File

@ -0,0 +1,157 @@
# @nrwl/react-native:library
Create a library
## Usage
```bash
nx generate library ...
```
```bash
nx g lib ... # same
```
By default, Nx will search for `library` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:library ...
```
Show what will be generated without writing to disk:
```bash
nx g library ... --dry-run
```
### Examples
Generate libs/myapp/mylib:
```bash
nx g lib mylib --directory=myapp
```
## Options
### name (_**required**_)
Type: `string`
Library name
### buildable
Default: `false`
Type: `boolean`
Generate a buildable library.
### directory
Alias(es): d
Type: `string`
A directory where the lib is placed.
### globalCss
Default: `false`
Type: `boolean`
When true, the stylesheet is generated using global CSS instead of CSS modules (e.g. file is '_.css' rather than '_.module.css').
### importPath
Type: `string`
The library name used to import it, like @myorg/my-awesome-lib
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`
The tool to use for running lint checks.
### pascalCaseFiles
Alias(es): P
Default: `false`
Type: `boolean`
Use pascal case component file name (e.g. App.tsx).
### publishable
Type: `boolean`
Create a publishable library.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files.
### skipTsConfig
Default: `false`
Type: `boolean`
Do not update tsconfig.json for development experience.
### strict
Default: `true`
Type: `boolean`
Whether to enable tsconfig strict mode or not.
### tags
Alias(es): t
Type: `string`
Add tags to the library (used for linting).
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests.

View File

@ -1,12 +1,14 @@
[ [
"angular", "angular",
"cypress", "cypress",
"detox",
"gatsby", "gatsby",
"jest", "jest",
"linter", "linter",
"next", "next",
"node", "node",
"nx-plugin", "nx-plugin",
"react-native",
"storybook", "storybook",
"web", "web",
"workspace" "workspace"

View File

@ -1,6 +1,7 @@
[ [
"angular", "angular",
"cypress", "cypress",
"detox",
"express", "express",
"gatsby", "gatsby",
"jest", "jest",
@ -9,6 +10,7 @@
"node", "node",
"nx-plugin", "nx-plugin",
"react", "react",
"react-native",
"storybook", "storybook",
"web", "web",
"workspace" "workspace"

View File

@ -908,6 +908,83 @@
} }
] ]
}, },
{
"name": "detox",
"id": "detox",
"itemList": [
{
"name": "application generator",
"id": "application",
"file": "angular/api-detox/generators/application"
},
{
"name": "build executor",
"id": "build",
"file": "angular/api-detox/executors/build"
},
{
"name": "test executor",
"id": "test",
"file": "angular/api-detox/executors/test"
}
]
},
{
"name": "react native",
"id": "react-native",
"itemList": [
{
"name": "application generator",
"id": "application",
"file": "angular/api-react-native/generators/application"
},
{
"name": "component generator",
"id": "component",
"file": "angular/api-react-native/generators/component"
},
{
"name": "library generator",
"id": "library",
"file": "angular/api-react-native/generators/library"
},
{
"name": "build android executor",
"id": "build-android",
"file": "angular/api-react-native/executors/build-android"
},
{
"name": "bundle executor",
"id": "bundle",
"file": "angular/api-react-native/executors/bundle"
},
{
"name": "ensure symlink executor",
"id": "ensure-symlink",
"file": "angular/api-react-native/executors/ensure-symlink"
},
{
"name": "run android executor",
"id": "run-android",
"file": "angular/api-react-native/executors/run-android"
},
{
"name": "run ios executor",
"id": "run-ios",
"file": "angular/api-react-native/executors/run-ios"
},
{
"name": "start executor",
"id": "start",
"file": "angular/api-react-native/executors/start"
},
{
"name": "sync deps executor",
"id": "sync-deps",
"file": "angular/api-react-native/executors/sync-deps"
}
]
},
{ {
"name": "Nx Plugin", "name": "Nx Plugin",
"id": "nx-plugin", "id": "nx-plugin",
@ -2120,6 +2197,104 @@
} }
] ]
}, },
{
"name": "detox",
"id": "detox",
"itemList": [
{
"name": "application generator",
"id": "application",
"file": "react/api-detox/generators/application"
},
{
"name": "build executor",
"id": "build",
"file": "react/api-detox/executors/build"
},
{
"name": "test executor",
"id": "test",
"file": "react/api-detox/executors/test"
}
]
},
{
"name": "detox",
"id": "detox",
"itemList": [
{
"name": "application generator",
"id": "application",
"file": "node/api-detox/generators/application"
},
{
"name": "build executor",
"id": "build",
"file": "node/api-detox/executors/build"
},
{
"name": "test executor",
"id": "test",
"file": "node/api-detox/executors/test"
}
]
},
{
"name": "react native",
"id": "react-native",
"itemList": [
{
"name": "application generator",
"id": "application",
"file": "react/api-react-native/generators/application"
},
{
"name": "component generator",
"id": "component",
"file": "react/api-react-native/generators/component"
},
{
"name": "library generator",
"id": "library",
"file": "react/api-react-native/generators/library"
},
{
"name": "build android executor",
"id": "build-android",
"file": "react/api-react-native/executors/build-android"
},
{
"name": "bundle executor",
"id": "bundle",
"file": "react/api-react-native/executors/bundle"
},
{
"name": "ensure symlink executor",
"id": "ensure-symlink",
"file": "react/api-react-native/executors/ensure-symlink"
},
{
"name": "run android executor",
"id": "run-android",
"file": "react/api-react-native/executors/run-android"
},
{
"name": "run ios executor",
"id": "run-ios",
"file": "react/api-react-native/executors/run-ios"
},
{
"name": "start executor",
"id": "start",
"file": "react/api-react-native/executors/start"
},
{
"name": "sync deps executor",
"id": "sync-deps",
"file": "react/api-react-native/executors/sync-deps"
}
]
},
{ {
"name": "Nx Plugin", "name": "Nx Plugin",
"id": "nx-plugin", "id": "nx-plugin",
@ -3273,6 +3448,62 @@
} }
] ]
}, },
{
"name": "react native",
"id": "react-native",
"itemList": [
{
"name": "application generator",
"id": "application",
"file": "node/api-react-native/generators/application"
},
{
"name": "component generator",
"id": "component",
"file": "node/api-react-native/generators/component"
},
{
"name": "library generator",
"id": "library",
"file": "node/api-react-native/generators/library"
},
{
"name": "build android executor",
"id": "build-android",
"file": "node/api-react-native/executors/build-android"
},
{
"name": "bundle executor",
"id": "bundle",
"file": "node/api-react-native/executors/bundle"
},
{
"name": "ensure symlink executor",
"id": "ensure-symlink",
"file": "node/api-react-native/executors/ensure-symlink"
},
{
"name": "run android executor",
"id": "run-android",
"file": "node/api-react-native/executors/run-android"
},
{
"name": "run ios executor",
"id": "run-ios",
"file": "node/api-react-native/executors/run-ios"
},
{
"name": "start executor",
"id": "start",
"file": "node/api-react-native/executors/start"
},
{
"name": "sync deps executor",
"id": "sync-deps",
"file": "node/api-react-native/executors/sync-deps"
}
]
},
{ {
"name": "Nx Plugin", "name": "Nx Plugin",
"id": "nx-plugin", "id": "nx-plugin",

View File

@ -0,0 +1,24 @@
# @nrwl/detox:build
Run the command defined in build property of the specified configuration.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### configPath
Alias(es): cp
Type: `string`
Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or "detox" section in package.json
### detoxConfiguration
Alias(es): C
Type: `string`
Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it

View File

@ -0,0 +1,178 @@
# @nrwl/detox:test
Initiating your detox test suite.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### appLaunchArgs
Type: `number`
Custom arguments to pass (through) onto the app every time it is launched.
### artifactsLocation
Alias(es): a
Type: `string`
Artifacts (logs, screenshots, etc) root directory.
### captureViewHierarchy
Type: `string`
[iOS Only] Capture \*.uihierarchy snapshots on view action errors and device.captureViewHierarchy() calls.
### cleanup
Type: `boolean`
Shutdown simulator when test is over, useful for CI scripts, to make sure detox exists cleanly with no residue
### configPath
Alias(es): cp
Type: `string`
Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or "detox" section in package.json
### debugSynchronization
Alias(es): d
Type: `string`
Customize how long an action/expectation can take to complete before Detox starts querying the app why it is busy. By default, the app status will be printed if the action takes more than 10s to complete.
### detoxConfiguration
Alias(es): C
Type: `string`
Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it
### deviceLaunchArgs
Type: `string`
A list of passthrough-arguments to use when (if) devices (Android emulator / iOS simulator) are launched by Detox.
### deviceName
Alias(es): n
Type: `string`
Override the device name specified in a configuration. Useful for running a single build configuration on multiple devices.
### forceAdbInstall
Type: `boolean`
Due to problems with the adb install command on Android, Detox resorts to a different scheme for install APK's. Setting true will disable that and force usage of adb install, instead.
### gpu
Type: `boolean`
[Android Only] Launch Emulator with the specific -gpu [gpu mode] parameter.
### headless
Type: `boolean`
Android Only] Launch Emulator in headless mode. Useful when running on CI.
### inspectBrk
Type: `boolean`
Uses node's --inspect-brk flag to let users debug the jest/mocha test runner
### jestReportSpecs
Type: `boolean`
[Jest Only] Whether to output logs per each running spec, in real-time. By default, disabled with multiple workers.
### loglevel
Alias(es): l
Type: `string`
Log level: fatal, error, warn, info, verbose, trace
### noColor
Type: `boolean`
Disable colors in log output
### recordLogs
Type: `string`
Save logs during each test to artifacts directory. Pass "failing" to save logs of failing tests only.
### recordPerformance
Type: `string`
[iOS Only] Save Detox Instruments performance recordings of each test to artifacts directory.
### recordTimeline
Type: `string`
[Jest Only] Record tests and events timeline, for visual display on the chrome://tracing tool.
### recordVideos
Type: `string`
Save screen recordings of each test to artifacts directory. Pass "failing" to save recordings of failing tests only.
### retries
Type: `number`
[Jest Circus Only] Re-spawn the test runner for individual failing suite files until they pass, or <N> times at least.
### reuse
Type: `boolean`
Reuse existing installed app (do not delete + reinstall) for a faster run.
### runnerConfig
Alias(es): o
Type: `string`
Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest.
### takeScreenshots
Type: `string`
Save screenshots before and after each test to artifacts directory. Pass "failing" to save screenshots of failing tests only.
### useCustomLogger
Type: `boolean`
Use Detox' custom console-logging implementation, for logging Detox (non-device) logs. Disabling will fallback to node.js / test-runner's implementation (e.g. Jest / Mocha).
### workers
Type: `number`
Specifies number of workers the test runner should spawn, requires a test runner with parallel execution support (Detox CLI currently supports Jest).

View File

@ -0,0 +1,81 @@
# @nrwl/detox:application
Create a detox application
## Usage
```bash
nx generate application ...
```
```bash
nx g app ... # same
```
By default, Nx will search for `application` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/detox:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
## Options
### name (_**required**_)
Type: `string`
Name of the E2E Project
### project (_**required**_)
Type: `string`
The name of the frontend project to test.
### directory
Type: `string`
A directory where the project is placed
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`, `none`
The tool to use for running lint checks.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files

View File

@ -0,0 +1,14 @@
# @nrwl/react-native:build-android
Release Build for Android.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### apk
Type: `boolean`
Generate apk file(s) rather than a bundle (.aab).

View File

@ -0,0 +1,46 @@
# @nrwl/react-native:bundle
Builds the JS bundle.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### bundleOutput (_**required**_)
Type: `string`
The output path of the generated files.
### entryFile (_**required**_)
Type: `string`
The entry file relative to project root.
### platform (_**required**_)
Type: `string`
Platform to build for (ios, android).
### dev
Default: `true`
Type: `boolean`
Generate a development build.
### maxWorkers
Type: `number`
The number of workers we should parallelize the transformer on.
### sourceMap
Type: `boolean`
Whether source maps should be generated or not.

View File

@ -0,0 +1,6 @@
# @nrwl/react-native:ensure-symlink
Ensure workspace node_modules is symlink under app's node_modules folder.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.

View File

@ -0,0 +1,86 @@
# @nrwl/react-native:run-android
Runs Android application.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### appId
Type: `string`
Specify an applicationId to launch after build. If not specified, 'package' from AndroidManifest.xml will be used.
### appIdSuffix
Type: `string`
Specify an applicationIdSuffix to launch after build.
### deviceId
Type: `string`
Builds your app and starts it on a specific device/simulator with the given device id (listed by running "adb devices" on the command line).
### jetifier
Default: `true`
Type: `boolean`
Run jetifier the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don't support AndroidX yet.
### mainActivity
Default: `MainActivity`
Type: `string`
Name of the activity to start.
### packager
Default: `true`
Type: `boolean`
Starts the packager server
### port
Default: `8081`
Type: `number`
The port where the packager server is listening on.
### sync
Default: `true`
Type: `boolean`
Syncs npm dependencies to package.json (for React Native autolink).
### tasks
Type: `string`
Run custom gradle tasks. If this argument is provided, then --variant option is ignored. Example: yarn react-native run-android --tasks clean,installDebug.
### terminal
Type: `string`
Launches the Metro Bundler in a new window using the specified terminal path.
### variant
Default: `debug`
Type: `string`
Specify your app's build variant (e.g. debug, release).

View File

@ -0,0 +1,74 @@
# @nrwl/react-native:run-ios
Runs iOS application.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### device
Type: `string`
Explicitly set device to use by name. The value is not required if you have a single device connected.
### install
Default: `true`
Type: `boolean`
Runs 'pod install' for native modules before building iOS app.
### packager
Default: `true`
Type: `boolean`
Starts the packager server
### port
Default: `8081`
Type: `number`
The port where the packager server is listening on.
### scheme
Type: `string`
Explicitly set the Xcode scheme to use
### simulator
Default: `iPhone X`
Type: `string`
Explicitly set simulator to use. Optionally include iOS version between parenthesis at the end to match an exact version: "iPhone X (12.1)"
### sync
Default: `true`
Type: `boolean`
Syncs npm dependencies to package.json (for React Native autolink). Always true when --install is used.
### terminal
Type: `string`
Launches the Metro Bundler in a new window using the specified terminal path.
### xcodeConfiguration
Default: `Debug`
Type: `string`
Explicitly set the Xcode configuration to use

View File

@ -0,0 +1,24 @@
# @nrwl/react-native:start
Starts the dev server for JS bundle.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### port
Default: `8081`
Type: `number`
The port to listen on.
### resetCache
Default: `false`
Type: `boolean`
Resets metro cache.

View File

@ -0,0 +1,14 @@
# @nrwl/react-native:sync-deps
Syncs dependencies to package.json (required for autolinking).
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### include
Type: `string`
A comma-separated list of additional npm packages to include. e.g. 'nx sync-deps --include=react-native-gesture-handler,react-native-safe-area-context'

View File

@ -0,0 +1,125 @@
# @nrwl/react-native:application
Create an application
## Usage
```bash
nx generate application ...
```
```bash
nx g app ... # same
```
By default, Nx will search for `application` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
### Examples
Generate apps/nested/myapp:
```bash
nx g app myapp --directory=nested
```
Use class components instead of functional components:
```bash
nx g app myapp --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
The directory of the new application.
### displayName
Type: `string`
The display name to show in the application. Defaults to name.
### e2eTestRunner
Default: `detox`
Type: `string`
Possible values: `detox`, `none`
Adds the specified e2e test runner
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`
The tool to use for running lint checks.
### name
Type: `string`
The name of the application.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files
### tags
Alias(es): t
Type: `string`
Add tags to the application (used for linting)
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests

View File

@ -0,0 +1,119 @@
# @nrwl/react-native:component
Create a component
## Usage
```bash
nx generate component ...
```
```bash
nx g c ... # same
```
By default, Nx will search for `component` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:component ...
```
Show what will be generated without writing to disk:
```bash
nx g component ... --dry-run
```
### Examples
Generate a component in the mylib library:
```bash
nx g component my-component --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g component my-component --project=mylib --classComponent
```
## Options
### name (_**required**_)
Type: `string`
The name of the component.
### project (_**required**_)
Alias(es): p
Type: `string`
The name of the project.
### classComponent
Alias(es): C
Default: `false`
Type: `boolean`
Use class components instead of functional component.
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### pascalCaseFiles
Alias(es): P
Default: `false`
Type: `boolean`
Use pascal case component file name (e.g. App.tsx).
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.

View File

@ -0,0 +1,157 @@
# @nrwl/react-native:library
Create a library
## Usage
```bash
nx generate library ...
```
```bash
nx g lib ... # same
```
By default, Nx will search for `library` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:library ...
```
Show what will be generated without writing to disk:
```bash
nx g library ... --dry-run
```
### Examples
Generate libs/myapp/mylib:
```bash
nx g lib mylib --directory=myapp
```
## Options
### name (_**required**_)
Type: `string`
Library name
### buildable
Default: `false`
Type: `boolean`
Generate a buildable library.
### directory
Alias(es): d
Type: `string`
A directory where the lib is placed.
### globalCss
Default: `false`
Type: `boolean`
When true, the stylesheet is generated using global CSS instead of CSS modules (e.g. file is '_.css' rather than '_.module.css').
### importPath
Type: `string`
The library name used to import it, like @myorg/my-awesome-lib
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`
The tool to use for running lint checks.
### pascalCaseFiles
Alias(es): P
Default: `false`
Type: `boolean`
Use pascal case component file name (e.g. App.tsx).
### publishable
Type: `boolean`
Create a publishable library.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files.
### skipTsConfig
Default: `false`
Type: `boolean`
Do not update tsconfig.json for development experience.
### strict
Default: `true`
Type: `boolean`
Whether to enable tsconfig strict mode or not.
### tags
Alias(es): t
Type: `string`
Add tags to the library (used for linting).
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests.

View File

@ -1,12 +1,14 @@
[ [
"angular", "angular",
"cypress", "cypress",
"detox",
"gatsby", "gatsby",
"jest", "jest",
"linter", "linter",
"next", "next",
"node", "node",
"nx-plugin", "nx-plugin",
"react-native",
"storybook", "storybook",
"web", "web",
"workspace" "workspace"

View File

@ -1,6 +1,7 @@
[ [
"angular", "angular",
"cypress", "cypress",
"detox",
"express", "express",
"gatsby", "gatsby",
"jest", "jest",
@ -9,6 +10,7 @@
"node", "node",
"nx-plugin", "nx-plugin",
"react", "react",
"react-native",
"storybook", "storybook",
"web", "web",
"workspace" "workspace"

View File

@ -0,0 +1,24 @@
# @nrwl/detox:build
Run the command defined in build property of the specified configuration.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### configPath
Alias(es): cp
Type: `string`
Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or "detox" section in package.json
### detoxConfiguration
Alias(es): C
Type: `string`
Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it

View File

@ -0,0 +1,178 @@
# @nrwl/detox:test
Initiating your detox test suite.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### appLaunchArgs
Type: `number`
Custom arguments to pass (through) onto the app every time it is launched.
### artifactsLocation
Alias(es): a
Type: `string`
Artifacts (logs, screenshots, etc) root directory.
### captureViewHierarchy
Type: `string`
[iOS Only] Capture \*.uihierarchy snapshots on view action errors and device.captureViewHierarchy() calls.
### cleanup
Type: `boolean`
Shutdown simulator when test is over, useful for CI scripts, to make sure detox exists cleanly with no residue
### configPath
Alias(es): cp
Type: `string`
Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or "detox" section in package.json
### debugSynchronization
Alias(es): d
Type: `string`
Customize how long an action/expectation can take to complete before Detox starts querying the app why it is busy. By default, the app status will be printed if the action takes more than 10s to complete.
### detoxConfiguration
Alias(es): C
Type: `string`
Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it
### deviceLaunchArgs
Type: `string`
A list of passthrough-arguments to use when (if) devices (Android emulator / iOS simulator) are launched by Detox.
### deviceName
Alias(es): n
Type: `string`
Override the device name specified in a configuration. Useful for running a single build configuration on multiple devices.
### forceAdbInstall
Type: `boolean`
Due to problems with the adb install command on Android, Detox resorts to a different scheme for install APK's. Setting true will disable that and force usage of adb install, instead.
### gpu
Type: `boolean`
[Android Only] Launch Emulator with the specific -gpu [gpu mode] parameter.
### headless
Type: `boolean`
Android Only] Launch Emulator in headless mode. Useful when running on CI.
### inspectBrk
Type: `boolean`
Uses node's --inspect-brk flag to let users debug the jest/mocha test runner
### jestReportSpecs
Type: `boolean`
[Jest Only] Whether to output logs per each running spec, in real-time. By default, disabled with multiple workers.
### loglevel
Alias(es): l
Type: `string`
Log level: fatal, error, warn, info, verbose, trace
### noColor
Type: `boolean`
Disable colors in log output
### recordLogs
Type: `string`
Save logs during each test to artifacts directory. Pass "failing" to save logs of failing tests only.
### recordPerformance
Type: `string`
[iOS Only] Save Detox Instruments performance recordings of each test to artifacts directory.
### recordTimeline
Type: `string`
[Jest Only] Record tests and events timeline, for visual display on the chrome://tracing tool.
### recordVideos
Type: `string`
Save screen recordings of each test to artifacts directory. Pass "failing" to save recordings of failing tests only.
### retries
Type: `number`
[Jest Circus Only] Re-spawn the test runner for individual failing suite files until they pass, or <N> times at least.
### reuse
Type: `boolean`
Reuse existing installed app (do not delete + reinstall) for a faster run.
### runnerConfig
Alias(es): o
Type: `string`
Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest.
### takeScreenshots
Type: `string`
Save screenshots before and after each test to artifacts directory. Pass "failing" to save screenshots of failing tests only.
### useCustomLogger
Type: `boolean`
Use Detox' custom console-logging implementation, for logging Detox (non-device) logs. Disabling will fallback to node.js / test-runner's implementation (e.g. Jest / Mocha).
### workers
Type: `number`
Specifies number of workers the test runner should spawn, requires a test runner with parallel execution support (Detox CLI currently supports Jest).

View File

@ -0,0 +1,81 @@
# @nrwl/detox:application
Create a detox application
## Usage
```bash
nx generate application ...
```
```bash
nx g app ... # same
```
By default, Nx will search for `application` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/detox:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
## Options
### name (_**required**_)
Type: `string`
Name of the E2E Project
### project (_**required**_)
Type: `string`
The name of the frontend project to test.
### directory
Type: `string`
A directory where the project is placed
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`, `none`
The tool to use for running lint checks.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files

View File

@ -0,0 +1,14 @@
# @nrwl/react-native:build-android
Release Build for Android.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### apk
Type: `boolean`
Generate apk file(s) rather than a bundle (.aab).

View File

@ -0,0 +1,46 @@
# @nrwl/react-native:bundle
Builds the JS bundle.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### bundleOutput (_**required**_)
Type: `string`
The output path of the generated files.
### entryFile (_**required**_)
Type: `string`
The entry file relative to project root.
### platform (_**required**_)
Type: `string`
Platform to build for (ios, android).
### dev
Default: `true`
Type: `boolean`
Generate a development build.
### maxWorkers
Type: `number`
The number of workers we should parallelize the transformer on.
### sourceMap
Type: `boolean`
Whether source maps should be generated or not.

View File

@ -0,0 +1,6 @@
# @nrwl/react-native:ensure-symlink
Ensure workspace node_modules is symlink under app's node_modules folder.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.

View File

@ -0,0 +1,86 @@
# @nrwl/react-native:run-android
Runs Android application.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### appId
Type: `string`
Specify an applicationId to launch after build. If not specified, 'package' from AndroidManifest.xml will be used.
### appIdSuffix
Type: `string`
Specify an applicationIdSuffix to launch after build.
### deviceId
Type: `string`
Builds your app and starts it on a specific device/simulator with the given device id (listed by running "adb devices" on the command line).
### jetifier
Default: `true`
Type: `boolean`
Run jetifier the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don't support AndroidX yet.
### mainActivity
Default: `MainActivity`
Type: `string`
Name of the activity to start.
### packager
Default: `true`
Type: `boolean`
Starts the packager server
### port
Default: `8081`
Type: `number`
The port where the packager server is listening on.
### sync
Default: `true`
Type: `boolean`
Syncs npm dependencies to package.json (for React Native autolink).
### tasks
Type: `string`
Run custom gradle tasks. If this argument is provided, then --variant option is ignored. Example: yarn react-native run-android --tasks clean,installDebug.
### terminal
Type: `string`
Launches the Metro Bundler in a new window using the specified terminal path.
### variant
Default: `debug`
Type: `string`
Specify your app's build variant (e.g. debug, release).

View File

@ -0,0 +1,74 @@
# @nrwl/react-native:run-ios
Runs iOS application.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### device
Type: `string`
Explicitly set device to use by name. The value is not required if you have a single device connected.
### install
Default: `true`
Type: `boolean`
Runs 'pod install' for native modules before building iOS app.
### packager
Default: `true`
Type: `boolean`
Starts the packager server
### port
Default: `8081`
Type: `number`
The port where the packager server is listening on.
### scheme
Type: `string`
Explicitly set the Xcode scheme to use
### simulator
Default: `iPhone X`
Type: `string`
Explicitly set simulator to use. Optionally include iOS version between parenthesis at the end to match an exact version: "iPhone X (12.1)"
### sync
Default: `true`
Type: `boolean`
Syncs npm dependencies to package.json (for React Native autolink). Always true when --install is used.
### terminal
Type: `string`
Launches the Metro Bundler in a new window using the specified terminal path.
### xcodeConfiguration
Default: `Debug`
Type: `string`
Explicitly set the Xcode configuration to use

View File

@ -0,0 +1,24 @@
# @nrwl/react-native:start
Starts the dev server for JS bundle.
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### port
Default: `8081`
Type: `number`
The port to listen on.
### resetCache
Default: `false`
Type: `boolean`
Resets metro cache.

View File

@ -0,0 +1,14 @@
# @nrwl/react-native:sync-deps
Syncs dependencies to package.json (required for autolinking).
Options can be configured in `workspace.json` when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/getting-started/nx-cli#common-commands.
## Options
### include
Type: `string`
A comma-separated list of additional npm packages to include. e.g. 'nx sync-deps --include=react-native-gesture-handler,react-native-safe-area-context'

View File

@ -0,0 +1,125 @@
# @nrwl/react-native:application
Create an application
## Usage
```bash
nx generate application ...
```
```bash
nx g app ... # same
```
By default, Nx will search for `application` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
### Examples
Generate apps/nested/myapp:
```bash
nx g app myapp --directory=nested
```
Use class components instead of functional components:
```bash
nx g app myapp --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
The directory of the new application.
### displayName
Type: `string`
The display name to show in the application. Defaults to name.
### e2eTestRunner
Default: `detox`
Type: `string`
Possible values: `detox`, `none`
Adds the specified e2e test runner
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`
The tool to use for running lint checks.
### name
Type: `string`
The name of the application.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files
### tags
Alias(es): t
Type: `string`
Add tags to the application (used for linting)
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests

View File

@ -0,0 +1,119 @@
# @nrwl/react-native:component
Create a component
## Usage
```bash
nx generate component ...
```
```bash
nx g c ... # same
```
By default, Nx will search for `component` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:component ...
```
Show what will be generated without writing to disk:
```bash
nx g component ... --dry-run
```
### Examples
Generate a component in the mylib library:
```bash
nx g component my-component --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g component my-component --project=mylib --classComponent
```
## Options
### name (_**required**_)
Type: `string`
The name of the component.
### project (_**required**_)
Alias(es): p
Type: `string`
The name of the project.
### classComponent
Alias(es): C
Default: `false`
Type: `boolean`
Use class components instead of functional component.
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### pascalCaseFiles
Alias(es): P
Default: `false`
Type: `boolean`
Use pascal case component file name (e.g. App.tsx).
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.

View File

@ -0,0 +1,157 @@
# @nrwl/react-native:library
Create a library
## Usage
```bash
nx generate library ...
```
```bash
nx g lib ... # same
```
By default, Nx will search for `library` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/react-native:library ...
```
Show what will be generated without writing to disk:
```bash
nx g library ... --dry-run
```
### Examples
Generate libs/myapp/mylib:
```bash
nx g lib mylib --directory=myapp
```
## Options
### name (_**required**_)
Type: `string`
Library name
### buildable
Default: `false`
Type: `boolean`
Generate a buildable library.
### directory
Alias(es): d
Type: `string`
A directory where the lib is placed.
### globalCss
Default: `false`
Type: `boolean`
When true, the stylesheet is generated using global CSS instead of CSS modules (e.g. file is '_.css' rather than '_.module.css').
### importPath
Type: `string`
The library name used to import it, like @myorg/my-awesome-lib
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### linter
Default: `eslint`
Type: `string`
Possible values: `eslint`, `tslint`
The tool to use for running lint checks.
### pascalCaseFiles
Alias(es): P
Default: `false`
Type: `boolean`
Use pascal case component file name (e.g. App.tsx).
### publishable
Type: `boolean`
Create a publishable library.
### setParserOptionsProject
Default: `false`
Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### skipFormat
Default: `false`
Type: `boolean`
Skip formatting files.
### skipTsConfig
Default: `false`
Type: `boolean`
Do not update tsconfig.json for development experience.
### strict
Default: `true`
Type: `boolean`
Whether to enable tsconfig strict mode or not.
### tags
Alias(es): t
Type: `string`
Add tags to the library (used for linting).
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests.

View File

@ -1,12 +1,14 @@
[ [
"angular", "angular",
"cypress", "cypress",
"detox",
"gatsby", "gatsby",
"jest", "jest",
"linter", "linter",
"next", "next",
"node", "node",
"nx-plugin", "nx-plugin",
"react-native",
"storybook", "storybook",
"web", "web",
"workspace" "workspace"

View File

@ -1,6 +1,7 @@
[ [
"angular", "angular",
"cypress", "cypress",
"detox",
"express", "express",
"gatsby", "gatsby",
"jest", "jest",
@ -9,6 +10,7 @@
"node", "node",
"nx-plugin", "nx-plugin",
"react", "react",
"react-native",
"storybook", "storybook",
"web", "web",
"workspace" "workspace"

11
e2e/detox/jest.config.js Normal file
View File

@ -0,0 +1,11 @@
module.exports = {
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'e2e-detox',
testTimeout: 600000,
};

34
e2e/detox/project.json Normal file
View File

@ -0,0 +1,34 @@
{
"root": "e2e/detox",
"sourceRoot": "e2e/detox",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
{
"command": "yarn e2e-start-local-registry"
},
{
"command": "yarn e2e-build-package-publish"
},
{
"command": "nx run-e2e-tests e2e-detox"
}
],
"parallel": false
}
},
"run-e2e-tests": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "e2e/detox/jest.config.js",
"passWithNoTests": true,
"runInBand": true
},
"outputs": ["coverage/e2e/detox"]
}
},
"implicitDependencies": ["detox"]
}

View File

@ -0,0 +1,56 @@
import {
checkFilesExist,
isOSX,
newProject,
runCLI,
runCLIAsync,
uniq,
getSelectedPackageManager,
} from '@nrwl/e2e/utils';
describe('Detox', () => {
beforeEach(() => newProject());
it('should create files and run lint command', async () => {
// currently react native does not support pnpm: https://github.com/pnpm/pnpm/issues/3321
if (getSelectedPackageManager() === 'pnpm') return;
const appName = uniq('myapp');
runCLI(
`generate @nrwl/react-native:app ${appName} --e2eTestRunner=detox --linter=eslint`
);
checkFilesExist(`apps/${appName}-e2e/.detoxrc.json`);
checkFilesExist(`apps/${appName}-e2e/tsconfig.json`);
checkFilesExist(`apps/${appName}-e2e/tsconfig.e2e.json`);
checkFilesExist(`apps/${appName}-e2e/test-setup.ts`);
checkFilesExist(`apps/${appName}-e2e/src/app.spec.ts`);
const lintResults = await runCLIAsync(`lint ${appName}-e2e`);
expect(lintResults.combinedOutput).toContain('All files pass linting');
});
it('should build and test ios', async () => {
if (!isOSX()) return;
const appName = uniq('myapp');
runCLI(
`generate @nrwl/react-native:app ${appName} --e2eTestRunner=detox --linter=eslint`
);
expect(runCLI(`build-ios ${appName}-e2e`)).toContain(
'Running target "build-ios" succeeded'
);
// comment out due to github issue that unable to build xcode error 12.5 https://github.com/facebook/react-native/issues/31480
/* expect(runCLI(`build-ios ${appName}-e2e --pod`)).toContain(
'Running target "build-ios" succeeded'
);
expect(
runCLI(
`test-ios ${appName}-e2e --prod --debugSynchronization=true --loglevel=trace`
)
).toContain('Running target "test-ios" succeeded');
await killPorts(8081); // kill the port for the serve command
*/
}, 1000000);
});

13
e2e/detox/tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.spec.js",
"**/*.spec.jsx",
"**/*.d.ts"
]
}

View File

@ -0,0 +1,11 @@
module.exports = {
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'e2e-react-native',
testTimeout: 600000,
};

View File

@ -0,0 +1,34 @@
{
"root": "e2e/react-native",
"sourceRoot": "e2e/react-native",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
{
"command": "yarn e2e-start-local-registry"
},
{
"command": "yarn e2e-build-package-publish"
},
{
"command": "nx run-e2e-tests e2e-react-native"
}
],
"parallel": false
}
},
"run-e2e-tests": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "e2e/react-native/jest.config.js",
"passWithNoTests": true,
"runInBand": true
},
"outputs": ["coverage/e2e/react-native"]
}
},
"implicitDependencies": ["react-native"]
}

View File

@ -0,0 +1,96 @@
import {
checkFilesExist,
getSelectedPackageManager,
newProject,
readJson,
runCLI,
runCLIAsync,
uniq,
updateFile,
} from '@nrwl/e2e/utils';
import { join } from 'path';
describe('react native', () => {
let proj: string;
beforeEach(() => (proj = newProject()));
it('should test, create ios and android JS bundles', async () => {
// currently react native does not support pnpm: https://github.com/pnpm/pnpm/issues/3321
if (getSelectedPackageManager() === 'pnpm') return;
const appName = uniq('my-app');
const libName = uniq('lib');
const componentName = uniq('component');
runCLI(`generate @nrwl/react-native:application ${appName}`);
runCLI(`generate @nrwl/react-native:library ${libName}`);
runCLI(
`generate @nrwl/react-native:component ${componentName} --project=${libName} --export`
);
updateFile(`apps/${appName}/src/app/App.tsx`, (content) => {
let updated = `import ${componentName} from '${proj}/${libName}';\n${content}`;
return updated;
});
const appTestResults = await runCLIAsync(`test ${appName}`);
expect(appTestResults.combinedOutput).toContain(
'Test Suites: 1 passed, 1 total'
);
const libTestResults = await runCLIAsync(`test ${libName}`);
expect(libTestResults.combinedOutput).toContain(
'Test Suites: 1 passed, 1 total'
);
const iosBundleResult = await runCLIAsync(`bundle-ios ${appName}`);
expect(iosBundleResult.combinedOutput).toContain(
'Done writing bundle output'
);
expect(() =>
checkFilesExist(`dist/apps/${appName}/ios/main.jsbundle`)
).not.toThrow();
const androidBundleResult = await runCLIAsync(`bundle-android ${appName}`);
expect(androidBundleResult.combinedOutput).toContain(
'Done writing bundle output'
);
expect(() =>
checkFilesExist(`dist/apps/${appName}/android/main.jsbundle`)
).not.toThrow();
});
it('sync npm dependencies for autolink', async () => {
// currently react native does not support pnpm: https://github.com/pnpm/pnpm/issues/3321
if (getSelectedPackageManager() === 'pnpm') return;
const appName = uniq('my-app');
runCLI(`generate @nrwl/react-native:application ${appName}`);
// Add npm package with native modules
updateFile(join('package.json'), (content) => {
const json = JSON.parse(content);
json.dependencies['react-native-image-picker'] = '1.0.0';
json.dependencies['react-native-gesture-handler'] = '1.0.0';
json.dependencies['react-native-safe-area-contex'] = '1.0.0';
return JSON.stringify(json, null, 2);
});
// Add import for Nx to pick up
updateFile(join('apps', appName, 'src/app/App.tsx'), (content) => {
return `import { launchImageLibrary } from 'react-native-image-picker';\n${content}`;
});
await runCLIAsync(
`sync-deps ${appName} --include=react-native-gesture-handler,react-native-safe-area-context`
);
const result = readJson(join('apps', appName, 'package.json'));
expect(result).toMatchObject({
dependencies: {
'react-native-image-picker': '*',
'react-native-gesture-handler': '*',
'react-native-safe-area-context': '*',
},
});
});
});

View File

@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.spec.js",
"**/*.spec.jsx",
"**/*.d.ts"
]
}

View File

@ -188,6 +188,7 @@ export function newProject({ name = uniq('proj') } = {}): string {
`@nrwl/react`, `@nrwl/react`,
`@nrwl/storybook`, `@nrwl/storybook`,
`@nrwl/web`, `@nrwl/web`,
`@nrwl/react-native`,
]; ];
packageInstall(packages.join(` `), projScope); packageInstall(packages.join(` `), projScope);

View File

@ -175,6 +175,7 @@
"license-webpack-plugin": "2.3.15", "license-webpack-plugin": "2.3.15",
"loader-utils": "1.2.3", "loader-utils": "1.2.3",
"memfs": "^3.0.1", "memfs": "^3.0.1",
"metro-resolver": "^0.66.2",
"mime": "2.4.4", "mime": "2.4.4",
"mini-css-extract-plugin": "0.8.0", "mini-css-extract-plugin": "0.8.0",
"minimatch": "3.0.4", "minimatch": "3.0.4",
@ -182,6 +183,7 @@
"next-sitemap": "^1.6.108", "next-sitemap": "^1.6.108",
"ng-packagr": "~12.2.0", "ng-packagr": "~12.2.0",
"ngrx-store-freeze": "0.2.4", "ngrx-store-freeze": "0.2.4",
"node-fetch": "^2.6.1",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"open": "^7.4.2", "open": "^7.4.2",
"parse-markdown-links": "^1.0.4", "parse-markdown-links": "^1.0.4",

View File

@ -25,6 +25,7 @@ export enum Preset {
AngularWithNest = 'angular-nest', AngularWithNest = 'angular-nest',
React = 'react', React = 'react',
ReactWithExpress = 'react-express', ReactWithExpress = 'react-express',
ReactNative = 'react-native',
NextJs = 'next', NextJs = 'next',
Gatsby = 'gatsby', Gatsby = 'gatsby',
Nest = 'nest', Nest = 'nest',
@ -74,6 +75,11 @@ const presetOptions: { name: Preset; message: string }[] = [
message: message:
'web components [a workspace with a single app built using web components]', 'web components [a workspace with a single app built using web components]',
}, },
{
name: Preset.ReactNative,
message:
'react-native [a workspace with a single React Native application]',
},
{ {
name: Preset.ReactWithExpress, name: Preset.ReactWithExpress,
message: message:
@ -339,7 +345,8 @@ function determineStyle(preset: Preset, parsedArgs: any) {
preset === Preset.Empty || preset === Preset.Empty ||
preset === Preset.NPM || preset === Preset.NPM ||
preset === Preset.Nest || preset === Preset.Nest ||
preset === Preset.Express preset === Preset.Express ||
preset === Preset.ReactNative
) { ) {
return Promise.resolve(null); return Promise.resolve(null);
} }

View File

@ -0,0 +1 @@
{ "extends": "../../.eslintrc", "rules": {}, "ignorePatterns": ["!**/*"] }

80
packages/detox/README.md Normal file
View File

@ -0,0 +1,80 @@
# Detox Plugin for Nx
[![License](https://img.shields.io/npm/l/@nrwl/workspace.svg?style=flat-square)]()
[![NPM Version](https://badge.fury.io/js/%40nrwl%2Fdetox.svg)](https://www.npmjs.com/@nrwl/detox)
[![Join the chat at https://gitter.im/nrwl-nx/community](https://badges.gitter.im/nrwl-nx/community.svg)](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Join us @nrwl/community on slack](https://img.shields.io/badge/slack-%40nrwl%2Fcommunity-brightgreen)](https://join.slack.com/t/nrwlcommunity/shared_invite/enQtNzU5MTE4OTQwOTk0LTgxY2E0ZWYzMWE0YzA5ZDA2MWM1NDVhNmI2ZWMyYmZhNWJiODk3MjkxZjY3MzU5ZjRmM2NmNWU1OTgyZmE4Mzc)
</div>
## Table of Contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Setup](#setup)
- [Install applesimutils (Mac only)](#install-applesimutils-mac-only)
- [Install Jest Globally](#install-jest-globally)
- [Commands](#commands)
- [Manually Add E2E Folder](#manually-add-e2e-folder)
- [Change Testing Simulator/Emulator](#change-testing-simulatoremulator)
- [Learn more](#learn-more)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Setup
#### Install applesimutils (Mac only)
[applesimutils](https://github.com/wix/AppleSimulatorUtils) is a collection of utils for Apple simulators.
```sh
brew tap wix/brew
brew install applesimutils
```
#### Install Jest Globally
```sh
npm install -g jest
```
### Commands
Note: For e2e tests to work, the app must be running (`nx start <app-name>`). A built app must exist before run test commands.
- `nx build-ios <app-name-e2e>`: build the iOS app (Mac only)
- `nx test-ios <app-name-e2e>`: run e2e tests on the built iOS app (Mac only)
- `nx build-ios <app-name-e2e> --prod` and `nx test-ios <app-name-e2e> --prod`: build and run release version of iOS app. Note: you might need open the xcode project under iOS and choose a team under "Sign & Capabilities".
- `nx build-android <app-name-e2e>`: build the android app
- `nx test-android <app-name-e2d>`: run e2e tests on the built android app
- `nx build-android <app-name-e2e> --prod` and `nx test-android <app-name-e2e> --prod`: build and run release version of android app.
### Manually Add E2E Folder
A `<app-name-e2e>` folder is automatically generated when you create a react native app. However, if you want to add e2e folder manually, you need to:
- Install @nrwl/detox
```sh
# Using npm
npm install --save-dev @nrwl/detox
# Using yarn
yarn add -D @nrwl/detox
```
- Run `nx generate @nrwl/detox:app <app-name-e2e>`
- Follow instructions https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md to manully change android files.
### Change Testing Simulator/Emulator
For iOS, in terminal, run `xcrun simctl list` to view a list of simulators on your Mac. To open your active simulator, `run open -a simulator`. In `<app-name-e2e>/.detoxrc.json`, you could change the simulator under `devices.simulator.device`.
For Android: in terminal, run `emulator -list-avds` to view a list of emulators installed. To open your emulator, run `emulator -avd <your emulator name>`. In `<app-name-e2e>/.detoxrc.json`, you could change the simulator under `devices.emulator.device`.
To override the device name specified in a configuration, you could use `--device-name` option: `nx test-ios <app-name-e2e> --device-name "iPhone 11"`.
## Learn more
Visit the [Nx Documentation](https://nx.dev) to learn more.

View File

@ -0,0 +1,14 @@
{
"executors": {
"build": {
"implementation": "./src/executors/build/build.impl",
"schema": "./src/executors/build/schema.json",
"description": "Run the command defined in build property of the specified configuration."
},
"test": {
"implementation": "./src/executors/test/test.impl",
"schema": "./src/executors/test/schema.json",
"description": "Initiating your detox test suite."
}
}
}

View File

@ -0,0 +1,33 @@
{
"name": "Nx Detox",
"version": "0.1",
"extends": ["@nrwl/workspace"],
"schematics": {
"init": {
"factory": "./src/generators/init/init#detoxInitSchematic",
"schema": "./src/generators/init/schema.json",
"description": "Initialize the @nrwl/detox plugin",
"hidden": true
},
"application": {
"factory": "./src/generators/application/application#detoxApplicationSchematic",
"schema": "./src/generators/application/schema.json",
"aliases": ["app"],
"description": "Create a detox application"
}
},
"generators": {
"init": {
"factory": "./src/generators/init/init#detoxInitGenerator",
"schema": "./src/generators/init/schema.json",
"description": "Initialize the @nrwl/detox plugin",
"hidden": true
},
"application": {
"factory": "./src/generators/application/application#detoxApplicationGenerator",
"schema": "./src/generators/application/schema.json",
"aliases": ["app"],
"description": "Create a detox application"
}
}
}

2
packages/detox/index.ts Normal file
View File

@ -0,0 +1,2 @@
export { detoxInitGenerator } from './src/generators/init/init';
export { detoxApplicationGenerator } from './src/generators/application/application';

View File

@ -0,0 +1,12 @@
module.exports = {
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'],
globals: {
'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' },
},
displayName: 'react-native',
testEnvironment: 'node',
};

View File

@ -0,0 +1,13 @@
{
"packageJsonUpdates": {
"12.8.0": {
"version": "12.8.0-beta.0",
"packages": {
"detox": {
"version": "18.20.2",
"alwaysAddToPackageJson": false
}
}
}
}
}

View File

@ -0,0 +1,42 @@
{
"name": "@nrwl/detox",
"version": "0.0.1",
"description": "Detox Plugin for Nx",
"keywords": [
"Monorepo",
"React",
"Web",
"Native",
"CLI",
"Detox"
],
"homepage": "https://nx.dev",
"bugs": {
"url": "https://github.com/nrwl/nx/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nrwl/nx.git"
},
"license": "MIT",
"author": "Victor Savkin",
"main": "index.js",
"types": "index.d.ts",
"dependencies": {
"@nrwl/devkit": "*",
"@nrwl/jest": "*",
"@nrwl/linter": "*",
"@nrwl/react": "*",
"chalk": "^4.1.0"
},
"peerDependencies": {
"@nrwl/workspace": "*",
"detox": "18.18.0"
},
"builders": "./executors.json",
"ng-update": {
"requirements": {},
"migrations": "./migrations.json"
},
"schematics": "./generators.json"
}

View File

@ -0,0 +1,82 @@
{
"root": "packages/detox",
"sourceRoot": "packages/detox/src",
"projectType": "library",
"targets": {
"lint": {
"builder": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": [
"packages/detox/**/*.ts",
"packages/detox/**/*.spec.ts",
"packages/detox/**/*.spec.tsx",
"packages/detox/**/*.spec.js",
"packages/detox/**/*.spec.jsx",
"packages/detox/**/*.d.ts"
]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "packages/detox/jest.config.js",
"passWithNoTests": true
},
"outputs": ["coverage/packages/detox"]
},
"build-base": {
"builder": "@nrwl/node:package",
"options": {
"outputPath": "build/packages/detox",
"tsConfig": "packages/detox/tsconfig.lib.json",
"packageJson": "packages/detox/package.json",
"main": "packages/detox/index.ts",
"updateBuildableProjectDepsInPackageJson": false,
"assets": [
{
"input": "packages/detox",
"glob": "**/files/**",
"output": "/"
},
{
"input": "packages/detox",
"glob": "**/files/**/.gitkeep",
"output": "/"
},
{
"input": "packages/detox",
"glob": "**/files/**/.babelrc.template",
"output": "/"
},
{
"input": "packages/detox",
"glob": "**/files/**/.detoxrc.json.template",
"output": "/"
},
{
"input": "./packages/detox",
"glob": "**/*.json",
"ignore": ["**/tsconfig*.json"],
"output": "/"
},
"LICENSE"
]
},
"build": {
"executor": "@nrwl/workspace:run-commands",
"outputs": ["build/packages/detox"],
"options": {
"command": "node ./scripts/copy-readme.js detox"
}
},
"outputs": ["{options.outputPath}"]
},
"build": {
"executor": "@nrwl/workspace:run-commands",
"outputs": ["build/packages/detox"],
"options": {
"command": "node ./scripts/copy-readme.js detox"
}
}
}
}

View File

@ -0,0 +1,71 @@
import { ExecutorContext } from '@nrwl/devkit';
import { join } from 'path';
import { ChildProcess, fork } from 'child_process';
import { DetoxBuildOptions } from './schema';
export interface DetoxBuildOutput {
success: boolean;
}
let childProcess: ChildProcess;
export default async function* detoxBuildExecutor(
options: DetoxBuildOptions,
context: ExecutorContext
): AsyncGenerator<DetoxBuildOutput> {
const projectRoot = context.workspace.projects[context.projectName].root;
try {
await runCliBuild(context.root, projectRoot, options);
yield { success: true };
} finally {
if (childProcess) {
childProcess.kill();
}
}
}
function runCliBuild(
workspaceRoot: string,
projectRoot: string,
options: DetoxBuildOptions
) {
return new Promise((resolve, reject) => {
childProcess = fork(
join(workspaceRoot, './node_modules/detox/local-cli/cli.js'),
['build', ...createDetoxBuildOptions(options)],
{
cwd: projectRoot,
}
);
// Ensure the child process is killed when the parent exits
process.on('exit', () => childProcess.kill());
process.on('SIGTERM', () => childProcess.kill());
childProcess.on('error', (err) => {
reject(err);
});
childProcess.on('exit', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(code);
}
});
});
}
function createDetoxBuildOptions(options) {
return Object.keys(options).reduce((acc, k) => {
const v = options[k];
if (k === 'detoxConfiguration') {
acc.push('--configuration', v);
} else if (k === 'configPath') {
acc.push('--config-path', v);
} else acc.push(`--${k}`, options[k]);
return acc;
}, []);
}

View File

@ -0,0 +1,5 @@
import { convertNxExecutor } from '@nrwl/devkit';
import detoxBuildExecutor from './build.impl';
export default convertNxExecutor(detoxBuildExecutor);

View File

@ -0,0 +1,5 @@
// options from https://github.com/wix/Detox/blob/master/docs/APIRef.DetoxCLI.md#build
export interface DetoxBuildOptions {
detoxConfiguration?: string;
configPath?: string;
}

View File

@ -0,0 +1,19 @@
{
"title": "Run detox build",
"description": "Run detox build options",
"type": "object",
"cli": "nx",
"properties": {
"detoxConfiguration": {
"type": "string",
"description": "Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it",
"alias": "C"
},
"configPath": {
"type": "string",
"description": "Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or \"detox\" section in package.json",
"alias": "cp"
}
},
"required": []
}

View File

@ -0,0 +1,5 @@
import { convertNxExecutor } from '@nrwl/devkit';
import detoxTestExecutor from './test.impl';
export default convertNxExecutor(detoxTestExecutor);

View File

@ -0,0 +1,30 @@
// options from https://github.com/wix/Detox/blob/master/docs/APIRef.DetoxCLI.md#test
// detox test args: https://github.com/wix/Detox/blob/master/detox/local-cli/utils/testCommandArgs.js
export interface DetoxTestOptions {
configPath: string;
detoxConfiguration: string;
runnerConfig: string;
deviceName: string;
loglevel: string;
debugSynchronization: string;
artifactsLocation: string;
recordLogs: 'failing' | 'all' | 'none';
takeScreenshots: 'manual' | 'failing' | 'all' | 'none';
recordVideos: 'failing' | 'all' | 'none';
recordPerformance: 'all' | 'none';
recordTimeline: 'all' | 'none';
captureViewHierarchy: 'enabled' | 'disabled';
retries: number;
resuse: boolean;
cleanup: boolean;
workers: number;
jestReportSpecs: boolean;
headeless: boolean;
gpu: boolean;
deviceLauchArgs: string;
appLaunchArgs: string;
noColor: boolean;
useCutsomeLogger: boolean;
forceAdbInstall: boolean;
inspectBrk: boolean;
}

View File

@ -0,0 +1,120 @@
{
"title": "Run detox test",
"description": "Run detox test options",
"type": "object",
"cli": "nx",
"properties": {
"detoxConfiguration": {
"type": "string",
"description": "Select a device configuration from your defined configurations, if not supplied, and there's only one configuration, detox will default to it",
"alias": "C"
},
"configPath": {
"type": "string",
"description": "Specify Detox config file path. If not supplied, detox searches for .detoxrc[.js] or \"detox\" section in package.json",
"alias": "cp"
},
"runnerConfig": {
"type": "string",
"description": "Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest.",
"alias": "o"
},
"deviceName": {
"type": "string",
"description": "Override the device name specified in a configuration. Useful for running a single build configuration on multiple devices.",
"alias": "n"
},
"loglevel": {
"type": "string",
"description": "Log level: fatal, error, warn, info, verbose, trace",
"alias": "l"
},
"debugSynchronization": {
"type": "string",
"description": "Customize how long an action/expectation can take to complete before Detox starts querying the app why it is busy. By default, the app status will be printed if the action takes more than 10s to complete.",
"alias": "d"
},
"artifactsLocation": {
"type": "string",
"description": "Artifacts (logs, screenshots, etc) root directory.",
"alias": "a"
},
"recordLogs": {
"type": "string",
"description": "Save logs during each test to artifacts directory. Pass \"failing\" to save logs of failing tests only."
},
"takeScreenshots": {
"type": "string",
"description": "Save screenshots before and after each test to artifacts directory. Pass \"failing\" to save screenshots of failing tests only. "
},
"recordVideos": {
"type": "string",
"description": "Save screen recordings of each test to artifacts directory. Pass \"failing\" to save recordings of failing tests only."
},
"recordPerformance": {
"type": "string",
"description": "[iOS Only] Save Detox Instruments performance recordings of each test to artifacts directory."
},
"recordTimeline": {
"type": "string",
"description": "[Jest Only] Record tests and events timeline, for visual display on the chrome://tracing tool."
},
"captureViewHierarchy": {
"type": "string",
"description": "[iOS Only] Capture *.uihierarchy snapshots on view action errors and device.captureViewHierarchy() calls."
},
"retries": {
"type": "number",
"description": "[Jest Circus Only] Re-spawn the test runner for individual failing suite files until they pass, or <N> times at least."
},
"reuse": {
"type": "boolean",
"description": "Reuse existing installed app (do not delete + reinstall) for a faster run."
},
"cleanup": {
"type": "boolean",
"description": "Shutdown simulator when test is over, useful for CI scripts, to make sure detox exists cleanly with no residue"
},
"workers": {
"type": "number",
"description": "Specifies number of workers the test runner should spawn, requires a test runner with parallel execution support (Detox CLI currently supports Jest)."
},
"jestReportSpecs": {
"type": "boolean",
"description": "[Jest Only] Whether to output logs per each running spec, in real-time. By default, disabled with multiple workers."
},
"headless": {
"type": "boolean",
"description": "Android Only] Launch Emulator in headless mode. Useful when running on CI."
},
"gpu": {
"type": "boolean",
"description": "[Android Only] Launch Emulator with the specific -gpu [gpu mode] parameter."
},
"deviceLaunchArgs": {
"type": "string",
"description": "A list of passthrough-arguments to use when (if) devices (Android emulator / iOS simulator) are launched by Detox."
},
"appLaunchArgs": {
"type": "number",
"description": "Custom arguments to pass (through) onto the app every time it is launched."
},
"noColor": {
"type": "boolean",
"description": "Disable colors in log output"
},
"useCustomLogger": {
"type": "boolean",
"description": "Use Detox' custom console-logging implementation, for logging Detox (non-device) logs. Disabling will fallback to node.js / test-runner's implementation (e.g. Jest / Mocha)."
},
"forceAdbInstall": {
"type": "boolean",
"description": "Due to problems with the adb install command on Android, Detox resorts to a different scheme for install APK's. Setting true will disable that and force usage of adb install, instead."
},
"inspectBrk": {
"type": "boolean",
"description": "Uses node's --inspect-brk flag to let users debug the jest/mocha test runner"
}
},
"required": []
}

View File

@ -0,0 +1,77 @@
import { ExecutorContext } from '@nrwl/devkit';
import { toFileName } from '@nrwl/workspace/src/devkit-reexport';
import { join } from 'path';
import { ChildProcess, fork } from 'child_process';
import { DetoxTestOptions } from './schema';
export interface DetoxTestOutput {
success: boolean;
}
let childProcess: ChildProcess;
export default async function* detoxTestExecutor(
options: DetoxTestOptions,
context: ExecutorContext
): AsyncGenerator<DetoxTestOutput> {
const projectRoot = context.workspace.projects[context.projectName].root;
try {
await runCliTest(context.root, projectRoot, options);
yield { success: true };
} finally {
if (childProcess) {
childProcess.kill();
}
}
}
function runCliTest(
workspaceRoot: string,
projectRoot: string,
options: DetoxTestOptions
) {
return new Promise((resolve, reject) => {
childProcess = fork(
join(workspaceRoot, './node_modules/detox/local-cli/cli.js'),
['test', ...createDetoxTestOptions(options)],
{
cwd: projectRoot,
}
);
// Ensure the child process is killed when the parent exits
process.on('exit', () => childProcess.kill());
process.on('SIGTERM', () => childProcess.kill());
childProcess.on('error', (err) => {
reject(err);
});
childProcess.on('exit', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(code);
}
});
});
}
function createDetoxTestOptions(options: DetoxTestOptions): string[] {
return Object.keys(options).reduce((acc, k) => {
const propertyName = toFileName(k); // convert camelCase to kebab-case
const propertyValue = options[k];
if (k === 'detoxConfiguration') {
acc.push('--configuration', propertyValue);
} else if (k === 'deviceLaunchArgs') {
acc.push(`--device-launch-args="${propertyValue}"`); // the value must be specified after an equal sign (=) and inside quotes.
} else if (k === 'appLaunchArgs') {
acc.push(`--app-launch-argss="${propertyValue}"`); // the value must be specified after an equal sign (=) and inside quotes.
} else {
acc.push(`--${propertyName}`, propertyValue);
}
return acc;
}, []);
}

View File

@ -0,0 +1,34 @@
import { convertNxGenerator, formatFiles, Tree } from '@nrwl/devkit';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import detoxInitGenerator from '../init/init';
import { addGitIgnoreEntry } from './lib/add-git-ignore-entry';
import { addLinting } from './lib/add-linting';
import { addProject } from './lib/add-project';
import { createFiles } from './lib/create-files';
import { normalizeOptions } from './lib/normalize-options';
import { Schema } from './schema';
export async function detoxApplicationGenerator(host: Tree, schema: Schema) {
const options = normalizeOptions(host, schema);
const initTask = await detoxInitGenerator(host, {
skipFormat: true,
});
createFiles(host, options);
addProject(host, options);
addGitIgnoreEntry(host, options);
const lintingTask = await addLinting(host, options);
if (!options.skipFormat) {
await formatFiles(host);
}
return runTasksInSerial(initTask, lintingTask);
}
export default detoxApplicationGenerator;
export const detoxApplicationSchematic = convertNxGenerator(
detoxApplicationGenerator
);

View File

@ -0,0 +1,11 @@
{
"presets": [
[
"@nrwl/react/babel",
{
"runtime": "automatic"
}
]
],
"plugins": []
}

View File

@ -0,0 +1,58 @@
{
"testRunner": "jest",
"runnerConfig": "jest.config.json",
"apps": {
"ios.debug": {
"type": "ios.app",
"build": "cd ../<%= appFileName %>/ios && xcodebuild -workspace <%= appClassName %>.xcworkspace -scheme <%= appClassName %> -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12' -derivedDataPath ./build -quiet",
"binaryPath": "../<%= appFileName %>/ios/build/Build/Products/Debug-iphonesimulator/<%= appClassName %>.app"
},
"ios.release": {
"type": "ios.app",
"build": "cd ../<%= appFileName %>/ios && xcodebuild -workspace <%= appClassName %>.xcworkspace -scheme <%= appClassName %> -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12' -derivedDataPath ./build -quiet",
"binaryPath": "../<%= appFileName %>/ios/build/Build/Products/Release-iphonesimulator/<%= appClassName %>.app"
},
"android.debug": {
"type": "android.apk",
"build": "cd ../<%= appFileName %>/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug",
"binaryPath": "../<%= appFileName %>/android/app/build/outputs/apk/debug/app-debug.apk"
},
"android.release": {
"type": "android.apk",
"build": "cd ../<%= appFileName %>/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release",
"binaryPath": "../<%= appFileName %>/android/app/build/outputs/apk/release/app-release.apk"
}
},
"devices": {
"simulator": {
"type": "ios.simulator",
"device": {
"type": "iPhone 12"
}
},
"emulator": {
"type": "android.emulator",
"device": {
"avdName": "Pixel_4a_API_30"
}
}
},
"configurations": {
"ios.sim.release": {
"device": "simulator",
"app": "ios.release"
},
"ios.sim.debug": {
"device": "simulator",
"app": "ios.debug"
},
"android.emu.release": {
"device": "emulator",
"app": "android.release"
},
"android.emu.debug": {
"device": "emulator",
"app": "android.debug"
}
}
}

View File

@ -0,0 +1,23 @@
const {
DetoxCircusEnvironment,
SpecReporter,
WorkerAssignReporter,
} = require('detox/runners/jest-circus');
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
constructor(config, context) {
super(config, context);
// Can be safely removed, if you are content with the default value (=300000ms)
this.initTimeout = 300000;
// This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
// This is strictly optional.
this.registerListeners({
SpecReporter,
WorkerAssignReporter,
});
}
}
module.exports = CustomDetoxEnvironment;

View File

@ -0,0 +1,12 @@
{
"preset": "../../jest.preset",
"testEnvironment": "./environment",
"testRunner": "jest-circus/runner",
"testTimeout": 120000,
"reporters": ["detox/runners/jest/streamlineReporter"],
"setupFilesAfterEnv": ["<rootDir>/test-setup.ts"],
"transform": {
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nrwl/react/plugins/jest",
"^.+\\.[tj]sx?$": "babel-jest"
}
}

View File

@ -0,0 +1,16 @@
import { device, element, by, expect } from 'detox';
describe('<%= appClassName %>', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should display welcome message', async () => {
await expect(element(by.id('heading'))).toHaveText('Welcome to <%= appClassName %>');
});
it('should open nx link', async () => {
await expect(element(by.id('nx-link'))).toBeVisible();
element(by.id('nx-link')).tap();
});
});

View File

@ -0,0 +1,6 @@
import { device } from 'detox';
beforeAll(async () => {
await device.launchApp();
await device.disableSynchronization();
});

View File

@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"outDir": "<%= offsetFromRoot %>dist/out-tsc",
"allowJs": true,
"types": ["node", "jest", "detox"]
},
"include": ["src/**/*.ts", "src/**/*.js"]
}

View File

@ -0,0 +1,10 @@
{
"extends": "<%= offsetFromRoot %>tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.e2e.json"
}
]
}

View File

@ -0,0 +1,12 @@
import { logger, Tree } from '@nrwl/devkit';
import { NormalizedSchema } from './normalize-options';
export function addGitIgnoreEntry(host: Tree, options: NormalizedSchema) {
if (host.exists('.gitignore')) {
let content = host.read('.gitignore', 'utf-8');
content = `${content}\n${options.projectRoot}/artifacts\n`;
host.write('.gitignore', content);
} else {
logger.warn(`Couldn't find .gitignore file to update`);
}
}

View File

@ -0,0 +1,71 @@
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Linter } from '@nrwl/linter';
import { addLinting } from './add-linting';
import { addProject } from './add-project';
describe('Add Linting', () => {
let tree: Tree;
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
addProject(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.EsLint,
});
});
it('should add update `workspace.json` file properly when eslint is passed', () => {
addLinting(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.EsLint,
});
const project = readProjectConfiguration(tree, 'my-app-e2e');
expect(project.targets.lint).toBeDefined();
expect(project.targets.lint.executor).toEqual('@nrwl/linter:eslint');
});
it('should add update `workspace.json` file properly when tslint is passed', () => {
addLinting(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.TsLint,
});
const project = readProjectConfiguration(tree, 'my-app-e2e');
expect(project.targets.lint).toBeDefined();
expect(project.targets.lint.executor).toEqual(
'@angular-devkit/build-angular:tslint'
);
});
it('should not add lint target when "none" is passed', async () => {
addLinting(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.None,
});
const project = readProjectConfiguration(tree, 'my-app-e2e');
expect(project.targets.lint).toBeUndefined();
});
});

View File

@ -0,0 +1,49 @@
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import {
addDependenciesToPackageJson,
joinPathFragments,
updateJson,
Tree,
} from '@nrwl/devkit';
import { extraEslintDependencies, createReactEslintJson } from '@nrwl/react';
import { NormalizedSchema } from './normalize-options';
export async function addLinting(host: Tree, options: NormalizedSchema) {
if (options.linter === Linter.None) {
return () => {};
}
const lintTask = await lintProjectGenerator(host, {
linter: options.linter,
project: options.projectName,
tsConfigPaths: [
joinPathFragments(options.projectRoot, 'tsconfig.app.json'),
],
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
skipFormat: true,
});
if (options.linter === Linter.TsLint) {
return () => {};
}
const reactEslintJson = createReactEslintJson(
options.projectRoot,
options.setParserOptionsProject
);
updateJson(
host,
joinPathFragments(options.projectRoot, '.eslintrc.json'),
() => reactEslintJson
);
const installTask = await addDependenciesToPackageJson(
host,
extraEslintDependencies.dependencies,
extraEslintDependencies.devDependencies
);
return runTasksInSerial(lintTask, installTask);
}

View File

@ -0,0 +1,60 @@
import {
addProjectConfiguration,
readProjectConfiguration,
Tree,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Linter } from '@nrwl/linter';
import { addProject } from './add-project';
describe('Add Project', () => {
let tree: Tree;
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
addProjectConfiguration(tree, 'my-app', {
root: 'my-app',
targets: {
serve: {
executor: 'serve-executor',
options: {},
configurations: {
production: {},
},
},
},
});
});
it('should update workspace.json', async () => {
addProject(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.EsLint,
});
const project = readProjectConfiguration(tree, 'my-app-e2e');
expect(project.root).toEqual('apps/my-app-e2e');
expect(project.sourceRoot).toEqual('apps/my-app-e2e/src');
});
it('should update nx.json', async () => {
addProject(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.EsLint,
});
const project = readProjectConfiguration(tree, 'my-app-e2e');
expect(project.tags).toEqual([]);
expect(project.implicitDependencies).toEqual(['my-app']);
});
});

View File

@ -0,0 +1,71 @@
import {
addProjectConfiguration,
TargetConfiguration,
Tree,
} from '@nrwl/devkit';
import { NormalizedSchema } from './normalize-options';
export function addProject(host: Tree, options: NormalizedSchema) {
addProjectConfiguration(host, options.projectName, {
root: options.projectRoot,
sourceRoot: `${options.projectRoot}/src`,
projectType: 'application',
targets: { ...getTargets(options) },
tags: [],
implicitDependencies: options.project ? [options.project] : undefined,
});
}
function getTargets(options: NormalizedSchema) {
const architect: { [key: string]: TargetConfiguration } = {};
architect['build-ios'] = {
executor: '@nrwl/detox:build',
options: {
detoxConfiguration: 'ios.sim.debug',
},
configurations: {
production: {
detoxConfiguration: 'ios.sim.release',
},
},
};
architect['test-ios'] = {
executor: '@nrwl/detox:test',
options: {
detoxConfiguration: 'ios.sim.debug',
},
configurations: {
production: {
detoxConfiguration: 'ios.sim.release',
},
},
};
architect['build-android'] = {
executor: '@nrwl/detox:build',
options: {
detoxConfiguration: 'android.emu.debug',
},
configurations: {
production: {
detoxConfiguration: 'android.emu.release',
},
},
};
architect['test-android'] = {
executor: '@nrwl/detox:test',
options: {
detoxConfiguration: 'android.emu.debug',
},
configurations: {
production: {
detoxConfiguration: 'android.emu.release',
},
},
};
return architect;
}

View File

@ -0,0 +1,29 @@
import { Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Linter } from '@nrwl/linter';
import { createFiles } from './create-files';
describe('Create Files', () => {
let tree: Tree;
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
});
it('should generate files', () => {
createFiles(tree, {
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.EsLint,
});
expect(tree.exists('apps/my-app-e2e/.detoxrc.json')).toBeTruthy();
expect(tree.exists('apps/my-app-e2e/tsconfig.json')).toBeTruthy();
expect(tree.exists('apps/my-app-e2e/tsconfig.e2e.json')).toBeTruthy();
expect(tree.exists('apps/my-app-e2e/test-setup.ts')).toBeTruthy();
});
});

View File

@ -0,0 +1,13 @@
import { generateFiles, offsetFromRoot, toJS, Tree } from '@nrwl/devkit';
import { join } from 'path';
import { NormalizedSchema } from './normalize-options';
export function createFiles(host: Tree, options: NormalizedSchema) {
generateFiles(host, join(__dirname, '../files/app'), options.projectRoot, {
...options,
offsetFromRoot: offsetFromRoot(options.projectRoot),
});
if (options.js) {
toJS(host);
}
}

View File

@ -0,0 +1,77 @@
import { addProjectConfiguration, Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Linter } from '@nrwl/linter';
import { Schema } from '../schema';
import { normalizeOptions } from './normalize-options';
describe('Normalize Options', () => {
let appTree: Tree;
beforeEach(() => {
appTree = createTreeWithEmptyWorkspace();
});
it('should normalize options with name in kebab case', () => {
addProjectConfiguration(appTree, 'my-app', {
root: 'apps/my-app',
targets: {},
});
const schema: Schema = {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.EsLint,
};
const options = normalizeOptions(appTree, schema);
expect(options).toEqual({
name: 'my-app-e2e',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
project: 'my-app',
appFileName: 'my-app',
appClassName: 'MyApp',
linter: Linter.EsLint,
});
});
it('should normalize options with name in camel case', () => {
addProjectConfiguration(appTree, 'my-app', {
root: 'apps/my-app',
targets: {},
});
const schema: Schema = {
name: 'myAppE2e',
project: 'myApp',
};
const options = normalizeOptions(appTree, schema);
expect(options).toEqual({
appClassName: 'MyApp',
appFileName: 'my-app',
name: 'my-app-e2e',
project: 'myApp',
projectName: 'my-app-e2e',
projectRoot: 'apps/my-app-e2e',
});
});
it('should normalize options with directory', () => {
addProjectConfiguration(appTree, 'my-app', {
root: 'apps/my-app',
targets: {},
});
const schema: Schema = {
name: 'my-app-e2e',
project: 'my-app',
directory: 'directory',
};
const options = normalizeOptions(appTree, schema);
expect(options).toEqual({
project: 'my-app',
appClassName: 'MyApp',
appFileName: 'my-app',
projectRoot: 'apps/directory/my-app-e2e',
name: 'my-app-e2e',
directory: 'directory',
projectName: 'directory-my-app-e2e',
});
});
});

View File

@ -0,0 +1,50 @@
import {
getWorkspaceLayout,
joinPathFragments,
names,
Tree,
} from '@nrwl/devkit';
import { Schema } from '../schema';
export interface NormalizedSchema extends Schema {
appFileName: string; // the file name of app to be tested
appClassName: string; // the class name of app to be tested
projectName: string; // the name of e2e project
projectRoot: string; // the root path of e2e project
}
/**
* if options.name = 'my-app-e2e' with no options.directory
* projectName = 'my-app', projectRoot = 'apps/my-app'
* if options.name = 'my-app' with options.directory = 'my-dir'
* projectName = 'my-dir-my-app', projectRoot = 'apps/my-dir/my-apps'
*/
export function normalizeOptions(
host: Tree,
options: Schema
): NormalizedSchema {
const { appsDir } = getWorkspaceLayout(host);
const fileName = names(options.name).fileName;
const directoryFileName = options.directory
? names(options.directory).fileName
: '';
const projectName = directoryFileName
? `${directoryFileName.replace(new RegExp('/', 'g'), '-')}-${fileName}`
: fileName;
const projectRoot = directoryFileName
? joinPathFragments(appsDir, directoryFileName, fileName)
: joinPathFragments(appsDir, fileName);
const { fileName: appFileName, className: appClassName } = names(
options.project
);
return {
...options,
appFileName,
appClassName,
name: fileName,
projectName,
projectRoot,
};
}

View File

@ -0,0 +1,11 @@
import { Linter } from '@nrwl/linter';
export interface Schema {
project: string;
name: string;
directory?: string;
linter?: Linter;
js?: boolean;
skipFormat?: boolean;
setParserOptionsProject?: boolean;
}

View File

@ -0,0 +1,50 @@
{
"$schema": "http://json-schema.org/schema",
"title": "Create Detox Configuration for the workspace",
"type": "object",
"properties": {
"project": {
"type": "string",
"description": "The name of the frontend project to test.",
"$default": {
"$source": "projectName"
},
"x-prompt": "What is the name of the frontend project to test?"
},
"name": {
"type": "string",
"description": "Name of the E2E Project",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the e2e project?"
},
"directory": {
"type": "string",
"description": "A directory where the project is placed"
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["eslint", "tslint", "none"],
"default": "eslint"
},
"js": {
"description": "Generate JavaScript files rather than TypeScript files",
"type": "boolean",
"default": false
},
"skipFormat": {
"description": "Skip formatting files",
"type": "boolean",
"default": false
},
"setParserOptionsProject": {
"type": "boolean",
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
"default": false
}
},
"required": ["name", "project"]
}

View File

@ -0,0 +1,19 @@
import { Tree, readJson } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { detoxInitGenerator } from './init';
describe('init', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should add detox dependencies', async () => {
await detoxInitGenerator(tree, {});
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['@nrwl/detox']).toBeDefined();
expect(packageJson.devDependencies['@types/detox']).toBeDefined();
expect(packageJson.devDependencies['detox']).toBeDefined();
});
});

View File

@ -0,0 +1,47 @@
import {
addDependenciesToPackageJson,
convertNxGenerator,
formatFiles,
removeDependenciesFromPackageJson,
Tree,
} from '@nrwl/devkit';
import { jestVersion } from '@nrwl/jest/src/utils/versions';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { Schema } from './schema';
import {
detoxVersion,
nxVersion,
testingLibraryJestDom,
typesDetoxVersion,
} from '../../utils/versions';
export async function detoxInitGenerator(host: Tree, schema: Schema) {
const tasks = [moveDependency(host), updateDependencies(host)];
if (!schema.skipFormat) {
await formatFiles(host);
}
return runTasksInSerial(...tasks);
}
export function updateDependencies(host: Tree) {
return addDependenciesToPackageJson(
host,
{},
{
'@nrwl/detox': nxVersion,
detox: detoxVersion,
'@types/detox': typesDetoxVersion,
'@testing-library/jest-dom': testingLibraryJestDom,
'jest-circus': jestVersion,
}
);
}
function moveDependency(host: Tree) {
return removeDependenciesFromPackageJson(host, ['@nrwl/detox'], []);
}
export default detoxInitGenerator;
export const detoxInitSchematic = convertNxGenerator(detoxInitGenerator);

Some files were not shown because too many files have changed in this diff Show More