bugfix(detox): allow to pass in appName to detox (#12436)
This commit is contained in:
parent
e74a54d139
commit
0c7c4822e0
@ -48,27 +48,35 @@
|
|||||||
"description": "Create Detox Configuration for the workspace.",
|
"description": "Create Detox Configuration for the workspace.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"project": {
|
"appProject": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The name of the frontend project to test.",
|
"description": "Name of the frontend project to be tested.",
|
||||||
"$default": { "$source": "projectName" },
|
"$default": { "$source": "projectName" },
|
||||||
"x-prompt": "What is the name of the frontend project to test?"
|
"x-prompt": "What is the name of the frontend project to test?"
|
||||||
},
|
},
|
||||||
"name": {
|
"e2eName": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Name of the E2E Project.",
|
"description": "Name of the E2E Project.",
|
||||||
"$default": { "$source": "argv", "index": 0 },
|
"$default": { "$source": "argv", "index": 0 },
|
||||||
"x-prompt": "What name would you like to use for the E2E project?"
|
"x-prompt": "What name would you like to use for the E2E project?"
|
||||||
},
|
},
|
||||||
|
"appName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the app to be tested if different from appProject"
|
||||||
|
},
|
||||||
|
"appDisplayName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Display name of the app to be tested if different from appProject"
|
||||||
|
},
|
||||||
"framework": {
|
"framework": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "App framework to test",
|
"description": "App framework to test",
|
||||||
"enum": ["react-native", "expo"],
|
"enum": ["react-native", "expo"],
|
||||||
"x-prompt": "What app framework should detox test?"
|
"x-prompt": "What app framework should detox test?"
|
||||||
},
|
},
|
||||||
"directory": {
|
"e2eDirectory": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A directory where the project is placed."
|
"description": "A directory where the project is placed relative to apps directory."
|
||||||
},
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"description": "The tool to use for running lint checks.",
|
"description": "The tool to use for running lint checks.",
|
||||||
@ -92,7 +100,7 @@
|
|||||||
"default": false
|
"default": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["name", "project", "framework"],
|
"required": ["e2eName", "appProject", "framework"],
|
||||||
"presets": []
|
"presets": []
|
||||||
},
|
},
|
||||||
"aliases": ["app"],
|
"aliases": ["app"],
|
||||||
|
|||||||
@ -24,8 +24,8 @@ describe('detox application generator', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await detoxApplicationGenerator(tree, {
|
await detoxApplicationGenerator(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
linter: Linter.None,
|
linter: Linter.None,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -34,6 +34,43 @@ describe('detox application generator', () => {
|
|||||||
it('should generate files', () => {
|
it('should generate files', () => {
|
||||||
expect(tree.exists('apps/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
||||||
expect(tree.exists('apps/my-app-e2e/src/app.spec.ts')).toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/src/app.spec.ts')).toBeTruthy();
|
||||||
|
|
||||||
|
const detoxrc = tree.read('apps/my-app-e2e/.detoxrc.json').toString();
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
const appsDetoxrcJson = detoxrcJson['apps'];
|
||||||
|
expect(appsDetoxrcJson).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../my-app/ios/build/Build/Products/Debug-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../my-app/ios/build/Build/Products/Release-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add update `workspace.json` file', async () => {
|
it('should add update `workspace.json` file', async () => {
|
||||||
@ -49,16 +86,16 @@ describe('detox application generator', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with directory specified', () => {
|
describe('with directory specified that is same as e2e project', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
addProjectConfiguration(tree, 'my-dir-my-app', {
|
addProjectConfiguration(tree, 'my-dir-my-app', {
|
||||||
root: 'my-dir/my-app',
|
root: 'my-dir/my-app',
|
||||||
});
|
});
|
||||||
|
|
||||||
await detoxApplicationGenerator(tree, {
|
await detoxApplicationGenerator(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
directory: 'my-dir',
|
e2eDirectory: 'my-dir',
|
||||||
project: 'my-dir-my-app',
|
appProject: 'my-dir-my-app',
|
||||||
linter: Linter.None,
|
linter: Linter.None,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -69,6 +106,45 @@ describe('detox application generator', () => {
|
|||||||
expect(
|
expect(
|
||||||
tree.exists('apps/my-dir/my-app-e2e/src/app.spec.ts')
|
tree.exists('apps/my-dir/my-app-e2e/src/app.spec.ts')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
|
const detoxrc = tree
|
||||||
|
.read('apps/my-dir/my-app-e2e/.detoxrc.json')
|
||||||
|
.toString();
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
const appsDetoxrcJson = detoxrcJson['apps'];
|
||||||
|
expect(appsDetoxrcJson).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Release-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add update `workspace.json` file', async () => {
|
it('should add update `workspace.json` file', async () => {
|
||||||
@ -84,6 +160,81 @@ describe('detox application generator', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('with directory specified that is different from as e2e project', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
addProjectConfiguration(tree, 'my-dir-my-app', {
|
||||||
|
root: 'my-dir/my-app',
|
||||||
|
});
|
||||||
|
|
||||||
|
await detoxApplicationGenerator(tree, {
|
||||||
|
e2eName: 'my-app-e2e',
|
||||||
|
e2eDirectory: 'e2e-dir',
|
||||||
|
appProject: 'my-dir-my-app',
|
||||||
|
linter: Linter.None,
|
||||||
|
framework: 'react-native',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate files', () => {
|
||||||
|
expect(tree.exists('apps/e2e-dir/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
||||||
|
expect(
|
||||||
|
tree.exists('apps/e2e-dir/my-app-e2e/src/app.spec.ts')
|
||||||
|
).toBeTruthy();
|
||||||
|
|
||||||
|
const detoxrc = tree
|
||||||
|
.read('apps/e2e-dir/my-app-e2e/.detoxrc.json')
|
||||||
|
.toString();
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
const appsDetoxrcJson = detoxrcJson['apps'];
|
||||||
|
expect(appsDetoxrcJson).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Release-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add update `workspace.json` file', async () => {
|
||||||
|
const workspaceJson = readJson(tree, 'workspace.json');
|
||||||
|
const project = workspaceJson.projects['e2e-dir-my-app-e2e'];
|
||||||
|
|
||||||
|
expect(project.root).toEqual('apps/e2e-dir/my-app-e2e');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update nx.json', async () => {
|
||||||
|
const project = readProjectConfiguration(tree, 'e2e-dir-my-app-e2e');
|
||||||
|
expect(project.tags).toEqual([]);
|
||||||
|
expect(project.implicitDependencies).toEqual(['my-dir-my-app']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('with directory in name', () => {
|
describe('with directory in name', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
addProjectConfiguration(tree, 'my-dir-my-app', {
|
addProjectConfiguration(tree, 'my-dir-my-app', {
|
||||||
@ -91,8 +242,8 @@ describe('detox application generator', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await detoxApplicationGenerator(tree, {
|
await detoxApplicationGenerator(tree, {
|
||||||
name: 'my-dir/my-app-e2e',
|
e2eName: 'my-dir/my-app-e2e',
|
||||||
project: 'my-dir-my-app',
|
appProject: 'my-dir-my-app',
|
||||||
linter: Linter.None,
|
linter: Linter.None,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -103,6 +254,143 @@ describe('detox application generator', () => {
|
|||||||
expect(
|
expect(
|
||||||
tree.exists('apps/my-dir/my-app-e2e/src/app.spec.ts')
|
tree.exists('apps/my-dir/my-app-e2e/src/app.spec.ts')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
|
const detoxrc = tree
|
||||||
|
.read('apps/my-dir/my-app-e2e/.detoxrc.json')
|
||||||
|
.toString();
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
const appsDetoxrcJson = detoxrcJson['apps'];
|
||||||
|
expect(appsDetoxrcJson).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Release-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add update `workspace.json` file', async () => {
|
||||||
|
const workspaceJson = readJson(tree, 'workspace.json');
|
||||||
|
const project = workspaceJson.projects['my-dir-my-app-e2e'];
|
||||||
|
|
||||||
|
expect(project.root).toEqual('apps/my-dir/my-app-e2e');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update nx.json', async () => {
|
||||||
|
const project = readProjectConfiguration(tree, 'my-dir-my-app-e2e');
|
||||||
|
expect(project.tags).toEqual([]);
|
||||||
|
expect(project.implicitDependencies).toEqual(['my-dir-my-app']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('expo', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
addProjectConfiguration(tree, 'my-dir-my-app', {
|
||||||
|
root: 'my-dir/my-app',
|
||||||
|
});
|
||||||
|
|
||||||
|
await detoxApplicationGenerator(tree, {
|
||||||
|
e2eName: 'my-dir/my-app-e2e',
|
||||||
|
appProject: 'my-dir-my-app',
|
||||||
|
linter: Linter.None,
|
||||||
|
framework: 'expo',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate files', () => {
|
||||||
|
expect(tree.exists('apps/my-dir/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
||||||
|
expect(
|
||||||
|
tree.exists('apps/my-dir/my-app-e2e/src/app.spec.ts')
|
||||||
|
).toBeTruthy();
|
||||||
|
|
||||||
|
const detoxrc = tree
|
||||||
|
.read('apps/my-dir/my-app-e2e/.detoxrc.json')
|
||||||
|
.toString();
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
const appsDetoxrcJson = detoxrcJson['apps'];
|
||||||
|
expect(appsDetoxrcJson).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.eas': {
|
||||||
|
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-dir-my-app:download --platform android --output=my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.local': {
|
||||||
|
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-dir-my-app:build --platform android --profile preview --wait --local --no-interactive --output=my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../my-dir/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.eas': {
|
||||||
|
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-dir-my-app:download --platform ios --distribution simulator --output=my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.local': {
|
||||||
|
binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-dir-my-app:build --platform ios --profile preview --wait --local --no-interactive --output=my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../my-dir/my-app/ios/build/Build/Products/Release-iphonesimulator/MyDirMyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add update `workspace.json` file', async () => {
|
it('should add update `workspace.json` file', async () => {
|
||||||
@ -125,8 +413,8 @@ describe('detox application generator', () => {
|
|||||||
|
|
||||||
it('should extend from tsconfig.base.json', async () => {
|
it('should extend from tsconfig.base.json', async () => {
|
||||||
await detoxApplicationGenerator(tree, {
|
await detoxApplicationGenerator(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
linter: Linter.None,
|
linter: Linter.None,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -139,8 +427,8 @@ describe('detox application generator', () => {
|
|||||||
tree.rename('tsconfig.base.json', 'tsconfig.json');
|
tree.rename('tsconfig.base.json', 'tsconfig.json');
|
||||||
|
|
||||||
await detoxApplicationGenerator(tree, {
|
await detoxApplicationGenerator(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
linter: Linter.None,
|
linter: Linter.None,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,46 +4,46 @@
|
|||||||
"apps": {
|
"apps": {
|
||||||
"ios.debug": {
|
"ios.debug": {
|
||||||
"type": "ios.app",
|
"type": "ios.app",
|
||||||
"build": "cd ../<%= appFileName %>/ios && xcodebuild -workspace <%= appClassName %>.xcworkspace -scheme <%= appClassName %> -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
"build": "cd <%= offsetFromRoot %><%= appRoot %>/ios && xcodebuild -workspace <%= appClassName %>.xcworkspace -scheme <%= appClassName %> -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
"binaryPath": "../<%= appFileName %>/ios/build/Build/Products/Debug-iphonesimulator/<%= appClassName %>.app"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/ios/build/Build/Products/Debug-iphonesimulator/<%= appClassName %>.app"
|
||||||
},
|
},
|
||||||
"ios.release": {
|
"ios.release": {
|
||||||
"type": "ios.app",
|
"type": "ios.app",
|
||||||
"build": "cd ../<%= appFileName %>/ios && xcodebuild -workspace <%= appClassName %>.xcworkspace -scheme <%= appClassName %> -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
"build": "cd <%= offsetFromRoot %><%= appRoot %>/ios && xcodebuild -workspace <%= appClassName %>.xcworkspace -scheme <%= appClassName %> -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
"binaryPath": "../<%= appFileName %>/ios/build/Build/Products/Release-iphonesimulator/<%= appClassName %>.app"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/ios/build/Build/Products/Release-iphonesimulator/<%= appClassName %>.app"
|
||||||
},
|
},
|
||||||
<% if (framework === 'expo') { %>
|
<% if (framework === 'expo') { %>
|
||||||
"ios.eas": {
|
"ios.eas": {
|
||||||
"type": "ios.app",
|
"type": "ios.app",
|
||||||
"build": "<%= exec %> nx run <%= appFileName %>:download --platform ios --distribution simulator --output=<%= projectDirectory %>/<%= appFileName %>/dist/",
|
"build": "<%= exec %> nx run <%= appFileName %>:download --platform ios --distribution simulator --output=<%= appRoot %>/dist/",
|
||||||
"binaryPath": "../<%= appFileName %>/dist/<%= appDisplayName %>.app"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.app"
|
||||||
},
|
},
|
||||||
"ios.local": {
|
"ios.local": {
|
||||||
"type": "ios.app",
|
"type": "ios.app",
|
||||||
"build": "<%= exec %> nx run <%= appFileName %>:build --platform ios --profile preview --wait --local --no-interactive --output=<%= projectDirectory %>/<%= appFileName %>/dist/",
|
"build": "<%= exec %> nx run <%= appFileName %>:build --platform ios --profile preview --wait --local --no-interactive --output=<%= appRoot %>/dist/",
|
||||||
"binaryPath": "../<%= appFileName %>/dist/<%= appDisplayName %>.app"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.app"
|
||||||
},
|
},
|
||||||
<% } %>
|
<% } %>
|
||||||
"android.debug": {
|
"android.debug": {
|
||||||
"type": "android.apk",
|
"type": "android.apk",
|
||||||
"build": "cd ../<%= appFileName %>/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug",
|
"build": "cd <%= offsetFromRoot %><%= appRoot %>/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug",
|
||||||
"binaryPath": "../<%= appFileName %>/android/app/build/outputs/apk/debug/app-debug.apk"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/android/app/build/outputs/apk/debug/app-debug.apk"
|
||||||
},
|
},
|
||||||
"android.release": {
|
"android.release": {
|
||||||
"type": "android.apk",
|
"type": "android.apk",
|
||||||
"build": "cd ../<%= appFileName %>/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release",
|
"build": "cd <%= offsetFromRoot %><%= appRoot %>/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release",
|
||||||
"binaryPath": "../<%= appFileName %>/android/app/build/outputs/apk/release/app-release.apk"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/android/app/build/outputs/apk/release/app-release.apk"
|
||||||
},
|
},
|
||||||
<% if (framework === 'expo') { %>
|
<% if (framework === 'expo') { %>
|
||||||
"android.eas": {
|
"android.eas": {
|
||||||
"type": "ios.app",
|
"type": "ios.app",
|
||||||
"build": "<%= exec %> nx run <%= appFileName %>:download --platform android --output=<%= projectDirectory %>/<%= appFileName %>/dist/",
|
"build": "<%= exec %> nx run <%= appFileName %>:download --platform android --output=<%= appRoot %>/dist/",
|
||||||
"binaryPath": "../<%= appFileName %>/dist/<%= appDisplayName %>.apk"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.apk"
|
||||||
},
|
},
|
||||||
"android.local": {
|
"android.local": {
|
||||||
"type": "ios.app",
|
"type": "ios.app",
|
||||||
"build": "<%= exec %> nx run <%= appFileName %>:build --platform android --profile preview --wait --local --no-interactive --output=<%= projectDirectory %>/<%= appFileName %>/dist/",
|
"build": "<%= exec %> nx run <%= appFileName %>:build --platform android --profile preview --wait --local --no-interactive --output=<%= appRoot %>/dist/",
|
||||||
"binaryPath": "../<%= appFileName %>/dist/<%= appDisplayName %>.apk"
|
"binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.apk"
|
||||||
},
|
},
|
||||||
<% } %>
|
<% } %>
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"preset": "../../jest.preset",
|
"preset": "<%= offsetFromRoot %>jest.preset",
|
||||||
"testEnvironment": "./environment",
|
"testEnvironment": "./environment",
|
||||||
"testRunner": "jest-circus/runner",
|
"testRunner": "jest-circus/runner",
|
||||||
"testTimeout": 120000,
|
"testTimeout": 120000,
|
||||||
@ -6,6 +6,6 @@ describe('<%= appClassName %>', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should display welcome message', async () => {
|
it('should display welcome message', async () => {
|
||||||
await expect(element(by.id('heading'))).toHaveText('Welcome <%= appClassName %> 👋');
|
await expect(element(by.id('heading'))).toHaveText('Welcome <%= appDisplayName %> 👋');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { NormalizedSchema } from './normalize-options';
|
|||||||
export function addGitIgnoreEntry(host: Tree, options: NormalizedSchema) {
|
export function addGitIgnoreEntry(host: Tree, options: NormalizedSchema) {
|
||||||
if (host.exists('.gitignore')) {
|
if (host.exists('.gitignore')) {
|
||||||
let content = host.read('.gitignore', 'utf-8');
|
let content = host.read('.gitignore', 'utf-8');
|
||||||
content = `${content}\n${options.projectRoot}/artifacts\n`;
|
content = `${content}\n${options.e2eProjectRoot}/artifacts\n`;
|
||||||
host.write('.gitignore', content);
|
host.write('.gitignore', content);
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`Couldn't find .gitignore file to update`);
|
logger.warn(`Couldn't find .gitignore file to update`);
|
||||||
|
|||||||
@ -10,14 +10,16 @@ describe('Add Linting', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
tree = createTreeWithEmptyV1Workspace();
|
tree = createTreeWithEmptyV1Workspace();
|
||||||
addProject(tree, {
|
addProject(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -25,14 +27,16 @@ describe('Add Linting', () => {
|
|||||||
|
|
||||||
it('should add update `workspace.json` file properly when eslint is passed', () => {
|
it('should add update `workspace.json` file properly when eslint is passed', () => {
|
||||||
addLinting(tree, {
|
addLinting(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -44,14 +48,16 @@ describe('Add Linting', () => {
|
|||||||
|
|
||||||
it('should not add lint target when "none" is passed', async () => {
|
it('should not add lint target when "none" is passed', async () => {
|
||||||
addLinting(tree, {
|
addLinting(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-app',
|
||||||
linter: Linter.None,
|
linter: Linter.None,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,22 +16,22 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
|
|||||||
|
|
||||||
const lintTask = await lintProjectGenerator(host, {
|
const lintTask = await lintProjectGenerator(host, {
|
||||||
linter: options.linter,
|
linter: options.linter,
|
||||||
project: options.projectName,
|
project: options.e2eProjectName,
|
||||||
tsConfigPaths: [
|
tsConfigPaths: [
|
||||||
joinPathFragments(options.projectRoot, 'tsconfig.app.json'),
|
joinPathFragments(options.e2eProjectRoot, 'tsconfig.app.json'),
|
||||||
],
|
],
|
||||||
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
|
eslintFilePatterns: [`${options.e2eProjectRoot}/**/*.{ts,tsx,js,jsx}`],
|
||||||
skipFormat: true,
|
skipFormat: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const reactEslintJson = createReactEslintJson(
|
const reactEslintJson = createReactEslintJson(
|
||||||
options.projectRoot,
|
options.e2eProjectRoot,
|
||||||
options.setParserOptionsProject
|
options.setParserOptionsProject
|
||||||
);
|
);
|
||||||
|
|
||||||
updateJson(
|
updateJson(
|
||||||
host,
|
host,
|
||||||
joinPathFragments(options.projectRoot, '.eslintrc.json'),
|
joinPathFragments(options.e2eProjectRoot, '.eslintrc.json'),
|
||||||
() => reactEslintJson
|
() => reactEslintJson
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -29,14 +29,16 @@ describe('Add Project', () => {
|
|||||||
describe('app at root', () => {
|
describe('app at root', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
addProject(tree, {
|
addProject(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
@ -77,14 +79,16 @@ describe('Add Project', () => {
|
|||||||
describe('app with directory', () => {
|
describe('app with directory', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
addProject(tree, {
|
addProject(tree, {
|
||||||
name: 'my-dir-my-app-e2e',
|
e2eName: 'my-dir-my-app-e2e',
|
||||||
projectName: 'my-dir-my-app-e2e',
|
e2eProjectName: 'my-dir-my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-dir/my-app-e2e',
|
e2eProjectRoot: 'apps/my-dir/my-app-e2e',
|
||||||
project: 'my-dir-my-app',
|
appProject: 'my-dir-my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-dir/my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,13 +12,13 @@ import {
|
|||||||
import { NormalizedSchema } from './normalize-options';
|
import { NormalizedSchema } from './normalize-options';
|
||||||
|
|
||||||
export function addProject(host: Tree, options: NormalizedSchema) {
|
export function addProject(host: Tree, options: NormalizedSchema) {
|
||||||
addProjectConfiguration(host, options.projectName, {
|
addProjectConfiguration(host, options.e2eProjectName, {
|
||||||
root: options.projectRoot,
|
root: options.e2eProjectRoot,
|
||||||
sourceRoot: `${options.projectRoot}/src`,
|
sourceRoot: `${options.e2eProjectRoot}/src`,
|
||||||
projectType: 'application',
|
projectType: 'application',
|
||||||
targets: { ...getTargets(options) },
|
targets: { ...getTargets(options) },
|
||||||
tags: [],
|
tags: [],
|
||||||
implicitDependencies: options.project ? [options.project] : undefined,
|
implicitDependencies: [options.appProject],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ function getTargets(options: NormalizedSchema) {
|
|||||||
targets['test-ios'] = {
|
targets['test-ios'] = {
|
||||||
executor: '@nrwl/detox:test',
|
executor: '@nrwl/detox:test',
|
||||||
...(options.framework === 'react-native'
|
...(options.framework === 'react-native'
|
||||||
? reactNativeTestTarget('ios.sim', options.name)
|
? reactNativeTestTarget('ios.sim', options.e2eName)
|
||||||
: expoTestTarget('ios.sim', options.name)),
|
: expoTestTarget('ios.sim', options.e2eName)),
|
||||||
};
|
};
|
||||||
|
|
||||||
targets['build-android'] = {
|
targets['build-android'] = {
|
||||||
@ -49,8 +49,8 @@ function getTargets(options: NormalizedSchema) {
|
|||||||
targets['test-android'] = {
|
targets['test-android'] = {
|
||||||
executor: '@nrwl/detox:test',
|
executor: '@nrwl/detox:test',
|
||||||
...(options.framework === 'react-native'
|
...(options.framework === 'react-native'
|
||||||
? reactNativeTestTarget('android.emu', options.name)
|
? reactNativeTestTarget('android.emu', options.e2eName)
|
||||||
: expoTestTarget('android.emu', options.name)),
|
: expoTestTarget('android.emu', options.e2eName)),
|
||||||
};
|
};
|
||||||
|
|
||||||
return targets;
|
return targets;
|
||||||
|
|||||||
@ -12,14 +12,16 @@ describe('Create Files', () => {
|
|||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', () => {
|
||||||
createFiles(tree, {
|
createFiles(tree, {
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
|
|||||||
@ -11,11 +11,14 @@ import { join } from 'path';
|
|||||||
import { NormalizedSchema } from './normalize-options';
|
import { NormalizedSchema } from './normalize-options';
|
||||||
|
|
||||||
export function createFiles(host: Tree, options: NormalizedSchema) {
|
export function createFiles(host: Tree, options: NormalizedSchema) {
|
||||||
generateFiles(host, join(__dirname, '../files/app'), options.projectRoot, {
|
generateFiles(host, join(__dirname, '../files/app'), options.e2eProjectRoot, {
|
||||||
...options,
|
...options,
|
||||||
exec: getPackageManagerCommand(detectPackageManager(host.root)).exec,
|
exec: getPackageManagerCommand(detectPackageManager(host.root)).exec,
|
||||||
offsetFromRoot: offsetFromRoot(options.projectRoot),
|
offsetFromRoot: offsetFromRoot(options.e2eProjectRoot),
|
||||||
rootTsConfigPath: getRelativePathToRootTsConfig(host, options.projectRoot),
|
rootTsConfigPath: getRelativePathToRootTsConfig(
|
||||||
|
host,
|
||||||
|
options.e2eProjectRoot
|
||||||
|
),
|
||||||
});
|
});
|
||||||
if (options.js) {
|
if (options.js) {
|
||||||
toJS(host);
|
toJS(host);
|
||||||
|
|||||||
@ -32,17 +32,17 @@ export function expoBuildTarget(platform: 'ios.sim' | 'android.emu') {
|
|||||||
|
|
||||||
export function reactNativeTestTarget(
|
export function reactNativeTestTarget(
|
||||||
platform: 'ios.sim' | 'android.emu',
|
platform: 'ios.sim' | 'android.emu',
|
||||||
name: string
|
e2eName: string
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
options: {
|
options: {
|
||||||
detoxConfiguration: `${platform}.debug`,
|
detoxConfiguration: `${platform}.debug`,
|
||||||
buildTarget: `${name}:build-ios`,
|
buildTarget: `${e2eName}:build-ios`,
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
production: {
|
production: {
|
||||||
detoxConfiguration: `${platform}.release`,
|
detoxConfiguration: `${platform}.release`,
|
||||||
buildTarget: `${name}:build-ios:production`,
|
buildTarget: `${e2eName}:build-ios:production`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -50,25 +50,25 @@ export function reactNativeTestTarget(
|
|||||||
|
|
||||||
export function expoTestTarget(
|
export function expoTestTarget(
|
||||||
platform: 'ios.sim' | 'android.emu',
|
platform: 'ios.sim' | 'android.emu',
|
||||||
name: string
|
e2eName: string
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
options: {
|
options: {
|
||||||
detoxConfiguration: `${platform}.eas`,
|
detoxConfiguration: `${platform}.eas`,
|
||||||
buildTarget: `${name}:build-ios`,
|
buildTarget: `${e2eName}:build-ios`,
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
local: {
|
local: {
|
||||||
detoxConfiguration: `${platform}.local`,
|
detoxConfiguration: `${platform}.local`,
|
||||||
buildTarget: `${name}:build-ios:local`,
|
buildTarget: `${e2eName}:build-ios:local`,
|
||||||
},
|
},
|
||||||
bare: {
|
bare: {
|
||||||
detoxConfiguration: `${platform}.debug`,
|
detoxConfiguration: `${platform}.debug`,
|
||||||
buildTarget: `${name}:build-ios:bare`,
|
buildTarget: `${e2eName}:build-ios:bare`,
|
||||||
},
|
},
|
||||||
production: {
|
production: {
|
||||||
detoxConfiguration: `${platform}.release`,
|
detoxConfiguration: `${platform}.release`,
|
||||||
buildTarget: `${name}:build-ios:production`,
|
buildTarget: `${e2eName}:build-ios:production`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { addProjectConfiguration, Tree } from '@nrwl/devkit';
|
import { addProjectConfiguration, Tree } from '@nrwl/devkit';
|
||||||
import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing';
|
import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing';
|
||||||
import { Linter } from '@nrwl/linter';
|
import { Linter } from '@nrwl/linter';
|
||||||
|
|
||||||
import { Schema } from '../schema';
|
import { Schema } from '../schema';
|
||||||
import { normalizeOptions } from './normalize-options';
|
import { normalizeOptions } from './normalize-options';
|
||||||
|
|
||||||
@ -18,21 +19,23 @@ describe('Normalize Options', () => {
|
|||||||
});
|
});
|
||||||
const schema: Schema = {
|
const schema: Schema = {
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
};
|
};
|
||||||
const options = normalizeOptions(appTree, schema);
|
const options = normalizeOptions(appTree, schema);
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectDirectory: 'apps',
|
e2eProjectDirectory: 'apps',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
|
appRoot: 'apps/my-app',
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -44,19 +47,21 @@ describe('Normalize Options', () => {
|
|||||||
});
|
});
|
||||||
const schema: Schema = {
|
const schema: Schema = {
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
name: 'myAppE2e',
|
e2eName: 'myAppE2e',
|
||||||
project: 'myApp',
|
appProject: 'myApp',
|
||||||
};
|
};
|
||||||
const options = normalizeOptions(appTree, schema);
|
const options = normalizeOptions(appTree, schema);
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
name: 'my-app-e2e',
|
appRoot: 'apps/my-app',
|
||||||
project: 'myApp',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
appProject: 'myApp',
|
||||||
projectDirectory: 'apps',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectDirectory: 'apps',
|
||||||
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -68,21 +73,22 @@ describe('Normalize Options', () => {
|
|||||||
});
|
});
|
||||||
const schema: Schema = {
|
const schema: Schema = {
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
name: 'myAppE2e',
|
e2eName: 'myAppE2e',
|
||||||
project: 'myApp',
|
appProject: 'myApp',
|
||||||
displayName: 'app display name',
|
appDisplayName: 'app display name',
|
||||||
};
|
};
|
||||||
const options = normalizeOptions(appTree, schema);
|
const options = normalizeOptions(appTree, schema);
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
displayName: 'app display name',
|
appDisplayName: 'app display name',
|
||||||
|
appExpoName: 'appdisplayname',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'AppDisplayName',
|
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
name: 'my-app-e2e',
|
appRoot: 'apps/my-app',
|
||||||
project: 'myApp',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'my-app-e2e',
|
appProject: 'myApp',
|
||||||
projectDirectory: 'apps',
|
e2eProjectName: 'my-app-e2e',
|
||||||
projectRoot: 'apps/my-app-e2e',
|
e2eProjectDirectory: 'apps',
|
||||||
|
e2eProjectRoot: 'apps/my-app-e2e',
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -94,21 +100,23 @@ describe('Normalize Options', () => {
|
|||||||
});
|
});
|
||||||
const schema: Schema = {
|
const schema: Schema = {
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
name: 'my-app-e2e',
|
e2eName: 'my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
directory: 'directory',
|
e2eDirectory: 'directory',
|
||||||
};
|
};
|
||||||
const options = normalizeOptions(appTree, schema);
|
const options = normalizeOptions(appTree, schema);
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
projectDirectory: 'apps/directory',
|
appRoot: 'apps/my-app',
|
||||||
projectRoot: 'apps/directory/my-app-e2e',
|
e2eProjectDirectory: 'apps/directory',
|
||||||
name: 'my-app-e2e',
|
e2eProjectRoot: 'apps/directory/my-app-e2e',
|
||||||
directory: 'directory',
|
e2eName: 'my-app-e2e',
|
||||||
projectName: 'directory-my-app-e2e',
|
e2eDirectory: 'directory',
|
||||||
|
e2eProjectName: 'directory-my-app-e2e',
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -120,19 +128,21 @@ describe('Normalize Options', () => {
|
|||||||
});
|
});
|
||||||
const schema: Schema = {
|
const schema: Schema = {
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
name: 'directory/my-app-e2e',
|
e2eName: 'directory/my-app-e2e',
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
};
|
};
|
||||||
const options = normalizeOptions(appTree, schema);
|
const options = normalizeOptions(appTree, schema);
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
project: 'my-app',
|
appProject: 'my-app',
|
||||||
appClassName: 'MyApp',
|
appClassName: 'MyApp',
|
||||||
|
appExpoName: 'MyApp',
|
||||||
appDisplayName: 'MyApp',
|
appDisplayName: 'MyApp',
|
||||||
appFileName: 'my-app',
|
appFileName: 'my-app',
|
||||||
projectRoot: 'apps/directory/my-app-e2e',
|
appRoot: 'apps/my-app',
|
||||||
projectDirectory: 'apps',
|
e2eProjectRoot: 'apps/directory/my-app-e2e',
|
||||||
name: 'directory/my-app-e2e',
|
e2eProjectDirectory: 'apps',
|
||||||
projectName: 'directory-my-app-e2e',
|
e2eName: 'directory/my-app-e2e',
|
||||||
|
e2eProjectName: 'directory-my-app-e2e',
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
getProjects,
|
||||||
getWorkspaceLayout,
|
getWorkspaceLayout,
|
||||||
joinPathFragments,
|
joinPathFragments,
|
||||||
names,
|
names,
|
||||||
@ -9,49 +10,55 @@ import { Schema } from '../schema';
|
|||||||
export interface NormalizedSchema extends Schema {
|
export interface NormalizedSchema extends Schema {
|
||||||
appFileName: string; // the file name of app to be tested
|
appFileName: string; // the file name of app to be tested
|
||||||
appClassName: string; // the class name of app to be tested
|
appClassName: string; // the class name of app to be tested
|
||||||
appDisplayName: string; // the display name of the app to be tested
|
appExpoName: string; // the expo name of app to be tested in class case
|
||||||
projectName: string; // the name of e2e project
|
appRoot: string; // the root path of e2e project. e.g. apps/app-directory/app
|
||||||
projectDirectory: string; // the directory of e2e project
|
e2eProjectName: string; // the name of e2e project
|
||||||
projectRoot: string; // the root path of e2e project
|
e2eProjectDirectory: string; // root path the directory of e2e project directory. e,g. apps/e2e-directory
|
||||||
|
e2eProjectRoot: string; // the root path of e2e project. e.g. apps/e2e-directory/e2e-app
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if options.name = 'my-app-e2e' with no options.directory
|
* if options.e2eName = 'my-app-e2e' with no options.directory
|
||||||
* projectName = 'my-app', projectRoot = 'apps/my-app'
|
* e2eProjectName = 'my-app', e2eProjectRoot = 'apps/my-app'
|
||||||
* if options.name = 'my-app' with options.directory = 'my-dir'
|
* if options.e2eName = 'my-app' with options.e2eDirectory = 'my-dir'
|
||||||
* projectName = 'my-dir-my-app', projectRoot = 'apps/my-dir/my-apps'
|
* e2eProjectName = 'my-dir-my-app', e2eProjectRoot = 'apps/my-dir/my-apps'
|
||||||
*/
|
*/
|
||||||
export function normalizeOptions(
|
export function normalizeOptions(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
options: Schema
|
options: Schema
|
||||||
): NormalizedSchema {
|
): NormalizedSchema {
|
||||||
const { appsDir } = getWorkspaceLayout(host);
|
const { appsDir } = getWorkspaceLayout(host);
|
||||||
const fileName = names(options.name).fileName;
|
const e2eFileName = names(options.e2eName).fileName;
|
||||||
const directoryFileName = options.directory
|
const e2eDirectoryFileName = options.e2eDirectory
|
||||||
? names(options.directory).fileName
|
? names(options.e2eDirectory).fileName
|
||||||
: '';
|
: '';
|
||||||
const projectName = (
|
const e2eProjectName = (
|
||||||
directoryFileName ? `${directoryFileName}-${fileName}` : fileName
|
e2eDirectoryFileName
|
||||||
).replace(new RegExp('/', 'g'), '-');
|
? `${e2eDirectoryFileName}-${e2eFileName}`
|
||||||
const projectDirectory = directoryFileName
|
: e2eFileName
|
||||||
? joinPathFragments(appsDir, directoryFileName)
|
).replace(/\//g, '-');
|
||||||
|
const e2eProjectDirectory = e2eDirectoryFileName
|
||||||
|
? joinPathFragments(appsDir, e2eDirectoryFileName)
|
||||||
: appsDir;
|
: appsDir;
|
||||||
const projectRoot = joinPathFragments(projectDirectory, fileName);
|
const e2eProjectRoot = joinPathFragments(e2eProjectDirectory, e2eFileName);
|
||||||
|
|
||||||
const { fileName: appFileName, className: appClassName } = names(
|
const { fileName: appFileName, className: appClassName } = names(
|
||||||
options.project
|
options.appName || options.appProject
|
||||||
);
|
);
|
||||||
|
const project = getProjects(host).get(options.appProject);
|
||||||
|
const appRoot =
|
||||||
|
project?.root || joinPathFragments(e2eProjectDirectory, appFileName);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...options,
|
...options,
|
||||||
appFileName,
|
appFileName,
|
||||||
appClassName,
|
appClassName,
|
||||||
appDisplayName: options.displayName
|
appDisplayName: options.appDisplayName || appClassName,
|
||||||
? names(options.displayName).className
|
appExpoName: options.appDisplayName?.replace(/\s/g, '') || appClassName,
|
||||||
: appClassName,
|
appRoot,
|
||||||
name: fileName,
|
e2eName: e2eFileName,
|
||||||
projectName,
|
e2eProjectName,
|
||||||
projectDirectory,
|
e2eProjectDirectory,
|
||||||
projectRoot,
|
e2eProjectRoot,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { Linter } from '@nrwl/linter';
|
import { Linter } from '@nrwl/linter';
|
||||||
|
|
||||||
export interface Schema {
|
export interface Schema {
|
||||||
project: string; // name of the project app to be tested
|
appProject: string; // name of the project app to be tested (directory + app name in kebab class)
|
||||||
displayName?: string; // display name of the mobile app
|
appDisplayName?: string; // display name of the app to be tested
|
||||||
name: string; // name of the e2e app
|
appName?: string; // name of app to be tested if different form appProject, case insenstive
|
||||||
directory?: string;
|
e2eDirectory?: string; // the directory where e2e app going to be located
|
||||||
|
e2eName: string; // name of the e2e app
|
||||||
linter?: Linter;
|
linter?: Linter;
|
||||||
js?: boolean;
|
js?: boolean;
|
||||||
skipFormat?: boolean;
|
skipFormat?: boolean;
|
||||||
|
|||||||
@ -4,15 +4,15 @@
|
|||||||
"description": "Create Detox Configuration for the workspace.",
|
"description": "Create Detox Configuration for the workspace.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"project": {
|
"appProject": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The name of the frontend project to test.",
|
"description": "Name of the frontend project to be tested.",
|
||||||
"$default": {
|
"$default": {
|
||||||
"$source": "projectName"
|
"$source": "projectName"
|
||||||
},
|
},
|
||||||
"x-prompt": "What is the name of the frontend project to test?"
|
"x-prompt": "What is the name of the frontend project to test?"
|
||||||
},
|
},
|
||||||
"name": {
|
"e2eName": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Name of the E2E Project.",
|
"description": "Name of the E2E Project.",
|
||||||
"$default": {
|
"$default": {
|
||||||
@ -21,15 +21,23 @@
|
|||||||
},
|
},
|
||||||
"x-prompt": "What name would you like to use for the E2E project?"
|
"x-prompt": "What name would you like to use for the E2E project?"
|
||||||
},
|
},
|
||||||
|
"appName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the app to be tested if different from appProject"
|
||||||
|
},
|
||||||
|
"appDisplayName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Display name of the app to be tested if different from appProject"
|
||||||
|
},
|
||||||
"framework": {
|
"framework": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "App framework to test",
|
"description": "App framework to test",
|
||||||
"enum": ["react-native", "expo"],
|
"enum": ["react-native", "expo"],
|
||||||
"x-prompt": "What app framework should detox test?"
|
"x-prompt": "What app framework should detox test?"
|
||||||
},
|
},
|
||||||
"directory": {
|
"e2eDirectory": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A directory where the project is placed."
|
"description": "A directory where the project is placed relative to apps directory."
|
||||||
},
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"description": "The tool to use for running lint checks.",
|
"description": "The tool to use for running lint checks.",
|
||||||
@ -53,5 +61,5 @@
|
|||||||
"default": false
|
"default": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["name", "project", "framework"]
|
"required": ["e2eName", "appProject", "framework"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,4 +89,244 @@ describe('app', () => {
|
|||||||
|
|
||||||
expect(appTree.exists('apps/my-app/.eslintrc.json')).toBe(true);
|
expect(appTree.exists('apps/my-app/.eslintrc.json')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('detox', () => {
|
||||||
|
it('should create e2e app with directory', async () => {
|
||||||
|
await expoApplicationGenerator(appTree, {
|
||||||
|
name: 'myApp',
|
||||||
|
directory: 'myDir',
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
e2eTestRunner: 'detox',
|
||||||
|
js: false,
|
||||||
|
skipFormat: false,
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
});
|
||||||
|
|
||||||
|
const workspaceJson = readWorkspaceConfiguration(appTree);
|
||||||
|
const projects = getProjects(appTree);
|
||||||
|
expect(projects.get('my-dir-my-app').root).toEqual('apps/my-dir/my-app');
|
||||||
|
expect(workspaceJson.defaultProject).toEqual('my-dir-my-app');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
appTree.exists('apps/my-dir/my-app-e2e/.detoxrc.json')
|
||||||
|
).toBeTruthy();
|
||||||
|
const detoxrc = appTree.read(
|
||||||
|
'apps/my-dir/my-app-e2e/.detoxrc.json',
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
expect(detoxrcJson.apps).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../apps/my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.eas': {
|
||||||
|
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:download --platform android --output=apps/my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.local': {
|
||||||
|
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:build --platform android --profile preview --wait --local --no-interactive --output=apps/my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../apps/my-dir/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../apps/my-dir/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.eas': {
|
||||||
|
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:download --platform ios --distribution simulator --output=apps/my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.local': {
|
||||||
|
binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:build --platform ios --profile preview --wait --local --no-interactive --output=apps/my-dir/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/ios/build/Build/Products/Release-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../apps/my-dir/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create e2e app without directory', async () => {
|
||||||
|
await expoApplicationGenerator(appTree, {
|
||||||
|
name: 'myApp',
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
e2eTestRunner: 'detox',
|
||||||
|
js: false,
|
||||||
|
skipFormat: false,
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
});
|
||||||
|
|
||||||
|
const workspaceJson = readWorkspaceConfiguration(appTree);
|
||||||
|
const projects = getProjects(appTree);
|
||||||
|
expect(projects.get('my-app').root).toEqual('apps/my-app');
|
||||||
|
expect(workspaceJson.defaultProject).toEqual('my-app');
|
||||||
|
|
||||||
|
expect(appTree.exists('apps/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
||||||
|
const detoxrc = appTree.read('apps/my-app-e2e/.detoxrc.json', 'utf-8');
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
expect(detoxrcJson.apps).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.eas': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/MyApp.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:download --platform android --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.local': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/MyApp.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:build --platform android --profile preview --wait --local --no-interactive --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../apps/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.eas': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/MyApp.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:download --platform ios --distribution simulator --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.local': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/MyApp.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:build --platform ios --profile preview --wait --local --no-interactive --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/ios/build/Build/Products/Release-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create e2e app with display name', async () => {
|
||||||
|
await expoApplicationGenerator(appTree, {
|
||||||
|
name: 'myApp',
|
||||||
|
displayName: 'my app name',
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
e2eTestRunner: 'detox',
|
||||||
|
js: false,
|
||||||
|
skipFormat: false,
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
});
|
||||||
|
|
||||||
|
const workspaceJson = readWorkspaceConfiguration(appTree);
|
||||||
|
const projects = getProjects(appTree);
|
||||||
|
expect(projects.get('my-app').root).toEqual('apps/my-app');
|
||||||
|
expect(workspaceJson.defaultProject).toEqual('my-app');
|
||||||
|
|
||||||
|
expect(appTree.exists('apps/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
||||||
|
const detoxrc = appTree.read('apps/my-app-e2e/.detoxrc.json', 'utf-8');
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
expect(detoxrcJson.apps).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.eas': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/myappname.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:download --platform android --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.local': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/myappname.apk',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:build --platform android --profile preview --wait --local --no-interactive --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../apps/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.eas': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/myappname.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:download --platform ios --distribution simulator --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.local': {
|
||||||
|
binaryPath: '../../apps/my-app/dist/myappname.app',
|
||||||
|
build:
|
||||||
|
'npx nx run my-app:build --platform ios --profile preview --wait --local --no-interactive --output=apps/my-app/dist/',
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/ios/build/Build/Products/Release-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -11,9 +11,11 @@ export async function addDetox(host: Tree, options: NormalizedSchema) {
|
|||||||
return detoxApplicationGenerator(host, {
|
return detoxApplicationGenerator(host, {
|
||||||
...options,
|
...options,
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
name: `${options.name}-e2e`,
|
e2eName: `${options.name}-e2e`,
|
||||||
directory: options.directory,
|
e2eDirectory: options.directory,
|
||||||
project: options.projectName,
|
appProject: options.projectName,
|
||||||
|
appDisplayName: options.displayName,
|
||||||
|
appName: options.name,
|
||||||
framework: 'expo',
|
framework: 'expo',
|
||||||
setParserOptionsProject: options.setParserOptionsProject,
|
setParserOptionsProject: options.setParserOptionsProject,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -79,4 +79,114 @@ describe('app', () => {
|
|||||||
const tsconfig = readJson(appTree, 'apps/my-app/tsconfig.json');
|
const tsconfig = readJson(appTree, 'apps/my-app/tsconfig.json');
|
||||||
expect(tsconfig.extends).toEqual('../../tsconfig.json');
|
expect(tsconfig.extends).toEqual('../../tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('detox', () => {
|
||||||
|
it('should create e2e app with directory', async () => {
|
||||||
|
await reactNativeApplicationGenerator(appTree, {
|
||||||
|
name: 'myApp',
|
||||||
|
directory: 'myDir',
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
e2eTestRunner: 'detox',
|
||||||
|
install: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const workspaceJson = readWorkspaceConfiguration(appTree);
|
||||||
|
const projects = getProjects(appTree);
|
||||||
|
expect(projects.get('my-dir-my-app').root).toEqual('apps/my-dir/my-app');
|
||||||
|
expect(workspaceJson.defaultProject).toEqual('my-dir-my-app');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
appTree.exists('apps/my-dir/my-app-e2e/.detoxrc.json')
|
||||||
|
).toBeTruthy();
|
||||||
|
const detoxrc = appTree.read(
|
||||||
|
'apps/my-dir/my-app-e2e/.detoxrc.json',
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
expect(detoxrcJson.apps).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../apps/my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../../apps/my-dir/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../apps/my-dir/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../../apps/my-dir/my-app/ios/build/Build/Products/Release-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../../apps/my-dir/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create e2e app without directory', async () => {
|
||||||
|
await reactNativeApplicationGenerator(appTree, {
|
||||||
|
name: 'myApp',
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
e2eTestRunner: 'detox',
|
||||||
|
install: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const workspaceJson = readWorkspaceConfiguration(appTree);
|
||||||
|
const projects = getProjects(appTree);
|
||||||
|
expect(projects.get('my-app').root).toEqual('apps/my-app');
|
||||||
|
expect(workspaceJson.defaultProject).toEqual('my-app');
|
||||||
|
|
||||||
|
expect(appTree.exists('apps/my-app-e2e/.detoxrc.json')).toBeTruthy();
|
||||||
|
const detoxrc = appTree.read('apps/my-app-e2e/.detoxrc.json', 'utf-8');
|
||||||
|
// Strip trailing commas
|
||||||
|
const detoxrcJson = JSON.parse(
|
||||||
|
detoxrc.replace(/(?<=(true|false|null|["\d}\]])\s*),(?=\s*[}\]])/g, '')
|
||||||
|
);
|
||||||
|
expect(detoxrcJson.apps).toEqual({
|
||||||
|
'android.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/android/app/build/outputs/apk/debug/app-debug.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'android.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/android/app/build/outputs/apk/release/app-release.apk',
|
||||||
|
build:
|
||||||
|
'cd ../../apps/my-app/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
|
||||||
|
type: 'android.apk',
|
||||||
|
},
|
||||||
|
'ios.debug': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/ios/build/Build/Products/Debug-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
'ios.release': {
|
||||||
|
binaryPath:
|
||||||
|
'../../apps/my-app/ios/build/Build/Products/Release-iphonesimulator/MyApp.app',
|
||||||
|
build:
|
||||||
|
"cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13' -derivedDataPath ./build -quiet",
|
||||||
|
type: 'ios.app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -11,9 +11,11 @@ export async function addDetox(host: Tree, options: NormalizedSchema) {
|
|||||||
return detoxApplicationGenerator(host, {
|
return detoxApplicationGenerator(host, {
|
||||||
...options,
|
...options,
|
||||||
linter: Linter.EsLint,
|
linter: Linter.EsLint,
|
||||||
name: `${options.name}-e2e`,
|
e2eName: `${options.name}-e2e`,
|
||||||
directory: options.directory,
|
e2eDirectory: options.directory,
|
||||||
project: options.projectName,
|
appProject: options.projectName,
|
||||||
|
appDisplayName: options.displayName,
|
||||||
|
appName: options.name,
|
||||||
framework: 'react-native',
|
framework: 'react-native',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,10 +8,10 @@ import { join } from 'path';
|
|||||||
import { Schema } from '../schema';
|
import { Schema } from '../schema';
|
||||||
|
|
||||||
export interface NormalizedSchema extends Schema {
|
export interface NormalizedSchema extends Schema {
|
||||||
className: string;
|
className: string; // app name in class name
|
||||||
projectName: string;
|
projectName: string; // directory + app name in kebab case
|
||||||
appProjectRoot: string;
|
appProjectRoot: string; // app directory path
|
||||||
lowerCaseName: string;
|
lowerCaseName: string; // app name in lower case
|
||||||
iosProjectRoot: string;
|
iosProjectRoot: string;
|
||||||
androidProjectRoot: string;
|
androidProjectRoot: string;
|
||||||
parsedTags: string[];
|
parsedTags: string[];
|
||||||
@ -32,7 +32,7 @@ export function normalizeOptions(
|
|||||||
? `${directoryName}/${fileName}`
|
? `${directoryName}/${fileName}`
|
||||||
: fileName;
|
: fileName;
|
||||||
|
|
||||||
const appProjectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
|
const appProjectName = projectDirectory.replace(/\//g, '-');
|
||||||
|
|
||||||
const appProjectRoot = joinPathFragments(appsDir, projectDirectory);
|
const appProjectRoot = joinPathFragments(appsDir, projectDirectory);
|
||||||
const iosProjectRoot = join(appProjectRoot, 'ios');
|
const iosProjectRoot = join(appProjectRoot, 'ios');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user