* Add telemetry for Expo host types (#1204)

* Added handling for an iOS device target concrete device (#1207)

* Added handling for a iOS device target concrete device using format 'device=<iOS_device_name>'
* Update docs

* Add expo tests for different Expo network scenarios (#1208)

* Refactor Expo tests

* Fix dependency vulnerabilities (#1219)

* Bump acorn from 6.4.0 to 6.4.1 in /test/smoke/package (#1222)

Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump minimist from 1.2.0 to 1.2.2

Bumps [minimist](https://github.com/substack/minimist) from 1.2.0 to 1.2.2.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.0...1.2.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump vulnerable dependencies

* Bump several dependencies, fix security vulnerabilities (#1224)

* Fix use of custom Xcode scheme in iOS project (#1213)

* Add unit tests

* Prepare for 0.14.2 (#1225)

* Fix security vulnerabilities in mkdirp package (#1227)

* Fix minimist security vulnerabilities
https://npmjs.com/advisories/1179

* Add YAML pipelines for the smoke tests (#1234)

* Enhance error message in case of error when projectRoot parameter is missing (#1237)

* Add unit tests YAML pipelines (#1241)

* Fix YAML master pipeline (#1244)

* Bump React Native version up to 0.62.0 in smoke tests (#1240)

* Bump RN version up to 0.62.0

* Update Hermes build.gradle

* Fix artifacts generation (#1245)

* Fix smoke tests for Expo 37 SDK (#1247)

* docs: reorganize content of readme.md (#1243)

* transfer launch params (env and envFIle) to packager (#1248)

* transfer launch params (env and envFIle) to packager
add runOption setter to packager for transer launch params

* transfer launch params (env and envFIle) to packager  add runOption setter to packager for transer launch params change args for getEnvArguments and create tests to getEnvArguments

* Update src/common/packager.ts

Co-Authored-By: RedMickey <33267199+RedMickey@users.noreply.github.com>

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: RedMickey <33267199+RedMickey@users.noreply.github.com>

* port and status indicator from packager getters to codestyle

* change dir of tmp .env and add able to use standart .env file ro project path

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: RedMickey <33267199+RedMickey@users.noreply.github.com>

* Update test/extension/generalMobilePlatform.test.ts

Co-Authored-By: RedMickey <33267199+RedMickey@users.noreply.github.com>

* add to readme description  of passing custom enviroment variables for the `react-native` packager

* Update README.md

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* Update README.md

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* fix logic for choice source for env vars
and add check and test for file еxistence

* add some more info to readme

* Update README.md

Co-Authored-By: Yuri Skorokhodov <yurapkr@yandex.ru>

* Update README.md

Co-Authored-By: RedMickey <33267199+RedMickey@users.noreply.github.com>

Co-authored-by: Mikhail Suendukov <mikhail.suendukov@inyar.ru>
Co-authored-by: RedMickey <33267199+RedMickey@users.noreply.github.com>
Co-authored-by: Yuri Skorokhodov <yurapkr@yandex.ru>
Co-authored-by: Yuri Skorokhodov <v-yuskor@microsoft.com>

* Update command palette commands table in documentation (#1250)

* Update Expo documentation (#1251)

* Prepare for 0.15.0 (#1255)

* Migrate unit tests to vscode-test  (#1256)

* Fix security vulnerabilities (#1253)

* Fix vulnerabilities

* Fix fonts usage for Expo 37 (#1260)

* Fix runOptions check for packager (#1264)

* add check run options

* remove font fix for expo 37 from changelog

* fix getiing of status indicator

* fix unit tests in gulpfile

* remove extensions tests from ci

* fix .ci -remove debugger tests

* cleanup

* Delete yarn.lock

Co-authored-by: Yuri Skorokhodov <v-yuskor@microsoft.com>
Co-authored-by: RedMickey <33267199+RedMickey@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Antón Molleda <molant@users.noreply.github.com>
Co-authored-by: Mikhail Suendukov <mikhail.suendukov@inyar.ru>
Co-authored-by: Yuri Skorokhodov <yurapkr@yandex.ru>
This commit is contained in:
JiglioNero 2020-05-18 14:41:55 +03:00 коммит произвёл GitHub
Родитель 984ca036ea
Коммит de838bbf6b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
50 изменённых файлов: 5104 добавлений и 3816 удалений

46
.ci/common-validation.yml Normal file
Просмотреть файл

@ -0,0 +1,46 @@
steps:
- task: NodeTool@0
displayName: 'Use Node 10.x'
inputs:
versionSpec: 10.x
- bash: npm install gulp react-devtools vsce -g --force
displayName: 'npm install gulp react-devtools vsce -g'
- bash: npm ci
displayName: 'npm ci'
- bash: npm run vscode:prepublish
displayName: 'npm run vscode:prepublish'
- bash: |
/usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
echo ">>> Started xvfb"
displayName: Start xvfb
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
- bash: npm run test-localization
displayName: 'Run localization tests'
env:
DISPLAY: ':99.0'
- bash: 'npm test --verbose'
displayName: 'Run host tests'
env:
DISPLAY: ':99.0'
- task: PublishTestResults@2
displayName: 'Publish Extension Test Results'
inputs:
testResultsFiles: test/ExtensionTests.xml
failTaskOnFailedTests: true
testRunTitle: '[Extension Context] $(Agent.OS) React Native unit tests - Attempt №$(System.JobAttempt)'
condition: always()
- task: PublishTestResults@2
displayName: 'Publish Localization Test Results'
inputs:
testResultsFiles: test/LocalizationTests.xml
failTaskOnFailedTests: true
testRunTitle: '[Localization Context] $(Agent.OS) React Native unit tests - Attempt №$(System.JobAttempt)'
condition: always()

68
.ci/master-pipeline.yml Normal file
Просмотреть файл

@ -0,0 +1,68 @@
trigger:
- master
pr:
- none
jobs:
- job: Linux
pool:
vmImage: ubuntu-latest
timeoutInMinutes: 20
steps:
- checkout: self
clean: true
- template: common-validation.yml
- job: Windows
pool:
vmImage: windows-latest
timeoutInMinutes: 20
steps:
- checkout: self
clean: true
- template: common-validation.yml
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: 'Component Detection'
inputs:
ignoreDirectories: '.vscode-test'
- task: msospo.ospo-extension.8d7f9abb-6896-461d-9e25-4f74ed65ddb2.notice@0
displayName: 'NOTICE File Generator'
inputs:
outputfile: 'ThirdPartyNotices_Generated.txt'
additionaldata: release/AdditionalAttributions.txt
- script: 'move ThirdPartyNotices_Generated.txt $(Build.ArtifactStagingDirectory)\ThirdPartyNotices.txt'
displayName: 'Move generated TPN to: $(Build.ArtifactStagingDirectory)'
- bash: gulp release
displayName: 'gulp release'
- bash: 'node -e "console.log(require(''./package.json'').version)" -> version.txt'
displayName: 'Strip version from package.json and save to version.txt'
- task: CopyFiles@2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
Contents: |
*.vsix
CHANGELOG.md
version.txt
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
displayName: 'Publish artifacts: drop-win'
inputs:
ArtifactName: 'drop-win'
- job: macOS
pool:
vmImage: macOS-latest
timeoutInMinutes: 20
steps:
- checkout: self
clean: true
- template: common-validation.yml

34
.ci/pr-pipeline.yml Normal file
Просмотреть файл

@ -0,0 +1,34 @@
pr:
branches:
include: ['*']
trigger:
- none
jobs:
- job: Linux
pool:
vmImage: ubuntu-latest
timeoutInMinutes: 20
steps:
- checkout: self
clean: true
- template: common-validation.yml
- job: Windows
pool:
vmImage: windows-latest
timeoutInMinutes: 20
steps:
- checkout: self
clean: true
- template: common-validation.yml
- job: macOS
pool:
vmImage: macOS-latest
timeoutInMinutes: 20
steps:
- checkout: self
clean: true
- template: common-validation.yml

Просмотреть файл

@ -0,0 +1,93 @@
steps:
- bash: 'rm -rf $(Agent.WorkFolder)/_tools/node'
displayName: 'Clear Node cache'
- bash: |
rm -rf /tmp/metro-bundler-cache-*
rm -rf /tmp/haste-map-react-native-packager-*
rm -rf ~/.cache/yarn
displayName: Clear RN, Yarn cache
condition: and(succeeded(), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')))
- task: NodeTool@0
displayName: Use Node
inputs:
versionSpec: 10.x
checkLatest: true
- task: Npm@1
displayName: 'npm i gulp vsce -g'
inputs:
command: custom
verbose: false
customCommand: 'i gulp vsce -g'
- task: Npm@1
displayName: 'npm ci'
inputs:
command: custom
verbose: false
customCommand: ci
- task: Gulp@0
displayName: 'gulp release'
inputs:
targets: release
- task: CopyFiles@2
displayName: 'Copy Files to: test/smoke/package/resources/drop-win'
inputs:
Contents: '*.vsix'
TargetFolder: 'test/smoke/package/resources/drop-win'
- bash: |
/usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
echo ">>> Started xvfb"
displayName: Start xvfb
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
- bash: |
npm install -g yarn react-native-cli
npm install -g appium@$(appiumVersion)
npm install -g expo-cli@$(expoCLIVersion)
displayName: 'npm install -g yarn react-native-cli expo-cli appium'
- bash: npm install --global windows-build-tools --vs2015
displayName: 'npm install --global windows-build-tools --vs2015'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- bash: |
export MOCHA_FILE=./ReactNativeSmokeTests.xml
export BASIC_ONLY=""
export NIGHTLY=""
if [ $(nightlyBuild) = true ]; then
NIGHTLY="true"
fi
if [ $(basicOnly) = true ]; then
BASIC_ONLY="--basic-only"
fi
yarn smoke-tests $BASIC_ONLY
displayName: 'Run smoke tests'
env:
DISPLAY: ':99.0'
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFiles: './$(smokeTestDirectory)/vscode/test/smoke/ReactNativeSmokeTests.xml'
failTaskOnFailedTests: true
testRunTitle: $(Agent.OS) React Native extension smoke tests - Attempt №$(System.JobAttempt)
condition: always()
- task: ArchiveFiles@2
displayName: 'Archive SmokeTestLogs'
inputs:
rootFolderOrFile: SmokeTestLogs
archiveFile: '$(Build.ArtifactStagingDirectory)/SmokeTestLogs_$(Agent.JobName)'
condition: always()
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: SmokeTestLogs'
inputs:
ArtifactName: SmokeTestLogs
condition: always()

Просмотреть файл

@ -0,0 +1,22 @@
trigger:
- master
pr:
- master
variables:
vswdbotLogin: vswdbot
appiumVersion: 1.17.0
basicOnly: false
expoCLIVersion: latest
nightlyBuild: false
smokeTestDirectory: test/smoke
jobs:
- job: Linux
pool:
name: 'React Native smoke tests - Linux'
timeoutInMinutes: 30
steps:
- checkout: self
clean: true
- template: smoke-tests-common-validation.yml

Просмотреть файл

@ -0,0 +1,22 @@
trigger:
- master
pr:
- master
variables:
vswdbotLogin: vswdbot
appiumVersion: 1.17.0
basicOnly: false
expoCLIVersion: latest
nightlyBuild: false
smokeTestDirectory: test/smoke
jobs:
- job: macOS
pool:
name: 'React Native smoke tests - macOS'
timeoutInMinutes: 60
steps:
- checkout: self
clean: true
- template: smoke-tests-common-validation.yml

Просмотреть файл

@ -0,0 +1,29 @@
trigger:
- master
pr:
- master
variables:
vswdbotLogin: vswdbot
appiumVersion: 1.17.0
basicOnly: false
expoCLIVersion: latest
nightlyBuild: false
smokeTestDirectory: test/smoke
jobs:
- job: Windows
pool:
name: 'React Native smoke tests - Windows'
timeoutInMinutes: 60
steps:
- checkout: self
clean: true
- bash: |
cd $APPDATA && cd ../Local
rm -rf ./Temp/metro-cache
rm -rf ./Temp/haste-map-metro-*
rm -rf ./Temp/react-native-*
rm -rf ./Yarn/Cache
displayName: Clear RN, Yarn cache
- template: smoke-tests-common-validation.yml

Просмотреть файл

@ -1,3 +1,20 @@
## 0.15.0
* Improved extension security [#1227](https://github.com/microsoft/vscode-react-native/pull/1227)
* Added an option to add environment variables to the React Native packager process. [More info](https://github.com/microsoft/vscode-react-native#custom-environment-variables) [#1248](https://github.com/microsoft/vscode-react-native/pull/1248)
* Readme extension homepage has been updated [#1243](https://github.com/microsoft/vscode-react-native/pull/1243), [#1250](https://github.com/microsoft/vscode-react-native/pull/1250), [#1251](https://github.com/microsoft/vscode-react-native/pull/1251)
* Minor logging improvement [#1237](https://github.com/microsoft/vscode-react-native/pull/1237)
* Internal changes:
* Added YAML Azure Pipelines support for the extension repository
* Smoke tests were updated to work with React Native 0.62 and Expo SDK 37
## 0.14.2
* Improved extension security [#1219](https://github.com/microsoft/vscode-react-native/pull/1219), [#1222](https://github.com/microsoft/vscode-react-native/pull/1222), [#1223](https://github.com/microsoft/vscode-react-native/pull/1223), [#1224](https://github.com/microsoft/vscode-react-native/pull/1224)
* Updated extension dependencies [#1224](https://github.com/microsoft/vscode-react-native/pull/1224)
* Added support for running iOS debugging on a specific device using flag `target: 'device=<iOS_device_name>'`. [More info](https://github.com/microsoft/vscode-react-native/blob/master/doc/debugging.md#debugging-on-ios-device). [#1207](https://github.com/microsoft/vscode-react-native/pull/1207)
* Fixed launch of iOS apps with custom project's configuration: custom scheme name, custom app bundle name. [#1213](https://github.com/microsoft/vscode-react-native/pull/1213)
## 0.14.1
* Implemented Expo debugging without mandatory logging in and Internet connection [#1188](https://github.com/microsoft/vscode-react-native/issues/1188)
* Added `expoHostType` parameter to Expo debug scenario configuration. See the [documentation](https://github.com/microsoft/vscode-react-native#react-native-debug-configuration-properties) for more details

468
README.md
Просмотреть файл

@ -1,25 +1,78 @@
# React Native Tools
[![Build status](https://dev.azure.com/vscode-webdiag-extensions/VS%20Code%20WebDiag%20extensions/_apis/build/status/vscode-react-native%20%5Bmaster%5D)](https://dev.azure.com/vscode-webdiag-extensions/VS%20Code%20WebDiag%20extensions/_build/latest?definitionId=2)
[![Build Status](https://dev.azure.com/vscode-webdiag-extensions/VS%20Code%20WebDiag%20extensions/_apis/build/status/%5BUnit%20tests%5D%20vscode-react-native%20%5Bmaster%5D?branchName=master)](https://dev.azure.com/vscode-webdiag-extensions/VS%20Code%20WebDiag%20extensions/_build/latest?definitionId=60&branchName=master)
This extension provides a development environment for React Native projects.
Using this extension, you can debug your code and quickly run `react-native` commands from the command palette.
This VS Code extension provides a development environment for React Native projects.
Using this extension, you can **debug your code and quickly run `react-native` commands** from the command palette.
![React Native features](images/react-features.gif)
## Getting started
* [Install VS Code](https://code.visualstudio.com).
* [Install the extension](https://code.visualstudio.com/docs/editor/extension-gallery) in VS Code:
1. Press `Ctrl + Shift + X` (`Cmd + Shift + X` on macOS), wait a moment while the list of available extensions is populated
2. Type `react-native` and install **React Native Tools**
3. For more guidance view [VS Code Extension Gallery](https://code.visualstudio.com/docs/editor/extension-gallery)
* If you haven't already, set up React Native using the steps detailed on the React Native [getting started documentation](https://facebook.github.io/react-native/docs/getting-started.html)
* Open your React Native project root folder in VS Code.
<!-- TABLE OF CONTENTS -->
# Table of Contents
- [Getting started](#getting-started)
- [React Native commands in the Command Palette](#react-native-commands-in-the-command-palette)
- [Debugging React Native applications](#debugging-react-native-applications)
- [Hermes (Android)](#hermes-android)
- [iOS devices](#ios-devices)
- [Custom scheme for iOS apps](#custom-scheme-for-ios-apps)
- [Expo applications](#expo-applications)
- [Configuring Expo](#configuring-expo)
- [Windows applications](#react-native-for-windows)
- [TypeScript and Haul](#typescript-and-haul)
- [Debugger configuration properties](#debugger-configuration-properties)
- [Customization](#customization)
- [Logging](#logging)
- [Build APK and generate bundle](#build-apk-and-generate-bundle)
- [Specifying custom arguments for `react-native run-*` command](#specifying-custom-arguments-for-react-native-run--command)
- [Setting up the react-native packager](#setting-up-the-react-native-packager)
- [Change project root](#change-project-root)
- [Developing inside a Docker Container](#developing-inside-a-docker-container)
- [Contributing](#contributing)
- [Known Issues](#known-issues)
# Getting started
Before going any further make sure that you:
* [have a working React Native environment](https://reactnative.dev/docs/environment-setup).
* are using [VS Code](https://code.visualstudio.com) and have [installed this extension from the Marketplace](https://marketplace.visualstudio.com/items?itemName=msjsdiag.vscode-react-native).
* have your React Native project root folder open in VS Code.
Please notice that the extension uses `.vscode/.react` directory at the project root to store intermediate files required for debugging. Although these files usually get removed after debug session ends, you may want to add this directory to your project's `.gitignore` file.
## Debugging React Native applications
# React Native commands in the Command Palette
In the Command Palette, type `React Native` and choose a command.
![React Native commands](images/command-palette.png)
The **Run Android** command triggers `react-native run-android` and starts your app for Android.
The **Run iOS** command similarly triggers `react-native run-ios` and starts your app in the iOS simulator (e.g. iPhone 6).
The **Packager** commands allow you to start/stop the [**Metro Bundler**](https://github.com/facebook/metro-bundler) (formerly React Packager).
The full list of commands is:
|Name|Description|
|---|---|
|Run Android on Emulator|Run an Android application on Emulator. Launch order: check target platform support, load run arguments, start Packager, run app in all connected emulators|
|Run Android on Device|Run an Android application on Device. Launch order: check target platform support, load run arguments, start Packager, run app in all connected devices|
|Run iOS on Simulator|Run an iOS application on Simulator. Launch order: load run arguments, check target platform support, start Packager, run app in only one connected emulator|
|Run iOS on Device|Run an iOS application on Device. Launch order: load run arguments, check target platform support, start Packager, run app in only one connected device|
|Run Expo|Run Exponent application. Launch order: login to exponent, load run arguments, start Packager, run app|
|Start Packager|Start Packager in context project workspace folder|
|Stop Packager|Stop Packager|
|Restart Packager|Restart Packager|
|Publish To Expo|Publish to Exponent Host. Launch order: login to exponent, execute `Run Expo` command, then publish app to host|
|Show Dev Menu|Show development menu for running aplication on iOS or Android device or emulator|
|ReloadApp|Reload an application|
|Run Element Inspector|Load development tools for inspect application UI elements|
# Debugging React Native applications
To start debugging create a new debug configuration for your ReactNative app in your `.vscode/launch.json`. Adding a new configuration can be done by opening your `launch.json` file and clicking on `Add Configuration...` button and choosing a relevant debug configuration. All available debug configurations for ReactNative can be accessed by typing in *ReactNative* and picking one from the list populated by Intellisense as shown in the image below.
@ -33,25 +86,179 @@ VS Code will generate a `launch.json` in your project with some default configur
![React Native launch targets](images/debug-targets.png)
Once app is loaded and ran, [open Developer Menu](https://facebook.github.io/react-native/docs/debugging#accessing-the-in-app-developer-menu) inside your application and enable remote debugging by clicking on `Debug JS Remotely` button.
Once app is loaded and running, [open the developer menu](https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu) inside your application and enable remote debugging by clicking on `Debug JS Remotely` button.
![React Native enable remote debug](images/enable-remote-debug.png)
You can debug your app on an Android emulator, Android device or iOS simulator. This extension provides [experimental support](doc/debugging.md#debugging-on-ios-device) for iOS devices.
The extension allows you to debug multiple devices and configurations, please read the following sections for more information for your particular use case.
Since version 0.60.2 [React Native supports Hermes engine for Android applications](https://facebook.github.io/react-native/blog/2019/07/17/hermes). Extension provides experimental support for debugging React Native Android applications with Hermes enabled. Please see [Debugging React Native apps with Hermes enabled](doc/debugging.md#debugging-react-native-apps-with-hermes-enabled) for more details.
## Hermes (Android)
More information about debugging using VS Code can be found in this [guide](https://code.visualstudio.com/docs/editor/debugging).
Hermes is the new JavaScript engine optimized for running React Native apps on Android. It improves app performance and decreases app size.
See [Setting up debug environment](doc/debugging.md) for more details.
Click [here](https://reactnative.dev/docs/hermes) to learn more about Hermes.
## React Native debug configuration properties
Debugging apps with Hermes enabled is currently experimental. Please, see [this issue](https://github.com/microsoft/vscode-react-native/issues/1073) for current known issues on Hermes support.
To debug while using Hermes engine, please choose one of the following debug configurations:
- React Native (Hermes): Debug Android - Experimental
```json
{
"name": "Debug Android (Hermes) - Experimental",
"cwd": "${workspaceFolder}",
"type": "reactnativedirect",
"request": "launch",
"platform": "android"
}
```
- React Native (Hermes): Attach to Hermes application - Experimental
```json
{
"name": "Attach to Hermes application - Experimental",
"cwd": "${workspaceFolder}",
"type": "reactnativedirect",
"request": "attach"
}
```
## iOS devices
Debugging on an iOS device requires following manual steps:
* Install [ios-deploy](https://www.npmjs.com/package/ios-deploy) `npm install -g ios-deploy`.
* Install a valid iOS development certificate.
* In your project's `launch.json` file set `target` to `device`. If you need to specify the exact device to run, you can set `target` to `device=<iOS_device_name>`, or you can also use `runArguments` property to specify a particular device to run on in case multiple devices are connected (e.g. `"runArguments": [ "--device", "My iPhone" ]`)
* Choose the **Debug iOS** option from the "Configuration" dropdown and press F5.
* Shake the device to open the development menu and select "Debug JS Remotely".
## Customs scheme for iOS apps
If you want to use a custom scheme for your application you can either pass it as part of the `runArguments` parameter arguments, or set the `scheme` configuration parameter as shown below:
```js
"runArguments": ["--scheme", "customScheme", ...]
// or
"runArguments": ["--scheme=customScheme", ...]
// or
"scheme" : "customScheme"
```
Please be aware, specifying the scheme value as a part of the `runArguments` parameter arguments will override the `scheme` configuration parameter value, if it set.
## Expo applications
To debug a project created using Expo or the `create-react-native-app` task, you can use embedded support for Expo.
Prepare your environment by following the [Expo CLI Quickstart instruction](https://reactnative.dev/docs/environment-setup).
For correct work with Expo this extension **`requires Android SDK`**.
So also pay attention to the `React Native CLI Quickstart` tab, where you can find the Android SDK installation guide:
- Install the [Expo app](https://getexponent.com/) on the target device or emulator
- Ensure that the `Android SDK` is installed on your computer (You may install it using the [`React Native CLI Quickstart` guide](https://reactnative.dev/docs/environment-setup))
- Ensure that the `expo-cli` is installed globally (`npm install -g expo-cli`)
You can verify that everything is working correctly and that the environment is ready for use with the `npx react-native doctor` command.
To start debugging in Expo follow these steps:
1. Open your project in VS Code with this extension installed.
1. Create a debug configuration (as described in [Debugging React Native applications](#debugging-react-native-applications)), select `Debug in Exponent` in the debug drop-down menu, and start debugging
1. Wait while some dependencies are configured - the extension will install [`Expo Development Library(@expo/xdl)`](https://www.npmjs.com/package/@expo/xdl) when this feature is used for the first time.
1. If you have not used Exponent on this system before, you will be prompted for an Exponent username and password.
Exponent account allows you to use Expo cloud services. More info about how it works is available [here](https://docs.expo.io/versions/latest/workflow/how-expo-works/).
If you have not created an Exponent account, then specifying a new username and password will create one.
Note that there is no e-mail associated with the account, and no way to recover a forgotten password.
If you don't want to create an Exponent account, you can specify `expoHostType` parameter in your debug configuration to make Expo work locally (via LAN or on localhost).
1. Once the packager starts, the extension will open a separate tab with QR code to scan from the Exponent app. Once you do so, the Exponent app will connect to the packager and begin running your app.
1. Once the app is loaded and running, [open the developer menu](https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu) and enable remote debugging by clicking on `Debug JS Remotely` button.
![React Native developer menu](./images/enable-remote-debug.png)
From here you can run and debug the app as normal.
### Configuring Expo
The extension supports running through Exponent not just the applications created with Expo but even pure React Native applications (in that case you need to add `expo` package to `node_modules` in order to make it work with Expo: `npm install expo --save-dev`. In either cases it uses `app.json` configuration file in the root of the project.
If you are running `Debug in Exponent` configuration or any of pallette commands like `Run in Exponent`, `Publish to Exponent` then this file will be created automatically if absent or updated with the following basic configuration section:
```json
{
"expo": {
"slug": "MyApp", // Project slug
"name": "MyApp", // Project name
"sdkVersion": "31.0.0", // Expo SDK version
"entryPoint": ".vscode\\exponentIndex.js" // Entrypoint for the project
},
"name": "MyApp" // Project name
}
```
Full list of configuration parameters for `expo` section in `app.json` may be found on [official Expo documentation page](https://docs.expo.io/versions/latest/workflow/configuration).
For running **pure React Native app**, the extension, creates and uses `.vscode/exponentIndex.js` which points to the app entrypoint (`index.js` or `index.android.js` or `index.ios.js`) file.
If you want to change your app entrypoint (for example, from `index.js` to `index.android.js`), delete `.vscode/exponentIndex.js` and then restart your debugging session.
**NOTE**: The extension caches the version of the exponent SDK used by your project. This is helpful since we don't want to install the SDK each time you run exponent. If you want the extension to update the SDK version based on your React Native version, just restart VS Code and if it is supported it should work. If it does not please open an issue.
## Windows applications
You can debug UWP and WPF React Native for Windows applications by changing the `platform` in your `launch.json` configuration:
* For `UWP` use `windows`:
```json
{
"name": "Debug UWP",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "windows"
}
```
* For `WPF` use `wpf`:
```json
{
"name": "Debug WPF",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "wpf"
}
```
## TypeScript and Haul
If you use [Haul](https://callstack.github.io/haul/users.html) as your React Native bundler instead of the default [Metro](https://facebook.github.io/metro/), you must add `sourceMapPathOverrides` to the `launch.json` file.
For example:
```json
{
// Other configurations
"sourceMapPathOverrides": {
"webpack:///./~/*": "${workspaceRoot}/node_modules/*",
"webpack:///./*": "${workspaceRoot}/*",
"webpack:///*": "*"
}
}
```
Learn more about source map overrides [here](https://github.com/Microsoft/vscode-node-debug2#sourcemappathoverrides)
## Debugger configuration properties
The following is a list of all the configuration properties the debugger accepts in `launch.json`:
|Name |Description|Type|Defaults|
|---|---|---|---|
|`cwd`|The path to the project root folder|`string`|`${workspaceFolder}`|
|`sourceMaps`|Whether to use JavaScript source maps to map the generated bundled code back to its original sources|`boolean`|`true`|
|`sourceMapPathOverrides`|A set of mappings for rewriting the locations of source files from what the source map says, to their locations on disk. See [Debugging with TypeScript and Haul](https://github.com/Microsoft/vscode-react-native/blob/master/doc/debugging.md#debugging-with-typescript-and-haul) for details|`object`|n/a|
|`sourceMapPathOverrides`|A set of mappings for rewriting the locations of source files from what the source map says, to their locations on disk. See [Debugging with TypeScript and Haul](#typescript-and-haul) for details|`object`|n/a|
|`trace`|Logging level in debugger process. May be useful for diagnostics. If set to "Trace" all debugger process logs will be available in `Debug Console` output window|`string`|`log`|
|`address`|TCP/IP address of packager to attach to for debugging|`string`|`localhost`|
|`port`|Port of packager to attach to for debugging|`string`|`8081`|
@ -60,7 +267,7 @@ See [Setting up debug environment](doc/debugging.md) for more details.
|`skipFiles`|An array of file or folder names, or glob patterns, to skip when debugging|`array`|`[]`|
|`debuggerWorkerUrlPath`|Path to the app debugger worker to override. For example, if debugger tries to attach to http://localhost:8081/debugger-ui/debuggerWorker.js and you get 404 error from packager output then you may want to change debuggerWorkerUrlPath to another value suitable for your packager (\"debugger-ui\" will be replaced with the value you provide)|`string`|`debugger-ui/`|
|`platform`|The platform to target. Possible values: `android`, `ios`, `exponent`, `windows`, `wpf`|`string`|n/a|
|`target`|Target to run on. Possible values: `simulator`, `device`, `<Android emulator/device id>`, `<iOS simulator/device name>`|`string`|`simulator`|
|`target`|Target to run on. Possible values: `simulator`, `device`, `device=<iOS device name>`, [`<Android emulator/device id>`](https://github.com/react-native-community/cli/blob/master/docs/commands.md#--deviceid-string), `<iOS simulator name>`|`string`|`simulator`|
|`logCatArguments`|Arguments to be used for LogCat (The LogCat output will appear on an Output Channel). It can be an array such as: `[":S", "ReactNative:V", "ReactNativeJS:V"]`|`array`|`["*:S", "ReactNative:V", "ReactNativeJS:V"]`|
|`runArguments`|Run arguments to be passed to `react-native run-<platform>` command (override all other configuration params)|`array`|n/a|
|`launchActivity`|The Android activity to be launched for debugging, e.g. it specifies [`--main-activity`](https://github.com/react-native-community/cli/blob/master/docs/commands.md#--main-activity-string) parameter in `react-native` run arguments|`string`|`MainActivity`|
@ -69,41 +276,222 @@ See [Setting up debug environment](doc/debugging.md) for more details.
|`envFile`|Absolute path to a file containing environment variable definitions|`string`|`${workspaceFolder}/.env`|
|`variant`|A variant to be passed to `react-native run-android`, e.g. use `devDebug` to specify `--variant=devDebug`|`string`|n/a|
|`scheme`|A scheme name to be passed to `react-native run-ios`, e.g. `devDebug` to specify `--scheme=devDebug`|`string`|n/a|
|`productName`|iOS bundle display name e.g. `AwesomeProject` value means that extension will search for `AwesomeProject.app` bundle|`string`|n/a|
|`productName`|iOS bundle display name e.g. `AwesomeProject` value means that the extension will search for `AwesomeProject.app` bundle|`string`|n/a|
## Using React Native commands in the Command Palette
# Customization
In the Command Palette, type `React Native` and choose a command.
The extension can be further customized for other React Native scenarios. These are the most common:
![React Native commands](images/command-palette.png)
## Logging
The **Run Android** command triggers `react-native run-android` and starts your app for Android.
To expose internal logs to the output, set the following properties:
The **Run iOS** command similarly triggers `react-native run-ios` and starts your app in the iOS simulator (iPhone 6).
```json
{
"react-native-tools": {
"logLevel": "Trace"
}
}
```
The **Packager** commands allow you to start/stop the [**Metro Bundler**](https://github.com/facebook/metro-bundler) (formerly React Packager).
`logLevel` can be `None` (no logs), `Error`, `Warning`, `Info`, `Debug`, `Trace` (all logs). Default is `Info`.
## Using Expo
We support using Expo to run, debug and publish applications. For more details about configuring and debugging Expo applications see [Expo docs](doc/expo.md).
## Build APK and generate bundle
## Developing inside a Docker Container
You can add VSCode tasks to build an `.apk` file and generate iOS/Android bundles.
The extension provides support of [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview) features on Linux. For more details about configuring and debugging React Native Android applications inside Docker Container see [Containerization docs](doc/containerization.md).
The following is an example of a `tasks.json` for `react-native init` projects.
Place it in the `.vscode` folder in your project to use it:
## Build APK and Generate Bundle
```json
{
"version": "2.0.0",
"presentation": {
"reveal": "always",
"panel": "new"
},
"tasks": [
{
"taskName": "Build APK Debug",
"group": "build",
"type": "shell",
"windows": {
"command": "cd android; if($?) {./gradlew assembleDebug}"
},
"linux": {
"command": "cd android && ./gradlew assembleDebug"
}
},
{
"taskName": "Build APK Release",
"group": "build",
"type": "shell",
"windows": {
"command": "cd android; if($?) {./gradlew assembleRelease}"
},
"linux": {
"command": "cd android && ./gradlew assembleRelease"
}
},
{
"taskName": "Generate Android Bundle",
"group": "build",
"type": "shell",
"command": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/main.jsbundle"
},
{
"taskName": "Generate iOS Bundle",
"group": "build",
"type": "shell",
"command": "react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/main.jsbundle"
}
]
}
```
You can add VSCode tasks to build an .apk file and generate iOS/Android bundles. See [here](doc/tasks.md) for more info.
To learn more about `tasks` in VSCode read [the official documentation](https://code.visualstudio.com/docs/editor/tasks).
## Customization
Visit [generating Signed APK](https://reactnative.dev/docs/signed-apk-android.html) to learn more about this subject.
Extension can be customized for different use cases. Please, follow [Customization](doc/customization.md) section for more details.
## Specifying custom arguments for `react-native run-*` command
## Contributing
Using custom run arguments for `react-native run-<platform>`:
**NOTE:** This overrides all other configuration parameters.
Please see our [contributing guide](CONTRIBUTING.md) for more information
```json
{
"react-native.android.runArguments.simulator": ["--appFolder", "/Users/test/AwesomeProject/android/app", "--deviceId", "emulator-5555"],
"react-native.ios.runArguments.device": ["--project-path", "ios", "--device", "Max's iPhone"],
}
```
## Known Issues
**NOTE:** You can get the list of installed simulator devices by:
iOS devices (macOS only):
```
xcrun simctl list --json devices
```
Android devices:
```
adb devices
```
**NOTE:** If you want to run the application on an iOS device, make sure you have `ios-deploy` installed globally.
```npm install -g ios-deploy```
## Setting up the react-native packager
To use a custom port for the `react-native` packager:
```json
{
"react-native": {
"packager" : {
"port": portNumber
}
}
}
```
If you change this port, then for iOS device and simulator scenarios you will have to modify the native code files. [Instructions here](https://blog.binoy.io/running-react-native-on-a-different-port-7deb43887cd4).
If you use Android, you need to change the debug server by:
1. CTRL+M(CMD+M) in the emulator
2. Go to Dev Settings
3. Debug server host for device => enter localhost:\<yourPortNumber\>.
4. Reload application (press `R` twice)
**NOTE:** Some aspects of React Native hard-code the port to the default as specified in [this issue](https://github.com/facebook/react-native/issues/9145).
### Custom environment variables
Extension supports passing custom environment variables to the React Native Packager process context. To add custom variables you can create `.env` file in the root folder of your project and add needed environment variables in the following format:
```
Variable1_name=Variable1_value
Variable2_name=Variable2_value
```
Variables that are declared in this `.env` file can override the original environment variables from `process.env` of the Packager process.
It is possible to transfer environment variables (via `env` and `envFile` arguments in `launch.json`) from the `launch` or `attach` debug scenarios to the Packager. If these variables are defined, then they will be used, otherwise the `.env` file is used.
## Change project root
To specify a subfolder in which the react-native project is located, set `react-native-tools.projectRoot`. You can use either an absolute or relative path here:
```json
{
"react-native-tools": {
"projectRoot": "./your/react-native/project"
}
}
```
# Developing inside a Docker Container
The extension supports [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview) features on Linux. Please follow the [VS Code official documentation](https://code.visualstudio.com/docs/remote/containers) to setup your environment to use a remote development approach.
You can use [official React Native Docker image](https://hub.docker.com/r/reactnativecommunity/react-native-android) provided by the [react-native-community](https://github.com/react-native-community/docker-android).
Here are the steps to run React Native debugging inside a Docker Container on a real Android device:
1. Open Command Palette and run the following command
```
Remote-Containers: Add Development Container Configuration Files...
```
Then select `Existing Dockerfile` to create `.devcontainer/devcontainer.json` configuration file.
1. Сreate Dockerfile extending [reactnativecommunity/react-native-android image](https://hub.docker.com/r/reactnativecommunity/react-native-android). For example you can use the following Dockerfile:
```
FROM reactnativecommunity/react-native-android:latest
RUN npm install -g expo-cli react-native-cli
```
1. Configure your `devcontainer.json` file as needed. Below is a sample configuration:
```json
{
"name": "React Native Android Container",
// Sets the run context to one level up instead of the .devcontainer folder.
"context": "..",
// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
"dockerFile": "Dockerfile",
// The optional 'runArgs' property can be used to specify additional runtime arguments.
"runArgs": [
"--privileged", // give all capabilities to a container, in other words, the container can then do almost everything that the host can do
"--net", "host", // forwarding all host machine ports
"-v", "/dev/bus/usb:/dev/bus/usb" // mount connected USB devices to a container
],
"settings": {
// This will ignore your local shell user setting for Linux since shells like zsh are typically
// not in base container images. You can also update this to an specific shell to ensure VS Code
// uses the right one for terminals and tasks. For example, /bin/bash (or /bin/ash for Alpine).
"terminal.integrated.shell.linux": null
},
// Add the IDs of extensions you want installed when the container is created in the array below.
"extensions": ["msjsdiag.vscode-react-native"]
}
```
1. Open Command Palette and run the following command `Remote-Containers: Open Folder in Container` to reopen your project in a container
1. Connect your device via USB and start debugging the same way as on local machine.
Currently the above scenario doesn't work on macOS and Windows. Docker Container implementation on these OS uses Virtual Machine tools which may have problems with USB forwarding for mobile devices.
# Contributing
Please see our [contributing guide](CONTRIBUTING.md) for more information.
# Known Issues
Here is the list of common known issues you may experience while using the extension:
@ -117,12 +505,12 @@ Can't communicate with socket pipe | (Linux only) If you have two workspaces
[Known-Issues](https://github.com/Microsoft/vscode-react-native/issues?q=is%3Aissue+label%3Aknown-issues) provides a complete list of active and resolved issues.
## Telemetry reporting
# Telemetry reporting
VS Code React Native extension collects usage data and sends it to Microsoft to help improve our products and services. Read our [privacy statement](https://www.visualstudio.com/en-us/dn948229) to learn more.
If you dont wish to send usage data to Microsoft, edit `VSCodeTelemetrySettings.json` file at `~/.vscode-react-native` and add `optIn:false`.
## Code of conduct
# Code of conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

Просмотреть файл

@ -1,58 +0,0 @@
# Containerization
The extension supports [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview) features on Linux.
Please follow the [VS Code official documentation](https://code.visualstudio.com/docs/remote/containers) to setup your environment to use remote development approach.
## Developing inside a Docker Container on Linux
For development of React Native Android application in Docker Container you can use [official React Native Docker image](https://hub.docker.com/r/reactnativecommunity/react-native-android) provided by [react-native-community](https://github.com/react-native-community/docker-android).
Here are the steps to run React Native debugging inside Docker Container on a real Android device:
1. Open Command Palette and run the following command
```
Remote-Containers: Add Development Container Configuration Files...
```
Then select `Existing Dockerfile` to create `.devcontainer/devcontainer.json` configuration file.
1. Сreate Dockerfile extending [reactnativecommunity/react-native-android image](https://hub.docker.com/r/reactnativecommunity/react-native-android). For example you can use the following Dockerfile:
```
FROM reactnativecommunity/react-native-android:latest
RUN npm install -g expo-cli react-native-cli
```
1. Configure your `devcontainer.json` file just about like this: <br> **NOTE**: This is just a sample of configuration, you can modify your `devcontainer.json` file as you need.
```
{
"name": "React Native Android Container",
// Sets the run context to one level up instead of the .devcontainer folder.
"context": "..",
// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
"dockerFile": "Dockerfile",
// The optional 'runArgs' property can be used to specify additional runtime arguments.
"runArgs": [
"--privileged", // give all capabilities to a container, in other words, the container can then do almost everything that the host can do
"--net", "host", // forwarding all host machine ports
"-v", "/dev/bus/usb:/dev/bus/usb" // mount connected USB devices to a container
],
"settings": {
// This will ignore your local shell user setting for Linux since shells like zsh are typically
// not in base container images. You can also update this to an specific shell to ensure VS Code
// uses the right one for terminals and tasks. For example, /bin/bash (or /bin/ash for Alpine).
"terminal.integrated.shell.linux": null
},
// Add the IDs of extensions you want installed when the container is created in the array below.
"extensions": ["msjsdiag.vscode-react-native"]
}
```
1. Open Command Palette and run the following command `Remote-Containers: Open Folder in Container` to reopen your project in container
1. Connect your device via USB and start debugging the same way as on local machine
Currently the above scenario doesn't work on macOS and Windows. Docker Container implementation on these OS uses Virtual Machine tools which may have problems with USB forwarding for mobile devices.

Просмотреть файл

@ -1,105 +0,0 @@
# Customization
There are a few customizations supported by this extension; they can be added to your `.vscode/settings.json` if you need them.
**NOTE**: To apply changes you made to `.vscode/settings.json`, please, save it and then **restart VS Code instance**.
## Specifying custom arguments for `react-native run-*` command
For using custom run arguments for `react-native run-<platform>`:
* **Note:** This overrides all other configuration parameters.
```
{
"react-native.android.runArguments.simulator": ["--appFolder", "/Users/test/AwesomeProject/android/app", "--deviceId", "emulator-5555"],
"react-native.ios.runArguments.device": ["--project-path", "ios", "--device", "Max's iPhone"],
}
```
* **Note:** You can get the list of installed simulator devices by:
iOS devices(MacOS only):
```
xcrun simctl list --json devices
```
Android devices:
```
adb devices
```
* **Note:** If you want run application on iOS devices make sure you have `ios-deploy` installed globally.
```npm install -g ios-deploy```
## Setting up the react-native packager
To use a custom port for the `react-native` packager:
```
{
"react-native": {
"packager" : {
"port": portNumber
}
}
}
```
If you change this port, then for iOS device and simulator scenarios you will have to modify the native code files. Instruction [here](https://blog.binoy.io/running-react-native-on-a-different-port-7deb43887cd4).<br>
If you use android, you need to change debug server by:
1. CTRL+M(CMD+M) in the emulator
2. Go to Dev Settings
3. Debug server host for device => enter localhost:\<yourPortNumber\>.
4. Reload application (double R)
* Note that some aspects of React Native hard-code the port to the default as specified in [this issue](https://github.com/facebook/react-native/issues/9145).
## Setting up React Native global CLI
By default React Native Tools extension uses React Native local CLI from React Native project's dependencies to run React Native commands. Local CLI module is available at the following path: `yourProjectDir/node_modules/.bin/react-native`. But it is possible to change that approach and use globally installed React Native CLI that is available from your PATH environment variable.
To specify React Native CLI installed globally, you can use `reactNativeGlobalCommandName` parameter. This parameter is responsible for launcher command name, which is used to run React Native commands. If you edit `reactNativeGlobalCommandName` parameter in your `settings.json` file, the extension will use specified launcher command name to run React Native commands (e.g. `react-native run-android` instead of `yourProjectDir/node_modules/.bin/react-native run-android`).
For example, `react-native` is launcher command name for Facebook React Native CLI. You can specify it like this:
```
{
"react-native-tools.reactNativeGlobalCommandName": "react-native"
}
```
You can also use custom React Native CLI compatible with Facebook React Native CLI, by setting up `reactNativeGlobalCommandName` parameter:
```
{
"react-native-tools.reactNativeGlobalCommandName": "custom-react-native"
}
```
## Logging
To expose internal logs to the output, set the following properties:
```
{
"react-native-tools": {
"logLevel": "Trace"
}
}
```
`logLevel` can be `None` (no logs), `Error`, `Warning`, `Info`, `Debug`, `Trace` (all logs). Default is `Info`.
## Project structure
To specify a subfolder in which the react-native project is located, set `react-native-tools.projectRoot`. You can use either an absolute or relative path here:
```
{
"react-native-tools": {
"projectRoot": "./your/react-native/project"
}
}
```

Просмотреть файл

@ -1,100 +0,0 @@
# Setting up debug environment
Once you have set up a `launch.json` file with default configurations, you can modify these configurations, or add new ones to the list. You can use other fields in these configurations as well.
![React Native launch configuration file](../images/launch-config.png)
For example, you can modify the `target` field to specify the simulator you want to target for iOS debugging or the device using the one from output of `adb devices` command for Android debugging.
## Debugging with TypeScript and Haul
If you use Haul instead of the react-native packager, you must add `sourceMapPathOverrides` to the `launch.json` file.
For example:
```
"sourceMapPathOverrides": {
"webpack:///./~/*": "${workspaceRoot}/node_modules/*",
"webpack:///./*": "${workspaceRoot}/*",
"webpack:///*": "*"
}
```
See more about source map overrides [here](https://github.com/Microsoft/vscode-node-debug2#sourcemappathoverrides)
## Specifying scheme for iOS app
If you want to use custom scheme for your application you can either pass it as part of `runArguments` parameter arguments or set `scheme` configuration parameter as shown below:
```js
"runArguments": ["--scheme", "customScheme", ...]
// or
"runArguments": ["--scheme=customScheme", ...]
// or
"scheme" : "customScheme"
```
Please be aware, specifying scheme value as a part of `runArguments` parameter arguments will override `scheme` configuration parameter value if it set.
## Debugging on iOS device
Debugging on an iOS device require following manual steps:
* Install [ios-deploy](https://www.npmjs.com/package/ios-deploy) `npm install -g ios-deploy`.
* Have a valid iOS Development certificate installed.
* In your project's `launch.json` file set `target` to `device` or use 'launchArguments' property to specify particular device to run on in case of multiple devices connected, e.g. `"runArguments": [ "--device", "My iPhone" ]`
* Choose **Debug iOS** configuration from the Configuration dropdown and press F5.
* Shake the device to open the development menu and select "Debug JS Remotely".
## Debugging React Native Windows
For UWP apps use `windows` target platform in `launch.json` configuration, e.g.:
```
{
"name": "Debug UWP",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "windows"
}
```
For WPF apps use `wpf`, e.g.(WPF debugging available only for react-native-windows gt 0.55.0):
```
{
"name": "Debug WPF",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "wpf"
}
```
## Debugging React Native apps with Hermes enabled
Hermes is the new JavaScript engine optimized for running React Native apps on Android. It improves app performance and decreases app size.
Click [here](https://facebook.github.io/react-native/docs/hermes/) to learn more about Hermes.
Debugging apps with Hermes enabled is currently experimental. Please, see [this issue](https://github.com/microsoft/vscode-react-native/issues/1073) for current known issues on Hermes support.
To debug while using Hermes engine, please choose one of the following debug configurations:
- React Native (Hermes): Debug Android - Experimental
```
{
"name": "Debug Android (Hermes) - Experimental",
"cwd": "${workspaceFolder}",
"type": "reactnativedirect",
"request": "launch",
"platform": "android"
}
```
- React Native (Hermes): Attach to Hermes application - Experimental
```
{
"name": "Attach to Hermes application - Experimental",
"cwd": "${workspaceFolder}",
"type": "reactnativedirect",
"request": "attach"
}
```

Просмотреть файл

@ -1,52 +0,0 @@
## Debugging Expo applications
To debug a project created using Expo or the create-react-native-app task, you can use embedded support for Expo.
Your environment must meet the following prerequisites:
- Install the [Expo app](https://getexponent.com/) on the target device or emulator
- Ensure that the react-native-cli is installed globally (`npm install -g react-native-cli`)
To start debugging in Expo follow these steps:
1. Open your project in VS Code with this extension installed.
2. Create a debug configuration (as described in [Debugging React Native applications](../README.md#debugging-react-native-applications)), select `Debug in Exponent` in the debug drop-down menu, and start debugging
4. Wait while some dependencies are configured - the extension will install `xde` and `@expo/ngrok` when this feature is used for the first time.
5. If you have not used exponent on this system before, you will be prompted for an exponent username and password.
If you have not created an exponent account, then specifying a new username and password will create one.
Note that there is no e-mail associated with the account, and no way to recover a forgotten password.
6. Once the packager starts, the extension will open a separate tab with QR code to scan from the Exponent app. Once you do so, the Exponent app will connect to the packager and begin running your app.
7. Once app is loaded and ran, [open Developer Menu](https://facebook.github.io/react-native/docs/debugging#accessing-the-in-app-developer-menu) inside your application and enable remote debugging by clicking on `Debug JS Remotely` button.
![React Native enable remote debug](../images/enable-remote-debug.png)
From here you can run and debug the app as normal.
## Configuring Expo
The extension supports running through Exponent not just the applications created with Expo but even pure React Native applications (in that case you need to add `expo` package to `node_modules` in order to make it work with Expo: `npm install expo --save-dev`. In either cases it uses `app.json` configuration file in the root of the project.
If you are running `Debug in Exponent` configuration or any of pallette commands like `Run in Exponent`, `Publish to Exponent` then this file will be created automatically if absent or updated with the following basic configuration section:
```
"expo": {
"slug": "MyApp", // Project slug
"name": "MyApp", // Project name
"sdkVersion": "31.0.0", // Expo SDK version
"entryPoint": ".vscode\\exponentIndex.js" // Entrypoint for the project
},
"name": "MyApp", // Project name
```
Full list of configurational parameters for `expo` section in `app.json` may be found on [official Expo documentation page](https://docs.expo.io/versions/latest/workflow/configuration).
For running **pure React Native app**, extension, also, creates and uses `.vscode/exponentIndex.js` which is point to the app entrypoint (`index.js` or `index.android.js` or `index.ios.js`) file.
If you want to change your app entrypoint (for example, from `index.js` to `index.android.js`), delete `.vscode/exponentIndex.js` and then restart your debugging session.
## FAQ
**Q: I was working with a React Native version and after debugging in exponent I decided to update it, why is exponent not updating automatically?**
The extension caches the version of the exponent SDK used by your project. This is helpful since we don't want to install the SDK each time you run exponent. If you want the extension to update the SDK version based on your React Native version, just restart VS Code and we should be able to do it if it's supported.

Просмотреть файл

@ -1,53 +0,0 @@
This is default `tasks.json` for `react-native init` projects.
Put it into `.vscode` folder in your project.
```
{
"version": "2.0.0",
"presentation": {
"reveal": "always",
"panel": "new"
},
"tasks": [
{
"taskName": "Build APK Debug",
"group": "build",
"type": "shell",
"windows": {
"command": "cd android; if($?) {./gradlew assembleDebug}"
},
"linux": {
"command": "cd android && ./gradlew assembleDebug"
}
},
{
"taskName": "Build APK Release",
"group": "build",
"type": "shell",
"windows": {
"command": "cd android; if($?) {./gradlew assembleRelease}"
},
"linux": {
"command": "cd android && ./gradlew assembleRelease"
}
},
{
"taskName": "Generate Android Bundle",
"group": "build",
"type": "shell",
"command": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/main.jsbundle"
},
{
"taskName": "Generate iOS Bundle",
"group": "build",
"type": "shell",
"command": "react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/main.jsbundle"
}
]
}
```
* Note: if you use `react-native@0.48` or lower change `index.js` to `index.ios.js`/`index.android.js` or your own entry-file.
More about `tasks` in VSCode read [here](https://code.visualstudio.com/docs/editor/tasks)
How to [Generating Signed APK](https://facebook.github.io/react-native/docs/signed-apk-android.html)

Просмотреть файл

@ -20,6 +20,7 @@ const remapIstanbul = require("remap-istanbul/lib/gulpRemapIstanbul");
const nls = require("vscode-nls-dev");
const libtslint = require("tslint");
const tslint = require("gulp-tslint");
const vscodeTest = require("vscode-test");
const copyright = GulpExtras.checkCopyright;
const imports = GulpExtras.checkImports;
@ -93,7 +94,8 @@ function build(failOnError, buildNls) {
});
}
function test() {
async function test() {
// Check if arguments were passed
if (options.pattern) {
log(`\nTesting cases that match pattern: ${options.pattern}`);
@ -101,19 +103,25 @@ function test() {
log("\nTesting cases that don't match pattern: extensionContext|localizationContext");
}
const testResultsPath = path.join(__dirname, "test", "DebuggerTests.xml");
process.env.MOCHA_FILE = testResultsPath;
return gulp.src(["test/**/*.test.js", "!test/extension/**"])
.pipe(mocha({
ui: "tdd",
useColors: true,
invert: !options.pattern,
grep: options.pattern || "(extensionContext|localizationContext)",
reporter: "mocha-multi-reporters",
reporterOptions: {
configFile: path.resolve("test/mochaReporterConfig.json"),
},
}));
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = __dirname;
// The path to the extension test runner script
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, "test", "index");
console.log(extensionTestsPath);
// Download VS Code, unzip it and run the integration test
await vscodeTest.runTests({
extensionDevelopmentPath,
extensionTestsPath,
});
} catch (err) {
console.error(err);
console.error("Failed to run tests");
process.exit(1);
}
}
gulp.task("check-imports", () => {

2610
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,7 +1,7 @@
{
"name": "vscode-react-native",
"displayName": "React Native Tools",
"version": "0.14.1",
"version": "0.15.0",
"private": true,
"publisher": "msjsdiag",
"icon": "images/icon.png",
@ -681,69 +681,69 @@
"dependencies": {
"extract-opts": "2.2.0",
"flatten-source-map": "0.0.2",
"glob": "^7.1.2",
"glob": "^7.1.6",
"ip": "^1.1.5",
"mkdirp": "^0.5.1",
"mkdirp": "^1.0.3",
"noice-json-rpc": "^1.0.2",
"options": "0.0.6",
"q": "1.4.1",
"qr-image": "^3.2.0",
"semver": "^6.3.0",
"source-map": "0.5.2",
"source-map-resolve": "^0.5.0",
"source-map-resolve": "^0.5.3",
"strip-json-comments": "2.0.1",
"typechecker": "2.0.8",
"ultron": "1.0.2",
"vscode-cdp-proxy": "^0.2.0",
"vscode-debugadapter": "^1.37.1",
"vscode-debugprotocol": "^1.37.0",
"vscode-debugadapter": "^1.39.1",
"vscode-debugprotocol": "^1.39.0",
"vscode-extension-telemetry": "0.0.5",
"vscode-nls": "^3.2.2",
"vscode-nls": "3.2.2",
"ws": "^3.2.0"
},
"devDependencies": {
"@types/ip": "^1.1.0",
"@types/mkdirp": "^0.5.2",
"@types/mocha": "^2.2.40",
"@types/ncp": "^2.0.2",
"@types/node": "^10.14.4",
"@types/mkdirp": "^1.0.0",
"@types/mocha": "^7.0.2",
"@types/ncp": "^2.0.3",
"@types/node": "^10.17.17",
"@types/qr-image": "^3.2.0",
"@types/rimraf": "^2.0.2",
"@types/semver": "^6.2.0",
"@types/rimraf": "^2.0.3",
"@types/semver": "^6.2.1",
"@types/shelljs": "^0.7.0",
"@types/source-map": "0.5.2",
"@types/source-map-support": "^0.2.28",
"@types/vscode": "^1.33.0",
"@types/websocket": "0.0.33",
"@types/ws": "^0.0.39",
"ansi-colors": "^3.1.0",
"ansi-colors": "^3.2.4",
"del": "^2.2.0",
"devtools-protocol": "0.0.762508",
"event-stream": "3.3.4",
"fancy-log": "^1.3.2",
"gulp": "^4.0.0",
"fancy-log": "^1.3.3",
"gulp": "^4.0.2",
"gulp-istanbul": "^1.1.3",
"gulp-mocha": "^6.0.0",
"gulp-preprocess": "^3.0.2",
"gulp-sourcemaps": "^1.6.0",
"gulp-tslint": "^8.1.2",
"gulp-typescript": "^4.0.2",
"gulp-mocha": "^7.0.2",
"gulp-preprocess": "^3.0.3",
"gulp-sourcemaps": "^2.6.5",
"gulp-tslint": "^8.1.4",
"gulp-typescript": "^5.0.1",
"isparta": "^4.1.1",
"minimist": "^1.2.0",
"minimist": "^1.2.5",
"mocha": "^7.1.1",
"mocha-junit-reporter": "^1.22.0",
"mocha-junit-reporter": "^1.23.3",
"mocha-multi-reporters": "^1.1.7",
"ncp": "^2.0.0",
"plugin-error": "^1.0.1",
"remap-istanbul": "^0.13.0",
"rimraf": "^2.6.3",
"rimraf": "^2.7.1",
"should": "^8.3.0",
"sinon": "^1.17.3",
"source-map-support": "^0.4.0",
"through2": "^2.0.1",
"tslint": "^5.17.0",
"tslint": "^5.20.1",
"typescript": "^3.7.5",
"vsce": "^1.65.0",
"vsce": "^1.74.0",
"vscode-nls-dev": "^3.3.1",
"vscode-test": "^1.3.0"
},

Просмотреть файл

@ -35,7 +35,7 @@
"reactNative.launch.platform.description":"The platform to target. Possible values: 'android', 'ios', 'exponent', 'windows', 'wpf'",
"reactNative.launch.program.description":"[DEPRECATED. USE cwd INSTEAD] The path to launchReactNative.js in the vscode folder",
"reactNative.launch.cwd.description":"The path to the project root folder",
"reactNative.launch.target.description":"Target to run on. Possible values: 'simulator', 'device', '<Android emulator/device id>', '<iOS simulator/device name>'",
"reactNative.launch.target.description":"Target to run on. Possible values: 'simulator', 'device', 'device=<iOS device name>', '<Android emulator/device id>', '<iOS simulator name>'",
"reactNative.launch.sourceMaps.description":"Whether to use JavaScript source maps to map the generated bundled code back to its original sources",
"reactNative.launch.logCatArguments.description":"Arguments to be used for LogCat (The LogCat output will appear on an Output Channel). It can be an array such as: [\":S\", \"ReactNative:V\", \"ReactNativeJS:V\"]",
"reactNative.launch.outDir.description":"The location of the generated JavaScript code (the bundle file). Normally this should be \"${workspaceRoot}/.vscode/.react\"",

Просмотреть файл

@ -253,7 +253,7 @@ the licensed code:
-------------------------------------------------------------------
glob 7.1.3 - ISC
glob 7.1.6 - ISC
https://github.com/isaacs/node-glob#readme
Copyright (c) Isaac Z. Schlueter and Contributors
@ -273,6 +273,12 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
## Glob Logo
Glob's logo created by Tanya Brassie <http://tanyabrassie.com/>, licensed
under a Creative Commons Attribution-ShareAlike 4.0 International License
https://creativecommons.org/licenses/by-sa/4.0/
-------------------------------------------------------------------
@ -735,7 +741,38 @@ THE SOFTWARE.
-------------------------------------------------------------------
minimist 0.0.8 - MIT
is-arrayish 0.2.1 - MIT
https://github.com/qix-/node-is-arrayish#readme
Copyright (c) 2015 JD Ballard
The MIT License (MIT)
Copyright (c) 2015 JD Ballard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-------------------------------------------------------------------
-------------------------------------------------------------------
minimist 1.2.5 - MIT
https://github.com/substack/minimist
This software is released under the MIT license:
@ -762,7 +799,38 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------
mkdirp 0.5.1 - MIT
mkdirp 1.0.3 - MIT
https://github.com/isaacs/node-mkdirp#readme
Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me)
Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me)
This project is free software released under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-------------------------------------------------------------------
-------------------------------------------------------------------
mkdirp 0.5.3 - MIT
https://github.com/substack/node-mkdirp#readme
Copyright 2010 James Halliday (mail@substack.net)
@ -1025,17 +1093,15 @@ THE SOFTWARE.
-------------------------------------------------------------------
source-map-resolve 0.5.2 - MIT
source-map-resolve 0.5.3 - MIT
https://github.com/lydell/source-map-resolve#readme
Copyright 2014 Simon Lydell X11
Copyright 2017 Simon Lydell X11
Copyright 2014, 2017 Simon Lydell X11
Copyright (c) 2014, 2015, 2016, 2017 Simon Lydell
Copyright 2014, 2015, 2016, 2017 Simon Lydell X11
Copyright (c) 2019 ZHAO Jinxiang
Copyright (c) 2014, 2015, 2016, 2017, 2018, 2019 Simon Lydell
The MIT License (MIT)
Copyright (c) 2014, 2015, 2016, 2017 Simon Lydell
Copyright (c) 2014, 2015, 2016, 2017, 2018, 2019 Simon Lydell
Copyright (c) 2019 ZHAO Jinxiang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -1248,7 +1314,7 @@ THE SOFTWARE.
-------------------------------------------------------------------
vscode-debugadapter 1.37.1 - MIT
vscode-debugadapter 1.39.1 - MIT
https://github.com/Microsoft/vscode-debugadapter-node#readme
Copyright (c) Microsoft Corporation.
@ -1269,7 +1335,7 @@ THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-------------------------------------------------------------------
vscode-debugprotocol 1.37.0 - MIT
vscode-debugprotocol 1.39.0 - MIT
https://github.com/Microsoft/vscode-debugadapter-node#readme
Copyright (c) Microsoft Corporation.
@ -1322,7 +1388,7 @@ SOFTWARE.
-------------------------------------------------------------------
vscode-nls 3.2.2 - MIT
vscode-nls 4.1.1 - MIT
https://github.com/Microsoft/vscode-nls#readme
Copyright (c) Microsoft Corporation.
@ -1349,7 +1415,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
-------------------------------------------------------------------
vscode-nls 4.1.1 - MIT
vscode-nls 3.2.2 - MIT
https://github.com/Microsoft/vscode-nls#readme
Copyright (c) Microsoft Corporation.

Просмотреть файл

@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
import {IRunOptions} from "./../extension/launchArgs";
import {GeneralMobilePlatform} from "./../extension/generalMobilePlatform";
import {ChildProcess} from "child_process";
import {CommandExecutor} from "./commandExecutor";
import {ExponentHelper} from "../extension/exponent/exponentHelper";
@ -45,6 +47,7 @@ export class Packager {
private static OPN_PACKAGE_MAIN_FILENAME = "index.js";
private static fs: FileSystem = new Node.FileSystem();
private expoHelper: ExponentHelper;
private runOptions: IRunOptions;
constructor(private workspacePath: string, private projectPath: string, private packagerPort?: number, packagerStatusIndicator?: PackagerStatusIndicator) {
this.packagerStatus = PackagerStatus.PACKAGER_STOPPED;
@ -52,19 +55,23 @@ export class Packager {
this.expoHelper = new ExponentHelper(this.workspacePath, this.projectPath);
}
public get port(): number {
public getPort(): number {
return this.packagerPort || SettingsHelper.getPackagerPort(this.workspacePath);
}
public setRunOptions(runOptions: IRunOptions) {
this.runOptions = runOptions;
}
public static getHostForPort(port: number): string {
return `localhost:${port}`;
}
public get statusIndicator(): PackagerStatusIndicator {
public getStatusIndicator(): PackagerStatusIndicator {
return this.packagerStatusIndicator;
}
public getHost(): string {
return Packager.getHostForPort(this.port);
return Packager.getHostForPort(this.getPort());
}
public getPackagerStatus(): PackagerStatus {
@ -76,7 +83,7 @@ export class Packager {
}
public getPackagerArgs(rnVersion: string, resetCache: boolean = false): Q.Promise<string[]> {
let args: string[] = ["--port", this.port.toString()];
let args: string[] = ["--port", this.getPort().toString()];
if (resetCache) {
args = args.concat("--resetCache");
@ -136,7 +143,15 @@ export class Packager {
// This bug will be fixed in 0.41
const failedRNVersions: string[] = ["0.38.0", "0.39.0", "0.40.0"];
let reactEnv = Object.assign({}, process.env, {
let env = process.env;
if (this.runOptions && (this.runOptions.env || this.runOptions.envFile)) {
env = GeneralMobilePlatform.getEnvArgument(env, this.runOptions.env, this.runOptions.envFile);
} else {
const rootEnv = path.join(this.getProjectPath(), ".env");
env = GeneralMobilePlatform.getEnvArgument(env, null, rootEnv);
}
let reactEnv = Object.assign({}, env, {
REACT_DEBUGGER: "echo A debugger is not needed: ",
REACT_EDITOR: failedRNVersions.indexOf(rnVersion) < 0 ? "code" : this.openFileAtLocationCommand(),
});
@ -147,6 +162,19 @@ export class Packager {
let spawnOptions = { env: reactEnv };
// Since Expo 37, you must specify the sourceExts parameter so that the packager can load additional files, such as custom fonts:
// (https://github.com/expo/expo-cli/blob/master/packages/xdl/src/Project.ts#L1720).
// Related to https://github.com/microsoft/vscode-react-native/issues/1252
if (this.runOptions && this.runOptions.platform === "exponent") {
const managedExtensions = this.getSourceExtensions();
// In order for the arguments to be processed normally, it is necessary to pass an array as an argument
args.push(
"--sourceExts",
<any>managedExtensions
);
}
const packagerSpawnResult = new CommandExecutor(this.projectPath, this.logger).spawnReactPackager(args, spawnOptions);
this.packagerProcess = packagerSpawnResult.spawnedProcess;
packagerSpawnResult.outcome.done(() => { }, () => { }); // Q prints a warning if we don't call .done(). We ignore all outcome errors
@ -196,8 +224,8 @@ export class Packager {
}
public restart(port: number): Q.Promise<void> {
if (this.port && this.port !== port) {
return Q.reject<void>(ErrorHelper.getInternalError(InternalErrorCode.PackagerRunningInDifferentPort, port, this.port));
if (this.getPort() && this.getPort() !== port) {
return Q.reject<void>(ErrorHelper.getInternalError(InternalErrorCode.PackagerRunningInDifferentPort, port, this.getPort()));
}
return this.isRunning()
@ -378,4 +406,16 @@ export class Packager {
return atomScript;
}
// Since Expo 37, the packager in expo scripts has stopped correctly finding additional resources, such as custom fonts.
// In order to solve this problem, you need to configure the packager to work with additional file extensions,
// similar to how it was done in `expo/xdl`
private getSourceExtensions(): Array<string> {
// Since the array is determined by parameters (as pointed by link below)
// (https://github.com/expo/expo-cli/blob/master/packages/xdl/src/Project.ts#L1719),
// which are always the same, since the array that we receive in `expo/xdl`
// (https://github.com/expo/expo-cli/blob/30844f1083d0b0804478a7dc6c7cbd19dc7254df/packages/config/src/paths/extensions.ts#L54)
// is always the same, return constant here
return ["expo.ts", "expo.tsx", "expo.js", "expo.jsx", "ts", "tsx", "js", "jsx", "json", "wasm"];
}
}

Просмотреть файл

@ -1,5 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
import * as path from "path";
export function getFileNameWithoutExtension(fileName: string) {
return path.basename(fileName, path.extname(fileName));
}
export function isNullOrUndefined(value: any): boolean {
return typeof value === "undefined" || value === null;
@ -26,4 +31,4 @@ function padZeroes(minDesiredLength: number, numberToPad: string): string {
} else {
return String("0".repeat(minDesiredLength) + numberToPad).slice(-minDesiredLength);
}
}
}

Просмотреть файл

@ -91,7 +91,7 @@ export class AndroidPlatform extends GeneralMobilePlatform {
extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.reactNativeVersions.reactNativeVersion, "reactNativeVersion", extProps);
return TelemetryHelper.generate("AndroidPlatform.runApp", extProps, () => {
const env = this.getEnvArgument();
const env = GeneralMobilePlatform.getEnvArgument(process.env, this.runOptions.env, this.runOptions.envFile);
if (
!semver.valid(this.runOptions.reactNativeVersions.reactNativeVersion) /*Custom RN implementations should support this flag*/ ||
@ -164,7 +164,7 @@ export class AndroidPlatform extends GeneralMobilePlatform {
this.runOptions.target === AndroidPlatform.deviceString) {
const message = localize("TargetIsNotSupportedForAndroid",
"Target {0} is not supported for Android platform. \n If you want to use particular device or simulator for launching Android app,\n please specify device id (as in 'adb devices' output) instead.",
"Target {0} is not supported for Android platform. \n If you want to use particular device or simulator for launching Android app,\n please specify device id (as in 'adb devices' output) instead.",
this.runOptions.target);
this.logger.warning(message);
} else {

Просмотреть файл

@ -113,7 +113,7 @@ export class AppLauncher {
}
public dispose(): void {
this.packager.statusIndicator.dispose();
this.packager.getStatusIndicator().dispose();
this.packager.stop(true);
this.stopMonitoringLogCat();
}

Просмотреть файл

@ -37,11 +37,12 @@ export class ExponentPlatform extends GeneralMobilePlatform {
};
extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.reactNativeVersions.reactNativeVersion, "reactNativeVersion", extProps);
extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.expoHostType, "expoHostType", extProps);
return TelemetryHelper.generate("ExponentPlatform.runApp", extProps, () => {
return this.loginToExponentOrSkip(this.runOptions.expoHostType)
.then(() =>
XDL.setOptions(this.projectPath, { packagerPort: this.packager.port })
XDL.setOptions(this.projectPath, { packagerPort: this.packager.getPort() })
)
.then(() =>
XDL.startExponentServer(this.projectPath)

Просмотреть файл

@ -34,6 +34,7 @@ export class GeneralMobilePlatform {
this.platformName = this.runOptions.platform;
this.projectPath = this.runOptions.projectRoot;
this.packager = platformDeps.packager || new Packager(this.runOptions.workspaceRoot, this.projectPath, SettingsHelper.getPackagerPort(this.runOptions.workspaceRoot), new PackagerStatusIndicator());
this.packager.setRunOptions(runOptions);
this.logger = OutputChannelLogger.getChannel(localize("ReactNativeRunPlatform", "React Native: Run {0}", this.platformName), true);
this.logger.clear();
this.runArguments = this.getRunArguments();
@ -132,12 +133,36 @@ export class GeneralMobilePlatform {
throw new Error("Not yet implemented: GeneralMobilePlatform.getRunArguments");
}
public getEnvArgument(): any {
let args = this.runOptions;
let env = process.env;
public static getEnvArgument(processEnv: any, env?: any, envFile?: string): any {
let modifyEnv = Object.assign({}, processEnv);
if (args.envFile) {
let buffer = fs.readFileSync(args.envFile, "utf8");
if (envFile) {
// .env variables never overwrite existing variables
const argsFromEnvFile = this.readEnvFile(envFile);
if (argsFromEnvFile != null) {
for (let key in argsFromEnvFile) {
if (!modifyEnv[key] && argsFromEnvFile.hasOwnProperty(key)) {
modifyEnv[key] = argsFromEnvFile[key];
}
}
}
}
if (env) {
// launch config env vars overwrite .env vars
for (let key in env) {
if (env.hasOwnProperty(key)) {
modifyEnv[key] = env[key];
}
}
}
return modifyEnv;
}
private static readEnvFile(filePath: string): any {
if (fs.existsSync(filePath)) {
let buffer = fs.readFileSync(filePath, "utf8");
let result = {};
// Strip BOM
if (buffer && buffer[0] === "\uFEFF") {
@ -148,26 +173,17 @@ export class GeneralMobilePlatform {
const r = line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/);
if (r !== null) {
const key = r[1];
if (!env[key]) { // .env variables never overwrite existing variables
let value = r[2] || "";
if (value.length > 0 && value.charAt(0) === "\"" && value.charAt(value.length - 1) === "\"") {
value = value.replace(/\\n/gm, "\n");
}
env[key] = value.replace(/(^['"]|['"]$)/g, "");
let value = r[2] || "";
if (value.length > 0 && value.charAt(0) === "\"" && value.charAt(value.length - 1) === "\"") {
value = value.replace(/\\n/gm, "\n");
}
result[key] = value.replace(/(^['"]|['"]$)/g, "");
}
});
}
if (args.env) {
// launch config env vars overwrite .env vars
for (let key in args.env) {
if (args.env.hasOwnProperty(key)) {
env[key] = args.env[key];
}
}
return result;
} else {
return null;
}
return env;
}
}

Просмотреть файл

@ -102,7 +102,7 @@ export class IOSPlatform extends GeneralMobilePlatform {
return TelemetryHelper.generate("iOSPlatform.runApp", extProps, () => {
// Compile, deploy, and launch the app on either a simulator or a device
const env = this.getEnvArgument();
const env = GeneralMobilePlatform.getEnvArgument(process.env, this.runOptions.env, this.runOptions.envFile);
if (!semver.valid(this.runOptions.reactNativeVersions.reactNativeVersion) /*Custom RN implementations should support this flag*/ || semver.gte(this.runOptions.reactNativeVersions.reactNativeVersion, IOSPlatform.NO_PACKAGER_VERSION)) {
this.runArguments.push("--no-packager");
@ -185,13 +185,7 @@ export class IOSPlatform extends GeneralMobilePlatform {
}
} else {
if (this.runOptions.target) {
if (this.runOptions.target === IOSPlatform.deviceString ||
this.runOptions.target === IOSPlatform.simulatorString) {
runArguments.push(`--${this.runOptions.target}`);
} else {
runArguments.push("--simulator", `${this.runOptions.target}`);
}
runArguments.push(...this.handleTargetArg(this.runOptions.target));
}
if (this.runOptions.iosRelativeProjectPath) {
@ -207,6 +201,20 @@ export class IOSPlatform extends GeneralMobilePlatform {
return runArguments;
}
private handleTargetArg(target: string): string[] {
if (target === IOSPlatform.deviceString ||
target === IOSPlatform.simulatorString) {
return [`--${this.runOptions.target}`];
} else {
if (target.indexOf(IOSPlatform.deviceString) !== -1) {
const deviceArgs = target.split("=");
return deviceArgs[1] ? [`--${IOSPlatform.deviceString}`, deviceArgs[1]] : [`--${IOSPlatform.deviceString}`];
} else {
return [`--${IOSPlatform.simulatorString}`, `${this.runOptions.target}`];
}
}
}
private generateSuccessPatterns(version: string): Q.Promise<string[]> {
// Clone RUN_IOS_SUCCESS_PATTERNS to avoid its runtime mutation
let successPatterns = [...IOSPlatform.RUN_IOS_SUCCESS_PATTERNS];

Просмотреть файл

@ -12,10 +12,19 @@ import { ChildProcess } from "../../common/node/childProcess";
import { ErrorHelper } from "../../common/error/errorHelper";
import { InternalErrorCode } from "../../common/error/internalErrorCode";
import { ProjectVersionHelper } from "../../common/projectVersionHelper";
import { getFileNameWithoutExtension } from "../../common/utils";
export interface ConfigurationData {
fullProductName: string;
configurationFolder: string;
}
export class PlistBuddy {
private static plistBuddyExecutable = "/usr/libexec/PlistBuddy";
private readonly TARGET_BUILD_DIR_SEARCH_KEY = "TARGET_BUILD_DIR";
private readonly FULL_PRODUCT_NAME_SEARCH_KEY = "FULL_PRODUCT_NAME";
private nodeChildProcess: ChildProcess;
constructor({
@ -42,22 +51,33 @@ export class PlistBuddy {
let executable = "";
if (productName) {
executable = `${productName}.app`;
if (!fs.existsSync(path.join(configurationFolder, executable))) {
const configurationData = this.getConfigurationData(
projectRoot,
rnVersions.reactNativeVersion,
iosProjectRoot,
configuration,
scheme,
sdkType,
configurationFolder
);
configurationFolder = configurationData.configurationFolder;
}
} else {
const executableList = this.findExecutable(configurationFolder);
if (!executableList.length) {
if (!scheme) {
throw ErrorHelper.getInternalError(InternalErrorCode.IOSCouldNotFoundExecutableInFolder, configurationFolder);
}
const projectWorkspaceConfigName = `${scheme}.xcworkspace`;
configurationFolder = this.getBuildPath(
const configurationData = this.getConfigurationData(
projectRoot,
rnVersions.reactNativeVersion,
iosProjectRoot,
projectWorkspaceConfigName,
configuration,
scheme,
sdkType
sdkType,
configurationFolder
);
executableList.push(`${scheme}.app`);
configurationFolder = configurationData.configurationFolder;
executableList.push(configurationData.fullProductName);
} else if (executableList.length > 1) {
throw ErrorHelper.getInternalError(InternalErrorCode.IOSFoundMoreThanOneExecutablesCleanupBuildFolder, configurationFolder);
}
@ -93,13 +113,13 @@ export class PlistBuddy {
return this.invokePlistBuddy(`Print ${property}`, plistFile);
}
public getBuildPath(
public getBuildPathAndProductName(
iosProjectRoot: string,
projectWorkspaceConfigName: string,
configuration: string,
scheme: string,
sdkType: string
): string {
): ConfigurationData {
const buildSettings = this.nodeChildProcess.execFileSync(
"xcodebuild",
[
@ -119,15 +139,28 @@ export class PlistBuddy {
}
);
const targetBuildDir = this.getTargetBuildDir(<string>buildSettings);
const targetBuildDir = this.fetchParameterFromBuildSettings(<string>buildSettings, this.TARGET_BUILD_DIR_SEARCH_KEY);
const fullProductName = this.fetchParameterFromBuildSettings(<string>buildSettings, this.FULL_PRODUCT_NAME_SEARCH_KEY);
if (!targetBuildDir) {
throw new Error("Failed to get the target build directory.");
}
return targetBuildDir;
if (!fullProductName) {
throw new Error("Failed to get full product name.");
}
return {
fullProductName,
configurationFolder: targetBuildDir,
};
}
public getInferredScheme(iosProjectRoot: string, projectRoot: string, rnVersion: string) {
const projectWorkspaceConfigName = this.getProjectWorkspaceConfigName(iosProjectRoot, projectRoot, rnVersion);
return getFileNameWithoutExtension(projectWorkspaceConfigName);
}
public getProjectWorkspaceConfigName(iosProjectRoot: string, projectRoot: string, rnVersion: string): string {
// Portion of code was taken from https://github.com/react-native-community/cli/blob/master/packages/platform-ios/src/commands/runIOS/index.js
// and modified a little bit
/**
@ -153,22 +186,38 @@ export class PlistBuddy {
);
}
const inferredSchemeName = path.basename(
xcodeProject.name,
path.extname(xcodeProject.name)
return xcodeProject.name;
}
public getConfigurationData(
projectRoot: string,
reactNativeVersion: string,
iosProjectRoot: string,
configuration: string,
scheme: string | undefined,
sdkType: string,
oldConfigurationFolder: string
): ConfigurationData {
if (!scheme) {
throw ErrorHelper.getInternalError(InternalErrorCode.IOSCouldNotFoundExecutableInFolder, oldConfigurationFolder);
}
const projectWorkspaceConfigName = this.getProjectWorkspaceConfigName(iosProjectRoot, projectRoot, reactNativeVersion);
return this.getBuildPathAndProductName(
iosProjectRoot,
projectWorkspaceConfigName,
configuration,
scheme,
sdkType
);
return inferredSchemeName;
}
/**
*
* The function was taken from https://github.com/react-native-community/cli/blob/master/packages/platform-ios/src/commands/runIOS/index.ts#L369-L374
*
* @param {string} buildSettings
* @param {string} parameterName
* @returns {string | null}
*/
private getTargetBuildDir(buildSettings: string) {
const targetBuildMatch = /TARGET_BUILD_DIR = (.+)$/m.exec(buildSettings);
public fetchParameterFromBuildSettings(buildSettings: string, parameterName: string) {
const targetBuildMatch = new RegExp(`${parameterName} = (.+)$`, "m").exec(buildSettings);
return targetBuildMatch && targetBuildMatch[1]
? targetBuildMatch[1].trim()
: null;

Просмотреть файл

@ -44,7 +44,7 @@ export class WindowsPlatform extends GeneralMobilePlatform {
extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.reactNativeVersions.reactNativeWindowsVersion, "reactNativeWindowsVersion", extProps);
return TelemetryHelper.generate("WindowsPlatform.runApp", extProps, () => {
const env = this.getEnvArgument();
const env = GeneralMobilePlatform.getEnvArgument(process.env, this.runOptions.env, this.runOptions.envFile);
if (enableDebug) {
this.runArguments.push("--proxy");

Просмотреть файл

@ -5,6 +5,7 @@ import * as Q from "q";
import * as semver from "semver";
import * as path from "path";
import {GeneralMobilePlatform} from "../generalMobilePlatform";
import {MobilePlatformDeps} from "../generalMobilePlatform";
import {IWindowsRunOptions} from "../launchArgs";
import {TelemetryHelper} from "../../common/telemetryHelper";
@ -34,7 +35,7 @@ export class WpfPlatform extends WindowsPlatform {
extProps = TelemetryHelper.addPropertyToTelemetryProperties(this.runOptions.reactNativeVersions.reactNativeWindowsVersion, "reactNativeWindowsVersion", extProps);
return TelemetryHelper.generate("WpfPlatform.runApp", extProps, () => {
const env = this.getEnvArgument();
const env = GeneralMobilePlatform.getEnvArgument(process.env, this.runOptions.env, this.runOptions.envFile);
if (enableDebug) {
this.runArguments.push("--proxy");

Просмотреть файл

@ -3,6 +3,8 @@
import * as assert from "assert";
import { GeneralMobilePlatform } from "../../src/extension/generalMobilePlatform";
import * as fs from "fs";
import * as path from "path";
suite("generalMobilePlatform", function () {
suite("extensionContext", function () {
@ -29,5 +31,55 @@ suite("generalMobilePlatform", function () {
assert.equal(GeneralMobilePlatform.getOptFromRunArgs(args, "param4", false), undefined);
});
});
suite("getEnvArgument", function() {
const origEnv: any = {"test1": "origEnv", "test2": "origEnv", "test3": "origEnv"};
const env: any = {"test2": "env", "test3": "env", "test4": "env"};
const envForFile: string = "test3=envFile\ntest4=envFile\ntest5=envFile";
const envFile: string = path.join(__dirname, "..", "resources", "auxiliaryFiles", ".env");
const fakeEnvFile: string = path.join(__dirname, "..", "resources", "auxiliaryFiles", ".envFake");
setup(() => {
fs.writeFileSync(envFile, envForFile);
});
teardown(() => {
fs.unlinkSync(envFile);
});
test("existing args should not should not depend on the existence of the envFile", function() {
assert.deepEqual(GeneralMobilePlatform.getEnvArgument(origEnv, undefined, fakeEnvFile), {
"test1": "origEnv",
"test2": "origEnv",
"test3": "origEnv"});
});
test("existing args should not depend on null or undefined env and envFile", function() {
assert.deepEqual(GeneralMobilePlatform.getEnvArgument(origEnv, undefined, undefined), {
"test1": "origEnv",
"test2": "origEnv",
"test3": "origEnv"});
});
test("args from envFile should not overwrite existing variables", function() {
assert.deepEqual(GeneralMobilePlatform.getEnvArgument(origEnv, null, envFile), {
"test1": "origEnv",
"test2": "origEnv",
"test3": "origEnv",
"test4": "envFile",
"test5": "envFile"});
});
test("args from envFile and original args should be overwritten by env args", function() {
assert.deepEqual(GeneralMobilePlatform.getEnvArgument(origEnv, env, envFile), {
"test1": "origEnv",
"test2": "env",
"test3": "env",
"test4": "env",
"test5": "envFile"});
});
});
});
});

Просмотреть файл

@ -55,5 +55,17 @@ suite("iOSPlatform", function () {
let platform = new IOSPlatform(runOptions);
assert.deepEqual(platform.runArguments, expected);
});
test("getRunArgument device Contoso iPhone", function () {
runOptions.target = "device=Contoso iPhone";
const expected = ["--device", "Contoso iPhone"];
let platform = new IOSPlatform(runOptions);
assert.deepEqual(platform.runArguments, expected);
});
test("getRunArgument device with incorrect 'device' field", function () {
runOptions.target = "device Contoso iPhone";
const expected = ["--device"];
let platform = new IOSPlatform(runOptions);
assert.deepEqual(platform.runArguments, expected);
});
});
});

Просмотреть файл

@ -6,7 +6,9 @@ import {PlistBuddy} from "../../../src/extension/ios/plistBuddy";
import * as assert from "assert";
import * as path from "path";
import * as Q from "q";
import * as fs from "fs";
import * as sinon from "sinon";
import { ConfigurationData } from "../../../src/extension/ios/plistBuddy";
import { ProjectVersionHelper } from "../../../src/common/projectVersionHelper";
suite("plistBuddy", function() {
@ -74,6 +76,7 @@ suite("plistBuddy", function() {
const plistBuddy = getPlistBuddy(appName, iosProjectRoot, undefined, simulatorBundleId, deviceBundleId);
sandbox.stub(ProjectVersionHelper, "getReactNativeVersions").returns(Q.resolve({reactNativeVersion: "0.58.5", reactNativeWindowsVersion: ""}));
sandbox.stub(plistBuddy, "getConfigurationData", fakeGetConfigurationData);
return Q.all([
plistBuddy.getBundleId(iosProjectRoot, projectRoot, true, "Debug", appName),
@ -98,6 +101,7 @@ suite("plistBuddy", function() {
const plistBuddy = getPlistBuddy(appName, iosProjectRoot, "myCustomScheme", simulatorBundleId, deviceBundleId);
sandbox.stub(ProjectVersionHelper, "getReactNativeVersions").returns(Q.resolve({reactNativeVersion: "0.59.0", reactNativeWindowsVersion: ""}));
sandbox.stub(plistBuddy, "getConfigurationData", fakeGetConfigurationData);
sandbox.stub(plistBuddy, "getInferredScheme").returns(scheme);
return Q.all([
@ -113,6 +117,52 @@ suite("plistBuddy", function() {
});
});
suite("fetchParameterFromBuildSettings", function() {
const buildSettingsFile = path.join(__dirname, "..", "..", "resources", "auxiliaryFiles", "buildSettings.txt");
const plistBuddy = new PlistBuddy();
let buildSettings: string | Buffer;
suiteSetup(() => {
buildSettings = fs.readFileSync(buildSettingsFile);
});
test("fetchParameterFromBuildSettings should return parameter value", function () {
const targetBuildDirRef = "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator";
const fullProductNameRef = "AwesomeProject0615.app";
const targetBuildDir = plistBuddy.fetchParameterFromBuildSettings(<string>buildSettings, "TARGET_BUILD_DIR");
const fullProductName = plistBuddy.fetchParameterFromBuildSettings(<string>buildSettings, "FULL_PRODUCT_NAME");
assert.equal(targetBuildDir, targetBuildDirRef);
assert.equal(fullProductName, fullProductNameRef);
});
test("fetchParameterFromBuildSettings should return null", function () {
const targetBuildDir = plistBuddy.fetchParameterFromBuildSettings(<string>buildSettings, "TARGET_BUILD_DIR1");
const testNull = plistBuddy.fetchParameterFromBuildSettings(<string>buildSettings, "TEST");
const emptyStringCase = plistBuddy.fetchParameterFromBuildSettings(<string>buildSettings, "");
assert.equal(targetBuildDir, null);
assert.equal(testNull, null);
assert.notEqual(emptyStringCase, null);
});
});
function fakeGetConfigurationData(
projectRoot: string,
reactNativeVersion: string,
iosProjectRoot: string,
configuration: string,
scheme: string | undefined,
sdkType: string,
oldConfigurationFolder: string
): ConfigurationData {
return {
fullProductName: "",
configurationFolder: oldConfigurationFolder,
};
}
function getPlistBuddy(appName: string, iosProjectRoot: string, scheme: string | undefined, simulatorBundleId: string, deviceBundleId: string) {
const infoPlistPath = (simulator: boolean) =>
scheme

Просмотреть файл

@ -36,4 +36,5 @@ export function run(): Promise<void> {
reject(err);
}
});
}
}

Просмотреть файл

@ -0,0 +1,434 @@
Build settings from command line:
SDKROOT = iphonesimulator13.2
Build settings for action build and target AwesomeProject0615:
ACTION = build
AD_HOC_CODE_SIGNING_ALLOWED = YES
ALTERNATE_GROUP = staff
ALTERNATE_MODE = u+w,go-w,a+rX
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
ALWAYS_SEARCH_USER_PATHS = NO
ALWAYS_USE_SEPARATE_HEADERMAPS = NO
APPLE_INTERNAL_DEVELOPER_DIR = /AppleInternal/Developer
APPLE_INTERNAL_DIR = /AppleInternal
APPLE_INTERNAL_DOCUMENTATION_DIR = /AppleInternal/Documentation
APPLE_INTERNAL_LIBRARY_DIR = /AppleInternal/Library
APPLE_INTERNAL_TOOLS = /AppleInternal/Developer/Tools
APPLICATION_EXTENSION_API_ONLY = NO
APPLY_RULES_IN_COPY_FILES = NO
APPLY_RULES_IN_COPY_HEADERS = NO
ARCHS = x86_64
ARCHS_STANDARD = i386 x86_64
ARCHS_STANDARD_32_64_BIT = i386 x86_64
ARCHS_STANDARD_32_BIT = i386
ARCHS_STANDARD_64_BIT = x86_64
ARCHS_STANDARD_INCLUDING_64_BIT = i386 x86_64
ARCHS_UNIVERSAL_IPHONE_OS = i386 x86_64
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
AVAILABLE_PLATFORMS = appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator
BITCODE_GENERATION_MODE = marker
BUILD_ACTIVE_RESOURCES_ONLY = NO
BUILD_COMPONENTS = headers build
BUILD_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products
BUILD_LIBRARY_FOR_DISTRIBUTION = NO
BUILD_ROOT = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products
BUILD_STYLE =
BUILD_VARIANTS = normal
BUILT_PRODUCTS_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator
CACHE_ROOT = /var/folders/yh/l05v9hvd6g3_6cspqq2n3nd00000gn/C/com.apple.DeveloperTools/11.3-11C29/Xcode
CCHROOT = /var/folders/yh/l05v9hvd6g3_6cspqq2n3nd00000gn/C/com.apple.DeveloperTools/11.3-11C29/Xcode
CHMOD = /bin/chmod
CHOWN = /usr/sbin/chown
CLANG_CXX_LANGUAGE_STANDARD = gnu++0x
CLANG_CXX_LIBRARY = libc++
CLANG_ENABLE_MODULES = YES
CLANG_ENABLE_OBJC_ARC = YES
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES
CLANG_WARN_BOOL_CONVERSION = YES
CLANG_WARN_COMMA = YES
CLANG_WARN_CONSTANT_CONVERSION = YES
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR
CLANG_WARN_EMPTY_BODY = YES
CLANG_WARN_ENUM_CONVERSION = YES
CLANG_WARN_INFINITE_RECURSION = YES
CLANG_WARN_INT_CONVERSION = YES
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES
CLANG_WARN_STRICT_PROTOTYPES = YES
CLANG_WARN_SUSPICIOUS_MOVE = YES
CLANG_WARN_UNREACHABLE_CODE = YES
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
CLASS_FILE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/JavaClasses
CLEAN_PRECOMPS = YES
CLONE_HEADERS = NO
CODESIGNING_FOLDER_PATH = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/AwesomeProject0615.app
CODE_SIGNING_ALLOWED = YES
CODE_SIGNING_REQUIRED = YES
CODE_SIGN_CONTEXT_CLASS = XCiPhoneSimulatorCodeSignContext
CODE_SIGN_IDENTITY = -
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES
COLOR_DIAGNOSTICS = YES
COMBINE_HIDPI_IMAGES = NO
COMPILER_INDEX_STORE_ENABLE = Default
COMPOSITE_SDK_DIRS = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/CompositeSDKs
COMPRESS_PNG_FILES = YES
CONFIGURATION = Debug
CONFIGURATION_BUILD_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator
CONFIGURATION_TEMP_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator
CONTENTS_FOLDER_PATH = AwesomeProject0615.app
COPYING_PRESERVES_HFS_DATA = NO
COPY_HEADERS_RUN_UNIFDEF = NO
COPY_PHASE_STRIP = NO
COPY_RESOURCES_FROM_STATIC_FRAMEWORKS = YES
CORRESPONDING_DEVICE_PLATFORM_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
CORRESPONDING_DEVICE_PLATFORM_NAME = iphoneos
CORRESPONDING_DEVICE_SDK_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk
CORRESPONDING_DEVICE_SDK_NAME = iphoneos13.2
CP = /bin/cp
CREATE_INFOPLIST_SECTION_IN_BINARY = NO
CURRENT_ARCH = x86_64
CURRENT_PROJECT_VERSION = 1
CURRENT_VARIANT = normal
DEAD_CODE_STRIPPING = NO
DEBUGGING_SYMBOLS = YES
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
DEFAULT_COMPILER = com.apple.compilers.llvm.clang.1_0
DEFAULT_DEXT_INSTALL_PATH = /System/Library/DriverExtensions
DEFAULT_KEXT_INSTALL_PATH = /System/Library/Extensions
DEFINES_MODULE = NO
DEPLOYMENT_LOCATION = NO
DEPLOYMENT_POSTPROCESSING = NO
DEPLOYMENT_TARGET_CLANG_ENV_NAME = IPHONEOS_DEPLOYMENT_TARGET
DEPLOYMENT_TARGET_CLANG_FLAG_NAME = mios-simulator-version-min
DEPLOYMENT_TARGET_CLANG_FLAG_PREFIX = -mios-simulator-version-min=
DEPLOYMENT_TARGET_LD_ENV_NAME = IPHONEOS_DEPLOYMENT_TARGET
DEPLOYMENT_TARGET_LD_FLAG_NAME = ios_simulator_version_min
DEPLOYMENT_TARGET_SETTING_NAME = IPHONEOS_DEPLOYMENT_TARGET
DEPLOYMENT_TARGET_SUGGESTED_VALUES = 8.0 8.1 8.2 8.3 8.4 9.0 9.1 9.2 9.3 10.0 10.1 10.2 10.3 11.0 11.1 11.2 11.3 11.4 12.0 12.1 12.2 12.3 12.4 13.0 13.1 13.2
DERIVED_FILES_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/DerivedSources
DERIVED_FILE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/DerivedSources
DERIVED_SOURCES_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/DerivedSources
DEVELOPER_APPLICATIONS_DIR = /Applications/Xcode.app/Contents/Developer/Applications
DEVELOPER_BIN_DIR = /Applications/Xcode.app/Contents/Developer/usr/bin
DEVELOPER_DIR = /Applications/Xcode.app/Contents/Developer
DEVELOPER_FRAMEWORKS_DIR = /Applications/Xcode.app/Contents/Developer/Library/Frameworks
DEVELOPER_FRAMEWORKS_DIR_QUOTED = /Applications/Xcode.app/Contents/Developer/Library/Frameworks
DEVELOPER_LIBRARY_DIR = /Applications/Xcode.app/Contents/Developer/Library
DEVELOPER_SDK_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
DEVELOPER_TOOLS_DIR = /Applications/Xcode.app/Contents/Developer/Tools
DEVELOPER_USR_DIR = /Applications/Xcode.app/Contents/Developer/usr
DEVELOPMENT_LANGUAGE = English
DEVELOPMENT_TEAM = 3478K72PL9
DOCUMENTATION_FOLDER_PATH = AwesomeProject0615.app/English.lproj/Documentation
DONT_GENERATE_INFOPLIST_FILE = NO
DO_HEADER_SCANNING_IN_JAM = NO
DSTROOT = /tmp/AwesomeProject0615.dst
DT_TOOLCHAIN_DIR = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
DWARF_DSYM_FILE_NAME = AwesomeProject0615.app.dSYM
DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT = NO
DWARF_DSYM_FOLDER_PATH = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator
EFFECTIVE_PLATFORM_NAME = -iphonesimulator
EMBEDDED_CONTENT_CONTAINS_SWIFT = NO
EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO
ENABLE_BITCODE = NO
ENABLE_DEFAULT_HEADER_SEARCH_PATHS = YES
ENABLE_HARDENED_RUNTIME = NO
ENABLE_HEADER_DEPENDENCIES = YES
ENABLE_ON_DEMAND_RESOURCES = YES
ENABLE_STRICT_OBJC_MSGSEND = YES
ENABLE_TESTABILITY = YES
ENTITLEMENTS_DESTINATION = __entitlements
ENTITLEMENTS_REQUIRED = YES
EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS = .DS_Store .svn .git .hg CVS
EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = *.nib *.lproj *.framework *.gch *.xcode* *.xcassets (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj
EXECUTABLES_FOLDER_PATH = AwesomeProject0615.app/Executables
EXECUTABLE_FOLDER_PATH = AwesomeProject0615.app
EXECUTABLE_NAME = AwesomeProject0615
EXECUTABLE_PATH = AwesomeProject0615.app/AwesomeProject0615
EXPANDED_CODE_SIGN_IDENTITY =
EXPANDED_CODE_SIGN_IDENTITY_NAME =
EXPANDED_PROVISIONING_PROFILE =
FILE_LIST = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/Objects/LinkFileList
FIXED_FILES_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/FixedFiles
FRAMEWORKS_FOLDER_PATH = AwesomeProject0615.app/Frameworks
FRAMEWORK_FLAG_PREFIX = -framework
FRAMEWORK_VERSION = A
FULL_PRODUCT_NAME = AwesomeProject0615.app
GCC3_VERSION = 3.3
GCC_C_LANGUAGE_STANDARD = gnu99
GCC_DYNAMIC_NO_PIC = NO
GCC_INLINES_ARE_PRIVATE_EXTERN = YES
GCC_NO_COMMON_BLOCKS = YES
GCC_OBJC_LEGACY_DISPATCH = YES
GCC_OPTIMIZATION_LEVEL = 0
GCC_PFE_FILE_C_DIALECTS = c objective-c c++ objective-c++
GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 COCOAPODS=1
GCC_SYMBOLS_PRIVATE_EXTERN = NO
GCC_TREAT_WARNINGS_AS_ERRORS = NO
GCC_VERSION = com.apple.compilers.llvm.clang.1_0
GCC_VERSION_IDENTIFIER = com_apple_compilers_llvm_clang_1_0
GCC_WARN_64_TO_32_BIT_CONVERSION = YES
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR
GCC_WARN_UNDECLARED_SELECTOR = YES
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE
GCC_WARN_UNUSED_FUNCTION = YES
GCC_WARN_UNUSED_VARIABLE = YES
GENERATE_MASTER_OBJECT_FILE = NO
GENERATE_PKGINFO_FILE = YES
GENERATE_PROFILING_CODE = NO
GENERATE_TEXT_BASED_STUBS = NO
GID = 20
GROUP = staff
HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT = YES
HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = YES
HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS = YES
HEADERMAP_INCLUDES_PROJECT_HEADERS = YES
HEADERMAP_USES_FRAMEWORK_PREFIX_ENTRIES = YES
HEADERMAP_USES_VFS = NO
HEADER_SEARCH_PATHS = "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/DoubleConversion" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/FBLazyVector" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/FBReactNativeSpec" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/RCTRequired" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/RCTTypeSafety" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-Core" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-RCTBlob" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-RCTText" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-cxxreact" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-jsi" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-jsiexecutor" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/React-jsinspector" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/ReactCommon" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/Yoga" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Public/glog" "/Users/user/Documents/test_react/AwesomeProject0615/ios/Pods/Headers/Private/React-Core"
HIDE_BITCODE_SYMBOLS = YES
HOME = /Users/user
ICONV = /usr/bin/iconv
INFOPLIST_EXPAND_BUILD_SETTINGS = YES
INFOPLIST_FILE = AwesomeProject0615/Info.plist
INFOPLIST_OUTPUT_FORMAT = binary
INFOPLIST_PATH = AwesomeProject0615.app/Info.plist
INFOPLIST_PREPROCESS = NO
INFOSTRINGS_PATH = AwesomeProject0615.app/English.lproj/InfoPlist.strings
INLINE_PRIVATE_FRAMEWORKS = NO
INSTALLHDRS_COPY_PHASE = NO
INSTALLHDRS_SCRIPT_PHASE = NO
INSTALL_DIR = /tmp/AwesomeProject0615.dst/Applications
INSTALL_GROUP = staff
INSTALL_MODE_FLAG = u+w,go-w,a+rX
INSTALL_OWNER = user
INSTALL_PATH = /Applications
INSTALL_ROOT = /tmp/AwesomeProject0615.dst
IPHONEOS_DEPLOYMENT_TARGET = 9.0
JAVAC_DEFAULT_FLAGS = -J-Xms64m -J-XX:NewSize=4M -J-Dfile.encoding=UTF8
JAVA_APP_STUB = /System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub
JAVA_ARCHIVE_CLASSES = YES
JAVA_ARCHIVE_TYPE = JAR
JAVA_COMPILER = /usr/bin/javac
JAVA_FOLDER_PATH = AwesomeProject0615.app/Java
JAVA_FRAMEWORK_RESOURCES_DIRS = Resources
JAVA_JAR_FLAGS = cv
JAVA_SOURCE_SUBDIR = .
JAVA_USE_DEPENDENCIES = YES
JAVA_ZIP_FLAGS = -urg
JIKES_DEFAULT_FLAGS = +E +OLDCSO
KEEP_PRIVATE_EXTERNS = NO
LD_DEPENDENCY_INFO_FILE = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/Objects-normal/x86_64/AwesomeProject0615_dependency_info.dat
LD_GENERATE_MAP_FILE = NO
LD_MAP_FILE_PATH = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/AwesomeProject0615-LinkMap-normal-x86_64.txt
LD_NO_PIE = NO
LD_QUOTE_LINKER_ARGUMENTS_FOR_COMPILER_DRIVER = YES
LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks
LEGACY_DEVELOPER_DIR = /Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer
LEX = lex
LIBRARY_DEXT_INSTALL_PATH = /Library/DriverExtensions
LIBRARY_FLAG_NOSPACE = YES
LIBRARY_FLAG_PREFIX = -l
LIBRARY_KEXT_INSTALL_PATH = /Library/Extensions
LIBRARY_SEARCH_PATHS = "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/DoubleConversion" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/FBReactNativeSpec" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/Folly" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/RCTTypeSafety" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-Core" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-CoreModules" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTActionSheet" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTAnimation" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTBlob" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTImage" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTLinking" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTNetwork" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTSettings" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTText" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-RCTVibration" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-cxxreact" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-jsi" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-jsiexecutor" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/React-jsinspector" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/ReactCommon" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/Yoga" "/Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/glog"
LINKER_DISPLAYS_MANGLED_NAMES = NO
LINK_FILE_LIST_normal_x86_64 =
LINK_WITH_STANDARD_LIBRARIES = YES
LLVM_TARGET_TRIPLE_OS_VERSION = ios9.0
LLVM_TARGET_TRIPLE_SUFFIX = -simulator
LLVM_TARGET_TRIPLE_VENDOR = apple
LOCALIZABLE_CONTENT_DIR =
LOCALIZED_RESOURCES_FOLDER_PATH = AwesomeProject0615.app/English.lproj
LOCALIZED_STRING_MACRO_NAMES = NSLocalizedString CFCopyLocalizedString
LOCALIZED_STRING_SWIFTUI_SUPPORT = YES
LOCAL_ADMIN_APPS_DIR = /Applications/Utilities
LOCAL_APPS_DIR = /Applications
LOCAL_DEVELOPER_DIR = /Library/Developer
LOCAL_LIBRARY_DIR = /Library
LOCROOT =
LOCSYMROOT =
MACH_O_TYPE = mh_execute
MAC_OS_X_PRODUCT_BUILD_VERSION = 19D76
MAC_OS_X_VERSION_ACTUAL = 101503
MAC_OS_X_VERSION_MAJOR = 101500
MAC_OS_X_VERSION_MINOR = 1503
METAL_LIBRARY_FILE_BASE = default
METAL_LIBRARY_OUTPUT_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/AwesomeProject0615.app
MODULES_FOLDER_PATH = AwesomeProject0615.app/Modules
MODULE_CACHE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/ModuleCache.noindex
MTL_ENABLE_DEBUG_INFO = YES
NATIVE_ARCH = i386
NATIVE_ARCH_32_BIT = i386
NATIVE_ARCH_64_BIT = x86_64
NATIVE_ARCH_ACTUAL = x86_64
NO_COMMON = YES
OBJC_ABI_VERSION = 2
OBJECT_FILE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/Objects
OBJECT_FILE_DIR_normal = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/Objects-normal
OBJROOT = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex
ONLY_ACTIVE_ARCH = YES
OS = MACOS
OSAC = /usr/bin/osacompile
OTHER_LDFLAGS = -ObjC -l"DoubleConversion" -l"FBReactNativeSpec" -l"Folly" -l"RCTTypeSafety" -l"React-Core" -l"React-CoreModules" -l"React-RCTActionSheet" -l"React-RCTAnimation" -l"React-RCTBlob" -l"React-RCTImage" -l"React-RCTLinking" -l"React-RCTNetwork" -l"React-RCTSettings" -l"React-RCTText" -l"React-RCTVibration" -l"React-cxxreact" -l"React-jsi" -l"React-jsiexecutor" -l"React-jsinspector" -l"ReactCommon" -l"Yoga" -l"glog" -l"stdc++" -framework "JavaScriptCore" -ObjC -lc++
PACKAGE_TYPE = com.apple.package-type.wrapper.application
PASCAL_STRINGS = YES
PATH = /Applications/Xcode.app/Contents/Developer/usr/bin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin:/opt/local/sbin:/Users/user/Library/Android/sdk/platform-tools:/Users/user/Library/Android/sdk/emulator:/Users/user/Library/Android/sdk/tools:/Users/user/Library/Android/sdk/tools/bin:/usr/local/bin/lldb-mi:/Users/user/Documents/Chrome_devTools/depot_tools:/Users/user/.npm-packages/bin:/Users/user/Library/Android/sdk/platform-tools:/Users/user/Library/Android/sdk/emulator:/Users/user/Library/Android/sdk/tools:/Users/user/Library/Android/sdk/tools/bin:/usr/local/bin/lldb-mi:/Users/user/Documents/Chrome_devTools/depot_tools:/opt/local/bin:/Users/user/.npm-packages/bin:/Users/user/Library/Android/sdk/platform-tools:/Users/user/Library/Android/sdk/emulator:/Users/user/Library/Android/sdk/tools:/Users/user/Library/Android/sdk/tools/bin
PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES = /usr/include /usr/local/include /System/Library/Frameworks /System/Library/PrivateFrameworks /Applications/Xcode.app/Contents/Developer/Headers /Applications/Xcode.app/Contents/Developer/SDKs /Applications/Xcode.app/Contents/Developer/Platforms
PBDEVELOPMENTPLIST_PATH = AwesomeProject0615.app/pbdevelopment.plist
PFE_FILE_C_DIALECTS = objective-c
PKGINFO_FILE_PATH = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/PkgInfo
PKGINFO_PATH = AwesomeProject0615.app/PkgInfo
PLATFORM_DEVELOPER_APPLICATIONS_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications
PLATFORM_DEVELOPER_BIN_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin
PLATFORM_DEVELOPER_LIBRARY_DIR = /Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library
PLATFORM_DEVELOPER_SDK_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs
PLATFORM_DEVELOPER_TOOLS_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Tools
PLATFORM_DEVELOPER_USR_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr
PLATFORM_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform
PLATFORM_DISPLAY_NAME = iOS Simulator
PLATFORM_NAME = iphonesimulator
PLATFORM_PREFERRED_ARCH = x86_64
PLATFORM_PRODUCT_BUILD_VERSION = 17B102
PLIST_FILE_OUTPUT_FORMAT = binary
PLUGINS_FOLDER_PATH = AwesomeProject0615.app/PlugIns
PODS_BUILD_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products
PODS_CONFIGURATION_BUILD_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator
PODS_PODFILE_DIR_PATH = /Users/user/Documents/test_react/AwesomeProject0615/ios/.
PODS_ROOT = /Users/user/Documents/test_react/AwesomeProject0615/ios/Pods
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES
PRECOMP_DESTINATION_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/PrefixHeaders
PRESERVE_DEAD_CODE_INITS_AND_TERMS = NO
PRIVATE_HEADERS_FOLDER_PATH = AwesomeProject0615.app/PrivateHeaders
PRODUCT_BUNDLE_IDENTIFIER = org.reactjs.native.example.AwesomeProject65dds
PRODUCT_BUNDLE_PACKAGE_TYPE = APPL
PRODUCT_MODULE_NAME = AwesomeProject0615
PRODUCT_NAME = AwesomeProject0615
PRODUCT_SETTINGS_PATH = /Users/user/Documents/test_react/AwesomeProject0615/ios/AwesomeProject0615/Info.plist
PRODUCT_TYPE = com.apple.product-type.application
PROFILING_CODE = NO
PROJECT = AwesomeProject0615
PROJECT_DERIVED_FILE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/DerivedSources
PROJECT_DIR = /Users/user/Documents/test_react/AwesomeProject0615/ios
PROJECT_FILE_PATH = /Users/user/Documents/test_react/AwesomeProject0615/ios/AwesomeProject0615.xcodeproj
PROJECT_NAME = AwesomeProject0615
PROJECT_TEMP_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build
PROJECT_TEMP_ROOT = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex
PUBLIC_HEADERS_FOLDER_PATH = AwesomeProject0615.app/Headers
RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS = YES
REMOVE_CVS_FROM_RESOURCES = YES
REMOVE_GIT_FROM_RESOURCES = YES
REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES = YES
REMOVE_HG_FROM_RESOURCES = YES
REMOVE_SVN_FROM_RESOURCES = YES
REZ_COLLECTOR_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/ResourceManagerResources
REZ_OBJECTS_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build/ResourceManagerResources/Objects
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = NO
SCRIPTS_FOLDER_PATH = AwesomeProject0615.app/Scripts
SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk
SDK_DIR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk
SDK_DIR_iphonesimulator13_2 = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk
SDK_NAME = iphonesimulator13.2
SDK_NAMES = iphonesimulator13.2
SDK_PRODUCT_BUILD_VERSION = 17B102
SDK_VERSION = 13.2
SDK_VERSION_ACTUAL = 130200
SDK_VERSION_MAJOR = 130000
SDK_VERSION_MINOR = 200
SED = /usr/bin/sed
SEPARATE_STRIP = NO
SEPARATE_SYMBOL_EDIT = NO
SET_DIR_MODE_OWNER_GROUP = YES
SET_FILE_MODE_OWNER_GROUP = NO
SHALLOW_BUNDLE = YES
SHARED_DERIVED_FILE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator/DerivedSources
SHARED_FRAMEWORKS_FOLDER_PATH = AwesomeProject0615.app/SharedFrameworks
SHARED_PRECOMPS_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/PrecompiledHeaders
SHARED_SUPPORT_FOLDER_PATH = AwesomeProject0615.app/SharedSupport
SKIP_INSTALL = NO
SOURCE_ROOT = /Users/user/Documents/test_react/AwesomeProject0615/ios
SRCROOT = /Users/user/Documents/test_react/AwesomeProject0615/ios
STRINGS_FILE_OUTPUT_ENCODING = binary
STRIP_BITCODE_FROM_COPIED_FILES = NO
STRIP_INSTALLED_PRODUCT = YES
STRIP_STYLE = all
STRIP_SWIFT_SYMBOLS = YES
SUPPORTED_DEVICE_FAMILIES = 1,2
SUPPORTED_PLATFORMS = iphonesimulator iphoneos
SUPPORTS_TEXT_BASED_API = NO
SWIFT_PLATFORM_TARGET_PREFIX = ios
SYMROOT = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products
SYSTEM_ADMIN_APPS_DIR = /Applications/Utilities
SYSTEM_APPS_DIR = /Applications
SYSTEM_CORE_SERVICES_DIR = /System/Library/CoreServices
SYSTEM_DEMOS_DIR = /Applications/Extras
SYSTEM_DEVELOPER_APPS_DIR = /Applications/Xcode.app/Contents/Developer/Applications
SYSTEM_DEVELOPER_BIN_DIR = /Applications/Xcode.app/Contents/Developer/usr/bin
SYSTEM_DEVELOPER_DEMOS_DIR = /Applications/Xcode.app/Contents/Developer/Applications/Utilities/Built Examples
SYSTEM_DEVELOPER_DIR = /Applications/Xcode.app/Contents/Developer
SYSTEM_DEVELOPER_DOC_DIR = /Applications/Xcode.app/Contents/Developer/ADC Reference Library
SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR = /Applications/Xcode.app/Contents/Developer/Applications/Graphics Tools
SYSTEM_DEVELOPER_JAVA_TOOLS_DIR = /Applications/Xcode.app/Contents/Developer/Applications/Java Tools
SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR = /Applications/Xcode.app/Contents/Developer/Applications/Performance Tools
SYSTEM_DEVELOPER_RELEASENOTES_DIR = /Applications/Xcode.app/Contents/Developer/ADC Reference Library/releasenotes
SYSTEM_DEVELOPER_TOOLS = /Applications/Xcode.app/Contents/Developer/Tools
SYSTEM_DEVELOPER_TOOLS_DOC_DIR = /Applications/Xcode.app/Contents/Developer/ADC Reference Library/documentation/DeveloperTools
SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR = /Applications/Xcode.app/Contents/Developer/ADC Reference Library/releasenotes/DeveloperTools
SYSTEM_DEVELOPER_USR_DIR = /Applications/Xcode.app/Contents/Developer/usr
SYSTEM_DEVELOPER_UTILITIES_DIR = /Applications/Xcode.app/Contents/Developer/Applications/Utilities
SYSTEM_DEXT_INSTALL_PATH = /System/Library/DriverExtensions
SYSTEM_DOCUMENTATION_DIR = /Library/Documentation
SYSTEM_KEXT_INSTALL_PATH = /System/Library/Extensions
SYSTEM_LIBRARY_DIR = /System/Library
TAPI_VERIFY_MODE = ErrorsOnly
TARGETED_DEVICE_FAMILY = 1
TARGETNAME = AwesomeProject0615
TARGET_BUILD_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Products/Debug-iphonesimulator
TARGET_NAME = AwesomeProject0615
TARGET_TEMP_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build
TEMP_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build
TEMP_FILES_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build
TEMP_FILE_DIR = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex/AwesomeProject0615.build/Debug-iphonesimulator/AwesomeProject0615.build
TEMP_ROOT = /Users/user/Library/Developer/Xcode/DerivedData/AwesomeProject0615-btdtcysqbddifyewiiztkumnopik/Build/Intermediates.noindex
TOOLCHAIN_DIR = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
TREAT_MISSING_BASELINES_AS_TEST_FAILURES = NO
UID = 501
UNLOCALIZED_RESOURCES_FOLDER_PATH = AwesomeProject0615.app
UNSTRIPPED_PRODUCT = NO
USER = user
USER_APPS_DIR = /Users/user/Applications
USER_LIBRARY_DIR = /Users/user/Library
USE_DYNAMIC_NO_PIC = YES
USE_HEADERMAP = YES
USE_HEADER_SYMLINKS = NO
USE_LLVM_TARGET_TRIPLES = YES
USE_LLVM_TARGET_TRIPLES_FOR_CLANG = YES
USE_LLVM_TARGET_TRIPLES_FOR_LD = YES
USE_LLVM_TARGET_TRIPLES_FOR_TAPI = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
VALIDATE_PRODUCT = NO
VALIDATE_WORKSPACE = NO
VALID_ARCHS = i386 x86_64
VERBOSE_PBXCP = NO
VERSIONING_SYSTEM = apple-generic
VERSIONPLIST_PATH = AwesomeProject0615.app/version.plist
VERSION_INFO_BUILDER = user
VERSION_INFO_FILE = AwesomeProject0615_vers.c
VERSION_INFO_STRING = "@(#)PROGRAM:AwesomeProject0615 PROJECT:AwesomeProject0615-1"
WRAPPER_EXTENSION = app
WRAPPER_NAME = AwesomeProject0615.app
WRAPPER_SUFFIX = .app
WRAP_ASSET_PACKS_IN_SEPARATE_DIRECTORIES = NO
XCODE_APP_SUPPORT_DIR = /Applications/Xcode.app/Contents/Developer/Library/Xcode
XCODE_PRODUCT_BUILD_VERSION = 11C29
XCODE_VERSION_ACTUAL = 1130
XCODE_VERSION_MAJOR = 1100
XCODE_VERSION_MINOR = 1130
XPCSERVICES_FOLDER_PATH = AwesomeProject0615.app/XPCServices
YACC = yacc
arch = x86_64
diagnostic_message_length = 123
variant = normal

Просмотреть файл

@ -17,7 +17,7 @@
"prepublishOnly": "npm run copy-package-version"
},
"devDependencies": {
"@types/mkdirp": "0.5.1",
"@types/mkdirp": "^1.0.0",
"@types/ncp": "2.0.1",
"@types/node": "8.0.33",
"@types/puppeteer": "^1.19.0",
@ -25,10 +25,13 @@
"typescript": "2.9.2"
},
"dependencies": {
"mkdirp": "^0.5.1",
"mkdirp": "^1.0.3",
"ncp": "^2.0.0",
"puppeteer": "^1.19.0",
"tmp": "0.1.0",
"vscode-uri": "^2.0.3"
},
"resolutions": {
"**/minimist": "^1.2.3"
}
}

Просмотреть файл

@ -7,7 +7,6 @@ import { Code, findElement } from "./code";
import { Editors } from "./editors";
import { Editor } from "./editor";
import { IElement } from "../src/driver";
import { QuickOpen } from ".";
const VIEWLET = "div[id=\"workbench.view.debug\"]";
const DEBUG_VIEW = `${VIEWLET} .debug-view-content`;
@ -50,7 +49,7 @@ function toStackFrame(element: IElement): IStackFrame {
export class Debug extends Viewlet {
constructor(code: Code, private commands: Commands, private editors: Editors, private editor: Editor, private quickopen: QuickOpen) {
constructor(code: Code, private commands: Commands, private editors: Editors, private editor: Editor) {
super(code);
}
@ -87,11 +86,6 @@ export class Debug extends Viewlet {
return await this.code.waitForElement(STACK_FRAME);
}
public async runDebugScenario(debugOption: string): Promise<any> {
await this.quickopen.openQuickOpen();
await this.quickopen.submit(`debug ${debugOption}`);
}
public async stepOver(): Promise<any> {
await this.code.waitAndClick(STEP_OVER);
}

Просмотреть файл

@ -90,6 +90,16 @@ export class QuickOpen {
await this.code.waitAndClick(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT);
}
public async runDebugScenario(scenario: string): Promise<void> {
await this.openQuickOpen(`debug ${scenario}`);
// wait for the best choice to be focused
await this.code.waitForTextContent(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT, scenario);
// wait and click on the best choice
await this.code.waitAndClick(QuickOpen.QUICK_OPEN_FOCUSED_ELEMENT);
}
public async openQuickOutline(): Promise<void> {
let retries = 0;

Просмотреть файл

@ -50,7 +50,7 @@ export class Workbench {
this.extensions = new Extensions(code);
this.editor = new Editor(code, this.quickopen);
this.scm = new SCM(code);
this.debug = new Debug(code, this.quickopen, this.editors, this.editor, this.quickopen);
this.debug = new Debug(code, this.quickopen, this.editors, this.editor);
this.statusbar = new StatusBar(code);
this.problems = new Problems(code);
this.settingsEditor = new SettingsEditor(code, userDataPath, this.editors, this.editor, this.quickopen);

Просмотреть файл

@ -2,10 +2,10 @@
# yarn lockfile v1
"@types/mkdirp@0.5.1":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.1.tgz#ea887cd024f691c1ca67cce20b7606b053e43b0f"
integrity sha512-XA4vNO6GCBz8Smq0hqSRo4yRWMqr4FPQrWjhJt6nKskzly4/p87SfuJMFYGRyYb6jo2WNIQU2FDBsY5r1BibUA==
"@types/mkdirp@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.0.tgz#16ce0eabe4a9a3afe64557ad0ee6886ec3d32927"
integrity sha512-ONFY9//bCEr3DWKON3iDv/Q8LXnhaYYaNDeFSN0AtO5o4sLf9F0pstJKKKjQhXE0kJEeHs8eR6SAsROhhc2Csw==
dependencies:
"@types/node" "*"
@ -193,18 +193,23 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
minimist@0.0.8, minimist@^1.2.3:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
mkdirp@0.5.1, mkdirp@^0.5.1:
mkdirp@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
mkdirp@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea"
integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"

Просмотреть файл

@ -59,15 +59,17 @@ Tests are running using [VS Code automation package](https://github.com/microsof
[System.EnvironmentVariableTarget]::Machine)
```
* **Mac**:
Add these lines to `~/.bash_profile` (create one if you haven't it):
Add these lines to `~/.bash_profile` (create one if it doesn't exist):
```bash
export JAVA_HOME="$(/usr/libexec/java_home)"
export ANDROID_HOME=/Users/<username>/Library/Android/sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME
PATH="$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools/bin"
```
* **Linux**:
Add these lines to `~/.bash_profile` (create one if you haven't it):
Add these lines to `~/.bash_profile` (create one if it doesn't exist):
```bash
export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")
export ANDROID_HOME=/home/<username>/Android/sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME
PATH="$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools/bin"

Просмотреть файл

@ -4,8 +4,8 @@
"IOS_SIMULATOR": "iPhone8",
"IOS_VERSION": "12.4",
"CODE_VERSION": "1.40.2",
"EXPO_XDL_VERSION": "57.5.2",
"RN_VERSION": "0.61.5",
"EXPO_XDL_VERSION": "57.8.32",
"RN_VERSION": "0.62.0",
"PURE_RN_VERSION": "0.59.8",
"PURE_EXPO_VERSION": "36.0.1"
"PURE_EXPO_VERSION": "36.0.2"
}

Просмотреть файл

@ -8,10 +8,10 @@
"mocha": "node ./node_modules/tslint/bin/tslint -c tslint.json --project tsconfig.json 'src/**' && tsc && node ./node_modules/mocha/bin/_mocha --reporter mocha-multi-reporters --reporter-options configFile=./mochaReporterConfig.json"
},
"devDependencies": {
"@expo/xdl": "57.5.2",
"@expo/xdl": "^57.8.14",
"@types/clipboardy": "^2.0.1",
"@types/gulp-filter": "^3.0.33",
"@types/mkdirp": "^0.5.2",
"@types/mkdirp": "^1.0.0",
"@types/mocha": "^5.2.7",
"@types/node": "^10.14.4",
"@types/request": "^2.48.1",
@ -28,14 +28,14 @@
"gulp-remote-src-vscode": "^0.5.1",
"gulp-untar": "^0.0.7",
"gulp-vinyl-zip": "^2.1.2",
"mkdirp": "^0.5.1",
"mocha": "^6.1.2",
"mkdirp": "^1.0.3",
"mocha": "6.2.3",
"mocha-junit-reporter": "^1.18.0",
"mocha-multi-reporters": "^1.1.7",
"portastic": "^1.0.1",
"request": "^2.88.0",
"rimraf": "^2.6.1",
"tree-kill": "^1.2.1",
"tree-kill": "^1.2.2",
"tslint": "^5.15.0",
"typescript": "^3.7.5",
"url-parse": "^1.4.3",
@ -45,6 +45,8 @@
},
"resolutions": {
"@expo/xdl/analytics-node/axios": "^0.19.0",
"**/serialize-javascript": "^2.1.1"
"**/serialize-javascript": "^2.1.1",
"**/tree-kill": "^1.2.2",
"**/minimist": "^1.2.3"
}
}

Просмотреть файл

@ -15,7 +15,9 @@ import com.android.build.OutputFile
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation
* // the entry file for bundle generation. If none specified and
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
* // default. Can be overridden with ENTRY_FILE environment variable.
* entryFile: "index.android.js",
*
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
@ -76,7 +78,6 @@ import com.android.build.OutputFile
*/
project.ext.react = [
entryFile: "index.js",
enableHermes: true, // clean and rebuild if changing
]
@ -162,6 +163,14 @@ android {
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
packagingOptions {
pickFirst "lib/armeabi-v7a/libc++_shared.so"
pickFirst "lib/arm64-v8a/libc++_shared.so"
pickFirst "lib/x86/libc++_shared.so"
pickFirst "lib/x86_64/libc++_shared.so"
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
@ -180,8 +189,23 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")

Просмотреть файл

@ -40,6 +40,22 @@
"type": "reactnative",
"request": "launch",
"platform": "exponent"
},
{
"name": "Debug in Exponent (LAN)",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "exponent",
"expoHostType": "lan"
},
{
"name": "Debug in Exponent (Local)",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "launch",
"platform": "exponent",
"expoHostType": "local"
}
]
}

Просмотреть файл

@ -20,17 +20,20 @@ const RNDebugConfigName = "Debug Android";
const RNHermesDebugConfigName = "Debug Android (Hermes) - Experimental";
const RNHermesAttachConfigName = "Attach to Hermes application - Experimental";
const ExpoDebugConfigName = "Debug in Exponent";
const ExpoLanDebugConfigName = "Debug in Exponent (LAN)";
const ExpoLocalDebugConfigName = "Debug in Exponent (Local)";
const RNSetBreakpointOnLine = 1;
const RNHermesSetBreakpointOnLine = 11;
const ExpoSetBreakpointOnLine = 1;
const PureRNExpoSetBreakpointOnLine = 1;
// Time for Android Debug Test before it reaches timeout
const debugAndroidTestTime = SmokeTestsConstants.androidAppBuildAndInstallTimeout + 100 * 1000;
// Time for Android Expo Debug Test before it reaches timeout
const debugExpoTestTime = SmokeTestsConstants.expoAppBuildAndInstallTimeout + 400 * 1000;
export function setup(testParameters?: TestRunArguments) {
describe("Debugging Android", () => {
let app: Application;
let clientInited: AppiumClient;
@ -45,19 +48,86 @@ export function setup(testParameters?: TestRunArguments) {
}
});
async function expoTest(testName: string, workspacePath: string, debugConfigName: string, triesToLaunchApp: number) {
app = await runVSCode(workspacePath);
console.log(`${testName}: ${workspacePath} directory is opened in VS Code`);
await app.workbench.quickopen.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log(`${testName}: App.js file is opened`);
await app.workbench.debug.setBreakpointOnLine(ExpoSetBreakpointOnLine);
console.log(`${testName}: Breakpoint is set on line ${ExpoSetBreakpointOnLine}`);
console.log(`${testName}: Chosen debug configuration: ${debugConfigName}`);
console.log(`${testName}: Starting debugging`);
// Scan logs only if launch retries provided (Expo Tunnel scenarios)
if (triesToLaunchApp <= 1) {
await app.workbench.quickopen.runDebugScenario(debugConfigName);
} else {
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
for (let retry = 1; retry <= triesToLaunchApp; retry++) {
let expoLaunchStatus: ExpoLaunch;
await app.workbench.quickopen.runDebugScenario(debugConfigName);
expoLaunchStatus = await findExpoSuccessAndFailurePatterns(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeLogFileName), SmokeTestsConstants.ExpoSuccessPattern, SmokeTestsConstants.ExpoFailurePattern);
if (expoLaunchStatus.successful) {
break;
} else {
if (retry === triesToLaunchApp) {
assert.fail(`App start has failed after ${retry} retries`);
}
console.log(`Attempt to start #${retry} failed, retrying...`);
}
}
} else {
assert.fail("REACT_NATIVE_TOOLS_LOGS_DIR is not defined");
}
}
await app.workbench.editors.waitForTab("Expo QR Code");
await app.workbench.editors.waitForActiveTab("Expo QR Code");
console.log(`${testName}: 'Expo QR Code' tab found`);
let expoURL;
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
expoURL = findExpoURLInLogFile(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeRunExpoLogFileName));
}
assert.notStrictEqual(expoURL, null, "Expo URL pattern is not found");
expoURL = expoURL as string;
const opts = AppiumHelper.prepareAttachOptsForAndroidActivity(EXPO_APP_PACKAGE_NAME, EXPO_APP_ACTIVITY_NAME, AndroidEmulatorHelper.androidEmulatorName);
let client = AppiumHelper.webdriverAttach(opts);
clientInited = client.init();
// TODO Add listener to trigger that main expo app has been ran
await AppiumHelper.openExpoApplication(Platform.Android, clientInited, expoURL, workspacePath);
// TODO Add listener to trigger that child expo app has been ran instead of using timeout
console.log(`${testName}: Waiting ${SmokeTestsConstants.expoAppBuildAndInstallTimeout}ms until Expo app is ready...`);
await sleep(SmokeTestsConstants.expoAppBuildAndInstallTimeout);
await AppiumHelper.disableDevMenuInformationalMsg(clientInited, Platform.Android_Expo);
await sleep(2 * 1000);
await AppiumHelper.enableRemoteDebugJS(clientInited, Platform.Android_Expo);
await app.workbench.debug.waitForDebuggingToStart();
console.log(`${testName}: Debugging started`);
await app.workbench.debug.waitForStackFrame(sf => sf.name === "App.js" && sf.lineNumber === ExpoSetBreakpointOnLine, `looking for App.js and line ${ExpoSetBreakpointOnLine}`);
console.log(`${testName}: Stack frame found`);
await app.workbench.debug.stepOver();
// Wait for debug string to be rendered in debug console
await sleep(SmokeTestsConstants.debugConsoleSearchTimeout);
console.log(`${testName}: Searching for \"Test output from debuggee\" string in console`);
let found = await app.workbench.debug.waitForOutput(output => output.some(line => line.indexOf("Test output from debuggee") >= 0));
assert.notStrictEqual(found, false, "\"Test output from debuggee\" string is missing in debug console");
console.log(`${testName}: \"Test output from debuggee\" string is found`);
await app.workbench.debug.stopDebugging();
console.log(`${testName}: Debugging is stopped`);
}
it("RN app Debug test", async function () {
this.timeout(debugAndroidTestTime);
app = await runVSCode(RNworkspacePath);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("App.js");
await app.workbench.quickopen.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log("Android Debug test: App.js file is opened");
await app.workbench.debug.setBreakpointOnLine(RNSetBreakpointOnLine);
console.log(`Android Debug test: Breakpoint is set on line ${RNSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`Android Debug test: Chosen debug configuration: ${RNDebugConfigName}`);
console.log("Android Debug test: Starting debugging");
await app.workbench.debug.runDebugScenario(RNDebugConfigName);
await app.workbench.quickopen.runDebugScenario(RNDebugConfigName);
const opts = AppiumHelper.prepareAttachOptsForAndroidActivity(RN_APP_PACKAGE_NAME, RN_APP_ACTIVITY_NAME, AndroidEmulatorHelper.androidEmulatorName);
await AndroidEmulatorHelper.checkIfAppIsInstalled(RN_APP_PACKAGE_NAME, SmokeTestsConstants.androidAppBuildAndInstallTimeout);
let client = AppiumHelper.webdriverAttach(opts);
@ -84,17 +154,14 @@ export function setup(testParameters?: TestRunArguments) {
prepareReactNativeProjectForHermesTesting();
AndroidEmulatorHelper.uninstallTestAppFromEmulator(RN_APP_PACKAGE_NAME);
app = await runVSCode(RNworkspacePath);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("AppTestButton.js");
await app.workbench.quickopen.openFile("AppTestButton.js");
await app.workbench.editors.scrollTop();
console.log("Android Debug Hermes test: AppTestButton.js file is opened");
await app.workbench.debug.setBreakpointOnLine(RNHermesSetBreakpointOnLine);
console.log(`Android Debug Hermes test: Breakpoint is set on line ${RNHermesSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`Android Debug Hermes test: Debug Viewlet opened`);
console.log(`Android Debug Hermes test: Chosen debug configuration: ${RNHermesDebugConfigName}`);
console.log("Android Debug Hermes test: Starting debugging");
await app.workbench.debug.runDebugScenario(RNHermesDebugConfigName);
await app.workbench.quickopen.runDebugScenario(RNHermesDebugConfigName);
const opts = AppiumHelper.prepareAttachOptsForAndroidActivity(RN_APP_PACKAGE_NAME, RN_APP_ACTIVITY_NAME, AndroidEmulatorHelper.androidEmulatorName);
await AndroidEmulatorHelper.checkIfAppIsInstalled(RN_APP_PACKAGE_NAME, SmokeTestsConstants.androidAppBuildAndInstallTimeout);
let client = AppiumHelper.webdriverAttach(opts);
@ -106,7 +173,7 @@ export function setup(testParameters?: TestRunArguments) {
assert.equal(isHermesWorking, true);
console.log("Android Debug Hermes test: Reattaching to Hermes app");
await app.workbench.debug.stopDebugging();
await app.workbench.debug.runDebugScenario(RNHermesAttachConfigName);
await app.workbench.quickopen.runDebugScenario(RNHermesAttachConfigName);
console.log("Android Debug Hermes test: Reattached successfully");
await sleep(7000);
console.log("Android Debug Hermes test: Click Test Button");
@ -126,122 +193,36 @@ export function setup(testParameters?: TestRunArguments) {
console.log("Android Debug Hermes test: Debugging is stopped");
});
it("Expo app Debug test", async function () {
it("Expo app Debug test(Tunnel)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
this.timeout(debugExpoTestTime);
app = await runVSCode(ExpoWorkspacePath);
console.log(`Android Expo Debug test: ${ExpoWorkspacePath} directory is opened in VS Code`);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log("Android Expo Debug test: App.js file is opened");
await app.workbench.debug.setBreakpointOnLine(ExpoSetBreakpointOnLine);
console.log(`Android Expo Debug test: Breakpoint is set on line ${ExpoSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`Android Expo Debug test: Chosen debug configuration: ${ExpoDebugConfigName}`);
console.log("Android Expo Debug test: Starting debugging");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
let expoLaunchStatus: ExpoLaunch;
expoLaunchStatus = await findExpoSuccessAndFailurePatterns(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeLogFileName), SmokeTestsConstants.ExpoSuccessPattern, SmokeTestsConstants.ExpoFailurePattern);
if (expoLaunchStatus.failed) {
console.log("First attempt to start failed, retrying...");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
}
}
await app.workbench.editors.waitForTab("Expo QR Code");
await app.workbench.editors.waitForActiveTab("Expo QR Code");
console.log("Android Expo Debug test: 'Expo QR Code' tab found");
let expoURL;
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
expoURL = findExpoURLInLogFile(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeRunExpoLogFileName));
}
assert.notStrictEqual(expoURL, null, "Expo URL pattern is not found");
expoURL = expoURL as string;
const opts = AppiumHelper.prepareAttachOptsForAndroidActivity(EXPO_APP_PACKAGE_NAME, EXPO_APP_ACTIVITY_NAME, AndroidEmulatorHelper.androidEmulatorName);
let client = AppiumHelper.webdriverAttach(opts);
clientInited = client.init();
// TODO Add listener to trigger that main expo app has been ran
await AppiumHelper.openExpoApplication(Platform.Android, clientInited, expoURL, ExpoWorkspacePath);
// TODO Add listener to trigger that child expo app has been ran instead of using timeout
console.log(`Android Expo Debug test: Waiting ${SmokeTestsConstants.expoAppBuildAndInstallTimeout}ms until Expo app is ready...`);
await sleep(SmokeTestsConstants.expoAppBuildAndInstallTimeout);
await AppiumHelper.enableRemoteDebugJS(clientInited, Platform.Android);
await app.workbench.debug.waitForDebuggingToStart();
console.log("Android Expo Debug test: Debugging started");
await app.workbench.debug.waitForStackFrame(sf => sf.name === "App.js" && sf.lineNumber === ExpoSetBreakpointOnLine, `looking for App.js and line ${ExpoSetBreakpointOnLine}`);
console.log("Android Expo Debug test: Stack frame found");
await app.workbench.debug.stepOver();
// Wait for debug string to be rendered in debug console
await sleep(SmokeTestsConstants.debugConsoleSearchTimeout);
console.log("Android Expo Debug test: Searching for \"Test output from debuggee\" string in console");
let found = await app.workbench.debug.waitForOutput(output => output.some(line => line.indexOf("Test output from debuggee") >= 0));
assert.notStrictEqual(found, false, "\"Test output from debuggee\" string is missing in debug console");
console.log("Android Expo Debug test: \"Test output from debuggee\" string is found");
await app.workbench.debug.stopDebugging();
console.log("Android Expo Debug test: Debugging is stopped");
await expoTest("Android Expo Debug test(Tunnel)", ExpoWorkspacePath, ExpoDebugConfigName, 5);
});
it("Pure RN app Expo test", async function () {
it("Pure RN app Expo test(LAN)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
this.timeout(debugExpoTestTime);
app = await runVSCode(pureRNWorkspacePath);
console.log(`Android pure RN Expo test: ${pureRNWorkspacePath} directory is opened in VS Code`);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log("Android pure RN Expo test: App.js file is opened");
await app.workbench.debug.setBreakpointOnLine(PureRNExpoSetBreakpointOnLine);
console.log(`Android pure RN Expo test: Breakpoint is set on line ${PureRNExpoSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`Android pure RN Expo test: Chosen debug configuration: ${ExpoDebugConfigName}`);
console.log("Android pure RN Expo test: Starting debugging");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
let expoLaunchStatus: ExpoLaunch;
expoLaunchStatus = await findExpoSuccessAndFailurePatterns(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeLogFileName), SmokeTestsConstants.ExpoSuccessPattern, SmokeTestsConstants.ExpoFailurePattern);
if (expoLaunchStatus.failed) {
console.log("First attempt to start failed, retrying...");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
}
}
await app.workbench.editors.waitForTab("Expo QR Code");
await app.workbench.editors.waitForActiveTab("Expo QR Code");
console.log("Android pure RN Expo test: 'Expo QR Code' tab found");
await expoTest("Android pure RN Expo test(LAN)", pureRNWorkspacePath, ExpoLanDebugConfigName, 1);
});
let expoURL;
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
expoURL = findExpoURLInLogFile(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeRunExpoLogFileName));
it("Expo app Debug test(LAN)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
this.timeout(debugExpoTestTime);
await expoTest("Android Expo Debug test(LAN)", ExpoWorkspacePath, ExpoLanDebugConfigName, 1);
});
assert.notStrictEqual(expoURL, null, "Expo URL pattern is not found");
expoURL = expoURL as string;
const opts = AppiumHelper.prepareAttachOptsForAndroidActivity(EXPO_APP_PACKAGE_NAME, EXPO_APP_ACTIVITY_NAME, AndroidEmulatorHelper.androidEmulatorName);
let client = AppiumHelper.webdriverAttach(opts);
clientInited = client.init();
await AppiumHelper.openExpoApplication(Platform.Android, clientInited, expoURL, pureRNWorkspacePath);
console.log(`Android pure RN Expo test: Waiting ${SmokeTestsConstants.expoAppBuildAndInstallTimeout}ms until Expo app is ready...`);
await sleep(SmokeTestsConstants.expoAppBuildAndInstallTimeout);
await AppiumHelper.enableRemoteDebugJS(clientInited, Platform.Android);
await app.workbench.debug.waitForDebuggingToStart();
console.log("Android pure RN Expo test: Debugging started");
await app.workbench.debug.waitForStackFrame(sf => sf.name === "App.js" && sf.lineNumber === PureRNExpoSetBreakpointOnLine, `looking for App.js and line ${PureRNExpoSetBreakpointOnLine}`);
console.log("Android pure RN Expo test: Stack frame found");
await app.workbench.debug.stepOver();
// Wait for debug string to be rendered in debug console
await sleep(SmokeTestsConstants.debugConsoleSearchTimeout);
console.log("Android pure RN Expo test: Searching for \"Test output from debuggee\" string in console");
let found = await app.workbench.debug.waitForOutput(output => output.some(line => line.indexOf("Test output from debuggee") >= 0));
assert.notStrictEqual(found, false, "\"Test output from debuggee\" string is missing in debug console");
console.log("Android pure RN Expo test: \"Test output from debuggee\" string is found");
await app.workbench.debug.stopDebugging();
console.log("Android pure RN Expo test: Debugging is stopped");
it("Expo app Debug test(localhost)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
this.timeout(debugExpoTestTime);
await expoTest("Android Expo Debug test(localhost)", ExpoWorkspacePath, ExpoLocalDebugConfigName, 1);
});
});
}

Просмотреть файл

@ -15,15 +15,18 @@ import { Application } from "../../automation";
const RnAppBundleId = "org.reactjs.native.example.latestRNApp";
const RNDebugConfigName = "Debug iOS";
const ExpoDebugConfigName = "Debug in Exponent";
const ExpoLanDebugConfigName = "Debug in Exponent (LAN)";
const ExpoLocalDebugConfigName = "Debug in Exponent (Local)";
const RNSetBreakpointOnLine = 1;
const ExpoSetBreakpointOnLine = 1;
const PureRNExpoSetBreakpointOnLine = 1;
// Time for OS Debug Test before it reaches timeout
const debugIosTestTime = SmokeTestsConstants.iosAppBuildAndInstallTimeout + 100 * 1000;
// Time for iOS Expo Debug Test before it reaches timeout
const debugExpoTestTime = SmokeTestsConstants.expoAppBuildAndInstallTimeout + 400 * 1000;
let expoFirstLaunch = true;
export function setup(testParameters?: TestRunArguments) {
describe("Debugging iOS", () => {
let app: Application;
@ -39,21 +42,97 @@ export function setup(testParameters?: TestRunArguments) {
}
});
async function expoTest(testName: string, workspacePath: string, debugConfigName: string, triesToLaunchApp: number) {
app = await runVSCode(workspacePath);
console.log(`${testName}: ${workspacePath} directory is opened in VS Code`);
await app.workbench.quickopen.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log(`${testName}: App.js file is opened`);
await app.workbench.debug.setBreakpointOnLine(ExpoSetBreakpointOnLine);
console.log(`${testName}: Breakpoint is set on line ${ExpoSetBreakpointOnLine}`);
console.log(`${testName}: Chosen debug configuration: ${debugConfigName}`);
console.log(`${testName}: Starting debugging`);
const device = <string>IosSimulatorHelper.getDevice();
// Scan logs only if launch retries provided (Expo Tunnel scenarios)
if (triesToLaunchApp <= 1) {
await app.workbench.quickopen.runDebugScenario(debugConfigName);
} else {
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
for (let retry = 1; retry <= triesToLaunchApp; retry++) {
let expoLaunchStatus: ExpoLaunch;
await app.workbench.quickopen.runDebugScenario(debugConfigName);
expoLaunchStatus = await findExpoSuccessAndFailurePatterns(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeLogFileName), SmokeTestsConstants.ExpoSuccessPattern, SmokeTestsConstants.ExpoFailurePattern);
if (expoLaunchStatus.successful) {
break;
} else {
if (retry === triesToLaunchApp) {
assert.fail(`App start has failed after ${retry} retries`);
}
console.log(`Attempt to start #${retry} failed, retrying...`);
}
}
} else {
assert.fail("REACT_NATIVE_TOOLS_LOGS_DIR is not defined");
}
}
await app.workbench.editors.waitForTab("Expo QR Code");
await app.workbench.editors.waitForActiveTab("Expo QR Code");
console.log(`${testName}: 'Expo QR Code' tab found`);
let expoURL;
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
expoURL = findExpoURLInLogFile(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeRunExpoLogFileName));
}
assert.notStrictEqual(expoURL, null, "Expo URL pattern is not found");
expoURL = expoURL as string;
let appFile = findFile(SetupEnvironmentHelper.iOSExpoAppsCacheDir, /.*\.(app)/);
if (!appFile) {
throw new Error(`iOS Expo app is not found in ${SetupEnvironmentHelper.iOSExpoAppsCacheDir}`);
}
const appPath = path.join(SetupEnvironmentHelper.iOSExpoAppsCacheDir, appFile);
const opts = AppiumHelper.prepareAttachOptsForIosApp(device, appPath);
let client = AppiumHelper.webdriverAttach(opts);
clientInited = client.init();
await AppiumHelper.openExpoApplication(Platform.iOS, clientInited, expoURL, workspacePath, expoFirstLaunch);
expoFirstLaunch = false;
console.log(`${testName}: Waiting ${SmokeTestsConstants.expoAppBuildAndInstallTimeout}ms until Expo app is ready...`);
await sleep(SmokeTestsConstants.expoAppBuildAndInstallTimeout);
await AppiumHelper.disableExpoErrorRedBox(clientInited);
await AppiumHelper.disableDevMenuInformationalMsg(clientInited, Platform.iOS_Expo);
await AppiumHelper.enableRemoteDebugJS(clientInited, Platform.iOS_Expo);
await sleep(5 * 1000);
await app.workbench.debug.waitForDebuggingToStart();
console.log(`${testName}: Debugging started`);
await app.workbench.debug.waitForStackFrame(sf => sf.name === "App.js" && sf.lineNumber === ExpoSetBreakpointOnLine, `looking for App.js and line ${ExpoSetBreakpointOnLine}`);
console.log(`${testName}: Stack frame found`);
await app.workbench.debug.stepOver();
// Wait for our debug string to render in debug console
await sleep(SmokeTestsConstants.debugConsoleSearchTimeout);
console.log(`${testName}: Searching for \"Test output from debuggee\" string in console`);
let found = await app.workbench.debug.waitForOutput(output => output.some(line => line.indexOf("Test output from debuggee") >= 0));
assert.notStrictEqual(found, false, "\"Test output from debuggee\" string is missing in debug console");
console.log(`${testName}: \"Test output from debuggee\" string is found`);
await app.workbench.debug.stopDebugging();
console.log(`${testName}: Debugging is stopped`);
}
it("RN app Debug test", async function () {
this.timeout(debugIosTestTime);
app = await runVSCode(RNworkspacePath);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("App.js");
await app.workbench.quickopen.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log("iOS Debug test: App.js file is opened");
await app.workbench.debug.setBreakpointOnLine(RNSetBreakpointOnLine);
console.log(`iOS Debug test: Breakpoint is set on line ${RNSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`iOS Debug test: Chosen debug configuration: ${RNDebugConfigName}`);
// We need to implicitly add target to "Debug iOS" configuration to avoid running additional simulator
SetupEnvironmentHelper.addIosTargetToLaunchJson(RNworkspacePath);
console.log("iOS Debug test: Starting debugging");
await app.workbench.debug.runDebugScenario(RNDebugConfigName);
await app.workbench.quickopen.runDebugScenario(RNDebugConfigName);
await IosSimulatorHelper.waitUntilIosAppIsInstalled(RnAppBundleId, SmokeTestsConstants.iosAppBuildAndInstallTimeout, 40 * 1000);
const device = <string>IosSimulatorHelper.getDevice();
@ -86,148 +165,36 @@ export function setup(testParameters?: TestRunArguments) {
console.log("iOS Debug test: Debugging is stopped");
});
it("Expo app Debug test", async function () {
it("Expo app Debug test(Tunnel)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
this.timeout(debugExpoTestTime);
app = await runVSCode(ExpoWorkspacePath);
console.log(`iOS Expo Debug test: ${ExpoWorkspacePath} directory is opened in VS Code`);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log("iOS Expo Debug test: App.js file is opened");
await app.workbench.debug.setBreakpointOnLine(ExpoSetBreakpointOnLine);
console.log(`iOS Expo Debug test: Breakpoint is set on line ${ExpoSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`iOS Expo Debug test: Chosen debug configuration: ${ExpoDebugConfigName}`);
// We need to implicitly add target to "Debug iOS" configuration to avoid running additional simulator
SetupEnvironmentHelper.addIosTargetToLaunchJson(RNworkspacePath);
console.log("iOS Expo Debug test: Starting debugging");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
const device = <string>IosSimulatorHelper.getDevice();
await sleep(5 * 1000);
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
let expoLaunchStatus: ExpoLaunch;
expoLaunchStatus = await findExpoSuccessAndFailurePatterns(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeLogFileName), SmokeTestsConstants.ExpoSuccessPattern, SmokeTestsConstants.ExpoFailurePattern);
if (expoLaunchStatus.failed) {
console.log("First attempt to start failed, retrying...");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
}
}
await app.workbench.editors.waitForTab("Expo QR Code");
await app.workbench.editors.waitForActiveTab("Expo QR Code");
console.log("iOS Expo Debug test: 'Expo QR Code' tab found");
let expoURL;
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
expoURL = findExpoURLInLogFile(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeRunExpoLogFileName));
}
assert.notStrictEqual(expoURL, null, "Expo URL pattern is not found");
expoURL = expoURL as string;
let appFile = findFile(SetupEnvironmentHelper.iOSExpoAppsCacheDir, /.*\.(app)/);
if (!appFile) {
throw new Error(`iOS Expo app is not found in ${SetupEnvironmentHelper.iOSExpoAppsCacheDir}`);
}
const appPath = path.join(SetupEnvironmentHelper.iOSExpoAppsCacheDir, appFile);
const opts = AppiumHelper.prepareAttachOptsForIosApp(device, appPath);
let client = AppiumHelper.webdriverAttach(opts);
clientInited = client.init();
await AppiumHelper.openExpoApplication(Platform.iOS, clientInited, expoURL, ExpoWorkspacePath);
console.log(`iOS Expo Debug test: Waiting ${SmokeTestsConstants.expoAppBuildAndInstallTimeout}ms until Expo app is ready...`);
await sleep(SmokeTestsConstants.expoAppBuildAndInstallTimeout);
await AppiumHelper.disableExpoErrorRedBox(clientInited);
await AppiumHelper.disableDevMenuInformationalMsg(clientInited);
await AppiumHelper.enableRemoteDebugJS(clientInited, Platform.iOS_Expo);
await sleep(5 * 1000);
await app.workbench.debug.waitForDebuggingToStart();
console.log("iOS Expo Debug test: Debugging started");
await app.workbench.debug.waitForStackFrame(sf => sf.name === "App.js" && sf.lineNumber === ExpoSetBreakpointOnLine, `looking for App.js and line ${ExpoSetBreakpointOnLine}`);
console.log("iOS Expo Debug test: Stack frame found");
await app.workbench.debug.stepOver();
// Wait for our debug string to render in debug console
await sleep(SmokeTestsConstants.debugConsoleSearchTimeout);
console.log("iOS Expo Debug test: Searching for \"Test output from debuggee\" string in console");
let found = await app.workbench.debug.waitForOutput(output => output.some(line => line.indexOf("Test output from debuggee") >= 0));
assert.notStrictEqual(found, false, "\"Test output from debuggee\" string is missing in debug console");
console.log("iOS Expo Debug test: \"Test output from debuggee\" string is found");
await app.workbench.debug.stopDebugging();
console.log("iOS Expo Debug test: Debugging is stopped");
await expoTest("iOS Expo Debug test(Tunnel)", ExpoWorkspacePath, ExpoDebugConfigName, 5);
});
it("Pure RN app Expo test", async function () {
it("Pure RN app Expo test(LAN)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
this.timeout(debugExpoTestTime);
app = await runVSCode(pureRNWorkspacePath);
console.log(`iOS pure RN Expo test: ${pureRNWorkspacePath} directory is opened in VS Code`);
await app.workbench.explorer.openExplorerView();
await app.workbench.explorer.openFile("App.js");
await app.workbench.editors.scrollTop();
console.log("iOS pure RN Expo test: App.js file is opened");
await app.workbench.debug.setBreakpointOnLine(PureRNExpoSetBreakpointOnLine);
console.log(`iOS pure RN Expo test: Breakpoint is set on line ${PureRNExpoSetBreakpointOnLine}`);
await app.workbench.debug.openDebugViewlet();
console.log(`iOS pure RN Expo test: Chosen debug configuration: ${ExpoDebugConfigName}`);
// We need to implicitly add target to "Debug iOS" configuration to avoid running additional simulator
SetupEnvironmentHelper.addIosTargetToLaunchJson(pureRNWorkspacePath);
console.log("iOS pure RN Expo test: Starting debugging");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
const device = <string>IosSimulatorHelper.getDevice();
await sleep(5 * 1000);
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
let expoLaunchStatus: ExpoLaunch;
expoLaunchStatus = await findExpoSuccessAndFailurePatterns(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeLogFileName), SmokeTestsConstants.ExpoSuccessPattern, SmokeTestsConstants.ExpoFailurePattern);
if (expoLaunchStatus.failed) {
console.log("First attempt to start failed, retrying...");
await app.workbench.debug.runDebugScenario(ExpoDebugConfigName);
}
await expoTest("iOS pure RN Expo test(LAN)", pureRNWorkspacePath, ExpoLanDebugConfigName, 1);
});
it("Expo app Debug test(LAN)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
await app.workbench.editors.waitForTab("Expo QR Code");
await app.workbench.editors.waitForActiveTab("Expo QR Code");
console.log("iOS pure RN Expo test: 'Expo QR Code' tab found");
this.timeout(debugExpoTestTime);
await expoTest("iOS Expo Debug test(LAN)", ExpoWorkspacePath, ExpoLanDebugConfigName, 1);
});
let expoURL;
if (process.env.REACT_NATIVE_TOOLS_LOGS_DIR) {
expoURL = findExpoURLInLogFile(path.join(process.env.REACT_NATIVE_TOOLS_LOGS_DIR, SmokeTestsConstants.ReactNativeRunExpoLogFileName));
it("Expo app Debug test(localhost)", async function () {
if (testParameters && testParameters.RunBasicTests) {
this.skip();
}
assert.notStrictEqual(expoURL, null, "Expo URL pattern is not found");
expoURL = expoURL as string;
let appFile = findFile(SetupEnvironmentHelper.iOSExpoAppsCacheDir, /.*\.(app)/);
if (!appFile) {
throw new Error(`iOS Expo app is not found in ${SetupEnvironmentHelper.iOSExpoAppsCacheDir}`);
}
const appPath = path.join(SetupEnvironmentHelper.iOSExpoAppsCacheDir, appFile);
const opts = AppiumHelper.prepareAttachOptsForIosApp(device, appPath);
let client = AppiumHelper.webdriverAttach(opts);
clientInited = client.init();
await AppiumHelper.openExpoApplication(Platform.iOS, clientInited, expoURL, pureRNWorkspacePath);
console.log(`iOS pure RN Expo test: Waiting ${SmokeTestsConstants.expoAppBuildAndInstallTimeout}ms until Expo app is ready...`);
await sleep(SmokeTestsConstants.expoAppBuildAndInstallTimeout);
await AppiumHelper.disableExpoErrorRedBox(clientInited);
await AppiumHelper.disableDevMenuInformationalMsg(clientInited);
await AppiumHelper.enableRemoteDebugJS(clientInited, Platform.iOS_Expo);
await sleep(5 * 1000);
await app.workbench.debug.waitForDebuggingToStart();
console.log("iOS pure RN Expo test: Debugging started");
await app.workbench.debug.waitForStackFrame(sf => sf.name === "App.js" && sf.lineNumber === PureRNExpoSetBreakpointOnLine, `looking for App.js and line ${PureRNExpoSetBreakpointOnLine}`);
console.log("iOS pure RN Expo test: Stack frame found");
await app.workbench.debug.stepOver();
// Wait for our debug string to render in debug console
await sleep(SmokeTestsConstants.debugConsoleSearchTimeout);
console.log("iOS pure RN Expo test: Searching for \"Test output from debuggee\" string in console");
let found = await app.workbench.debug.waitForOutput(output => output.some(line => line.indexOf("Test output from debuggee") >= 0));
assert.notStrictEqual(found, false, "\"Test output from debuggee\" string is missing in debug console");
console.log("iOS pure RN Expo test: \"Test output from debuggee\" string is found");
await app.workbench.debug.stopDebugging();
console.log("iOS pure RN Expo test: Debugging is stopped");
this.timeout(debugExpoTestTime);
await expoTest("iOS Expo Debug test(localhost)", ExpoWorkspacePath, ExpoLocalDebugConfigName, 1);
});
});
}

Просмотреть файл

@ -14,9 +14,12 @@ let appiumProcess: null | cp.ChildProcess;
export type AppiumClient = WebdriverIO.Client<WebdriverIO.RawResult<null>> & WebdriverIO.RawResult<null>;
export enum Platform {
Android,
Android_Expo,
iOS,
iOS_Expo,
}
const XDL = require("@expo/xdl");
type XPathSelector = { [TKey in Platform]: string };
type XPathSelectors = { [key: string]: XPathSelector };
@ -25,29 +28,40 @@ export class AppiumHelper {
public static XPATH: XPathSelectors = {
RN_RELOAD_BUTTON: {
[Platform.Android]: "//*[@text='Reload']",
[Platform.Android_Expo]: "//*[@text='Reload']",
[Platform.iOS]: "//XCUIElementTypeButton[@name='Reload']",
[Platform.iOS_Expo]: "//XCUIElementTypeOther[@name='Reload JS Bundle']",
},
RN_ENABLE_REMOTE_DEBUGGING_BUTTON: {
[Platform.Android]: "//*[@text='Debug JS Remotely' or @text='Debug']",
[Platform.Android_Expo]: "//*[@text='Debug Remote JS']",
[Platform.iOS]: "//XCUIElementTypeButton[@name='Debug JS Remotely' or @name='Debug']",
[Platform.iOS_Expo]: "//XCUIElementTypeOther[@name='Debug Remote JS']",
[Platform.iOS_Expo]: "//XCUIElementTypeOther[@name='Debug Remote JS']",
},
RN_STOP_REMOTE_DEBUGGING_BUTTON: {
[Platform.Android]: "//*[@text='Stop Remote JS Debugging' or @text='Stop Debugging']",
[Platform.Android_Expo]: "//*[@text='Stop Remote Debugging']",
[Platform.iOS]: "//XCUIElementTypeButton[@name='Stop Remote JS Debugging' or @name='Stop Debugging']",
[Platform.iOS_Expo]: "//XCUIElementTypeOther[@name='Stop Remote JS Debugging']",
[Platform.iOS_Expo]: "//XCUIElementTypeOther[@name='Stop Remote Debugging']",
},
RN_DEV_MENU_CANCEL: {
[Platform.Android]: "//*[@text='Cancel']",
[Platform.Android_Expo]: "//*[@text='Cancel']",
[Platform.iOS]: "//XCUIElementTypeButton[@name='Cancel']",
[Platform.iOS_Expo]: "(//XCUIElementTypeOther[@name='Cancel'])[1]",
},
EXPO_ELEMENT_LOAD_TRIGGER: {
[Platform.Android]: "//*[@text='Home']",
[Platform.Android]: "",
[Platform.Android_Expo]: "//*[@text='Home']",
[Platform.iOS]: "", // todo
[Platform.iOS_Expo]: "", // todo
},
GOT_IT_BUTTON: {
[Platform.Android]: "",
[Platform.Android_Expo]: "//*[@text='Got it']",
[Platform.iOS]: "",
[Platform.iOS_Expo]: "//XCUIElementTypeOther[@name='Got it']",
},
};
public static runAppium() {
@ -128,24 +142,23 @@ export class AppiumHelper {
return wdio.remote(attachArgs);
}
public static async openExpoApplication(platform: Platform, client: AppiumClient, expoURL: string, projectFolder: string) {
public static async openExpoApplication(platform: Platform, client: AppiumClient, expoURL: string, projectFolder: string, firstLaunch?: boolean) {
// There are two ways to run app in Expo app:
// - via clipboard
// - via expo android command
// - via expo XDL function
if (platform === Platform.Android) {
if (process.platform === "darwin") {
// Longer way to open Expo app, but
// it certainly works on Mac
return this.openExpoAppViaExpoAndroidCommand(client, projectFolder);
return this.openExpoAppViaExpoXDLAndroidFunction(client, projectFolder);
} else {
// The quickest way to open Expo app,
// it doesn't work on Mac though
return this.openExpoAppViaClipboardAndroid(client, expoURL);
}
} else if (platform === Platform.iOS) {
// Similar to openExpoAppViaClipboardAndroid approach
// but uses different XPath selectors
return this.openExpoAppViaProjectURL(client, expoURL);
// Launch Expo using XDL.Simulator function
return this.openExpoAppViaExpoXDLSimulatorFunction(client, projectFolder, firstLaunch);
} else {
throw new Error(`Unknown platform ${platform}`);
}
@ -160,6 +173,7 @@ export class AppiumHelper {
public static async callRNDevMenu(client: AppiumClient, platform: Platform) {
switch (platform) {
case Platform.Android:
case Platform.Android_Expo:
console.log("*** Opening DevMenu by calling 'adb shell input keyevent 82'...");
const devMenuCallCommand = "adb shell input keyevent 82";
cp.exec(devMenuCallCommand);
@ -194,13 +208,17 @@ export class AppiumHelper {
public static async enableRemoteDebugJS(client: AppiumClient, platform: Platform) {
console.log("*** Enabling Remote JS Debugging for application with DevMenu...");
await client
.waitUntil(async () => {
await this.callRNDevMenu(client, platform);
if (await client.isExisting(this.XPATH.RN_ENABLE_REMOTE_DEBUGGING_BUTTON[platform])) {
console.log("*** Debug JS Remotely button found...");
await client.click(this.XPATH.RN_ENABLE_REMOTE_DEBUGGING_BUTTON[platform]);
console.log("*** Debug JS Remotely button clicked...");
if (await client.isExisting(this.XPATH.RN_ENABLE_REMOTE_DEBUGGING_BUTTON[platform])) {
await client.click(this.XPATH.RN_ENABLE_REMOTE_DEBUGGING_BUTTON[platform]);
console.log("*** Debug JS Remotely button clicked second time...");
}
return true;
} else if (await client.isExisting(this.XPATH.RN_STOP_REMOTE_DEBUGGING_BUTTON[platform])) {
console.log("*** Stop Remote JS Debugging button found, closing Dev Menu...");
@ -210,9 +228,11 @@ export class AppiumHelper {
console.log("*** Cancel button clicked...");
return true;
} else {
await this.callRNDevMenu(client, platform);
return false;
}
}
await this.callRNDevMenu(client, platform);
return false;
}, SmokeTestsConstants.enableRemoteJSTimeout, `Remote debugging UI element not found after ${SmokeTestsConstants.enableRemoteJSTimeout}ms`, 1000);
}
@ -235,10 +255,10 @@ export class AppiumHelper {
}
}
// New Expo versions shows DevMenu on iOS at first launch with informational message,
// New Expo versions shows DevMenu at first launch with informational message,
// it is better to disable this message and then call DevMenu ourselves
public static async disableDevMenuInformationalMsg(client: AppiumClient) {
const GOT_IT_BUTTON = "//XCUIElementTypeOther[@name='Got it']";
public static async disableDevMenuInformationalMsg(client: AppiumClient, platform: Platform) {
const GOT_IT_BUTTON = this.XPATH.GOT_IT_BUTTON[platform];
if (await client.isExisting(GOT_IT_BUTTON)) {
console.log("*** Expo DevMenu informational message found, disabling...");
await client.click(GOT_IT_BUTTON);
@ -279,41 +299,35 @@ export class AppiumHelper {
console.log(`*** ${EXPO_OPEN_FROM_CLIPBOARD} clicked...`);
}
private static async openExpoAppViaProjectURL(client: AppiumClient, expoURL: string) {
console.log(`*** Opening Expo app via Project URL`);
console.log(`*** Pressing "Add" button...`);
const EXPO_ADD_BUTTON = `(//XCUIElementTypeOther[@name=""])[2]`;
const FIND_A_PROJECT_ELEMENT = `//XCUIElementTypeTextField`;
const OPEN_BUTTON = `//XCUIElementTypeButton[@name="Open"]`;
await client
.waitForExist(EXPO_ADD_BUTTON, 30 * 1000)
.click(EXPO_ADD_BUTTON);
console.log(`*** Pasting ${expoURL} to search field...`);
// Run Expo app by expoURL
await client
.waitForExist(FIND_A_PROJECT_ELEMENT, 30 * 1000)
.click(FIND_A_PROJECT_ELEMENT);
await sleep(5 * 1000);
client.keys(expoURL);
await sleep(2 * 1000);
console.log(`*** Clicking on Open button to run the app`);
await client
.waitForExist(OPEN_BUTTON, 30 * 1000)
.click(OPEN_BUTTON);
}
private static async openExpoAppViaExpoAndroidCommand(client: AppiumClient, projectFolder: string) {
console.log(`*** Opening Expo app via "expo android" command`);
private static async openExpoAppViaExpoXDLAndroidFunction(client: AppiumClient, projectFolder: string) {
console.log(`*** Opening Expo app via XDL.Android function`);
console.log(`*** Searching for the "Explore" button...`);
const EXPLORE_ELEMENT = "//android.widget.Button[@content-desc='Explore' or @content-desc='Explore, tab, 2 of 3']";
await client
.waitForExist(EXPLORE_ELEMENT, 30 * 1000);
cp.execSync("expo android", { cwd: projectFolder, stdio: "inherit" });
await XDL.Android.openProjectAsync(projectFolder);
}
private static async openExpoAppViaExpoXDLSimulatorFunction(client: AppiumClient, projectFolder: string, firstLaunch?: boolean) {
console.log(`*** Opening Expo app via XDL.Simulator function`);
console.log(`*** Searching for the "Explore" button...`);
const EXPLORE_ELEMENT = `//XCUIElementTypeButton[@name="Explore, tab, 2 of 4"]`;
await client
.waitForExist(EXPLORE_ELEMENT, 30 * 1000);
await XDL.Simulator.openProjectAsync(projectFolder);
if (firstLaunch) { // it's required to allow launch of an Expo application when it's launched for the first time
console.log(`*** First launch of Expo app`);
console.log(`*** Pressing "Open" button...`);
const OPEN_BUTTON = `//XCUIElementTypeButton[@name="Open"]`;
await client
.waitForExist(OPEN_BUTTON, 10 * 1000)
.click(OPEN_BUTTON);
}
}
}

Просмотреть файл

@ -16,7 +16,7 @@ export class SmokeTestsConstants {
// Timeout for driver to wait for UI elements response to interaction (in seconds)
public static elementResponseTimeout = 250;
// Timeout for enabling Remote JS Debugging while testing RN app
public static enableRemoteJSTimeout = 50 * 1000;
public static enableRemoteJSTimeout = 120 * 1000;
// Timeout for Android app to build and to install
public static androidAppBuildAndInstallTimeout = 300 * 1000;
// Timeout for iOS app to build and to install

Просмотреть файл

@ -179,7 +179,7 @@ export interface ExpoLaunch {
export async function findExpoSuccessAndFailurePatterns(filePath: string, successPattern: string, failurePattern: string): Promise<ExpoLaunch> {
let awaitRetries: number = SmokeTestsConstants.expoAppLaunchTimeout / 5000;
let retry = 1;
return new Promise<ExpoLaunch>((resolve, reject) => {
return new Promise<ExpoLaunch>((resolve) => {
let check = setInterval(async () => {
let expoStarted = findStringInFile(filePath, successPattern);
let expoFailed = findStringInFile(filePath, failurePattern);

Разница между файлами не показана из-за своего большого размера Загрузить разницу