diff --git a/.gitignore b/.gitignore index d3b4daac04d7..335efdc5586a 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,6 @@ tsconfig.tsbuildinfo # Yalc .yalc yalc.lock + +# Local https certificate/key +config/webpack/*.pem diff --git a/README.md b/README.md index 998f185939fa..b2d51b2a1709 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ #### Table of Contents * [Local Development](#local-development) +* [Testing on browsers on simulators and emulators](#testing-on-browsers-on-simulators-and-emulators) * [Running The Tests](#running-the-tests) * [Debugging](#debugging) * [App Structure and Conventions](#app-structure-and-conventions) @@ -34,12 +35,22 @@ These instructions should get you set up ready to work on New Expensify 🙌 1. Install `nvm` then `node` & `npm`: `brew install nvm && nvm install` 2. Install `watchman`: `brew install watchman` 3. Install dependencies: `npm install` +4. Install `mkcert`: `brew install mkcert` followed by `npm run setup-https`. If you are not using macOS, follow the instructions [here](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation). +5. Create a host entry in your local hosts file, `/etc/hosts` for dev.new.expensify.com pointing to localhost: +``` +127.0.0.1 dev.new.expensify.com +``` You can use any IDE or code editing tool for developing on any platform. Use your favorite! ## Recommended `node` setup In order to have more consistent builds, we use a strict `node` and `npm` version as defined in the `package.json` `engines` field and `.nvmrc` file. `npm install` will fail if you do not use the version defined, so it is recommended to install `node` via `nvm` for easy node version management. Automatic `node` version switching can be installed for [`zsh`](https://github.com/nvm-sh/nvm#zsh) or [`bash`](https://github.com/nvm-sh/nvm#bash) using `nvm`. +## Configuring HTTPS +The webpack development server now uses https. If you're using a mac, you can simply run `npm run setup-https`. + +If you're using another operating system, you will need to ensure `mkcert` is installed, and then follow the instructions in the repository to generate certificates valid for `new.expesify.com.dev` and `localhost`. The certificate should be named `certificate.pem` and the key should be named `key.pem`. They should be placed in `config/webpack`. + ## Running the web app 🕸 * To run the **development web app**: `npm run web` * Changes applied to Javascript will be applied automatically via WebPack as configured in `webpack.dev.js` @@ -103,6 +114,43 @@ variables referenced here get updated since your local `.env` file is ignored. ---- +# Testing on browsers in simulators and emulators + +The development server is reached through the HTTPS protocol, and any client that access the development server needs a certificate. + +You create this certificate by following the instructions in [`Configuring HTTPS`](#configuring-https) of this readme. When accessing the website served from the development server on browsers in iOS simulator or Android emulator, these virtual devices need to have the same certificate installed. Follow the steps below to install them. + +#### Pre-requisite for Android flow +1. Open any emulator using Android Studio +2. Use `adb push "$(mkcert -CAROOT)/rootCA.pem" /storage/emulated/0/Download/` to push certificate to install in Download folder. +3. Install the certificate as CA certificate from the settings. On the Android emulator, this option can be found in Settings > Security > Encryption & Credentials > Install a certificate > CA certificate. +4. Close the emulator. + +Note - If you want to run app on `https://127.0.0.1:8082`, then just install the certificate and use `adb reverse tcp:8082 tcp:8082` on every startup. + +#### Android Flow +1. Run `npm run setupNewDotWebForEmulators android` +2. Select the emulator you want to run if prompted. (If single emulator is available, then it will open automatically) +3. Let the script execute till the message `🎉 Done!`. + +Note - If you want to run app on `https://dev.new.expensify.com:8082`, then just do the Android flow and use `npm run startAndroidEmulator` to start the Android Emulator every time (It will configure the emulator). + + +Possible Scenario: +The flow may fail to root with error `adbd cannot run as root in production builds`. In this case, please refer to https://stackoverflow.com/a/45668555. Or use `https://127.0.0.1:8082` for less hassle. + +#### iOS Flow +1. Run `npm run setupNewDotWebForEmulators ios` +2. Select the emulator you want to run if prompted. (If single emulator is available, then it will open automatically) +3. Let the script execute till the message `🎉 Done!`. + +#### All Flow +1. Run `npm run setupNewDotWebForEmulators all` or `npm run setupNewDotWebForEmulators` +2. Check if the iOS flow runs first and then Android flow runs. +3. Let the script execute till the message `🎉 Done!`. + +---- + # Running the tests ## Unit tests Unit tests are valuable when you want to test one component. They should be short, fast, and ideally only test one thing. diff --git a/config/webpack/webpack.dev.js b/config/webpack/webpack.dev.js index 19999491395e..e28383eff557 100644 --- a/config/webpack/webpack.dev.js +++ b/config/webpack/webpack.dev.js @@ -44,6 +44,14 @@ module.exports = (env = {}) => ...proxySettings, historyApiFallback: true, port, + host: 'dev.new.expensify.com', + server: { + type: 'https', + options: { + key: path.join(__dirname, 'key.pem'), + cert: path.join(__dirname, 'certificate.pem'), + }, + }, }, plugins: [ new DefinePlugin({ diff --git a/contributingGuides/APPLE_GOOGLE_SIGNIN.md b/contributingGuides/APPLE_GOOGLE_SIGNIN.md index 9032a99dfbbd..3ade13554bd6 100644 --- a/contributingGuides/APPLE_GOOGLE_SIGNIN.md +++ b/contributingGuides/APPLE_GOOGLE_SIGNIN.md @@ -161,10 +161,10 @@ function beginAppleSignIn(idToken) { You can use any SSH tunneling service that allows you to configure custom subdomains so that we have a consistent address to use. We'll use ngrok in these examples, but ngrok requires a paid account for this. If you need a free option, try serveo.net. -After you've set ngrok up to be able to run on your machine (requires configuring a key with the command line tool, instructions provided by the ngrok website after you create an account), test hosting the web app on a custom subdomain. This example assumes the development web app is running at `localhost:8082`: +After you've set ngrok up to be able to run on your machine (requires configuring a key with the command line tool, instructions provided by the ngrok website after you create an account), test hosting the web app on a custom subdomain. This example assumes the development web app is running at `dev.new.expensify.com:8082`: ``` -ngrok http 8082 --host-header="localhost:8082" --subdomain=mysubdomain +ngrok http 8082 --host-header="dev.new.expensify.com:8082" --subdomain=mysubdomain ``` The `--host-header` flag is there to avoid webpack errors with header validation. In addition, add `allowedHosts: 'all'` to the dev server config in `webpack.dev.js`: diff --git a/desktop/main.js b/desktop/main.js index f2c11e73e513..5ae02377e2b9 100644 --- a/desktop/main.js +++ b/desktop/main.js @@ -90,7 +90,7 @@ _.assign(console, log.functions); // until it detects that it has been upgraded to the correct version. const EXPECTED_UPDATE_VERSION_FLAG = '--expected-update-version'; -const APP_DOMAIN = __DEV__ ? `http://localhost:${port}` : 'app://-'; +const APP_DOMAIN = __DEV__ ? `https://dev.new.expensify.com:${port}` : 'app://-'; let expectedUpdateVersion; for (let i = 0; i < process.argv.length; i++) { @@ -226,7 +226,7 @@ const mainWindow = () => { let deeplinkUrl; let browserWindow; - const loadURL = __DEV__ ? (win) => win.loadURL(`http://localhost:${port}`) : serve({directory: `${__dirname}/www`}); + const loadURL = __DEV__ ? (win) => win.loadURL(`https://dev.new.expensify.com:${port}`) : serve({directory: `${__dirname}/www`}); // Prod and staging set the icon in the electron-builder config, so only update it here for dev if (__DEV__) { diff --git a/desktop/start.js b/desktop/start.js index d9ec59b71c83..05a1b031350d 100644 --- a/desktop/start.js +++ b/desktop/start.js @@ -32,7 +32,7 @@ portfinder env, }, { - command: `wait-port localhost:${port} && npx electronmon ./desktop/dev.js`, + command: `wait-port dev.new.expensify.com:${port} && npx electronmon ./desktop/dev.js`, name: 'Electron', prefixColor: 'cyan.dim', env, diff --git a/docs/_includes/CONST.html b/docs/_includes/CONST.html index 4b87f87931d5..231423f10586 100644 --- a/docs/_includes/CONST.html +++ b/docs/_includes/CONST.html @@ -1,7 +1,7 @@ {% if jekyll.environment == "production" %} {% assign MAIN_SITE_URL = "https://new.expensify.com" %} {% else %} - {% assign MAIN_SITE_URL = "http://localhost:8082" %} + {% assign MAIN_SITE_URL = "https://dev.new.expensify.com:8082" %} {% endif %} {% capture CONCIERGE_CHAT_URL %}{{MAIN_SITE_URL}}/concierge{% endcapture %} diff --git a/package.json b/package.json index a8143fd2a809..c9be42b2c2ad 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,8 @@ "test:e2e:compare": "node tests/e2e/merge.js", "gh-actions-unused-styles": "./.github/scripts/findUnusedKeys.sh", "workflow-test": "./workflow_tests/scripts/runWorkflowTests.sh", - "workflow-test:generate": "node workflow_tests/utils/preGenerateTest.js" + "workflow-test:generate": "node workflow_tests/utils/preGenerateTest.js", + "setup-https": "mkcert -install && mkcert -cert-file config/webpack/certificate.pem -key-file config/webpack/key.pem dev.new.expensify.com localhost 127.0.0.1" }, "dependencies": { "@expensify/react-native-web": "0.18.15", diff --git a/src/CONST.ts b/src/CONST.ts index 3989d2b5cbff..8507072da5c8 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -468,7 +468,7 @@ const CONST = { ONFIDO_TERMS_OF_SERVICE_URL: 'https://onfido.com/terms-of-service/', // Use Environment.getEnvironmentURL to get the complete URL with port number - DEV_NEW_EXPENSIFY_URL: 'http://localhost:', + DEV_NEW_EXPENSIFY_URL: 'https://dev.new.expensify.com:', SIGN_IN_FORM_WIDTH: 300, diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index fff86b684872..b2db1758f24b 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -4,7 +4,7 @@ import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; export default { - prefixes: ['new-expensify://', 'https://www.expensify.cash', 'https://staging.expensify.cash', 'http://localhost', CONST.NEW_EXPENSIFY_URL, CONST.STAGING_NEW_EXPENSIFY_URL], + prefixes: ['new-expensify://', 'https://www.expensify.cash', 'https://staging.expensify.cash', 'https://dev.new.expensify.com', CONST.NEW_EXPENSIFY_URL, CONST.STAGING_NEW_EXPENSIFY_URL], config: { initialRouteName: SCREENS.HOME, screens: { diff --git a/tests/unit/ReportUtilsTest.js b/tests/unit/ReportUtilsTest.js index 2b836f8eb0bf..72de874a631e 100644 --- a/tests/unit/ReportUtilsTest.js +++ b/tests/unit/ReportUtilsTest.js @@ -519,8 +519,7 @@ describe('ReportUtils', () => { expect(ReportUtils.getReportIDFromLink('new-expensify://r/75431276')).toBe('75431276'); expect(ReportUtils.getReportIDFromLink('https://www.expensify.cash/r/75431276')).toBe('75431276'); expect(ReportUtils.getReportIDFromLink('https://staging.new.expensify.com/r/75431276')).toBe('75431276'); - expect(ReportUtils.getReportIDFromLink('http://localhost/r/75431276')).toBe('75431276'); - expect(ReportUtils.getReportIDFromLink('http://localhost:8080/r/75431276')).toBe('75431276'); + expect(ReportUtils.getReportIDFromLink('https://dev.new.expensify.com/r/75431276')).toBe('75431276'); expect(ReportUtils.getReportIDFromLink('https://staging.expensify.cash/r/75431276')).toBe('75431276'); expect(ReportUtils.getReportIDFromLink('https://new.expensify.com/r/75431276')).toBe('75431276'); });