@startupjs/cli 0.55.0-alpha.9 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,7 +14,7 @@ yarn add @startupjs/cli
14
14
  npx startupjs init myapp --version=next && cd myapp
15
15
  ```
16
16
 
17
- ## Licence
17
+ ## License
18
18
 
19
19
  MIT
20
20
 
package/index.js CHANGED
@@ -2,17 +2,11 @@ const commander = require('commander')
2
2
  const execa = require('execa')
3
3
  const path = require('path')
4
4
  const fs = require('fs')
5
- const Font = require('fonteditor-core').Font
6
5
  const template = require('lodash/template')
7
6
  const CLI_VERSION = require('./package.json').version
8
- const DETOXRC_TEMPLATE = require('./detoxTemplates/detoxrcTemplate')
9
- const ENVDETOX_TEMPLATE = require('./detoxTemplates/envdetoxTemplate')
10
- const FIRSTTEST_TEMPLATE = require('./detoxTemplates/firstTestTemplate')
11
7
 
12
8
  const IS_PRERELEASE = /(?:alpha|canary)/.test(CLI_VERSION)
13
9
  const STARTUPJS_VERSION = IS_PRERELEASE ? `^${CLI_VERSION.replace(/\.\d+$/, '.0')}` : 'latest'
14
- const APP_JSON_PATH = path.join(process.cwd(), 'app.json')
15
- const ROOT_PATH = process.env.ROOT_PATH || process.cwd()
16
10
 
17
11
  let PATCHES_DIR
18
12
  try {
@@ -100,214 +94,45 @@ const REMOVE_FILES = [
100
94
 
101
95
  const SCRIPTS_ORIG = {}
102
96
 
103
- // Web
104
-
105
- SCRIPTS_ORIG.web = ({ reset, vite, webpack } = {}) => {
106
- if (vite && !webpack) {
107
- return SCRIPTS_ORIG.webVite({ reset })
108
- } else {
109
- return SCRIPTS_ORIG.webWebpack
110
- }
111
- }
97
+ // Development
112
98
 
113
- SCRIPTS_ORIG.webVite = ({ reset } = {}) => oneLine(`
114
- ${reset ? 'npx rimraf node_modules/.vite_opt_cache &&' : ''}
115
- npx cross-env VITE_WEB=1
116
- npx vite
99
+ SCRIPTS_ORIG.start = ({ inspect } = {}) => oneLine(`
100
+ npx concurrently
101
+ "${SCRIPTS_ORIG.web}"
102
+ "${SCRIPTS_ORIG.server({ inspect })}"
117
103
  `)
118
104
 
119
- SCRIPTS_ORIG.webWebpack = oneLine(`
105
+ // Web
106
+
107
+ SCRIPTS_ORIG.web = oneLine(`
120
108
  npx cross-env WEBPACK_DEV=1
121
109
  npx webpack-dev-server --config webpack.web.config.cjs
122
110
  `)
123
111
 
124
- // Detox test
125
-
126
- SCRIPTS_ORIG.test = ({ ios, init, build, artifacts, updateScreenshot } = {}) => {
127
- const appName = require(APP_JSON_PATH).name
128
-
129
- if (init) {
130
- try {
131
- SCRIPTS_ORIG.testInit()
132
- } catch (err) {
133
- return oneLine(`
134
- echo '\\033[0;31m${err}'
135
- `)
136
- }
137
-
138
- return `
139
- echo "
140
- \\033[0;32mCreated a directory at path: /e2e
141
- Created a file at path: /e2e/firstTest.e2e.js
142
- Created a file at path: /.env.detox
143
- Created a file at path: /.detoxrc.js
144
- "
145
- `
146
- }
147
-
148
- if (build) {
149
- return SCRIPTS_ORIG.testBuild(appName)
150
- }
151
-
152
- if (ios) {
153
- return SCRIPTS_ORIG.testIos(appName, artifacts, updateScreenshot)
154
- }
155
- }
156
-
157
- SCRIPTS_ORIG.testInit = () => {
158
- const detoxrcPath = path.join(process.cwd(), '.detoxrc.js')
159
- const envdetoxPath = path.join(process.cwd(), '.env.detox')
160
- const e2eDirPath = path.join(process.cwd(), 'e2e')
161
-
162
- fs.writeFileSync(detoxrcPath, DETOXRC_TEMPLATE)
163
- fs.writeFileSync(envdetoxPath, ENVDETOX_TEMPLATE)
164
- if (!fs.existsSync(e2eDirPath)) {
165
- fs.mkdirSync(e2eDirPath)
166
- }
167
- fs.writeFileSync(path.join(e2eDirPath, 'firstTest.e2e.js'), FIRSTTEST_TEMPLATE)
168
- }
169
-
170
- SCRIPTS_ORIG.testBuild = appName => oneLine(`
171
- ${SCRIPTS_ORIG.testJsBundle(appName)}
172
- && npx detox build -c ios
173
- `)
174
-
175
- SCRIPTS_ORIG.testIos = (appName, artifacts, updateScreenshot) => oneLine(`
176
- ${updateScreenshot ? `npx rimraf \`find ${ROOT_PATH} -name "__image_snapshots__" -type d\` &&` : ''}
177
- npx concurrently
178
- -s first -k -n "S,T"
179
- -c white,cyan.bgBlue
180
- "mongo ${appName}_test --eval 'db.dropDatabase();'
181
- && npx cross-env ASYNC=1 startupjs build
182
- && PORT=3001 MONGO_URL=mongodb://localhost:27017/${appName}_test npx startupjs start-production"
183
- "${SCRIPTS_ORIG.testJsBundle(appName)}
184
- && npx wait-on http://localhost:3001
185
- && npx detox test -c ios
186
- ${artifacts ? '--artifacts-location $PWD/artifacts --take-screenshots all' : ''}
187
- ${updateScreenshot ? '--testNamePattern Screenshots:' : ''}"
188
- `)
189
-
190
- SCRIPTS_ORIG.testJsBundle = appName => oneLine(`
191
- mkdir -p ios/build/Build/Products/Release-iphonesimulator/${appName}.app/
192
- && npx cross-env APP_ENV=detox react-native bundle
193
- --entry-file="index.js"
194
- --bundle-output="./ios/build/Build/Products/Release-iphonesimulator/${appName}.app/main.jsbundle"
195
- --reset-cache --dev=false
196
- `)
197
-
198
112
  // Server
199
113
 
200
- SCRIPTS_ORIG.server = ({ inspect, vite, webpack, pure } = {}) => {
201
- if (pure && !webpack) {
202
- return SCRIPTS_ORIG.serverPure({ inspect, vite })
203
- } else {
204
- return SCRIPTS_ORIG.serverWebpack({ inspect, vite })
205
- }
206
- }
207
-
208
- SCRIPTS_ORIG.serverPure = ({ inspect, vite } = {}) => oneLine(`
209
- ${vite ? 'npx cross-env VITE=1' : ''}
210
- npx nodemon
211
- --experimental-specifier-resolution=node
212
- ${inspect ? '--inspect' : ''}
213
- -e js,mjs,cjs,json,yaml server.js
214
- --delay 3
215
- --watch model/
216
- --watch hooks/
217
- --watch cron/
218
- --watch helpers/
219
- --watch serverHelpers/
220
- --watch isomorphicHelpers/
221
- --watch '**/routes.js'
222
- --watch server/
223
- --watch config.json
224
- `)
225
-
226
- SCRIPTS_ORIG.serverWebpack = (options) => oneLine(`
227
- npx concurrently
228
- -r -s first -k -n 'S,B'
229
- -c black.bgWhite,black.bgWhite
230
- "${SCRIPTS_ORIG.serverWebpackRun(options)}"
231
- "${SCRIPTS_ORIG.serverWebpackBuild}"
232
- `)
233
-
234
- SCRIPTS_ORIG.serverWebpackBuild = oneLine(`
235
- npx cross-env WEBPACK_DEV=1
236
- npx webpack --watch --config webpack.server.config.cjs
237
- `)
238
-
239
- SCRIPTS_ORIG.serverWebpackRun = ({ inspect, vite }) => oneLine(`
240
- npx rimraf ./build/server.dev.cjs &&
241
- npx just-wait -t 1000 --pattern ./build/server.dev.cjs &&
242
- ${vite ? 'npx cross-env VITE=1' : ''}
243
- npx nodemon
244
- --experimental-specifier-resolution=node
114
+ SCRIPTS_ORIG.server = ({ inspect } = {}) => oneLine(`
115
+ node
245
116
  ${inspect ? '--inspect' : ''}
246
- ./build/server.dev.cjs
247
- -r source-map-support/register
248
- -e js,mjs,cjs,json,yaml
249
- --watch ./build/server.dev.cjs
250
- `)
251
-
252
- // Start (web and server)
253
-
254
- SCRIPTS_ORIG.start = (options = {}) => {
255
- if (options.pure && !options.webpack) {
256
- return SCRIPTS_ORIG.startPure(options)
257
- } else {
258
- return SCRIPTS_ORIG.startWebpack(options)
259
- }
260
- }
261
-
262
- SCRIPTS_ORIG.startPure = (...args) => oneLine(`
263
- npx concurrently
264
- -s first -k -n 'Server,Web'
265
- -c cyan.bgBlue,gray
266
- "${SCRIPTS_ORIG.server(...args)}"
267
- "${SCRIPTS_ORIG.web(...args)}"
268
- `)
269
-
270
- SCRIPTS_ORIG.startWebpack = (options) => oneLine(`
271
- npx concurrently
272
- -p "{name}:"
273
- -s first -k -n 'Server,ServerBuild,Web'
274
- -c cyan.bgBlue.bold,gray,gray
275
- "${SCRIPTS_ORIG.serverWebpackRun(options)}"
276
- "${SCRIPTS_ORIG.serverWebpackBuild}"
277
- "${SCRIPTS_ORIG.web(options)}"
117
+ --watch
118
+ --experimental-detect-module
119
+ server.js
278
120
  `)
279
121
 
280
- // Production build
122
+ // Production
281
123
 
282
- SCRIPTS_ORIG.build = ({ async, pure } = {}) => oneLine(`
124
+ SCRIPTS_ORIG.build = ({ async } = {}) => oneLine(`
283
125
  npx rimraf ./build &&
284
- ${pure ? '' : 'npx webpack --config webpack.server.config.cjs &&'}
285
126
  ${async ? 'npx cross-env ASYNC=1' : ''}
286
127
  npx webpack --config webpack.web.config.cjs
287
128
  `)
288
129
 
289
- SCRIPTS_ORIG.startProduction = ({ pure }) => {
290
- if (pure) {
291
- return SCRIPTS_ORIG.startProductionPure
292
- } else {
293
- return SCRIPTS_ORIG.startProductionWebpack
294
- }
295
- }
296
-
297
- SCRIPTS_ORIG.startProductionPure = oneLine(`
130
+ SCRIPTS_ORIG.startProduction = oneLine(`
298
131
  npx cross-env NODE_ENV=production
299
- node
300
- --experimental-specifier-resolution=node
301
- server.js
132
+ node --experimental-detect-module server.js
302
133
  `)
303
134
 
304
- SCRIPTS_ORIG.startProductionWebpack = oneLine(`
305
- npx cross-env NODE_ENV=production
306
- node
307
- --experimental-specifier-resolution=node
308
- -r source-map-support/register
309
- build/server.cjs
310
- `)
135
+ // Etc
311
136
 
312
137
  SCRIPTS_ORIG.patchPackage = () => oneLine(`
313
138
  npx patch-package --patch-dir ${PATCHES_DIR} && ${SCRIPTS_ORIG.patchGestureHandler()}
@@ -319,12 +144,8 @@ SCRIPTS_ORIG.patchGestureHandler = () => PATCHES_GESTURE_HANDLER_DIR
319
144
  `)
320
145
  : 'true'
321
146
 
322
- SCRIPTS_ORIG.fonts = () => oneLine(`
323
- npx react-native-asset
324
- `)
325
-
326
147
  SCRIPTS_ORIG.postinstall = () => oneLine(`
327
- ${SCRIPTS_ORIG.patchPackage()} && ${SCRIPTS_ORIG.fonts()}
148
+ ${SCRIPTS_ORIG.patchPackage()}
328
149
  `)
329
150
 
330
151
  const SCRIPTS = {
@@ -341,8 +162,7 @@ const SCRIPTS = {
341
162
  ios: 'react-native run-ios',
342
163
  'ios-release': 'react-native run-ios --configuration Release',
343
164
  build: 'startupjs build --async',
344
- 'start-production': 'startupjs start-production',
345
- fonts: 'startupjs fonts'
165
+ 'start-production': 'startupjs start-production'
346
166
  }
347
167
 
348
168
  const DEFAULT_TEMPLATE = 'ui'
@@ -466,7 +286,7 @@ commander
466
286
 
467
287
  // copy additional startupjs template files over react-native ones
468
288
  console.log(`> Copy template '${template}'`)
469
- for (let subTemplate of TEMPLATES[template].subTemplates) {
289
+ for (const subTemplate of TEMPLATES[template].subTemplates) {
470
290
  const subTemplatePath = path.join(templatesPath, subTemplate)
471
291
  await recursivelyCopyFiles(subTemplatePath, projectPath)
472
292
  }
@@ -494,8 +314,8 @@ commander
494
314
  console.log('> Update config.json')
495
315
  updateConfigJson(projectPath, { projectName })
496
316
 
497
- console.log('> Patch package.json with additional scripts')
498
- patchScriptsInPackageJson(projectPath)
317
+ console.log('> Patch package.json')
318
+ patchPackageJson(projectPath)
499
319
 
500
320
  console.log('> Add additional things to .gitignore')
501
321
  appendGitignore(projectPath)
@@ -529,10 +349,6 @@ commander
529
349
  .command('start')
530
350
  .description('Run "startupjs web" and "startupjs server" at the same time.')
531
351
  .option('-i, --inspect', 'Use node --inspect')
532
- .option('-p, --pure', 'Don\'t use any build system for node')
533
- .option('-v, --vite', 'Use ES Modules and Vite for development instead of Webpack')
534
- .option('-w, --webpack', 'Force use Webpack. This will take priority over --vite and --pure option.')
535
- .option('-r, --reset', 'Reset Vite cache before starting the server. This is helpful when you are directly monkey-patching node_modules')
536
352
  .action(async (options) => {
537
353
  await execa.command(
538
354
  SCRIPTS_ORIG.start(options),
@@ -541,31 +357,19 @@ commander
541
357
  })
542
358
 
543
359
  commander
544
- .command('test')
545
- .description('Init or run E2E Detox tests')
546
- .option('-s, --ios', 'Run tests on iOS simulator')
547
- .option('-i, --init', 'Init test environment in your project')
548
- .option('-b, --build', 'Build ios app /ios/build')
549
- .option('-a, --artifacts', 'Artifacts are disabled by default. To enable them, pass this flag') // https://github.com/wix/Detox/blob/master/docs/APIRef.Artifacts.md
550
- .option('-u, --updateScreenshot', 'Update tests screenshots')
360
+ .command('web')
361
+ .description('Compile (with webpack) and run web')
551
362
  .action(async (options) => {
552
- try {
553
- await execa.command(
554
- SCRIPTS_ORIG.test(options),
555
- { stdio: 'inherit', shell: true }
556
- )
557
- } catch (err) {
558
- console.error('Something went wrong...')
559
- }
363
+ await execa.command(
364
+ SCRIPTS_ORIG.web,
365
+ { stdio: 'inherit', shell: true }
366
+ )
560
367
  })
561
368
 
562
369
  commander
563
370
  .command('server')
564
371
  .description('Compile (with webpack) and run server')
565
372
  .option('-i, --inspect', 'Use node --inspect')
566
- .option('-p, --pure', 'Don\'t use any build system')
567
- .option('-w, --webpack', 'Force use Webpack for server build. This takes priority over --pure option')
568
- .option('-v, --vite', 'Automatically redirect to the web bundle served by Vite. Use this when running Vite for web client')
569
373
  .action(async (options) => {
570
374
  await execa.command(
571
375
  SCRIPTS_ORIG.server(options),
@@ -576,7 +380,6 @@ commander
576
380
  commander
577
381
  .command('build')
578
382
  .description('Build web bundles')
579
- .option('-p, --pure', 'Don\'t use any build system for node')
580
383
  .option('-a, --async', 'Build with splitting code into async chunks loaded dynamically')
581
384
  .action(async (options) => {
582
385
  await execa.command(
@@ -588,23 +391,9 @@ commander
588
391
  commander
589
392
  .command('start-production')
590
393
  .description('Start production')
591
- .option('-p, --pure', 'Don\'t use any build system for node')
592
394
  .action(async (options) => {
593
395
  await execa.command(
594
- SCRIPTS_ORIG.startProduction(options),
595
- { stdio: 'inherit', shell: true }
596
- )
597
- })
598
-
599
- commander
600
- .command('web')
601
- .description('Run web bundling (Webpack). Insead of bundling you can also use Vite and ES Modules by specifying --vite')
602
- .option('-v, --vite', 'Use ES Modules and Vite for development instead of Webpack')
603
- .option('-w, --webpack', 'Force use Webpack. This takes priority over --vite option.')
604
- .option('-r, --reset', 'Reset Vite cache before starting the server. This is helpful when you are directly monkey-patching node_modules')
605
- .action(async (options) => {
606
- await execa.command(
607
- SCRIPTS_ORIG.web(options),
396
+ SCRIPTS_ORIG.startProduction,
608
397
  { stdio: 'inherit', shell: true }
609
398
  )
610
399
  })
@@ -648,18 +437,6 @@ commander
648
437
  )
649
438
  })
650
439
 
651
- commander
652
- .command('fonts')
653
- .description('Rename fonts and react-native smart linking for assets')
654
- .action(async (options) => {
655
- renameFonts()
656
-
657
- await execa.command(
658
- SCRIPTS_ORIG.fonts(options),
659
- { stdio: 'inherit', shell: true }
660
- )
661
- })
662
-
663
440
  // ----- project management commands
664
441
 
665
442
  commander
@@ -691,10 +468,10 @@ async function recursivelyCopyFiles (sourcePath, targetPath) {
691
468
 
692
469
  if (fileNames.length === 0) return
693
470
 
694
- for (let fileName of fileNames) {
695
- let filePath = path.join(sourcePath, fileName)
471
+ for (const fileName of fileNames) {
472
+ const filePath = path.join(sourcePath, fileName)
696
473
  if (fs.lstatSync(filePath).isDirectory()) {
697
- let subTargetPath = path.join(targetPath, fileName)
474
+ const subTargetPath = path.join(targetPath, fileName)
698
475
  await execa(
699
476
  'mkdir',
700
477
  ['-p', subTargetPath],
@@ -711,40 +488,7 @@ async function recursivelyCopyFiles (sourcePath, targetPath) {
711
488
  }
712
489
  }
713
490
 
714
- function renameFonts () {
715
- const FONTS_PATH = process.cwd() + '/public/fonts'
716
- const EXT_WISHLIST = ['eot', 'otf', 'ttf', 'woff', 'woff2']
717
- const IGNORE = ['.gitignore', '.DS_Store', '.gitallowed']
718
-
719
- if (fs.existsSync(FONTS_PATH)) {
720
- const files = fs.readdirSync(FONTS_PATH)
721
-
722
- files.forEach(file => {
723
- if (IGNORE.includes(file)) return
724
-
725
- const [fileName, fileExt] = file.split('.')
726
- if (EXT_WISHLIST.indexOf(fileExt) === -1) {
727
- return console.error(`Font format error: ${fileExt} is not supported`)
728
- }
729
-
730
- const buffer = fs.readFileSync(`${FONTS_PATH}/${file}`)
731
- const font = Font.create(buffer, { type: fileExt })
732
-
733
- if (font.get().name.fontFamily === fileName) return
734
- font.get().name.fontFamily = fileName
735
- font.get().name.fontSubFamily = fileName
736
- font.get().name.preferredFamily = fileName
737
-
738
- const bufferUpdate = font.write({ type: fileExt })
739
- fs.writeFile(`${FONTS_PATH}/${file}`, bufferUpdate, (err) => {
740
- if (err) return console.log(err)
741
- console.log(`${file} rename font-family`)
742
- })
743
- })
744
- }
745
- }
746
-
747
- function patchScriptsInPackageJson (projectPath) {
491
+ function patchPackageJson (projectPath) {
748
492
  const packageJSONPath = path.join(projectPath, 'package.json')
749
493
  const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString())
750
494
 
@@ -752,7 +496,6 @@ function patchScriptsInPackageJson (projectPath) {
752
496
  delete packageJSON.devDependencies['babel-jest']
753
497
  delete packageJSON.devDependencies['react-test-renderer']
754
498
  delete packageJSON.devDependencies.jest
755
- delete packageJSON.jest
756
499
 
757
500
  packageJSON.scripts = {
758
501
  ...packageJSON.scripts,
@@ -809,13 +552,12 @@ function appendGitignore (projectPath) {
809
552
  /data/
810
553
  # Protection from accidentally commiting private npm keys to a public repo
811
554
  .npmrc
812
- # Detox
813
- /artifacts/
814
- /e2e/__diff_output__
815
555
  # Mongo data when running in a docker dev container
816
556
  /.mongo
817
557
  # yarn
818
558
  .yarn/
559
+ # sqlite
560
+ sqlite.db
819
561
  `.replace(/\n\s+/g, '\n')
820
562
 
821
563
  fs.writeFileSync(gitignorePath, gitignore)
@@ -4,21 +4,12 @@ const { pushNotificationsLinkerAndroid } = require('./pushNotificationsLinker')
4
4
  // uncomment when the android in Detox will be implemented
5
5
  // const DetoxLinker = require('./DetoxLinker')
6
6
 
7
- // it isn't need at currunt version because we use react-native-tab-view@3.0.0
8
- // const ActivityLinker = require('./activityLinker')
9
-
10
7
  module.exports = () => {
11
8
  infon('\nRunning Android postlink script\n')
12
9
 
13
- // React-native-gesture-handler is not used in the current version, but it is possible to link for it in the future
14
- // new ActivityLinker().link()
15
- // logn()
16
-
17
10
  new StylesLinker().link()
18
11
 
19
12
  logn()
20
13
  pushNotificationsLinkerAndroid()
21
- // logn()
22
- // new DetoxLinker().link()
23
14
  logn('\n')
24
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startupjs/cli",
3
- "version": "0.55.0-alpha.9",
3
+ "version": "0.55.0",
4
4
  "description": "start, watch and build startupjs project",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
@@ -8,17 +8,15 @@
8
8
  "access": "public"
9
9
  },
10
10
  "dependencies": {
11
- "@startupjs/pm": "^0.55.0-alpha.9",
11
+ "@startupjs/pm": "^0.55.0",
12
12
  "commander": "^3.0.1",
13
13
  "concurrently": "^6.4.0",
14
14
  "cross-env": "^7.0.3",
15
15
  "execa": "^2.0.4",
16
- "fonteditor-core": "2.1.11",
17
16
  "glob": "^7.1.6",
18
17
  "just-wait": "^1.0.11",
19
18
  "lodash": "^4.17.20",
20
19
  "nodemon": "2.0.22",
21
- "react-native-asset": "2.0.1",
22
20
  "rimraf": "^3.0.2",
23
21
  "source-map-support": "^0.5.19",
24
22
  "wait-on": "^5.2.1",
@@ -26,5 +24,5 @@
26
24
  "webpack-cli": "^4.9.1",
27
25
  "webpack-dev-server": "^4.4.0"
28
26
  },
29
- "gitHead": "2c8a2d6d1f32741c62c5d4e85edc7c599d07dad7"
27
+ "gitHead": "96bd7446a242b5c096b03a25a99e8a1fae3bb9a7"
30
28
  }
@@ -1,26 +0,0 @@
1
- module.exports = `const { name } = require('./app.json')
2
- const { configPath } = require('@startupjs/e2e')
3
-
4
- module.exports = {
5
- "testRunner": "jest",
6
- "runnerConfig": configPath,
7
- "configurations": {
8
- "ios": {
9
- "type": "ios.simulator",
10
- "binaryPath": \`ios/build/Build/Products/Release-iphonesimulator/\${name}.app\`,
11
- "build": \`xcodebuild -workspace ios/\${name}.xcworkspace -scheme \${name} -configuration Release -sdk iphonesimulator -derivedDataPath ios/build\`,
12
- "device": {
13
- "type": "iPhone 11"
14
- }
15
- },
16
- "android": {
17
- "binaryPath": "android/app/build/outputs/apk/release/app-release.apk",
18
- "build": "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..",
19
- "type": "android.emulator",
20
- "device": {
21
- "avdName": "Pixel_2_API_28"
22
- }
23
- }
24
- }
25
- }
26
- `
@@ -1 +0,0 @@
1
- module.exports = 'BASE_URL=http://localhost:3001'
@@ -1,18 +0,0 @@
1
- module.exports = `const { x } = require('@startupjs/e2e/helpers')
2
-
3
- describe('Example', () => {
4
- it('should have welcome screen', async () => {
5
- await x('#welcome').toBeVisible()
6
- })
7
-
8
- it('should show hello screen after tap', async () => {
9
- await x('#hello_button').tap()
10
- await x('=Hello!!!').toBeVisible()
11
- })
12
-
13
- it('should show world screen after tap', async () => {
14
- await x('#world_button').tap()
15
- await x('=World!!!').toBeVisible()
16
- })
17
- })
18
- `
@@ -1,220 +0,0 @@
1
- const fs = require('fs')
2
- const path = require('./path')
3
- const { DetoxTest, networkSecurityConfig } = require('./templates')
4
- const { errorn, warnn, logn, infon, debugn } = require('./log')
5
-
6
- class DetoxLinker {
7
- constructor () {
8
- this.networkSecurityConfigFolder = path.networkSecurityConfigFolder
9
- this.networkSecurityConfigRout = path.networkSecurityConfigRout
10
- this.detoxTestFolder = path.detoxTestFolder
11
- this.detoxTestRoute = path.detoxTestRoute
12
- this.mainBuildGradleAndroid = path.mainBuildGradleAndroid
13
- this.appBuildGradleAndroid = path.appBuildGradleAndroid
14
- this.androidManifestXML = path.androidManifestXML
15
- }
16
-
17
- link () {
18
- if (!this.checkRouts()) return
19
-
20
- logn(' Linking build.gradle')
21
- this.linkMainBuildGradle()
22
-
23
- logn(' Linking app/build.gradle')
24
- this.linkAppBuildGradleAndroid()
25
-
26
- logn(' Linking androidManifestXML')
27
- this.linkAndroidManifestXML()
28
-
29
- logn(' create network_security_config.xml')
30
- this.createNetworkSecurityConfig()
31
-
32
- logn(' create DetoxTest.java')
33
- this.createDetoxTest()
34
- }
35
-
36
- linkMainBuildGradle () {
37
- try {
38
- let content = fs.readFileSync(this.mainBuildGradleAndroid, 'utf8')
39
- content = this._linkMainBuildGradle(content)
40
- fs.writeFileSync(this.mainBuildGradleAndroid, content)
41
- infon(' build.gradle linked successfully!')
42
- } catch (e) {
43
- errorn('build.gradle was not linked. ' + e.message)
44
- }
45
- }
46
-
47
- _linkMainBuildGradle (content) {
48
- if (this._isLinkMainBuildGradle(content)) {
49
- warnn(' build.gradle already linked')
50
- return content
51
- }
52
-
53
- const extRegExp = /ext\s*\{[\s\S]*?\}/
54
- const detoxExt = 'ext {\n' +
55
- ' buildToolsVersion = "29.0.2"\n' +
56
- ' minSdkVersion = 18\n' +
57
- ' compileSdkVersion = 29\n' +
58
- ' targetSdkVersion = 29\n' +
59
- ' kotlinVersion = "1.4.21"\n' +
60
- ' }'
61
-
62
- const dependenciesRegExp = /dependencies\s*\{[\s\S]*?\}/
63
- const dependencies = 'dependencies {\n' +
64
- ' classpath("com.android.tools.build:gradle:3.5.3")\n' +
65
- ' // NOTE: Do not place your application dependencies here; they belong\n' +
66
- ' // in the individual module build.gradle files\n' +
67
- ' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"\n' +
68
- ' }'
69
-
70
- const allProgectsPlaceForDetox = /(allprojects[\s\S]*)google\(\)/
71
- const allProgectsDetox = '\n maven {\n' +
72
- ' // All of Detox\' artifacts are provided via the npm module\n' +
73
- ' url "$rootDir/../node_modules/detox/Detox-android"\n' +
74
- ' }\n'
75
-
76
- debugn(' Linking detox files in build.gradle')
77
- return content.replace(extRegExp, detoxExt)
78
- .replace(dependenciesRegExp, dependencies)
79
- .replace(allProgectsPlaceForDetox, content.match(allProgectsPlaceForDetox)[0] + allProgectsDetox)
80
- }
81
-
82
- linkAppBuildGradleAndroid () {
83
- try {
84
- let content = fs.readFileSync(this.appBuildGradleAndroid, 'utf8')
85
- content = this._linkAppBuildGradleAndroid(content)
86
- fs.writeFileSync(this.appBuildGradleAndroid, content)
87
- infon(' app/build.gradle linked successfully!')
88
- } catch (e) {
89
- errorn('app/build.gradle was not linked. ' + e.message)
90
- }
91
- }
92
-
93
- _linkAppBuildGradleAndroid (content) {
94
- if (this._isLinkAppBuildGradleAndroid(content)) {
95
- warnn(' app/build.gradle already linked')
96
- return content
97
- }
98
-
99
- const defaultConfigRegExp = /defaultConfig\s*\{[\s\S]*?\}/
100
- const defaultConfigDetox = content.match(defaultConfigRegExp)[0].replace(/\}$/,
101
- ' testBuildType System.getProperty(\'testBuildType\', \'debug\') // This will later be used to control the test apk build type\n' +
102
- ' testInstrumentationRunner \'androidx.test.runner.AndroidJUnitRunner\'\n' +
103
- ' }'
104
- )
105
-
106
- const progvardRegExp = /proguardFiles getDefaultProguardFile\("proguard-android\.txt"\), "proguard-rules\.pro"/
107
- const progvardDetox = 'proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"\n' +
108
- ' // Detox-specific additions to pro-guard\n' +
109
- // eslint-disable-next-line no-template-curly-in-string
110
- ' proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"'
111
-
112
- const dependencesEndRegExp = /else\s*\{[\s\S]*?implementation jscFlavor[\s\S]*?\}/
113
- const dependencesDetox = content.match(dependencesEndRegExp)[0].replace(/\}$/,
114
- '}\n' +
115
- ' androidTestImplementation(\'com.wix:detox:+\')'
116
- )
117
- return content.replace(defaultConfigRegExp, defaultConfigDetox)
118
- .replace(progvardRegExp, progvardDetox)
119
- .replace(dependencesEndRegExp, dependencesDetox)
120
- }
121
-
122
- linkAndroidManifestXML () {
123
- try {
124
- let content = fs.readFileSync(this.androidManifestXML, 'utf8')
125
- content = this._linkAndroidManifestXML(content)
126
- fs.writeFileSync(this.androidManifestXML, content)
127
- infon(' AndroidManifestXML linked successfully!')
128
- } catch (e) {
129
- errorn('AndroidManifestXML was not linked. ' + e.message)
130
- }
131
- }
132
-
133
- _linkAndroidManifestXML (content) {
134
- if (this._isLinkAndroidManifestXML(content)) {
135
- warnn(' AndroidManifestXML already linked')
136
- return content
137
- }
138
-
139
- const manifestApplicationEndRegExp = /<application[\s\S]*?>/
140
- const manifestApplicationEndDetox = content.match(manifestApplicationEndRegExp)[0].replace(/>$/,
141
- '\n android:networkSecurityConfig="@xml/network_security_config">'
142
- )
143
- return content.replace(manifestApplicationEndRegExp, manifestApplicationEndDetox)
144
- }
145
-
146
- createNetworkSecurityConfig () {
147
- try {
148
- if (fs.existsSync(this.networkSecurityConfigRout)) {
149
- warnn(' network_security_config.xml already exist')
150
- return
151
- }
152
- if (!fs.existsSync(this.networkSecurityConfigFolder)) {
153
- fs.mkdirSync(this.networkSecurityConfigFolder, { recursive: true })
154
- }
155
- fs.writeFileSync(this.networkSecurityConfigRout, networkSecurityConfig)
156
- infon(' network_security_config.xml created successfully!')
157
- } catch (e) {
158
- errorn('network_security_config.xml was not linked. ' + e.message)
159
- }
160
- }
161
-
162
- createDetoxTest () {
163
- try {
164
- if (fs.existsSync(this.detoxTestRoute)) {
165
- warnn(' DetoxTest.java already exist')
166
- return
167
- }
168
- if (!fs.existsSync(this.detoxTestFolder)) {
169
- fs.mkdirSync(this.detoxTestFolder, { recursive: true }, (err) => {
170
- if (err) throw err
171
- })
172
- }
173
- fs.writeFileSync(this.detoxTestRoute, DetoxTest)
174
- infon(' DetoxTest.java created successfully!')
175
- } catch (e) {
176
- errorn('DetoxTest.java was not linked. ' + e.message)
177
- }
178
- }
179
-
180
- _isLinkMainBuildGradle (content) {
181
- return (/kotlinVersion = "1\.4\.21"/.test(content) && /minSdkVersion=18/.test(content)) ||
182
- /classpath "org\.jetbrains\.kotlin:kotlin-gradle-plugin:\$kotlinVersion"/.test(content) ||
183
- /url "\$rootDir\/\.\.\/node_modules\/detox\/Detox-android"/.test(content)
184
- }
185
-
186
- _isLinkAppBuildGradleAndroid (content) {
187
- return /testBuildType System\.getProperty\('testBuildType', 'debug'\)/.test(content) ||
188
- /testInstrumentationRunner 'androidx\.test\.runner\.AndroidJUnitRunner'/.test(content) ||
189
- /proguardFile "\$\{rootProject\.projectDir\}\/\.\.\/node_modules\/detox\/android\/detox\/proguard-rules-app\.pro"/.test(content) ||
190
- /androidTestImplementation\('com\.wix:detox:\+'\)/.test(content)
191
- }
192
-
193
- _isLinkAndroidManifestXML (content) {
194
- return /android:networkSecurityConfig="@xml\/network_security_config"/.test(content)
195
- }
196
-
197
- checkRouts () {
198
- if (!this.mainBuildGradleAndroid) {
199
- errorn(
200
- 'build.gradle not found! Does the file exist in the correct folder?'
201
- )
202
- return false
203
- }
204
- if (!this.appBuildGradleAndroid) {
205
- errorn(
206
- 'app/build.gradle not found! Does the file exist in the correct folder?'
207
- )
208
- return false
209
- }
210
- if (!this.androidManifestXML) {
211
- errorn(
212
- 'main/AndroidManifest.xml not found! Does the file exist in the correct folder?'
213
- )
214
- return false
215
- }
216
- return true
217
- }
218
- }
219
-
220
- module.exports = DetoxLinker
@@ -1,66 +0,0 @@
1
- const fs = require('fs')
2
- const path = require('./path')
3
- const { errorn, warnn, logn, infon, debugn } = require('./log')
4
-
5
- class ActivityLinker {
6
- constructor () {
7
- this.path = path.mainActivityJava
8
- }
9
-
10
- link () {
11
- if (!this.path) {
12
- errorn(
13
- 'MainActivity not found! Does the file exist in the correct folder?'
14
- )
15
- return
16
- }
17
-
18
- logn(' Linking MainActivity')
19
-
20
- try {
21
- let content = fs.readFileSync(this.path, 'utf8')
22
- content = this._link(content)
23
- fs.writeFileSync(this.path, content)
24
- infon(' MainActivity linked successfully!')
25
- } catch (e) {
26
- errorn('MainActivity was not linked. ' + e.message)
27
- }
28
- }
29
-
30
- _link (content) {
31
- if (this._isGestureHandlerLinked(content)) {
32
- warnn(' react-native-gesture already linked')
33
- return content
34
- }
35
-
36
- debugn(' Linking react-native-gesture-handler')
37
- return content
38
- .replace(
39
- 'import com.facebook.react.ReactActivity;',
40
- 'import com.facebook.react.ReactActivity;\n' +
41
- 'import com.facebook.react.ReactActivityDelegate;\n' +
42
- 'import com.facebook.react.ReactRootView;\n' +
43
- 'import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;'
44
- )
45
- .replace(
46
- /\/\*\*\s*\n([^*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*String\s*getMainComponentName\s*\(\)\s*{\s*return.+\s*\}/,
47
- '$&\n' +
48
- ' @Override\n' +
49
- ' protected ReactActivityDelegate createReactActivityDelegate() {\n' +
50
- ' return new ReactActivityDelegate(this, getMainComponentName()) {\n' +
51
- ' @Override\n' +
52
- ' protected ReactRootView createRootView() {\n' +
53
- ' return new RNGestureHandlerEnabledRootView(MainActivity.this);\n' +
54
- ' }\n' +
55
- ' };\n' +
56
- ' }'
57
- )
58
- }
59
-
60
- _isGestureHandlerLinked (content) {
61
- return /new\sRNGestureHandlerEnabledRootView\(MainActivity\.this\)/
62
- .test(content)
63
- }
64
- }
65
-
66
- module.exports = ActivityLinker
@@ -1,35 +0,0 @@
1
- const { APP_NAME } = require('../path')
2
-
3
- exports.DetoxTest = `// Replace "com.example" here and below with your app's package name from the top of MainActivity.java
4
- package com.${APP_NAME};
5
-
6
- import com.wix.detox.Detox;
7
- import com.wix.detox.config.DetoxConfig;
8
-
9
- import org.junit.Rule;
10
- import org.junit.Test;
11
- import org.junit.runner.RunWith;
12
-
13
- import androidx.test.ext.junit.runners.AndroidJUnit4;
14
- import androidx.test.filters.LargeTest;
15
- import androidx.test.rule.ActivityTestRule;
16
-
17
- @RunWith(AndroidJUnit4.class)
18
- @LargeTest
19
- public class DetoxTest {
20
- @Rule
21
- // Replace 'MainActivity' with the value of android:name entry in
22
- // <activity> in AndroidManifest.xml
23
- public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
24
-
25
- @Test
26
- public void runDetoxTests() {
27
- DetoxConfig detoxConfig = new DetoxConfig();
28
- detoxConfig.idlePolicyConfig.masterTimeoutSec = 90;
29
- detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60;
30
- detoxConfig.rnContextLoadTimeoutSec = (com.${APP_NAME}.BuildConfig.DEBUG ? 180 : 60);
31
-
32
- Detox.runTests(mActivityRule, detoxConfig);
33
- }
34
- }
35
- `
@@ -1,7 +0,0 @@
1
- const { DetoxTest } = require('./DetoxTest.java')
2
- const { networkSecurityConfig } = require('./network_security_config.xml')
3
-
4
- module.exports = {
5
- DetoxTest,
6
- networkSecurityConfig
7
- }
@@ -1,7 +0,0 @@
1
- exports.networkSecurityConfig = `<?xml version="1.0" encoding="utf-8"?>
2
- <network-security-config>
3
- <domain-config cleartextTrafficPermitted="true">
4
- <domain includeSubdomains="true">10.0.2.2</domain>
5
- <domain includeSubdomains="true">localhost</domain>
6
- </domain-config>
7
- </network-security-config>`