From 4f35243c6cf504d9b490816bfbfa8ea3f2c700ef Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Mon, 16 Oct 2023 09:33:13 +0200 Subject: [PATCH 01/39] Run main and delta tests in different AWS device farm runs and merge results --- .github/workflows/e2ePerformanceTests.yml | 60 +++++++++++++----- .tool-versions | 1 + package.json | 4 +- tests/e2e/TestSpecDelta.yml | 26 ++++++++ tests/e2e/{TestSpec.yml => TestSpecMain.yml} | 2 +- tests/e2e/compare/compare.js | 5 +- tests/e2e/config.local.js | 7 +-- tests/e2e/merge.js | 27 +++++++++ tests/e2e/testRunner.js | 64 ++++++++++++-------- 9 files changed, 146 insertions(+), 50 deletions(-) create mode 100644 .tool-versions create mode 100644 tests/e2e/TestSpecDelta.yml rename tests/e2e/{TestSpec.yml => TestSpecMain.yml} (91%) create mode 100644 tests/e2e/merge.js diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 3666e8c7d3432..b2605c8d02af5 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -125,6 +125,11 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + - name: Make zip directory for everything to send to AWS Device Farm run: mkdir zip @@ -137,7 +142,7 @@ jobs: # The downloaded artifact will be a file named "app-e2e-release.apk" so we have to rename it - name: Rename baseline APK - run: mv "${{steps.downloadBaselineAPK.outputs.download-path}}/app-e2e-release.apk" "${{steps.downloadBaselineAPK.outputs.download-path}}/app-e2eRelease-baseline.apk" + run: mv "${{steps.downloadBaselineAPK.outputs.download-path}}/app-e2e-release.apk" "${{steps.downloadBaselineAPK.outputs.download-path}}/app-e2eRelease-main.apk" - name: Download delta APK uses: actions/download-artifact@e9ef242655d12993efdcda9058dee2db83a2cb9b @@ -147,7 +152,7 @@ jobs: path: zip - name: Rename delta APK - run: mv "${{steps.downloadDeltaAPK.outputs.download-path}}/app-e2e-release.apk" "${{steps.downloadDeltaAPK.outputs.download-path}}/app-e2eRelease-compare.apk" + run: mv "${{steps.downloadDeltaAPK.outputs.download-path}}/app-e2e-release.apk" "${{steps.downloadDeltaAPK.outputs.download-path}}/app-e2eRelease-delta.apk" - name: Copy e2e code into zip folder run: cp -r tests/e2e zip @@ -162,40 +167,67 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: us-west-2 - - name: Schedule AWS Device Farm test run + - name: Schedule AWS Device Farm test run on main branch + uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b + with: + name: App E2E Performance Regression Tests + project_arn: ${{ secrets.AWS_PROJECT_ARN }} + device_pool_arn: ${{ secrets.AWS_DEVICE_POOL_ARN }} + app_file: zip/app-e2eRelease-main.apk + app_type: ANDROID_APP + test_type: APPIUM_NODE + test_package_file: App.zip + test_package_type: APPIUM_NODE_TEST_PACKAGE + test_spec_file: tests/e2e/TestSpecMain.yml + test_spec_type: APPIUM_NODE_TEST_SPEC + remote_src: false + file_artifacts: mainArtifacts.zip + cleanup: true + + - name: Unzip AWS Device Farm results + if: ${{ always() }} + run: unzip mainArtifacts.zip -d mainResults + + - name: Schedule AWS Device Farm test run on delta branch uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b with: name: App E2E Performance Regression Tests project_arn: ${{ secrets.AWS_PROJECT_ARN }} device_pool_arn: ${{ secrets.AWS_DEVICE_POOL_ARN }} - app_file: zip/app-e2eRelease-baseline.apk + app_file: zip/app-e2eRelease-delta.apk app_type: ANDROID_APP test_type: APPIUM_NODE test_package_file: App.zip test_package_type: APPIUM_NODE_TEST_PACKAGE - test_spec_file: tests/e2e/TestSpec.yml + test_spec_file: tests/e2e/TestSpecDelta.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: Customer Artifacts.zip + file_artifacts: deltaArtifacts.zip cleanup: true - name: Unzip AWS Device Farm results if: ${{ always() }} - run: unzip "Customer Artifacts.zip" + run: unzip deltaArtifacts.zip -d deltaResults - - name: Print AWS Device Farm run results + + - name: Compare results if: ${{ always() }} - run: cat "./Host_Machine_Files/\$WORKING_DIRECTORY/output.md" + run: node "./Host_Machine_File/tests/e2e/merge.js --mainPath ../../mainResults/\$WORKING_DIRECTORY/main.json --deltaPath ../../deltaResults/\$WORKING_DIRECTORY/delta.json --outputPath ./Host_Machine_Files/output.md" + - - name: Print AWS Device Farm verbose run results - if: ${{ always() && runner.debug != null && fromJSON(runner.debug) }} - run: cat "./Host_Machine_Files/\$WORKING_DIRECTORY/debug.log" + - name: Print results + if: ${{ always() }} + run: cat "./Host_Machine_Files/output.md" + + # - name: Print AWS Device Farm verbose run results + # if: ${{ always() && runner.debug != null && fromJSON(runner.debug) }} + # run: cat "./Host_Machine_Files/debug.log" - name: Check if test failed, if so post the results and add the DeployBlocker label run: | - if grep -q '🔴' ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md; then + if grep -q '🔴' ./Host_Machine_Files/output.md; then gh pr edit ${{ inputs.PR_NUMBER }} --add-label DeployBlockerCash - gh pr comment ${{ inputs.PR_NUMBER }} -F ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md + gh pr comment ${{ inputs.PR_NUMBER }} -F ./Host_Machine_Files/output.md gh pr comment ${{ inputs.PR_NUMBER }} -b "@Expensify/mobile-deployers 📣 Please look into this performance regression as it's a deploy blocker." else echo '✅ no performance regression detected' diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000000000..97ad4f02c2247 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +nodejs 16.15.1 \ No newline at end of file diff --git a/package.json b/package.json index 3256b8f65199c..b972b435aa67f 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,9 @@ "analyze-packages": "ANALYZE_BUNDLE=true webpack --config config/webpack/webpack.common.js --env envFile=.env.production", "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map", "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map", - "test:e2e": "node tests/e2e/testRunner.js --development", + "test:e2e:main": "node tests/e2e/testRunner.js --development --branch main", + "test:e2e:delta": "node tests/e2e/testRunner.js --development --branch main --label delta", + "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" diff --git a/tests/e2e/TestSpecDelta.yml b/tests/e2e/TestSpecDelta.yml new file mode 100644 index 0000000000000..2d4906855ca8c --- /dev/null +++ b/tests/e2e/TestSpecDelta.yml @@ -0,0 +1,26 @@ +version: 0.1 + +phases: + install: + commands: + # Install correct version of node + - export NVM_DIR=$HOME/.nvm + - . $NVM_DIR/nvm.sh + - nvm install 16.15.1 + - nvm use 16.15.1 + + # Reverse ports using AWS magic + - PORT=4723 + - IP_ADDRESS=$(ip -4 addr show eth0 | grep -Po "(?<=inet\s)\d+(\.\d+){3}") + - reverse_values="{\"ip_address\":\"$IP_ADDRESS\",\"local_port\":\"$PORT\",\"remote_port\":\"$PORT\"}" + - "curl -H \"Content-Type: application/json\" -X POST -d \"$reverse_values\" http://localhost:31007/reverse_forward_tcp" + - adb reverse tcp:$PORT tcp:$PORT + + test: + commands: + - cd zip + - npm install underscore + - node e2e/testRunner.js -- --skipInstallDeps --buildMode "skip" --skipCheckout --label delta --appPath app-e2eRelease-delta.apk + +artifacts: +- $WORKING_DIRECTORY diff --git a/tests/e2e/TestSpec.yml b/tests/e2e/TestSpecMain.yml similarity index 91% rename from tests/e2e/TestSpec.yml rename to tests/e2e/TestSpecMain.yml index 6ea1d9570ae9d..6cf1c5d0b2734 100644 --- a/tests/e2e/TestSpec.yml +++ b/tests/e2e/TestSpecMain.yml @@ -20,7 +20,7 @@ phases: commands: - cd zip - npm install underscore - - node e2e/testRunner.js -- --skipInstallDeps --buildMode "skip" --skipCheckout + - node e2e/testRunner.js -- --skipInstallDeps --buildMode "skip" --skipCheckout --branch main --appPath app-e2eRelease-main.apk artifacts: - $WORKING_DIRECTORY diff --git a/tests/e2e/compare/compare.js b/tests/e2e/compare/compare.js index 2929b03f4d708..9d40ab2bf312a 100644 --- a/tests/e2e/compare/compare.js +++ b/tests/e2e/compare/compare.js @@ -1,7 +1,6 @@ const fs = require('fs/promises'); const fsSync = require('fs'); const _ = require('underscore'); -const {OUTPUT_DIR} = require('../config'); const {computeProbability, computeZ} = require('./math'); const printToConsole = require('./output/console'); const writeToMarkdown = require('./output/markdown'); @@ -119,7 +118,7 @@ function compareResults(compareEntries, baselineEntries) { }; } -module.exports = (baselineFile = `${OUTPUT_DIR}/baseline.json`, compareFile = `${OUTPUT_DIR}/compare.json`, outputFormat = 'all') => { +module.exports = (baselineFile, compareFile, outputFile, outputFormat = 'all') => { const hasBaselineFile = fsSync.existsSync(baselineFile); if (!hasBaselineFile) { throw new Error(`Baseline results files "${baselineFile}" does not exists.`); @@ -136,7 +135,7 @@ module.exports = (baselineFile = `${OUTPUT_DIR}/baseline.json`, compareFile = `$ printToConsole(outputData); } if (outputFormat === 'markdown' || outputFormat === 'all') { - return writeToMarkdown(`${OUTPUT_DIR}/output.md`, outputData); + return writeToMarkdown(outputFile, outputData); } }); }); diff --git a/tests/e2e/config.local.js b/tests/e2e/config.local.js index 0c38c3f1056f1..d60f6a5abdc7a 100644 --- a/tests/e2e/config.local.js +++ b/tests/e2e/config.local.js @@ -1,10 +1,7 @@ module.exports = { - APP_PACKAGE: 'com.expensify.chat.dev', + APP_PACKAGE: 'com.expensify.chat.adhoc', WARM_UP_RUNS: 1, RUNS: 8, - APP_PATHS: { - baseline: './android/app/build/outputs/apk/e2e/release/app-e2e-release.apk', - compare: './android/app/build/outputs/apk/e2e/release/app-e2e-release.apk', - }, + APP_PATH: './android/app/build/outputs/apk/e2e/release/app-e2e-release.apk', }; diff --git a/tests/e2e/merge.js b/tests/e2e/merge.js new file mode 100644 index 0000000000000..0ee4761373158 --- /dev/null +++ b/tests/e2e/merge.js @@ -0,0 +1,27 @@ +const compare = require('./compare/compare'); +const {OUTPUT_DIR} = require('./config'); + +const args = process.argv.slice(2); + +let mainPath = `${OUTPUT_DIR}/main.json`; +if (args.includes('--mainPath')) { + mainPath = args[args.indexOf('--mainPath') + 1]; +} + +let deltaPath = `${OUTPUT_DIR}/delta.json`; +if (args.includes('--deltaPath')) { + deltaPath = args[args.indexOf('--deltaPath') + 1]; +} + +let outputPath = `${OUTPUT_DIR}/output.md`; +if (args.includes('--outputPath')) { + outputPath = args[args.indexOf('--outputPath') + 1]; +} + +async function run() { + await compare(mainPath, deltaPath, outputPath, 'all'); + + process.exit(0); +} + +run(); diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 2a5aee78715fc..b2f5550497c18 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -10,7 +10,7 @@ const fs = require('fs'); const _ = require('underscore'); const defaultConfig = require('./config'); -const compare = require('./compare/compare'); +// const compare = require('./compare/compare'); const Logger = require('./utils/logger'); const execAsync = require('./utils/execAsync'); const killApp = require('./utils/killApp'); @@ -21,10 +21,26 @@ const math = require('./measure/math'); const writeTestStats = require('./measure/writeTestStats'); const withFailTimeout = require('./utils/withFailTimeout'); const reversePort = require('./utils/androidReversePort'); -const getCurrentBranchName = require('./utils/getCurrentBranchName'); const args = process.argv.slice(2); +const indexOfBranchLabel = _.findIndex(args, (t) => t === '--branch'); + +if (indexOfBranchLabel === -1) { + throw new Error('branch not specified, specify a branch with --branch [BRANCH NAME]'); +} + +let branch = 'main'; + +if (args.includes('--branch')) { + branch = args[args.indexOf('--branch') + 1]; +} + +let label = branch; +if (args.includes('--label')) { + label = args[args.indexOf('--label') + 1]; +} + let config = defaultConfig; const setConfigPath = (configPathParam) => { let configPath = configPathParam; @@ -35,8 +51,6 @@ const setConfigPath = (configPathParam) => { config = _.extend(defaultConfig, customConfig); }; -let baselineBranch = process.env.baseline || config.DEFAULT_BASELINE_BRANCH; - // There are three build modes: // 1. full: rebuilds the full native app in (e2e) release mode // 2. js-only: only rebuilds the js bundle, and then re-packages @@ -49,7 +63,6 @@ let buildMode = 'full'; const isDevMode = args.includes('--development'); if (isDevMode) { setConfigPath('config.local.js'); - baselineBranch = getCurrentBranchName(); buildMode = 'js-only'; } @@ -59,16 +72,19 @@ if (args.includes('--config')) { } // Clear all files from previous jobs -try { - fs.rmSync(config.OUTPUT_DIR, {recursive: true, force: true}); +if (!fs.existsSync(config.OUTPUT_DIR)) { fs.mkdirSync(config.OUTPUT_DIR); +} + +try { + fs.rmSync(`${config.OUTPUT_DIR}/${label}.json`); } catch (error) { // Do nothing console.error(error); } if (isDevMode) { - Logger.note(`Running in development mode. Set baseline branch to same as current ${baselineBranch}`); + Logger.note(`Running in development mode.`); } const restartApp = async () => { @@ -78,11 +94,15 @@ const restartApp = async () => { await launchApp('android', config.APP_PACKAGE); }; -const runTestsOnBranch = async (baselineOrCompare, branch) => { +const runTests = async () => { if (args.includes('--buildMode')) { buildMode = args[args.indexOf('--buildMode') + 1]; } - let appPath = baselineOrCompare === 'baseline' ? config.APP_PATHS.baseline : config.APP_PATHS.compare; + + let appPath = config.APP_PATH; + if (args.includes('--appPath')) { + appPath = args[args.indexOf('--appPath') + 1]; + } // check if using buildMode "js-only" or "none" is possible if (buildMode !== 'full') { @@ -97,21 +117,21 @@ const runTestsOnBranch = async (baselineOrCompare, branch) => { if (branch != null) { // Switch branch - Logger.log(`Preparing ${baselineOrCompare} tests on branch '${branch}'`); + Logger.log(`Preparing tests on branch '${branch}'`); await execAsync(`git checkout ${branch}`); } if (!args.includes('--skipInstallDeps')) { - Logger.log(`Preparing ${baselineOrCompare} tests on branch '${branch}' - npm install`); + Logger.log(`Preparing tests on branch '${branch}' - npm install`); await execAsync('npm i'); } // Build app if (buildMode === 'full') { - Logger.log(`Preparing ${baselineOrCompare} tests on branch '${branch}' - building app`); + Logger.log(`Preparing tests on branch '${branch}' - building app`); await execAsync('npm run android-build-e2e'); } else if (buildMode === 'js-only') { - Logger.log(`Preparing ${baselineOrCompare} tests on branch '${branch}' - building js bundle`); + Logger.log(`Preparing tests on branch '${branch}' - building js bundle`); // Build a new JS bundle const tempDir = `${config.OUTPUT_DIR}/temp`; @@ -220,7 +240,7 @@ const runTestsOnBranch = async (baselineOrCompare, branch) => { // Calculate statistics and write them to our work file progressLog = Logger.progressInfo('Calculating statics and writing results'); - const outputFileName = `${config.OUTPUT_DIR}/${baselineOrCompare}.json`; + const outputFileName = `${config.OUTPUT_DIR}/${label}.json`; for (const testName of _.keys(durationsByTestName)) { const stats = math.getStats(durationsByTestName[testName]); await writeTestStats( @@ -236,19 +256,11 @@ const runTestsOnBranch = async (baselineOrCompare, branch) => { await server.stop(); }; -const runTests = async () => { +const run = async () => { Logger.info('Running e2e tests'); try { - const skipCheckout = args.includes('--skipCheckout'); - - // Run tests on baseline branch - await runTestsOnBranch('baseline', skipCheckout ? null : baselineBranch); - - // Run tests on current branch - await runTestsOnBranch('compare', skipCheckout ? null : '-'); - - await compare(); + await runTests(); process.exit(0); } catch (e) { @@ -270,4 +282,4 @@ const runTests = async () => { } }; -runTests(); +run(); From 86c5d7189cafa71bb62555e4f02757adacfea07f Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Tue, 17 Oct 2023 07:52:02 +0200 Subject: [PATCH 02/39] Update paths and restore file_artifacts on aws step --- .github/workflows/e2ePerformanceTests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 1c6a685803152..7d1f0cf9575d6 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -181,12 +181,12 @@ jobs: test_spec_file: tests/e2e/TestSpecMain.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: mainArtifacts.zip + file_artifacts: Customer Artifacts.zip cleanup: true - - name: Unzip AWS Device Farm results + - name: Unzip AWS Device Farm main results if: ${{ always() }} - run: unzip mainArtifacts.zip -d mainResults + run: unzip "Customer Artifacts.zip" -d mainResults - name: Schedule AWS Device Farm test run on delta branch uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b @@ -202,12 +202,12 @@ jobs: test_spec_file: tests/e2e/TestSpecDelta.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: deltaArtifacts.zip + file_artifacts: Customer Artifacts.zip cleanup: true - - name: Unzip AWS Device Farm results + - name: Unzip AWS Device Farm delta results if: ${{ always() }} - run: unzip deltaArtifacts.zip -d deltaResults + run: unzip "Customer Artifacts.zip" -d deltaResults - name: Compare results From 073ea4196c988a79a89f069686362d5bcf2e6ed7 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Tue, 17 Oct 2023 17:58:52 +0200 Subject: [PATCH 03/39] Only delete json result file if it exists --- tests/e2e/testRunner.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index b2f5550497c18..116be8e8e4e73 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -77,7 +77,9 @@ if (!fs.existsSync(config.OUTPUT_DIR)) { } try { - fs.rmSync(`${config.OUTPUT_DIR}/${label}.json`); + if (fs.existsSync(`${config.OUTPUT_DIR}/${label}.json`)) { + fs.rmSync(`${config.OUTPUT_DIR}/${label}.json`); + } } catch (error) { // Do nothing console.error(error); From a357848fbd51f899d601c5195fada8356cdc0d45 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Tue, 17 Oct 2023 19:54:38 +0200 Subject: [PATCH 04/39] Re-insert deleting the output container --- .github/workflows/e2ePerformanceTests.yml | 14 ++++---------- tests/e2e/testRunner.js | 12 ++++-------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 7d1f0cf9575d6..4e48e9856b283 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -181,12 +181,11 @@ jobs: test_spec_file: tests/e2e/TestSpecMain.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: Customer Artifacts.zip + file_artifacts: MainArtifacts.zip cleanup: true - name: Unzip AWS Device Farm main results - if: ${{ always() }} - run: unzip "Customer Artifacts.zip" -d mainResults + run: unzip MainArtifacts.zip -d mainResults - name: Schedule AWS Device Farm test run on delta branch uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b @@ -202,21 +201,16 @@ jobs: test_spec_file: tests/e2e/TestSpecDelta.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: Customer Artifacts.zip + file_artifacts: DeltaArtifacts.zip cleanup: true - name: Unzip AWS Device Farm delta results - if: ${{ always() }} - run: unzip "Customer Artifacts.zip" -d deltaResults - + run: unzip DeltaArtifacts.zip -d deltaResults - name: Compare results - if: ${{ always() }} run: node "./Host_Machine_File/tests/e2e/merge.js --mainPath ../../mainResults/\$WORKING_DIRECTORY/main.json --deltaPath ../../deltaResults/\$WORKING_DIRECTORY/delta.json --outputPath ./Host_Machine_Files/output.md" - - name: Print results - if: ${{ always() }} run: cat "./Host_Machine_Files/output.md" # - name: Print AWS Device Farm verbose run results diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 116be8e8e4e73..96858494b6837 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -71,15 +71,11 @@ if (args.includes('--config')) { setConfigPath(configPath); } -// Clear all files from previous jobs -if (!fs.existsSync(config.OUTPUT_DIR)) { - fs.mkdirSync(config.OUTPUT_DIR); -} - try { - if (fs.existsSync(`${config.OUTPUT_DIR}/${label}.json`)) { - fs.rmSync(`${config.OUTPUT_DIR}/${label}.json`); - } + // Clear all files from previous jobs + fs.rmSync(config.OUTPUT_DIR, {recursive: true, force: true}); + + fs.mkdirSync(config.OUTPUT_DIR); } catch (error) { // Do nothing console.error(error); From 8944963d46b2e5911ea352a0ff98c3d279e32fd6 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 06:43:46 +0200 Subject: [PATCH 05/39] Handle skip checkout flag to avoid git operation on CI --- tests/e2e/testRunner.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 96858494b6837..50d71a5422ab4 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -51,6 +51,8 @@ const setConfigPath = (configPathParam) => { config = _.extend(defaultConfig, customConfig); }; +const skipCheckout = args.includes('--skipCheckout'); + // There are three build modes: // 1. full: rebuilds the full native app in (e2e) release mode // 2. js-only: only rebuilds the js bundle, and then re-packages @@ -113,9 +115,9 @@ const runTests = async () => { } } - if (branch != null) { + if (branch != null && !skipCheckout) { // Switch branch - Logger.log(`Preparing tests on branch '${branch}'`); + Logger.log(`Preparing tests on branch '${branch}' - git checkout`); await execAsync(`git checkout ${branch}`); } From d1531a0be1aff194435de5d7d9b06a5b6108835e Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 06:45:24 +0200 Subject: [PATCH 06/39] Revert Customer Artifacts.zip --- .github/workflows/e2ePerformanceTests.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 4e48e9856b283..057d535955a52 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -181,11 +181,14 @@ jobs: test_spec_file: tests/e2e/TestSpecMain.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: MainArtifacts.zip + file_artifacts: Customer Artifacts.zip cleanup: true - name: Unzip AWS Device Farm main results - run: unzip MainArtifacts.zip -d mainResults + run: unzip "Customer Artifacts.zip" -d mainResults + + - name: Delete Customer Artifacts.zip + run: rm "Customer Artifacts.zip" - name: Schedule AWS Device Farm test run on delta branch uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b @@ -201,11 +204,11 @@ jobs: test_spec_file: tests/e2e/TestSpecDelta.yml test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false - file_artifacts: DeltaArtifacts.zip + file_artifacts: Customer Artifacts.zip cleanup: true - name: Unzip AWS Device Farm delta results - run: unzip DeltaArtifacts.zip -d deltaResults + run: unzip "Customer Artifacts.zip" -d deltaResults - name: Compare results run: node "./Host_Machine_File/tests/e2e/merge.js --mainPath ../../mainResults/\$WORKING_DIRECTORY/main.json --deltaPath ../../deltaResults/\$WORKING_DIRECTORY/delta.json --outputPath ./Host_Machine_Files/output.md" From a855c928552425291f6b695ff004e2298606dc8b Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 09:30:41 +0200 Subject: [PATCH 07/39] Update script to make it a bit more undestandable and run in local builds --- tests/e2e/testRunner.js | 49 +++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 50d71a5422ab4..1bcb0b1e22293 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -1,16 +1,22 @@ /** - * The test runner takes care of running the e2e tests. - * It will run the tests twice. Once on the branch that - * we want to base the results on (e.g. main), and then - * again on another branch we want to compare against the - * base (e.g. a new feature branch). + * Multifaceted script, its main function is running the e2e tests. + * + * When running in a local environment it can take care of building the APKs required for e2e testing + * When running on the CI (depending on the flags passed to it) it will skip building and just package/re-sign + * the correct e2e JS bundle into an existing APK + * + * It will run only one set of tests per branch, for you to compare results to get a performance analysis + * You need to run it twice, once with the base branch (--branch main) and another time with another branch + * and a label to (--branch my_branch --label delta) + * + * This two runs will generate a main.json and a delta.json with the performance data, which then you can merge via + * node tests/e2e/merge.js */ /* eslint-disable @lwc/lwc/no-async-await,no-restricted-syntax,no-await-in-loop */ const fs = require('fs'); const _ = require('underscore'); const defaultConfig = require('./config'); -// const compare = require('./compare/compare'); const Logger = require('./utils/logger'); const execAsync = require('./utils/execAsync'); const killApp = require('./utils/killApp'); @@ -73,18 +79,29 @@ if (args.includes('--config')) { setConfigPath(configPath); } -try { - // Clear all files from previous jobs - fs.rmSync(config.OUTPUT_DIR, {recursive: true, force: true}); +// Create some variables after the correct config file has been loaded +const OUTPUT_FILE = `${config.OUTPUT_DIR}/${label}.json`; - fs.mkdirSync(config.OUTPUT_DIR); -} catch (error) { - // Do nothing - console.error(error); +if (isDevMode) { + Logger.note(`🟠 Running in development mode.`); } if (isDevMode) { - Logger.note(`Running in development mode.`); + // On dev mode only delete any existing output file but keep the folder + if (fs.existsSync(OUTPUT_FILE)) { + fs.rmSync(OUTPUT_FILE); + } +} else { + // On CI it is important to re-create the output dir, it has a different owner + // therefore this process cannot write to it + try { + fs.rmSync(config.OUTPUT_DIR, {recursive: true, force: true}); + + fs.mkdirSync(config.OUTPUT_DIR); + } catch (error) { + // Do nothing + console.error(error); + } } const restartApp = async () => { @@ -240,7 +257,7 @@ const runTests = async () => { // Calculate statistics and write them to our work file progressLog = Logger.progressInfo('Calculating statics and writing results'); - const outputFileName = `${config.OUTPUT_DIR}/${label}.json`; + for (const testName of _.keys(durationsByTestName)) { const stats = math.getStats(durationsByTestName[testName]); await writeTestStats( @@ -248,7 +265,7 @@ const runTests = async () => { name: testName, ...stats, }, - outputFileName, + OUTPUT_FILE, ); } progressLog.done(); From 5861ca784b3ca4404aa50a9a8c7f89758fd75a0b Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 09:32:37 +0200 Subject: [PATCH 08/39] Handle not passing branch name --- tests/e2e/testRunner.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 1bcb0b1e22293..7a9bc71dfffa7 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -30,12 +30,6 @@ const reversePort = require('./utils/androidReversePort'); const args = process.argv.slice(2); -const indexOfBranchLabel = _.findIndex(args, (t) => t === '--branch'); - -if (indexOfBranchLabel === -1) { - throw new Error('branch not specified, specify a branch with --branch [BRANCH NAME]'); -} - let branch = 'main'; if (args.includes('--branch')) { From 38d4b88933b1c4d59dafda3713f30f1420d50cbf Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 09:41:43 +0200 Subject: [PATCH 09/39] Move variable configuration to top of file --- tests/e2e/testRunner.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 7a9bc71dfffa7..cccca3d302e2b 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -28,10 +28,10 @@ const writeTestStats = require('./measure/writeTestStats'); const withFailTimeout = require('./utils/withFailTimeout'); const reversePort = require('./utils/androidReversePort'); +// VARIABLE CONFIGURATION const args = process.argv.slice(2); let branch = 'main'; - if (args.includes('--branch')) { branch = args[args.indexOf('--branch') + 1]; } @@ -53,6 +53,8 @@ const setConfigPath = (configPathParam) => { const skipCheckout = args.includes('--skipCheckout'); +const skipInstallDeps = args.includes('--skipInstallDeps'); + // There are three build modes: // 1. full: rebuilds the full native app in (e2e) release mode // 2. js-only: only rebuilds the js bundle, and then re-packages @@ -61,6 +63,15 @@ const skipCheckout = args.includes('--skipCheckout'); // 3. skip: does not rebuild anything, and just runs the existing native app let buildMode = 'full'; +if (args.includes('--buildMode')) { + buildMode = args[args.indexOf('--buildMode') + 1]; +} + +let appPath = config.APP_PATH; +if (args.includes('--appPath')) { + appPath = args[args.indexOf('--appPath') + 1]; +} + // When we are in dev mode we want to apply certain default params and configs const isDevMode = args.includes('--development'); if (isDevMode) { @@ -98,6 +109,8 @@ if (isDevMode) { } } +// START OF TEST CODE + const restartApp = async () => { Logger.log('Killing app …'); await killApp('android', config.APP_PACKAGE); @@ -106,15 +119,6 @@ const restartApp = async () => { }; const runTests = async () => { - if (args.includes('--buildMode')) { - buildMode = args[args.indexOf('--buildMode') + 1]; - } - - let appPath = config.APP_PATH; - if (args.includes('--appPath')) { - appPath = args[args.indexOf('--appPath') + 1]; - } - // check if using buildMode "js-only" or "none" is possible if (buildMode !== 'full') { const appExists = fs.existsSync(appPath); @@ -132,7 +136,7 @@ const runTests = async () => { await execAsync(`git checkout ${branch}`); } - if (!args.includes('--skipInstallDeps')) { + if (!skipInstallDeps) { Logger.log(`Preparing tests on branch '${branch}' - npm install`); await execAsync('npm i'); } From 8fb3826ea47e205a98a10621c4adc1e9696f16a3 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 14:24:09 +0200 Subject: [PATCH 10/39] Update config.local and fix detected appPath --- package.json | 4 ++-- tests/e2e/config.local.js | 3 --- tests/e2e/testRunner.js | 44 +++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 012260d06b571..58d768d7721b3 100644 --- a/package.json +++ b/package.json @@ -49,8 +49,8 @@ "analyze-packages": "ANALYZE_BUNDLE=true webpack --config config/webpack/webpack.common.js --env envFile=.env.production", "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map", "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map", - "test:e2e:main": "node tests/e2e/testRunner.js --development --branch main", - "test:e2e:delta": "node tests/e2e/testRunner.js --development --branch main --label delta", + "test:e2e:main": "node tests/e2e/testRunner.js --development --branch main --skipCheckout", + "test:e2e:delta": "node tests/e2e/testRunner.js --development --branch main --label delta --skipCheckout", "test:e2e:compare": "node tests/e2e/merge.js", "gh-actions-unused-styles": "./.github/scripts/findUnusedKeys.sh", "workflow-test": "./workflow_tests/scripts/runWorkflowTests.sh", diff --git a/tests/e2e/config.local.js b/tests/e2e/config.local.js index d60f6a5abdc7a..51e915e219b72 100644 --- a/tests/e2e/config.local.js +++ b/tests/e2e/config.local.js @@ -1,7 +1,4 @@ module.exports = { APP_PACKAGE: 'com.expensify.chat.adhoc', - - WARM_UP_RUNS: 1, - RUNS: 8, APP_PATH: './android/app/build/outputs/apk/e2e/release/app-e2e-release.apk', }; diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index cccca3d302e2b..97560eb815aa7 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -67,11 +67,6 @@ if (args.includes('--buildMode')) { buildMode = args[args.indexOf('--buildMode') + 1]; } -let appPath = config.APP_PATH; -if (args.includes('--appPath')) { - appPath = args[args.indexOf('--appPath') + 1]; -} - // When we are in dev mode we want to apply certain default params and configs const isDevMode = args.includes('--development'); if (isDevMode) { @@ -84,6 +79,12 @@ if (args.includes('--config')) { setConfigPath(configPath); } +// Important set app path after correct config file has been set +let appPath = config.APP_PATH; +if (args.includes('--appPath')) { + appPath = args[args.indexOf('--appPath') + 1]; +} + // Create some variables after the correct config file has been loaded const OUTPUT_FILE = `${config.OUTPUT_DIR}/${label}.json`; @@ -204,30 +205,29 @@ const runTests = async () => { server.setTestConfig(testConfig); - const warmupLogs = Logger.progressInfo(`Running test '${testConfig.name}'`); - for (let warmUpRuns = 0; warmUpRuns < config.WARM_UP_RUNS; warmUpRuns++) { - const progressText = `(${testIndex + 1}/${numOfTests}) Warmup for test '${testConfig.name}' (iteration ${warmUpRuns + 1}/${config.WARM_UP_RUNS})`; - warmupLogs.updateText(progressText); + const warmupLogs = Logger.progressInfo(`Running warmup '${testConfig.name}'`); - await restartApp(); + let progressText = `(${testIndex + 1}/${numOfTests}) Warmup for test '${testConfig.name}'`; + warmupLogs.updateText(progressText); + + await restartApp(); + + await withFailTimeout( + new Promise((resolve) => { + const cleanup = server.addTestDoneListener(() => { + cleanup(); + resolve(); + }); + }), + progressText, + ); - await withFailTimeout( - new Promise((resolve) => { - const cleanup = server.addTestDoneListener(() => { - Logger.log(`Warmup ${warmUpRuns + 1} done!`); - cleanup(); - resolve(); - }); - }), - progressText, - ); - } warmupLogs.done(); // We run each test multiple time to average out the results const testLog = Logger.progressInfo(''); for (let i = 0; i < config.RUNS; i++) { - const progressText = `(${testIndex + 1}/${numOfTests}) Running test '${testConfig.name}' (iteration ${i + 1}/${config.RUNS})`; + progressText = `(${testIndex + 1}/${numOfTests}) Running test '${testConfig.name}' (iteration ${i + 1}/${config.RUNS})`; testLog.updateText(progressText); await restartApp(); From 61ae5b703bb76e708a6caa49bb28d9fb47439ce1 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 14:30:03 +0200 Subject: [PATCH 11/39] Update configs --- tests/e2e/config.js | 10 ++-------- tests/e2e/config.local.js | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/e2e/config.js b/tests/e2e/config.js index 4f08754cfec28..fda993ce68a67 100644 --- a/tests/e2e/config.js +++ b/tests/e2e/config.js @@ -23,10 +23,7 @@ const TEST_NAMES = { module.exports = { APP_PACKAGE: 'com.expensify.chat.adhoc', - APP_PATHS: { - baseline: './app-e2eRelease-baseline.apk', - compare: './app-e2eRelease-compare.apk', - }, + APP_PATH: './app-e2eRelease-main.apk', ENTRY_FILE: 'src/libs/E2E/reactNativeLaunchingTest.js', @@ -34,13 +31,10 @@ module.exports = { SERVER_PORT: 4723, // The amount of times a test should be executed for average performance metrics - RUNS: 90, + RUNS: 30, DEFAULT_BASELINE_BRANCH: 'main', - // The amount of runs that should happen without counting test results - WARM_UP_RUNS: 3, - OUTPUT_DIR, // The file to write intermediate results to diff --git a/tests/e2e/config.local.js b/tests/e2e/config.local.js index 51e915e219b72..15b091d8ba70f 100644 --- a/tests/e2e/config.local.js +++ b/tests/e2e/config.local.js @@ -1,4 +1,5 @@ module.exports = { APP_PACKAGE: 'com.expensify.chat.adhoc', APP_PATH: './android/app/build/outputs/apk/e2e/release/app-e2e-release.apk', + RUNS: 8, }; From 8df571c0a9483bcec7a398c5475ce050f31b4e08 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 14:59:02 +0200 Subject: [PATCH 12/39] Logs improvements --- tests/e2e/testRunner.js | 4 +-- tests/e2e/utils/execAsync.js | 8 ++++-- tests/e2e/utils/logger.js | 53 +++++++++++++++++++++++++----------- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 97560eb815aa7..4439daf5ef6a6 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -207,7 +207,7 @@ const runTests = async () => { const warmupLogs = Logger.progressInfo(`Running warmup '${testConfig.name}'`); - let progressText = `(${testIndex + 1}/${numOfTests}) Warmup for test '${testConfig.name}'`; + let progressText = `Warmup for suite '${testConfig.name}' [${testIndex + 1}/${numOfTests}]\n`; warmupLogs.updateText(progressText); await restartApp(); @@ -227,7 +227,7 @@ const runTests = async () => { // We run each test multiple time to average out the results const testLog = Logger.progressInfo(''); for (let i = 0; i < config.RUNS; i++) { - progressText = `(${testIndex + 1}/${numOfTests}) Running test '${testConfig.name}' (iteration ${i + 1}/${config.RUNS})`; + progressText = `Suite '${testConfig.name}' [${testIndex + 1}/${numOfTests}], iteration [${i + 1}/${config.RUNS}]\n`; testLog.updateText(progressText); await restartApp(); diff --git a/tests/e2e/utils/execAsync.js b/tests/e2e/utils/execAsync.js index c51a328e914d6..98e1a3ec53863 100644 --- a/tests/e2e/utils/execAsync.js +++ b/tests/e2e/utils/execAsync.js @@ -10,7 +10,9 @@ const Logger = require('./logger'); module.exports = (command) => { let process; const promise = new Promise((resolve, reject) => { - Logger.log('Output of command:', command); + Logger.log(`\nRunning command:`); + Logger.important(command); + process = exec( command, { @@ -22,11 +24,11 @@ module.exports = (command) => { if (error && error.killed) { resolve(); } else { - Logger.log(`failed with error: ${error}`); + Logger.error(`failed with error: ${error}`); reject(error); } } else { - Logger.log(stdout); + Logger.note(stdout); resolve(stdout); } }, diff --git a/tests/e2e/utils/logger.js b/tests/e2e/utils/logger.js index 1f2fff315bfc1..7aae3ef8b1844 100644 --- a/tests/e2e/utils/logger.js +++ b/tests/e2e/utils/logger.js @@ -12,6 +12,9 @@ const LOGGER_PROGRESS_REFRESH_RATE = process.env.LOGGER_PROGRESS_REFRESH_RATE || const COLOR_DIM = '\x1b[2m'; const COLOR_RESET = '\x1b[0m'; const COLOR_YELLOW = '\x1b[33m'; +const COLOR_RED = '\x1b[31m'; +const COLOR_BLUE = '\x1b[34m'; +const COLOR_GREEN = '\x1b[32m'; const log = (...args) => { if (isVerbose) { @@ -27,6 +30,35 @@ const log = (...args) => { fs.appendFileSync(LOG_FILE, `[${timeStr}] ${args.join(' ')}\n`); }; +const info = (...args) => { + log('> ', ...args); +}; + +const important = (...args) => { + const lines = [`🟦 ${COLOR_BLUE}`, ...args, `${COLOR_RESET}\n`]; + log(...lines); +}; + +const success = (...args) => { + const lines = [`🟦 ${COLOR_GREEN}`, ...args, `${COLOR_RESET}\n`]; + log(...lines); +}; + +const warn = (...args) => { + const lines = [`\n${COLOR_YELLOW}⚠️`, ...args, `${COLOR_RESET}\n`]; + log(...lines); +}; + +const note = (...args) => { + const lines = [`${COLOR_DIM}`, ...args, `${COLOR_RESET}\n`]; + log(...lines); +}; + +const error = (...args) => { + const lines = [`\n🔴 ${COLOR_RED}`, ...args, `${COLOR_RESET}\n`]; + log(...lines); +}; + const progressInfo = (textParam) => { let text = textParam || ''; const getTexts = () => [`🕛 ${text}`, `🕔 ${text}`, `🕗 ${text}`, `🕙 ${text}`]; @@ -51,34 +83,23 @@ const progressInfo = (textParam) => { }, done: () => { clearInterval(timer); - process.stdout.write(`\r✅ ${text} ${getTimeText()}\n`); + success(`\r✅ ${text} ${getTimeText()}\n`); }, error: () => { clearInterval(timer); - process.stdout.write(`\r❌ ${text} ${getTimeText()}\n`); + error(`\r❌ ${text} ${getTimeText()}\n`); }, }; }; -const info = (...args) => { - log('> ', ...args); -}; - -const warn = (...args) => { - const lines = [`\n${COLOR_YELLOW}⚠️`, ...args, `${COLOR_RESET}\n`]; - log(...lines); -}; - -const note = (...args) => { - const lines = [`\n💡${COLOR_DIM}`, ...args, `${COLOR_RESET}\n`]; - log(...lines); -}; - module.exports = { log, info, warn, note, + error, + success, + important, progressInfo, setLogLevelVerbose, }; From 78d1e5f9c53f9ccbe4695745320f2d14e0024593 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 15:32:08 +0200 Subject: [PATCH 13/39] Correct paths on when running merge script --- .github/workflows/e2ePerformanceTests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 057d535955a52..570d69d33c943 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -211,10 +211,10 @@ jobs: run: unzip "Customer Artifacts.zip" -d deltaResults - name: Compare results - run: node "./Host_Machine_File/tests/e2e/merge.js --mainPath ../../mainResults/\$WORKING_DIRECTORY/main.json --deltaPath ../../deltaResults/\$WORKING_DIRECTORY/delta.json --outputPath ./Host_Machine_Files/output.md" + run: node tests/e2e/merge.js --mainPath ./mainResults/Host_Machine_Files/\$WORKING_DIRECTORY/main.json --deltaPath ./deltaResults//Host_Machine_Files/\$WORKING_DIRECTORY/delta.json --outputPath ./output.md - name: Print results - run: cat "./Host_Machine_Files/output.md" + run: cat "./output.md" # - name: Print AWS Device Farm verbose run results # if: ${{ always() && runner.debug != null && fromJSON(runner.debug) }} From ccae18e3b3665b6121dee256155e8422c244be25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Wed, 18 Oct 2023 17:22:09 +0200 Subject: [PATCH 14/39] use traditional child_process import --- tests/e2e/testRunner.js | 10 +++++----- tests/e2e/utils/execAsync.js | 2 +- tests/e2e/utils/getCurrentBranchName.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 4439daf5ef6a6..ef5f692dfcea5 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -282,13 +282,13 @@ const run = async () => { Logger.info('\n\nE2E test suite failed due to error:', e, '\nPrinting full logs:\n\n'); // Write logcat, meminfo, emulator info to file as well: - require('node:child_process').execSync(`adb logcat -d > ${config.OUTPUT_DIR}/logcat.txt`); - require('node:child_process').execSync(`adb shell "cat /proc/meminfo" > ${config.OUTPUT_DIR}/meminfo.txt`); - require('node:child_process').execSync(`adb shell "getprop" > ${config.OUTPUT_DIR}/emulator-properties.txt`); + require('child_process').execSync(`adb logcat -d > ${config.OUTPUT_DIR}/logcat.txt`); + require('child_process').execSync(`adb shell "cat /proc/meminfo" > ${config.OUTPUT_DIR}/meminfo.txt`); + require('child_process').execSync(`adb shell "getprop" > ${config.OUTPUT_DIR}/emulator-properties.txt`); - require('node:child_process').execSync(`cat ${config.LOG_FILE}`); + require('child_process').execSync(`cat ${config.LOG_FILE}`); try { - require('node:child_process').execSync(`cat ~/.android/avd/${process.env.AVD_NAME || 'test'}.avd/config.ini > ${config.OUTPUT_DIR}/emulator-config.ini`); + require('child_process').execSync(`cat ~/.android/avd/${process.env.AVD_NAME || 'test'}.avd/config.ini > ${config.OUTPUT_DIR}/emulator-config.ini`); } catch (ignoredError) { // the error is ignored, as the file might not exist if the test // run wasn't started with an emulator diff --git a/tests/e2e/utils/execAsync.js b/tests/e2e/utils/execAsync.js index 98e1a3ec53863..a9c1cc1948603 100644 --- a/tests/e2e/utils/execAsync.js +++ b/tests/e2e/utils/execAsync.js @@ -1,4 +1,4 @@ -const {exec} = require('node:child_process'); +const {exec} = require('child_process'); const Logger = require('./logger'); /** diff --git a/tests/e2e/utils/getCurrentBranchName.js b/tests/e2e/utils/getCurrentBranchName.js index 3380bd23ef153..ca2f0cba97b08 100644 --- a/tests/e2e/utils/getCurrentBranchName.js +++ b/tests/e2e/utils/getCurrentBranchName.js @@ -1,4 +1,4 @@ -const {execSync} = require('node:child_process'); +const {execSync} = require('child_process'); const getCurrentBranchName = () => { const stdout = execSync('git rev-parse --abbrev-ref HEAD', { From 95cc2143e488e1c9c4b8b6729a5d57e329995c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Wed, 18 Oct 2023 18:47:30 +0200 Subject: [PATCH 15/39] fix node setup --- .github/workflows/e2ePerformanceTests.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 570d69d33c943..4c24f6a73b2a3 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -125,10 +125,8 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 - with: - node-version: 16.x + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Make zip directory for everything to send to AWS Device Farm run: mkdir zip @@ -189,7 +187,7 @@ jobs: - name: Delete Customer Artifacts.zip run: rm "Customer Artifacts.zip" - + - name: Schedule AWS Device Farm test run on delta branch uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b with: @@ -209,17 +207,16 @@ jobs: - name: Unzip AWS Device Farm delta results run: unzip "Customer Artifacts.zip" -d deltaResults - + - name: Compare results run: node tests/e2e/merge.js --mainPath ./mainResults/Host_Machine_Files/\$WORKING_DIRECTORY/main.json --deltaPath ./deltaResults//Host_Machine_Files/\$WORKING_DIRECTORY/delta.json --outputPath ./output.md - name: Print results run: cat "./output.md" - + # - name: Print AWS Device Farm verbose run results # if: ${{ always() && runner.debug != null && fromJSON(runner.debug) }} # run: cat "./Host_Machine_Files/debug.log" - # TODO: Once tests are more reliable we should uncomment this # - name: Check if test failed, if so post the results and add the DeployBlocker label # run: | From 175cd23109a22fc0662da21b741445cc7466f74e Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Wed, 18 Oct 2023 23:34:37 +0200 Subject: [PATCH 16/39] Install underscore --- .github/workflows/e2ePerformanceTests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 4c24f6a73b2a3..30ef8d6a3d0b0 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -128,6 +128,9 @@ jobs: - name: Setup Node uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Install underscore + run: npm install underscore + - name: Make zip directory for everything to send to AWS Device Farm run: mkdir zip From b095730be5c9ed3473f06d1963f0d0ccfc7ee813 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 08:01:41 +0200 Subject: [PATCH 17/39] Remove underscore step --- .github/workflows/e2ePerformanceTests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 30ef8d6a3d0b0..4c24f6a73b2a3 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -128,9 +128,6 @@ jobs: - name: Setup Node uses: Expensify/App/.github/actions/composite/setupNode@main - - name: Install underscore - run: npm install underscore - - name: Make zip directory for everything to send to AWS Device Farm run: mkdir zip From 2cf1f75f4d3fb21b2ec159aae1ec4bb5b24d5f86 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 09:13:55 +0200 Subject: [PATCH 18/39] Move buildMode param below dev flag setting --- tests/e2e/testRunner.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index ef5f692dfcea5..446219a5464a5 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -63,10 +63,6 @@ const skipInstallDeps = args.includes('--skipInstallDeps'); // 3. skip: does not rebuild anything, and just runs the existing native app let buildMode = 'full'; -if (args.includes('--buildMode')) { - buildMode = args[args.indexOf('--buildMode') + 1]; -} - // When we are in dev mode we want to apply certain default params and configs const isDevMode = args.includes('--development'); if (isDevMode) { @@ -74,6 +70,10 @@ if (isDevMode) { buildMode = 'js-only'; } +if (args.includes('--buildMode')) { + buildMode = args[args.indexOf('--buildMode') + 1]; +} + if (args.includes('--config')) { const configPath = args[args.indexOf('--config') + 1]; setConfigPath(configPath); From 4900518f27fcfaf28d31a0faea4372a9e661a10b Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 09:52:15 +0200 Subject: [PATCH 19/39] add env variable to asyncExec --- tests/e2e/testRunner.js | 3 +-- tests/e2e/utils/execAsync.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 446219a5464a5..98bc935be284b 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -153,8 +153,7 @@ const runTests = async () => { const tempDir = `${config.OUTPUT_DIR}/temp`; const tempBundlePath = `${tempDir}/index.android.bundle`; await execAsync(`rm -rf ${tempDir} && mkdir ${tempDir}`); - await execAsync(`E2E_TESTING=true npx react-native bundle --platform android --dev false --entry-file ${config.ENTRY_FILE} --bundle-output ${tempBundlePath}`); - + await execAsync(`npx react-native bundle --platform android --dev false --entry-file ${config.ENTRY_FILE} --bundle-output ${tempBundlePath}`, {E2E_TESTING: true}); // Repackage the existing native app with the new bundle const tempApkPath = `${tempDir}/app-release.apk`; await execAsync(`./scripts/android-repackage-app-bundle-and-sign.sh ${appPath} ${tempBundlePath} ${tempApkPath}`); diff --git a/tests/e2e/utils/execAsync.js b/tests/e2e/utils/execAsync.js index a9c1cc1948603..1583c6d07b327 100644 --- a/tests/e2e/utils/execAsync.js +++ b/tests/e2e/utils/execAsync.js @@ -5,19 +5,24 @@ const Logger = require('./logger'); * Executes a command none-blocking by wrapping it in a promise. * In addition to the promise it returns an abort function. * @param {string} command + * @param {object} env environment variables * @returns {Promise} */ -module.exports = (command) => { - let process; +module.exports = (command, env = {}) => { + let childProcess; const promise = new Promise((resolve, reject) => { Logger.log(`\nRunning command:`); Logger.important(command); - process = exec( + childProcess = exec( command, { encoding: 'utf8', maxBuffer: 1024 * 1024 * 10, // Increase max buffer to 10MB, to avoid errors + env: { + ...process.env, + ...env, + }, }, (error, stdout) => { if (error) { @@ -36,7 +41,7 @@ module.exports = (command) => { }); promise.abort = () => { - process.kill('SIGINT'); + childProcess.kill('SIGINT'); }; return promise; From 09c0a4d46ae6095f2a775b5ea5fd4fedfcfb220c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Thu, 19 Oct 2023 09:57:26 +0200 Subject: [PATCH 20/39] fix crash because log dir doesn't exist --- tests/e2e/utils/logger.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/e2e/utils/logger.js b/tests/e2e/utils/logger.js index 7aae3ef8b1844..7da1e8330bfc6 100644 --- a/tests/e2e/utils/logger.js +++ b/tests/e2e/utils/logger.js @@ -1,4 +1,5 @@ const fs = require('fs'); +const path = require('path'); const {LOG_FILE} = require('../config'); let isVerbose = true; @@ -23,6 +24,12 @@ const log = (...args) => { // Write to log file if (!fs.existsSync(LOG_FILE)) { + // Check that the directory exists + const logDir = path.dirname(LOG_FILE); + if (!fs.existsSync(logDir)) { + fs.mkdirSync(logDir); + } + fs.writeFileSync(LOG_FILE, ''); } const time = new Date(); From 41a50785b6ca7604f4acf638b0f0d164ae1ad6bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Thu, 19 Oct 2023 10:01:41 +0200 Subject: [PATCH 21/39] wording --- tests/e2e/testRunner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 98bc935be284b..88b82d75cc3f2 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -58,7 +58,7 @@ const skipInstallDeps = args.includes('--skipInstallDeps'); // There are three build modes: // 1. full: rebuilds the full native app in (e2e) release mode // 2. js-only: only rebuilds the js bundle, and then re-packages -// the existing native app with the new package. If there +// the existing native app with the new bundle. If there // is no existing native app, it will fallback to mode "full" // 3. skip: does not rebuild anything, and just runs the existing native app let buildMode = 'full'; From 8dbd16ad1c19aec0b20a667328841cdb76fb60b9 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 10:06:43 +0200 Subject: [PATCH 22/39] Log execAsync environment --- metro.config.js | 2 +- package-lock.json | 307 +++++++++++++++----- package.json | 9 +- src/libs/E2E/API.mock.js | 6 + src/libs/E2E/apiMocks/beginSignin.js | 1 + src/libs/E2E/apiMocks/signInAttemptState.js | 21 ++ src/libs/E2E/apiMocks/signinUser.js | 1 + src/pages/signin/SignInPage.js | 4 + tests/e2e/testRunner.js | 2 +- tests/e2e/utils/execAsync.js | 17 +- 10 files changed, 279 insertions(+), 91 deletions(-) create mode 100644 src/libs/E2E/apiMocks/signInAttemptState.js diff --git a/metro.config.js b/metro.config.js index bf2ff904df702..f64881f69a12d 100644 --- a/metro.config.js +++ b/metro.config.js @@ -9,7 +9,7 @@ const defaultConfig = getDefaultConfig(__dirname); const isUsingMockAPI = process.env.E2E_TESTING === 'true'; if (isUsingMockAPI) { // eslint-disable-next-line no-console - console.warn('⚠️ Using mock API'); + console.log('⚠️ Using mock API'); } /** diff --git a/package-lock.json b/package-lock.json index b575c151364db..7c0016acea0ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.3.86-1", + "version": "1.3.84-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.3.86-1", + "version": "1.3.84-1", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -43,6 +43,7 @@ "@types/node": "^18.14.0", "@ua/react-native-airship": "^15.2.6", "awesome-phonenumber": "^5.4.0", + "babel-plugin-transform-remove-console": "^6.9.4", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", "core-js": "^3.32.0", @@ -50,7 +51,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", + "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", "fbjs": "^3.0.2", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", @@ -137,6 +138,8 @@ "@babel/runtime": "^7.20.0", "@electron/notarize": "^1.2.3", "@jest/globals": "^29.5.0", + "@kie/act-js": "^2.0.1", + "@kie/mock-github": "^1.0.0", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", "@octokit/plugin-throttling": "4.1.0", @@ -219,7 +222,7 @@ "react-native-performance-flipper-reporter": "^2.0.0", "react-native-svg-transformer": "^1.0.0", "react-test-renderer": "18.2.0", - "reassure": "^0.10.1", + "reassure": "^0.9.0", "setimmediate": "^1.0.5", "shellcheck": "^1.1.0", "style-loader": "^2.0.0", @@ -2625,12 +2628,12 @@ "license": "Apache-2.0" }, "node_modules/@callstack/reassure-cli": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.10.0.tgz", - "integrity": "sha512-CYgOGOAWcFgA2GrJw6RJAvImCpHCpPbtPoYMDol7esjlRCX2QwIKG7/9byq47hML57w94fhFAa76KD84YlgMBg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.9.1.tgz", + "integrity": "sha512-ctETa5REyA1KM50Q9MMdy9oLqMK1eQp3Uc5cmx1VNQrAY678xCqIbiK4Hi3r5kZeq9k+JzsRgs9j+h6yrP8Lyw==", "dev": true, "dependencies": { - "@callstack/reassure-compare": "0.6.0", + "@callstack/reassure-compare": "0.5.1", "@callstack/reassure-logger": "0.3.1", "chalk": "4.1.2", "simple-git": "^3.16.0", @@ -2761,9 +2764,9 @@ } }, "node_modules/@callstack/reassure-compare": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.6.0.tgz", - "integrity": "sha512-P3nmv36CJrQSXg0+z6EuEV/0xAbvxWbAZ7diQHnkbvqk2z8PKRXpkcthrRUpe02wLewa0MLxBUJwLenFnhxIRg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.5.1.tgz", + "integrity": "sha512-w3/W+1N8pNSdmoT0EZ0fTnhxqeIfkqTrLTrIGQQTgPbaekCSbvojG9eceHQ+XOsZfM3Y9tgDS5Uwx6k9h0JY5g==", "dev": true, "dependencies": { "@callstack/reassure-logger": "0.3.1", @@ -2858,9 +2861,9 @@ } }, "node_modules/@callstack/reassure-measure": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.6.0.tgz", - "integrity": "sha512-phXY5DAtKhnu8dA2pmnl+pqFOfrVEFFDJOi4AnObwIcpDSn3IUXgNSe7rSi+JP/mXNWMLoUS8rnH4iIFDyf7qQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.5.1.tgz", + "integrity": "sha512-M1tdWKoT2SGQYkITwFWlDiM/yZ+a2cbHSnuu3nEiyFn6YQHpL9FKDIIJjP6nCjHBk4ERj411mpO2Ss927KFu4Q==", "dev": true, "dependencies": { "@callstack/reassure-logger": "0.3.1", @@ -5462,6 +5465,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.3.0.tgz", "integrity": "sha512-Q9k0b05uA46jXKWmVfoGDW+0xsCcE7QPiHi8IH7h41P36DujHKBj4k28RCeIEx3IwUCxYHKwubN8DH4Vzc9XcA==", + "dev": true, "hasInstallScript": true, "dependencies": { "@kie/mock-github": "^2.0.0", @@ -5481,6 +5485,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.0.tgz", "integrity": "sha512-od6UyICJYKMnz9HgEWCQAFT/JsCpKkLp+JQH8fV23tf+ZmmQI1dK3C20k6aO5uJhAHA0yOcFtbKFVF4+8i3DTg==", + "dev": true, "dependencies": { "@octokit/openapi-types-ghec": "^18.0.0", "ajv": "^8.11.0", @@ -5495,12 +5500,14 @@ "node_modules/@kie/act-js/node_modules/@octokit/openapi-types-ghec": { "version": "18.1.1", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.1.1.tgz", - "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==" + "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==", + "dev": true }, "node_modules/@kie/act-js/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5514,6 +5521,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, "engines": { "node": ">=6" } @@ -5522,6 +5530,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-1.1.0.tgz", "integrity": "sha512-fD+utlOiyZSOutOcXL0G9jfjbtvOO44PLUyTfgfkrm1+575R/dbvU6AcJfjc1DtHeRv7FC7f4ebyU+a1wgL6CA==", + "dev": true, "dependencies": { "@octokit/openapi-types-ghec": "^14.0.0", "ajv": "^8.11.0", @@ -5537,6 +5546,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5550,6 +5560,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, "engines": { "node": ">=6" } @@ -5558,6 +5569,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, "dependencies": { "debug": "^4.1.1" } @@ -5565,7 +5577,8 @@ "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", @@ -5944,6 +5957,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -5957,6 +5971,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -5966,6 +5981,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -6096,7 +6112,8 @@ "node_modules/@octokit/openapi-types-ghec": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-14.0.0.tgz", - "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==" + "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==", + "dev": true }, "node_modules/@octokit/plugin-paginate-rest": { "version": "3.1.0", @@ -21201,6 +21218,7 @@ "version": "0.5.10", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "dev": true, "engines": { "node": ">=6.0" } @@ -21831,6 +21849,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, "license": "MIT" }, "node_modules/array-includes": { @@ -23273,6 +23292,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz", "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==", + "dev": true, "dependencies": { "cmd-shim": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -23287,6 +23307,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -23298,6 +23319,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -23380,6 +23402,7 @@ }, "node_modules/body-parser": { "version": "1.20.0", + "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -23404,6 +23427,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -23413,6 +23437,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -23422,6 +23447,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -23434,6 +23460,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, "license": "MIT" }, "node_modules/bonjour-service": { @@ -24509,6 +24536,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -24937,6 +24965,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", + "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -25379,6 +25408,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -25391,6 +25421,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -25409,6 +25440,7 @@ }, "node_modules/content-type": { "version": "1.0.4", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25423,6 +25455,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25432,6 +25465,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, "license": "MIT" }, "node_modules/copy-concurrently": { @@ -30189,8 +30223,8 @@ }, "node_modules/expensify-common": { "version": "1.0.0", - "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", - "integrity": "sha512-/kXD/18YQJY/iWB5MOSN0ixB1mpxUA+NXEYgKjac1tJd+DoY3K6+bDeu++Qfqg26LCNfvjTkjkDGZVdGsJQ7Hw==", + "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", + "integrity": "sha512-mD9p6Qj8FfvLdb6JLXvF0UNqLN6ymssUU67Fm37zmK18hd1Abw+vR/pQkNpHR2iv+KRs8HdcyuZ0vaOec4VrFQ==", "license": "MIT", "dependencies": { "classnames": "2.3.1", @@ -30286,6 +30320,7 @@ }, "node_modules/express": { "version": "4.18.1", + "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -30328,6 +30363,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -30337,12 +30373,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, "license": "MIT" }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -30544,6 +30582,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -30628,6 +30667,7 @@ }, "node_modules/fastq": { "version": "1.13.0", + "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -30861,6 +30901,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -30879,6 +30920,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -30888,6 +30930,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, "license": "MIT" }, "node_modules/find-babel-config": { @@ -31074,6 +31117,7 @@ "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true, "funding": [ { "type": "individual", @@ -31334,6 +31378,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -31410,6 +31455,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -31674,6 +31720,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -33493,6 +33540,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -33817,6 +33865,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -33892,6 +33941,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -37318,6 +37368,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, "license": "ISC" }, "node_modules/json5": { @@ -38833,6 +38884,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -39072,6 +39124,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true, "license": "MIT" }, "node_modules/merge-options": { @@ -39107,6 +39160,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -39116,6 +39170,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -41012,6 +41067,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -41062,6 +41118,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, "license": "MIT", "dependencies": { "minipass": "^3.0.0", @@ -41158,6 +41215,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" @@ -41393,6 +41451,7 @@ "version": "13.3.3", "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", + "dev": true, "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", @@ -41622,6 +41681,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -42833,6 +42893,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true, "license": "MIT" }, "node_modules/path-type": { @@ -43549,6 +43610,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true, "engines": { "node": ">= 8" } @@ -43576,6 +43638,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -43863,6 +43926,7 @@ "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -43923,6 +43987,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -44004,6 +44069,7 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -44019,6 +44085,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -44028,6 +44095,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -45879,6 +45947,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -46125,14 +46194,14 @@ "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" }, "node_modules/reassure": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.10.1.tgz", - "integrity": "sha512-+GANr5ojh32NZu1YGfa6W8vIJm3iOIZJUvXT5Gc9fQyre7okYsCzyBq9WsHbnAQDjNq1g9SsM/4bwcVET9OIqA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.9.1.tgz", + "integrity": "sha512-puPHh4LvDw9FJln58qpkwMDrkiAGO6E+QYe93Znotolefm2kzGytebklxd+z/ULKqL2e8eyDj51RqFOpwY/Ecw==", "dev": true, "dependencies": { - "@callstack/reassure-cli": "0.10.0", + "@callstack/reassure-cli": "0.9.1", "@callstack/reassure-danger": "0.1.1", - "@callstack/reassure-measure": "0.6.0" + "@callstack/reassure-measure": "0.5.1" } }, "node_modules/recast": { @@ -47033,6 +47102,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -47127,6 +47197,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -47861,6 +47932,7 @@ "version": "3.19.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.0.tgz", "integrity": "sha512-hyH2p9Ptxjf/xPuL7HfXbpYt9gKhC1yWDh3KYIAYJJePAKV7AEjLN4xhp7lozOdNiaJ9jlVvAbBymVlcS2jRiA==", + "dev": true, "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", @@ -49402,6 +49474,7 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -49418,6 +49491,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -50249,6 +50323,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -54807,12 +54882,12 @@ "dev": true }, "@callstack/reassure-cli": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.10.0.tgz", - "integrity": "sha512-CYgOGOAWcFgA2GrJw6RJAvImCpHCpPbtPoYMDol7esjlRCX2QwIKG7/9byq47hML57w94fhFAa76KD84YlgMBg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.9.1.tgz", + "integrity": "sha512-ctETa5REyA1KM50Q9MMdy9oLqMK1eQp3Uc5cmx1VNQrAY678xCqIbiK4Hi3r5kZeq9k+JzsRgs9j+h6yrP8Lyw==", "dev": true, "requires": { - "@callstack/reassure-compare": "0.6.0", + "@callstack/reassure-compare": "0.5.1", "@callstack/reassure-logger": "0.3.1", "chalk": "4.1.2", "simple-git": "^3.16.0", @@ -54909,9 +54984,9 @@ } }, "@callstack/reassure-compare": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.6.0.tgz", - "integrity": "sha512-P3nmv36CJrQSXg0+z6EuEV/0xAbvxWbAZ7diQHnkbvqk2z8PKRXpkcthrRUpe02wLewa0MLxBUJwLenFnhxIRg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.5.1.tgz", + "integrity": "sha512-w3/W+1N8pNSdmoT0EZ0fTnhxqeIfkqTrLTrIGQQTgPbaekCSbvojG9eceHQ+XOsZfM3Y9tgDS5Uwx6k9h0JY5g==", "dev": true, "requires": { "@callstack/reassure-logger": "0.3.1", @@ -54987,9 +55062,9 @@ } }, "@callstack/reassure-measure": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.6.0.tgz", - "integrity": "sha512-phXY5DAtKhnu8dA2pmnl+pqFOfrVEFFDJOi4AnObwIcpDSn3IUXgNSe7rSi+JP/mXNWMLoUS8rnH4iIFDyf7qQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.5.1.tgz", + "integrity": "sha512-M1tdWKoT2SGQYkITwFWlDiM/yZ+a2cbHSnuu3nEiyFn6YQHpL9FKDIIJjP6nCjHBk4ERj411mpO2Ss927KFu4Q==", "dev": true, "requires": { "@callstack/reassure-logger": "0.3.1", @@ -56813,6 +56888,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.3.0.tgz", "integrity": "sha512-Q9k0b05uA46jXKWmVfoGDW+0xsCcE7QPiHi8IH7h41P36DujHKBj4k28RCeIEx3IwUCxYHKwubN8DH4Vzc9XcA==", + "dev": true, "requires": { "@kie/mock-github": "^2.0.0", "adm-zip": "^0.5.10", @@ -56828,6 +56904,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.0.tgz", "integrity": "sha512-od6UyICJYKMnz9HgEWCQAFT/JsCpKkLp+JQH8fV23tf+ZmmQI1dK3C20k6aO5uJhAHA0yOcFtbKFVF4+8i3DTg==", + "dev": true, "requires": { "@octokit/openapi-types-ghec": "^18.0.0", "ajv": "^8.11.0", @@ -56842,12 +56919,14 @@ "@octokit/openapi-types-ghec": { "version": "18.1.1", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.1.1.tgz", - "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==" + "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==", + "dev": true }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -56857,7 +56936,8 @@ "totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true } } }, @@ -56865,6 +56945,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-1.1.0.tgz", "integrity": "sha512-fD+utlOiyZSOutOcXL0G9jfjbtvOO44PLUyTfgfkrm1+575R/dbvU6AcJfjc1DtHeRv7FC7f4ebyU+a1wgL6CA==", + "dev": true, "requires": { "@octokit/openapi-types-ghec": "^14.0.0", "ajv": "^8.11.0", @@ -56880,6 +56961,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -56889,7 +56971,8 @@ "totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true } } }, @@ -56897,6 +56980,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dev": true, "requires": { "debug": "^4.1.1" } @@ -56904,7 +56988,8 @@ "@kwsites/promise-deferred": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "dev": true }, "@leichtgewicht/ip-codec": { "version": "2.0.4", @@ -57186,6 +57271,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -57194,12 +57280,14 @@ "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -57311,7 +57399,8 @@ "@octokit/openapi-types-ghec": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-14.0.0.tgz", - "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==" + "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==", + "dev": true }, "@octokit/plugin-paginate-rest": { "version": "3.1.0", @@ -68224,7 +68313,8 @@ "adm-zip": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", - "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "dev": true }, "agent-base": { "version": "6.0.2", @@ -68702,7 +68792,8 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true }, "array-includes": { "version": "3.1.6", @@ -69758,6 +69849,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz", "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==", + "dev": true, "requires": { "cmd-shim": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -69768,12 +69860,14 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true }, "write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, "requires": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -69846,6 +69940,7 @@ }, "body-parser": { "version": "1.20.0", + "dev": true, "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -69864,12 +69959,14 @@ "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -69878,6 +69975,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -69885,7 +69983,8 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true } } }, @@ -70652,7 +70751,8 @@ "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true }, "chrome-trace-event": { "version": "1.0.3", @@ -70953,7 +71053,8 @@ "cmd-shim": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", - "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==" + "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", + "dev": true }, "co": { "version": "4.6.0", @@ -71287,6 +71388,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, "requires": { "safe-buffer": "5.2.1" }, @@ -71294,12 +71396,14 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, "content-type": { - "version": "1.0.4" + "version": "1.0.4", + "dev": true }, "convert-source-map": { "version": "1.9.0", @@ -71309,12 +71413,14 @@ "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true }, "copy-concurrently": { "version": "1.0.5", @@ -74774,9 +74880,9 @@ } }, "expensify-common": { - "version": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", - "integrity": "sha512-/kXD/18YQJY/iWB5MOSN0ixB1mpxUA+NXEYgKjac1tJd+DoY3K6+bDeu++Qfqg26LCNfvjTkjkDGZVdGsJQ7Hw==", - "from": "expensify-common@git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", + "version": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", + "integrity": "sha512-mD9p6Qj8FfvLdb6JLXvF0UNqLN6ymssUU67Fm37zmK18hd1Abw+vR/pQkNpHR2iv+KRs8HdcyuZ0vaOec4VrFQ==", + "from": "expensify-common@git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", "requires": { "classnames": "2.3.1", "clipboard": "2.0.4", @@ -74848,6 +74954,7 @@ }, "express": { "version": "4.18.1", + "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -74886,6 +74993,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -74893,12 +75001,14 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, @@ -75038,6 +75148,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -75096,6 +75207,7 @@ }, "fastq": { "version": "1.13.0", + "dev": true, "requires": { "reusify": "^1.0.4" } @@ -75274,6 +75386,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -75288,6 +75401,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -75295,7 +75409,8 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true } } }, @@ -75433,7 +75548,8 @@ "follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true }, "for-each": { "version": "0.3.3", @@ -75599,7 +75715,8 @@ "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true }, "fraction.js": { "version": "4.3.4", @@ -75651,6 +75768,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -75833,6 +75951,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, "requires": { "is-glob": "^4.0.1" } @@ -77122,7 +77241,8 @@ "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true }, "is-absolute-url": { "version": "3.0.3", @@ -77317,7 +77437,8 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true }, "is-finalizationregistry": { "version": "1.0.2", @@ -77364,6 +77485,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "requires": { "is-extglob": "^2.1.1" } @@ -79774,7 +79896,8 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true }, "json5": { "version": "2.2.3", @@ -80897,7 +81020,8 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true }, "mem": { "version": "8.1.1", @@ -81072,7 +81196,8 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true }, "merge-options": { "version": "3.0.4", @@ -81098,12 +81223,14 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true }, "metro": { "version": "0.76.8", @@ -82466,6 +82593,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -82501,6 +82629,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -82574,7 +82703,8 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mock-fs": { "version": "4.14.0", @@ -82746,6 +82876,7 @@ "version": "13.3.3", "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", + "dev": true, "requires": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", @@ -82921,7 +83052,8 @@ "npm-normalize-package-bin": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==" + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true }, "npm-run-path": { "version": "4.0.1", @@ -83767,7 +83899,8 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true }, "path-type": { "version": "4.0.0", @@ -84272,7 +84405,8 @@ "propagate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==" + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true }, "property-information": { "version": "5.6.0", @@ -84292,6 +84426,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, "requires": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -84508,6 +84643,7 @@ "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, "requires": { "side-channel": "^1.0.4" } @@ -84548,7 +84684,8 @@ "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true }, "quick-lru": { "version": "5.1.1", @@ -84598,6 +84735,7 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, "requires": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -84608,12 +84746,14 @@ "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -85864,7 +86004,8 @@ "read-cmd-shim": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", - "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==" + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true }, "read-config-file": { "version": "6.3.2", @@ -86050,14 +86191,14 @@ "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" }, "reassure": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.10.1.tgz", - "integrity": "sha512-+GANr5ojh32NZu1YGfa6W8vIJm3iOIZJUvXT5Gc9fQyre7okYsCzyBq9WsHbnAQDjNq1g9SsM/4bwcVET9OIqA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.9.1.tgz", + "integrity": "sha512-puPHh4LvDw9FJln58qpkwMDrkiAGO6E+QYe93Znotolefm2kzGytebklxd+z/ULKqL2e8eyDj51RqFOpwY/Ecw==", "dev": true, "requires": { - "@callstack/reassure-cli": "0.10.0", + "@callstack/reassure-cli": "0.9.1", "@callstack/reassure-danger": "0.1.1", - "@callstack/reassure-measure": "0.6.0" + "@callstack/reassure-measure": "0.5.1" } }, "recast": { @@ -86719,7 +86860,8 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "right-align": { "version": "0.1.3", @@ -86784,6 +86926,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -87329,6 +87472,7 @@ "version": "3.19.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.0.tgz", "integrity": "sha512-hyH2p9Ptxjf/xPuL7HfXbpYt9gKhC1yWDh3KYIAYJJePAKV7AEjLN4xhp7lozOdNiaJ9jlVvAbBymVlcS2jRiA==", + "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", @@ -88479,6 +88623,7 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -88491,7 +88636,8 @@ "minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true } } }, @@ -89088,6 +89234,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.24" diff --git a/package.json b/package.json index 7d540c0d35069..58d768d7721b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.3.86-1", + "version": "1.3.84-1", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", @@ -90,6 +90,7 @@ "@types/node": "^18.14.0", "@ua/react-native-airship": "^15.2.6", "awesome-phonenumber": "^5.4.0", + "babel-plugin-transform-remove-console": "^6.9.4", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", "core-js": "^3.32.0", @@ -97,7 +98,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", + "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", "fbjs": "^3.0.2", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", @@ -184,6 +185,8 @@ "@babel/runtime": "^7.20.0", "@electron/notarize": "^1.2.3", "@jest/globals": "^29.5.0", + "@kie/act-js": "^2.0.1", + "@kie/mock-github": "^1.0.0", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", "@octokit/plugin-throttling": "4.1.0", @@ -266,7 +269,7 @@ "react-native-performance-flipper-reporter": "^2.0.0", "react-native-svg-transformer": "^1.0.0", "react-test-renderer": "18.2.0", - "reassure": "^0.10.1", + "reassure": "^0.9.0", "setimmediate": "^1.0.5", "shellcheck": "^1.1.0", "style-loader": "^2.0.0", diff --git a/src/libs/E2E/API.mock.js b/src/libs/E2E/API.mock.js index 47f445f72222d..0d517eb9b6e24 100644 --- a/src/libs/E2E/API.mock.js +++ b/src/libs/E2E/API.mock.js @@ -9,6 +9,7 @@ import mockSigninUser from './apiMocks/signinUser'; import mockAuthenticatePusher from './apiMocks/authenticatePusher'; import mockOpenApp from './apiMocks/openApp'; import mockOpenReport from './apiMocks/openReport'; +import mockSignInAttemptState from './apiMocks/signInAttemptState'; /** * A dictionary which has the name of a API command as key, and a function which @@ -22,10 +23,15 @@ const mocks = { ReconnectApp: mockOpenApp, OpenReport: mockOpenReport, AuthenticatePusher: mockAuthenticatePusher, + SignInAttemptState: mockSignInAttemptState, }; function mockCall(command, apiCommandParameters, tag) { const mockResponse = mocks[command] && mocks[command](apiCommandParameters); + Log.warn('🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐'); + Log.warn('🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐'); + Log.warn(`Mock Call to ${command}`); + Log.warn('🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐'); if (!mockResponse || !_.isArray(mockResponse.onyxData)) { Log.warn(`[${tag}] for command ${command} is not mocked yet!`); return; diff --git a/src/libs/E2E/apiMocks/beginSignin.js b/src/libs/E2E/apiMocks/beginSignin.js index 44e68ef589928..7d457b66ce68a 100644 --- a/src/libs/E2E/apiMocks/beginSignin.js +++ b/src/libs/E2E/apiMocks/beginSignin.js @@ -12,6 +12,7 @@ export default ({email}) => ({ key: 'account', value: { validated: true, + hasEmailDeliveryFailure: false, }, }, { diff --git a/src/libs/E2E/apiMocks/signInAttemptState.js b/src/libs/E2E/apiMocks/signInAttemptState.js new file mode 100644 index 0000000000000..575bfbb5f030e --- /dev/null +++ b/src/libs/E2E/apiMocks/signInAttemptState.js @@ -0,0 +1,21 @@ +export default ({email}) => ({ + onyxData: [ + { + onyxMethod: 'merge', + key: 'account', + value: { + isLoading: false, + loadingForm: null, + }, + }, + { + onyxMethod: 'merge', + key: 'credenttials', + value: { + validateCode: null, + }, + }, + ], + jsonCode: 200, + requestID: '783e54ef4b38cff5-SJC', +}); diff --git a/src/libs/E2E/apiMocks/signinUser.js b/src/libs/E2E/apiMocks/signinUser.js index 26203bc492cfa..3ba19d07deb75 100644 --- a/src/libs/E2E/apiMocks/signinUser.js +++ b/src/libs/E2E/apiMocks/signinUser.js @@ -115,6 +115,7 @@ export default ({email}) => ({ key: 'account', value: { requiresTwoFactorAuth: false, + hasEmailDeliveryFailure: false, }, }, ], diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index 8aae45c279c67..5709abf452f1f 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -113,7 +113,11 @@ function getRenderOptions({hasLogin, hasValidateCode, account, isPrimaryLogin, i } const shouldShowLoginForm = isClientTheLeader && !hasLogin && !hasValidateCode; + console.warn('🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏'); + console.warn('🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏'); + console.warn('🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏'); const shouldShowEmailDeliveryFailurePage = hasLogin && hasEmailDeliveryFailure && !shouldShowChooseSSOOrMagicCode && !shouldInitiateSAMLLogin; + console.warn({shouldShowEmailDeliveryFailurePage, hasLogin, hasEmailDeliveryFailure}); const isUnvalidatedSecondaryLogin = hasLogin && !isPrimaryLogin && !account.validated && !hasEmailDeliveryFailure; const shouldShowValidateCodeForm = hasAccount && (hasLogin || hasValidateCode) && !isUnvalidatedSecondaryLogin && !hasEmailDeliveryFailure && !shouldShowChooseSSOOrMagicCode && !isSAMLRequired; diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index 88b82d75cc3f2..5c6c33bdf7e91 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -153,7 +153,7 @@ const runTests = async () => { const tempDir = `${config.OUTPUT_DIR}/temp`; const tempBundlePath = `${tempDir}/index.android.bundle`; await execAsync(`rm -rf ${tempDir} && mkdir ${tempDir}`); - await execAsync(`npx react-native bundle --platform android --dev false --entry-file ${config.ENTRY_FILE} --bundle-output ${tempBundlePath}`, {E2E_TESTING: true}); + await execAsync(`npx react-native bundle --platform android --dev false --entry-file ${config.ENTRY_FILE} --bundle-output ${tempBundlePath}`, {E2E_TESTING: 'true'}); // Repackage the existing native app with the new bundle const tempApkPath = `${tempDir}/app-release.apk`; await execAsync(`./scripts/android-repackage-app-bundle-and-sign.sh ${appPath} ${tempBundlePath} ${tempApkPath}`); diff --git a/tests/e2e/utils/execAsync.js b/tests/e2e/utils/execAsync.js index 1583c6d07b327..4d92ac0b021f7 100644 --- a/tests/e2e/utils/execAsync.js +++ b/tests/e2e/utils/execAsync.js @@ -1,4 +1,5 @@ const {exec} = require('child_process'); +const _ = require('underscore'); const Logger = require('./logger'); /** @@ -11,18 +12,22 @@ const Logger = require('./logger'); module.exports = (command, env = {}) => { let childProcess; const promise = new Promise((resolve, reject) => { - Logger.log(`\nRunning command:`); + const finalEnv = { + ...process.env, + ...env, + }; + + if (_.keys(env).length !== 0) { + Logger.log(`environment variables:`, JSON.stringify(finalEnv, null, 2)); + } + Logger.important(command); childProcess = exec( command, { - encoding: 'utf8', maxBuffer: 1024 * 1024 * 10, // Increase max buffer to 10MB, to avoid errors - env: { - ...process.env, - ...env, - }, + env: finalEnv, }, (error, stdout) => { if (error) { From e74a276b01054da1504f35024a84d2944dc03147 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 10:12:39 +0200 Subject: [PATCH 23/39] Fix path for API mock --- metro.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metro.config.js b/metro.config.js index f64881f69a12d..06ce5bacc4023 100644 --- a/metro.config.js +++ b/metro.config.js @@ -28,7 +28,7 @@ const config = { return { ...resolution, // TODO: Change API.mock.js extension once it is migrated to TypeScript - filePath: resolution.filePath.replace(/src\/libs\/API.js/, 'src/libs/E2E/API.mock.js'), + filePath: resolution.filePath.replace(/src\/libs\/API.ts/, 'src/libs/E2E/API.mock.js'), }; } return resolution; From f8e8a4f7ab2a562e8aacaa70a5333138e67e38b0 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 10:14:24 +0200 Subject: [PATCH 24/39] Undo unnecessary mocks --- package-lock.json | 307 +++++--------------- package.json | 9 +- src/libs/E2E/API.mock.js | 6 - src/libs/E2E/apiMocks/beginSignin.js | 1 - src/libs/E2E/apiMocks/signInAttemptState.js | 21 -- src/libs/E2E/apiMocks/signinUser.js | 1 - src/pages/signin/SignInPage.js | 4 - tests/e2e/utils/execAsync.js | 8 +- 8 files changed, 87 insertions(+), 270 deletions(-) delete mode 100644 src/libs/E2E/apiMocks/signInAttemptState.js diff --git a/package-lock.json b/package-lock.json index 7c0016acea0ce..b575c151364db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.3.84-1", + "version": "1.3.86-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.3.84-1", + "version": "1.3.86-1", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -43,7 +43,6 @@ "@types/node": "^18.14.0", "@ua/react-native-airship": "^15.2.6", "awesome-phonenumber": "^5.4.0", - "babel-plugin-transform-remove-console": "^6.9.4", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", "core-js": "^3.32.0", @@ -51,7 +50,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", + "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", "fbjs": "^3.0.2", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", @@ -138,8 +137,6 @@ "@babel/runtime": "^7.20.0", "@electron/notarize": "^1.2.3", "@jest/globals": "^29.5.0", - "@kie/act-js": "^2.0.1", - "@kie/mock-github": "^1.0.0", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", "@octokit/plugin-throttling": "4.1.0", @@ -222,7 +219,7 @@ "react-native-performance-flipper-reporter": "^2.0.0", "react-native-svg-transformer": "^1.0.0", "react-test-renderer": "18.2.0", - "reassure": "^0.9.0", + "reassure": "^0.10.1", "setimmediate": "^1.0.5", "shellcheck": "^1.1.0", "style-loader": "^2.0.0", @@ -2628,12 +2625,12 @@ "license": "Apache-2.0" }, "node_modules/@callstack/reassure-cli": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.9.1.tgz", - "integrity": "sha512-ctETa5REyA1KM50Q9MMdy9oLqMK1eQp3Uc5cmx1VNQrAY678xCqIbiK4Hi3r5kZeq9k+JzsRgs9j+h6yrP8Lyw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.10.0.tgz", + "integrity": "sha512-CYgOGOAWcFgA2GrJw6RJAvImCpHCpPbtPoYMDol7esjlRCX2QwIKG7/9byq47hML57w94fhFAa76KD84YlgMBg==", "dev": true, "dependencies": { - "@callstack/reassure-compare": "0.5.1", + "@callstack/reassure-compare": "0.6.0", "@callstack/reassure-logger": "0.3.1", "chalk": "4.1.2", "simple-git": "^3.16.0", @@ -2764,9 +2761,9 @@ } }, "node_modules/@callstack/reassure-compare": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.5.1.tgz", - "integrity": "sha512-w3/W+1N8pNSdmoT0EZ0fTnhxqeIfkqTrLTrIGQQTgPbaekCSbvojG9eceHQ+XOsZfM3Y9tgDS5Uwx6k9h0JY5g==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.6.0.tgz", + "integrity": "sha512-P3nmv36CJrQSXg0+z6EuEV/0xAbvxWbAZ7diQHnkbvqk2z8PKRXpkcthrRUpe02wLewa0MLxBUJwLenFnhxIRg==", "dev": true, "dependencies": { "@callstack/reassure-logger": "0.3.1", @@ -2861,9 +2858,9 @@ } }, "node_modules/@callstack/reassure-measure": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.5.1.tgz", - "integrity": "sha512-M1tdWKoT2SGQYkITwFWlDiM/yZ+a2cbHSnuu3nEiyFn6YQHpL9FKDIIJjP6nCjHBk4ERj411mpO2Ss927KFu4Q==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.6.0.tgz", + "integrity": "sha512-phXY5DAtKhnu8dA2pmnl+pqFOfrVEFFDJOi4AnObwIcpDSn3IUXgNSe7rSi+JP/mXNWMLoUS8rnH4iIFDyf7qQ==", "dev": true, "dependencies": { "@callstack/reassure-logger": "0.3.1", @@ -5465,7 +5462,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.3.0.tgz", "integrity": "sha512-Q9k0b05uA46jXKWmVfoGDW+0xsCcE7QPiHi8IH7h41P36DujHKBj4k28RCeIEx3IwUCxYHKwubN8DH4Vzc9XcA==", - "dev": true, "hasInstallScript": true, "dependencies": { "@kie/mock-github": "^2.0.0", @@ -5485,7 +5481,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.0.tgz", "integrity": "sha512-od6UyICJYKMnz9HgEWCQAFT/JsCpKkLp+JQH8fV23tf+ZmmQI1dK3C20k6aO5uJhAHA0yOcFtbKFVF4+8i3DTg==", - "dev": true, "dependencies": { "@octokit/openapi-types-ghec": "^18.0.0", "ajv": "^8.11.0", @@ -5500,14 +5495,12 @@ "node_modules/@kie/act-js/node_modules/@octokit/openapi-types-ghec": { "version": "18.1.1", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.1.1.tgz", - "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==", - "dev": true + "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==" }, "node_modules/@kie/act-js/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5521,7 +5514,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, "engines": { "node": ">=6" } @@ -5530,7 +5522,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-1.1.0.tgz", "integrity": "sha512-fD+utlOiyZSOutOcXL0G9jfjbtvOO44PLUyTfgfkrm1+575R/dbvU6AcJfjc1DtHeRv7FC7f4ebyU+a1wgL6CA==", - "dev": true, "dependencies": { "@octokit/openapi-types-ghec": "^14.0.0", "ajv": "^8.11.0", @@ -5546,7 +5537,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5560,7 +5550,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, "engines": { "node": ">=6" } @@ -5569,7 +5558,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, "dependencies": { "debug": "^4.1.1" } @@ -5577,8 +5565,7 @@ "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", @@ -5957,7 +5944,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -5971,7 +5957,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -5981,7 +5966,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -6112,8 +6096,7 @@ "node_modules/@octokit/openapi-types-ghec": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-14.0.0.tgz", - "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==", - "dev": true + "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==" }, "node_modules/@octokit/plugin-paginate-rest": { "version": "3.1.0", @@ -21218,7 +21201,6 @@ "version": "0.5.10", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", - "dev": true, "engines": { "node": ">=6.0" } @@ -21849,7 +21831,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true, "license": "MIT" }, "node_modules/array-includes": { @@ -23292,7 +23273,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz", "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==", - "dev": true, "dependencies": { "cmd-shim": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -23307,7 +23287,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -23319,7 +23298,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -23402,7 +23380,6 @@ }, "node_modules/body-parser": { "version": "1.20.0", - "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -23427,7 +23404,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -23437,7 +23413,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -23447,7 +23422,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -23460,7 +23434,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/bonjour-service": { @@ -24536,7 +24509,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -24965,7 +24937,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", - "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -25408,7 +25379,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -25421,7 +25391,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -25440,7 +25409,6 @@ }, "node_modules/content-type": { "version": "1.0.4", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25455,7 +25423,6 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25465,7 +25432,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true, "license": "MIT" }, "node_modules/copy-concurrently": { @@ -30223,8 +30189,8 @@ }, "node_modules/expensify-common": { "version": "1.0.0", - "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", - "integrity": "sha512-mD9p6Qj8FfvLdb6JLXvF0UNqLN6ymssUU67Fm37zmK18hd1Abw+vR/pQkNpHR2iv+KRs8HdcyuZ0vaOec4VrFQ==", + "resolved": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", + "integrity": "sha512-/kXD/18YQJY/iWB5MOSN0ixB1mpxUA+NXEYgKjac1tJd+DoY3K6+bDeu++Qfqg26LCNfvjTkjkDGZVdGsJQ7Hw==", "license": "MIT", "dependencies": { "classnames": "2.3.1", @@ -30320,7 +30286,6 @@ }, "node_modules/express": { "version": "4.18.1", - "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -30363,7 +30328,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -30373,14 +30337,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -30582,7 +30544,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -30667,7 +30628,6 @@ }, "node_modules/fastq": { "version": "1.13.0", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -30901,7 +30861,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -30920,7 +30879,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -30930,7 +30888,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/find-babel-config": { @@ -31117,7 +31074,6 @@ "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", - "dev": true, "funding": [ { "type": "individual", @@ -31378,7 +31334,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -31455,7 +31410,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -31720,7 +31674,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -33540,7 +33493,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -33865,7 +33817,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -33941,7 +33892,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -37368,7 +37318,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, "license": "ISC" }, "node_modules/json5": { @@ -38884,7 +38833,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -39124,7 +39072,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true, "license": "MIT" }, "node_modules/merge-options": { @@ -39160,7 +39107,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -39170,7 +39116,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -41067,7 +41012,6 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -41118,7 +41062,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, "license": "MIT", "dependencies": { "minipass": "^3.0.0", @@ -41215,7 +41158,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" @@ -41451,7 +41393,6 @@ "version": "13.3.3", "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", - "dev": true, "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", @@ -41681,7 +41622,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -42893,7 +42833,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true, "license": "MIT" }, "node_modules/path-type": { @@ -43610,7 +43549,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true, "engines": { "node": ">= 8" } @@ -43638,7 +43576,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -43926,7 +43863,6 @@ "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -43987,7 +43923,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -44069,7 +44004,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -44085,7 +44019,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -44095,7 +44028,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -45947,7 +45879,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", - "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -46194,14 +46125,14 @@ "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" }, "node_modules/reassure": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.9.1.tgz", - "integrity": "sha512-puPHh4LvDw9FJln58qpkwMDrkiAGO6E+QYe93Znotolefm2kzGytebklxd+z/ULKqL2e8eyDj51RqFOpwY/Ecw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.10.1.tgz", + "integrity": "sha512-+GANr5ojh32NZu1YGfa6W8vIJm3iOIZJUvXT5Gc9fQyre7okYsCzyBq9WsHbnAQDjNq1g9SsM/4bwcVET9OIqA==", "dev": true, "dependencies": { - "@callstack/reassure-cli": "0.9.1", + "@callstack/reassure-cli": "0.10.0", "@callstack/reassure-danger": "0.1.1", - "@callstack/reassure-measure": "0.5.1" + "@callstack/reassure-measure": "0.6.0" } }, "node_modules/recast": { @@ -47102,7 +47033,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -47197,7 +47127,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -47932,7 +47861,6 @@ "version": "3.19.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.0.tgz", "integrity": "sha512-hyH2p9Ptxjf/xPuL7HfXbpYt9gKhC1yWDh3KYIAYJJePAKV7AEjLN4xhp7lozOdNiaJ9jlVvAbBymVlcS2jRiA==", - "dev": true, "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", @@ -49474,7 +49402,6 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -49491,7 +49418,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -50323,7 +50249,6 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -54882,12 +54807,12 @@ "dev": true }, "@callstack/reassure-cli": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.9.1.tgz", - "integrity": "sha512-ctETa5REyA1KM50Q9MMdy9oLqMK1eQp3Uc5cmx1VNQrAY678xCqIbiK4Hi3r5kZeq9k+JzsRgs9j+h6yrP8Lyw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@callstack/reassure-cli/-/reassure-cli-0.10.0.tgz", + "integrity": "sha512-CYgOGOAWcFgA2GrJw6RJAvImCpHCpPbtPoYMDol7esjlRCX2QwIKG7/9byq47hML57w94fhFAa76KD84YlgMBg==", "dev": true, "requires": { - "@callstack/reassure-compare": "0.5.1", + "@callstack/reassure-compare": "0.6.0", "@callstack/reassure-logger": "0.3.1", "chalk": "4.1.2", "simple-git": "^3.16.0", @@ -54984,9 +54909,9 @@ } }, "@callstack/reassure-compare": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.5.1.tgz", - "integrity": "sha512-w3/W+1N8pNSdmoT0EZ0fTnhxqeIfkqTrLTrIGQQTgPbaekCSbvojG9eceHQ+XOsZfM3Y9tgDS5Uwx6k9h0JY5g==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@callstack/reassure-compare/-/reassure-compare-0.6.0.tgz", + "integrity": "sha512-P3nmv36CJrQSXg0+z6EuEV/0xAbvxWbAZ7diQHnkbvqk2z8PKRXpkcthrRUpe02wLewa0MLxBUJwLenFnhxIRg==", "dev": true, "requires": { "@callstack/reassure-logger": "0.3.1", @@ -55062,9 +54987,9 @@ } }, "@callstack/reassure-measure": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.5.1.tgz", - "integrity": "sha512-M1tdWKoT2SGQYkITwFWlDiM/yZ+a2cbHSnuu3nEiyFn6YQHpL9FKDIIJjP6nCjHBk4ERj411mpO2Ss927KFu4Q==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@callstack/reassure-measure/-/reassure-measure-0.6.0.tgz", + "integrity": "sha512-phXY5DAtKhnu8dA2pmnl+pqFOfrVEFFDJOi4AnObwIcpDSn3IUXgNSe7rSi+JP/mXNWMLoUS8rnH4iIFDyf7qQ==", "dev": true, "requires": { "@callstack/reassure-logger": "0.3.1", @@ -56888,7 +56813,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.3.0.tgz", "integrity": "sha512-Q9k0b05uA46jXKWmVfoGDW+0xsCcE7QPiHi8IH7h41P36DujHKBj4k28RCeIEx3IwUCxYHKwubN8DH4Vzc9XcA==", - "dev": true, "requires": { "@kie/mock-github": "^2.0.0", "adm-zip": "^0.5.10", @@ -56904,7 +56828,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.0.tgz", "integrity": "sha512-od6UyICJYKMnz9HgEWCQAFT/JsCpKkLp+JQH8fV23tf+ZmmQI1dK3C20k6aO5uJhAHA0yOcFtbKFVF4+8i3DTg==", - "dev": true, "requires": { "@octokit/openapi-types-ghec": "^18.0.0", "ajv": "^8.11.0", @@ -56919,14 +56842,12 @@ "@octokit/openapi-types-ghec": { "version": "18.1.1", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.1.1.tgz", - "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==", - "dev": true + "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==" }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -56936,8 +56857,7 @@ "totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" } } }, @@ -56945,7 +56865,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-1.1.0.tgz", "integrity": "sha512-fD+utlOiyZSOutOcXL0G9jfjbtvOO44PLUyTfgfkrm1+575R/dbvU6AcJfjc1DtHeRv7FC7f4ebyU+a1wgL6CA==", - "dev": true, "requires": { "@octokit/openapi-types-ghec": "^14.0.0", "ajv": "^8.11.0", @@ -56961,7 +56880,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -56971,8 +56889,7 @@ "totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" } } }, @@ -56980,7 +56897,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dev": true, "requires": { "debug": "^4.1.1" } @@ -56988,8 +56904,7 @@ "@kwsites/promise-deferred": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "dev": true + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "@leichtgewicht/ip-codec": { "version": "2.0.4", @@ -57271,7 +57186,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -57280,14 +57194,12 @@ "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -57399,8 +57311,7 @@ "@octokit/openapi-types-ghec": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-14.0.0.tgz", - "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==", - "dev": true + "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==" }, "@octokit/plugin-paginate-rest": { "version": "3.1.0", @@ -68313,8 +68224,7 @@ "adm-zip": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", - "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", - "dev": true + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" }, "agent-base": { "version": "6.0.2", @@ -68792,8 +68702,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { "version": "3.1.6", @@ -69849,7 +69758,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz", "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==", - "dev": true, "requires": { "cmd-shim": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -69860,14 +69768,12 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" }, "write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "dev": true, "requires": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -69940,7 +69846,6 @@ }, "body-parser": { "version": "1.20.0", - "dev": true, "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -69959,14 +69864,12 @@ "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -69975,7 +69878,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -69983,8 +69885,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -70751,8 +70652,7 @@ "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "chrome-trace-event": { "version": "1.0.3", @@ -71053,8 +70953,7 @@ "cmd-shim": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", - "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", - "dev": true + "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==" }, "co": { "version": "4.6.0", @@ -71388,7 +71287,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, "requires": { "safe-buffer": "5.2.1" }, @@ -71396,14 +71294,12 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, "content-type": { - "version": "1.0.4", - "dev": true + "version": "1.0.4" }, "convert-source-map": { "version": "1.9.0", @@ -71413,14 +71309,12 @@ "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "copy-concurrently": { "version": "1.0.5", @@ -74880,9 +74774,9 @@ } }, "expensify-common": { - "version": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", - "integrity": "sha512-mD9p6Qj8FfvLdb6JLXvF0UNqLN6ymssUU67Fm37zmK18hd1Abw+vR/pQkNpHR2iv+KRs8HdcyuZ0vaOec4VrFQ==", - "from": "expensify-common@git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", + "version": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", + "integrity": "sha512-/kXD/18YQJY/iWB5MOSN0ixB1mpxUA+NXEYgKjac1tJd+DoY3K6+bDeu++Qfqg26LCNfvjTkjkDGZVdGsJQ7Hw==", + "from": "expensify-common@git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", "requires": { "classnames": "2.3.1", "clipboard": "2.0.4", @@ -74954,7 +74848,6 @@ }, "express": { "version": "4.18.1", - "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -74993,7 +74886,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -75001,14 +74893,12 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, @@ -75148,7 +75038,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -75207,7 +75096,6 @@ }, "fastq": { "version": "1.13.0", - "dev": true, "requires": { "reusify": "^1.0.4" } @@ -75386,7 +75274,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -75401,7 +75288,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -75409,8 +75295,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -75548,8 +75433,7 @@ "follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", - "dev": true + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" }, "for-each": { "version": "0.3.3", @@ -75715,8 +75599,7 @@ "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fraction.js": { "version": "4.3.4", @@ -75768,7 +75651,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, "requires": { "minipass": "^3.0.0" } @@ -75951,7 +75833,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, "requires": { "is-glob": "^4.0.1" } @@ -77241,8 +77122,7 @@ "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "is-absolute-url": { "version": "3.0.3", @@ -77437,8 +77317,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-finalizationregistry": { "version": "1.0.2", @@ -77485,7 +77364,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, "requires": { "is-extglob": "^2.1.1" } @@ -79896,8 +79774,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { "version": "2.2.3", @@ -81020,8 +80897,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "mem": { "version": "8.1.1", @@ -81196,8 +81072,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-options": { "version": "3.0.4", @@ -81223,14 +81098,12 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "metro": { "version": "0.76.8", @@ -82593,7 +82466,6 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -82629,7 +82501,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -82703,8 +82574,7 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "mock-fs": { "version": "4.14.0", @@ -82876,7 +82746,6 @@ "version": "13.3.3", "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", - "dev": true, "requires": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", @@ -83052,8 +82921,7 @@ "npm-normalize-package-bin": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==" }, "npm-run-path": { "version": "4.0.1", @@ -83899,8 +83767,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "4.0.0", @@ -84405,8 +84272,7 @@ "propagate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==" }, "property-information": { "version": "5.6.0", @@ -84426,7 +84292,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, "requires": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -84643,7 +84508,6 @@ "version": "6.10.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, "requires": { "side-channel": "^1.0.4" } @@ -84684,8 +84548,7 @@ "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "quick-lru": { "version": "5.1.1", @@ -84735,7 +84598,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, "requires": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -84746,14 +84608,12 @@ "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -86004,8 +85864,7 @@ "read-cmd-shim": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", - "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", - "dev": true + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==" }, "read-config-file": { "version": "6.3.2", @@ -86191,14 +86050,14 @@ "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==" }, "reassure": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.9.1.tgz", - "integrity": "sha512-puPHh4LvDw9FJln58qpkwMDrkiAGO6E+QYe93Znotolefm2kzGytebklxd+z/ULKqL2e8eyDj51RqFOpwY/Ecw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/reassure/-/reassure-0.10.1.tgz", + "integrity": "sha512-+GANr5ojh32NZu1YGfa6W8vIJm3iOIZJUvXT5Gc9fQyre7okYsCzyBq9WsHbnAQDjNq1g9SsM/4bwcVET9OIqA==", "dev": true, "requires": { - "@callstack/reassure-cli": "0.9.1", + "@callstack/reassure-cli": "0.10.0", "@callstack/reassure-danger": "0.1.1", - "@callstack/reassure-measure": "0.5.1" + "@callstack/reassure-measure": "0.6.0" } }, "recast": { @@ -86860,8 +86719,7 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "right-align": { "version": "0.1.3", @@ -86926,7 +86784,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -87472,7 +87329,6 @@ "version": "3.19.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.0.tgz", "integrity": "sha512-hyH2p9Ptxjf/xPuL7HfXbpYt9gKhC1yWDh3KYIAYJJePAKV7AEjLN4xhp7lozOdNiaJ9jlVvAbBymVlcS2jRiA==", - "dev": true, "requires": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", @@ -88623,7 +88479,6 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -88636,8 +88491,7 @@ "minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" } } }, @@ -89234,7 +89088,6 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.24" diff --git a/package.json b/package.json index 58d768d7721b3..7d540c0d35069 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.3.84-1", + "version": "1.3.86-1", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", @@ -90,7 +90,6 @@ "@types/node": "^18.14.0", "@ua/react-native-airship": "^15.2.6", "awesome-phonenumber": "^5.4.0", - "babel-plugin-transform-remove-console": "^6.9.4", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", "core-js": "^3.32.0", @@ -98,7 +97,7 @@ "date-fns-tz": "^2.0.0", "dom-serializer": "^0.2.2", "domhandler": "^4.3.0", - "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#009c2ab79bf7ddeab0eea7a3a4c0d9cc4277c34b", + "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#bdbdf44825658500ba581d3e86237d7b8996cc2e", "fbjs": "^3.0.2", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", @@ -185,8 +184,6 @@ "@babel/runtime": "^7.20.0", "@electron/notarize": "^1.2.3", "@jest/globals": "^29.5.0", - "@kie/act-js": "^2.0.1", - "@kie/mock-github": "^1.0.0", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", "@octokit/plugin-throttling": "4.1.0", @@ -269,7 +266,7 @@ "react-native-performance-flipper-reporter": "^2.0.0", "react-native-svg-transformer": "^1.0.0", "react-test-renderer": "18.2.0", - "reassure": "^0.9.0", + "reassure": "^0.10.1", "setimmediate": "^1.0.5", "shellcheck": "^1.1.0", "style-loader": "^2.0.0", diff --git a/src/libs/E2E/API.mock.js b/src/libs/E2E/API.mock.js index 0d517eb9b6e24..47f445f72222d 100644 --- a/src/libs/E2E/API.mock.js +++ b/src/libs/E2E/API.mock.js @@ -9,7 +9,6 @@ import mockSigninUser from './apiMocks/signinUser'; import mockAuthenticatePusher from './apiMocks/authenticatePusher'; import mockOpenApp from './apiMocks/openApp'; import mockOpenReport from './apiMocks/openReport'; -import mockSignInAttemptState from './apiMocks/signInAttemptState'; /** * A dictionary which has the name of a API command as key, and a function which @@ -23,15 +22,10 @@ const mocks = { ReconnectApp: mockOpenApp, OpenReport: mockOpenReport, AuthenticatePusher: mockAuthenticatePusher, - SignInAttemptState: mockSignInAttemptState, }; function mockCall(command, apiCommandParameters, tag) { const mockResponse = mocks[command] && mocks[command](apiCommandParameters); - Log.warn('🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐'); - Log.warn('🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐'); - Log.warn(`Mock Call to ${command}`); - Log.warn('🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐🫐'); if (!mockResponse || !_.isArray(mockResponse.onyxData)) { Log.warn(`[${tag}] for command ${command} is not mocked yet!`); return; diff --git a/src/libs/E2E/apiMocks/beginSignin.js b/src/libs/E2E/apiMocks/beginSignin.js index 7d457b66ce68a..44e68ef589928 100644 --- a/src/libs/E2E/apiMocks/beginSignin.js +++ b/src/libs/E2E/apiMocks/beginSignin.js @@ -12,7 +12,6 @@ export default ({email}) => ({ key: 'account', value: { validated: true, - hasEmailDeliveryFailure: false, }, }, { diff --git a/src/libs/E2E/apiMocks/signInAttemptState.js b/src/libs/E2E/apiMocks/signInAttemptState.js deleted file mode 100644 index 575bfbb5f030e..0000000000000 --- a/src/libs/E2E/apiMocks/signInAttemptState.js +++ /dev/null @@ -1,21 +0,0 @@ -export default ({email}) => ({ - onyxData: [ - { - onyxMethod: 'merge', - key: 'account', - value: { - isLoading: false, - loadingForm: null, - }, - }, - { - onyxMethod: 'merge', - key: 'credenttials', - value: { - validateCode: null, - }, - }, - ], - jsonCode: 200, - requestID: '783e54ef4b38cff5-SJC', -}); diff --git a/src/libs/E2E/apiMocks/signinUser.js b/src/libs/E2E/apiMocks/signinUser.js index 3ba19d07deb75..26203bc492cfa 100644 --- a/src/libs/E2E/apiMocks/signinUser.js +++ b/src/libs/E2E/apiMocks/signinUser.js @@ -115,7 +115,6 @@ export default ({email}) => ({ key: 'account', value: { requiresTwoFactorAuth: false, - hasEmailDeliveryFailure: false, }, }, ], diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index 5709abf452f1f..8aae45c279c67 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -113,11 +113,7 @@ function getRenderOptions({hasLogin, hasValidateCode, account, isPrimaryLogin, i } const shouldShowLoginForm = isClientTheLeader && !hasLogin && !hasValidateCode; - console.warn('🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏'); - console.warn('🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏'); - console.warn('🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏'); const shouldShowEmailDeliveryFailurePage = hasLogin && hasEmailDeliveryFailure && !shouldShowChooseSSOOrMagicCode && !shouldInitiateSAMLLogin; - console.warn({shouldShowEmailDeliveryFailurePage, hasLogin, hasEmailDeliveryFailure}); const isUnvalidatedSecondaryLogin = hasLogin && !isPrimaryLogin && !account.validated && !hasEmailDeliveryFailure; const shouldShowValidateCodeForm = hasAccount && (hasLogin || hasValidateCode) && !isUnvalidatedSecondaryLogin && !hasEmailDeliveryFailure && !shouldShowChooseSSOOrMagicCode && !isSAMLRequired; diff --git a/tests/e2e/utils/execAsync.js b/tests/e2e/utils/execAsync.js index 4d92ac0b021f7..50ae76b500f54 100644 --- a/tests/e2e/utils/execAsync.js +++ b/tests/e2e/utils/execAsync.js @@ -1,5 +1,5 @@ const {exec} = require('child_process'); -const _ = require('underscore'); +// const _ = require('underscore'); const Logger = require('./logger'); /** @@ -17,9 +17,9 @@ module.exports = (command, env = {}) => { ...env, }; - if (_.keys(env).length !== 0) { - Logger.log(`environment variables:`, JSON.stringify(finalEnv, null, 2)); - } + // if (_.keys(env).length !== 0) { + // Logger.log(`environment variables:`, JSON.stringify(finalEnv, null, 2)); + // } Logger.important(command); From 25fe137b4585ea2a28aad213bd17b460bb27fa31 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 12:53:59 +0200 Subject: [PATCH 25/39] Add an attempt to log errors on github actions --- .github/workflows/e2ePerformanceTests.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 4c24f6a73b2a3..d6d32b6c65099 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -167,6 +167,7 @@ jobs: - name: Schedule AWS Device Farm test run on main branch uses: realm/aws-devicefarm/test-application@7b9a91236c456c97e28d384c9e476035d5ea686b + id: schedule-awsdf-main with: name: App E2E Performance Regression Tests project_arn: ${{ secrets.AWS_PROJECT_ARN }} @@ -180,8 +181,16 @@ jobs: test_spec_type: APPIUM_NODE_TEST_SPEC remote_src: false file_artifacts: Customer Artifacts.zip + log_artifacts: debug.log cleanup: true + - name: Print logs if run failed + if: failure() + run: | + echo ${{ steps.schedule-awsdf-main.outputs.data }} + unzip "Customer Artifacts.zip" -d mainResults + cat ./mainResults/Host_Machine_Files/\$WORKING_DIRECTORY/debug.log + - name: Unzip AWS Device Farm main results run: unzip "Customer Artifacts.zip" -d mainResults From 58ffed698551944773642ede9e6ea6f4bd79c973 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Thu, 19 Oct 2023 15:46:15 +0200 Subject: [PATCH 26/39] Try both ts replace and js replace on the mock api metro config --- metro.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metro.config.js b/metro.config.js index 06ce5bacc4023..8d659aa649223 100644 --- a/metro.config.js +++ b/metro.config.js @@ -28,7 +28,7 @@ const config = { return { ...resolution, // TODO: Change API.mock.js extension once it is migrated to TypeScript - filePath: resolution.filePath.replace(/src\/libs\/API.ts/, 'src/libs/E2E/API.mock.js'), + filePath: resolution.filePath.replace(/src\/libs\/API.ts/, 'src/libs/E2E/API.mock.js').replace(/src\/libs\/API.js/, 'src/libs/E2E/API.mock.js'), }; } return resolution; From 809355f5260090f643e9e6217a9ea098120d4a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Thu, 19 Oct 2023 18:28:19 +0200 Subject: [PATCH 27/39] add logging for replacing mock API --- metro.config.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/metro.config.js b/metro.config.js index 8d659aa649223..14e0a0fe8a0f9 100644 --- a/metro.config.js +++ b/metro.config.js @@ -25,10 +25,13 @@ const config = { resolveRequest: (context, moduleName, platform) => { const resolution = context.resolveRequest(context, moduleName, platform); if (isUsingMockAPI && moduleName.includes('/API')) { + const originalPath = resolution.filePath; + const mockPath = originalPath.replace('src/libs/API.ts', 'src/libs/E2E/API.mock.js').replace('/src/libs/API.js/', 'src/libs/E2E/API.mock.js'); + console.debug('> Replace', originalPath, ' => ', mockPath); + return { ...resolution, - // TODO: Change API.mock.js extension once it is migrated to TypeScript - filePath: resolution.filePath.replace(/src\/libs\/API.ts/, 'src/libs/E2E/API.mock.js').replace(/src\/libs\/API.js/, 'src/libs/E2E/API.mock.js'), + filePath: mockPath, }; } return resolution; From fb4b503e0c73ab967dd3bb468e4f78771d311666 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Fri, 20 Oct 2023 05:45:07 +0200 Subject: [PATCH 28/39] Add more logs to metro config --- metro.config.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/metro.config.js b/metro.config.js index 14e0a0fe8a0f9..818fbf5ad2274 100644 --- a/metro.config.js +++ b/metro.config.js @@ -7,6 +7,10 @@ require('dotenv').config(); const defaultConfig = getDefaultConfig(__dirname); const isUsingMockAPI = process.env.E2E_TESTING === 'true'; +// eslint-disable-next-line no-console +console.log(typeof process.env.E2E_TESTING); +// eslint-disable-next-line no-console +console.log(process.env.E2E_TESTING); if (isUsingMockAPI) { // eslint-disable-next-line no-console console.log('⚠️ Using mock API'); @@ -24,10 +28,13 @@ const config = { sourceExts: [...defaultSourceExts, 'jsx', 'svg'], resolveRequest: (context, moduleName, platform) => { const resolution = context.resolveRequest(context, moduleName, platform); + // eslint-disable-next-line no-console + console.log(`🟠 resolving module name ${moduleName} original path: ${resolution.filePath}`); if (isUsingMockAPI && moduleName.includes('/API')) { const originalPath = resolution.filePath; const mockPath = originalPath.replace('src/libs/API.ts', 'src/libs/E2E/API.mock.js').replace('/src/libs/API.js/', 'src/libs/E2E/API.mock.js'); - console.debug('> Replace', originalPath, ' => ', mockPath); + // eslint-disable-next-line no-console + console.log('🔴 Replace', originalPath, ' => ', mockPath); return { ...resolution, From 744323a21b05e2b9a6cf7a0f4be6e634d5ebc548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Fri, 20 Oct 2023 07:36:33 +0200 Subject: [PATCH 29/39] test: skip checking out release version --- .github/workflows/e2ePerformanceTests.yml | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index d6d32b6c65099..41ef9e62526a8 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -30,21 +30,21 @@ jobs: env: GITHUB_TOKEN: ${{ github.token }} - - name: Check if there's an existing artifact for this baseline - id: checkForExistingArtifact - uses: xSAVIKx/artifact-exists-action@3c5206b1411c0d2fc0840f56b7140646933d9d6a - with: - name: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} - - - name: Skip build if there's already an existing artifact for the baseline - if: ${{ fromJSON(steps.checkForExistingArtifact.outputs.exists) }} - run: echo 'APK for baseline ${{ steps.getMostRecentRelease.outputs.VERSION }} already exists, reusing existing build' - - - name: Checkout "Baseline" commit (last release) - if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} - run: | - git fetch origin tag ${{ steps.getMostRecentRelease.outputs.VERSION }} --no-tags --depth=1 - git switch --detach ${{ steps.getMostRecentRelease.outputs.VERSION }} + # - name: Check if there's an existing artifact for this baseline + # id: checkForExistingArtifact + # uses: xSAVIKx/artifact-exists-action@3c5206b1411c0d2fc0840f56b7140646933d9d6a + # with: + # name: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} + + # - name: Skip build if there's already an existing artifact for the baseline + # if: ${{ fromJSON(steps.checkForExistingArtifact.outputs.exists) }} + # run: echo 'APK for baseline ${{ steps.getMostRecentRelease.outputs.VERSION }} already exists, reusing existing build' + + # - name: Checkout "Baseline" commit (last release) + # if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} + # run: | + # git fetch origin tag ${{ steps.getMostRecentRelease.outputs.VERSION }} --no-tags --depth=1 + # git switch --detach ${{ steps.getMostRecentRelease.outputs.VERSION }} - name: Configure MapBox SDK run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} From 57db0ac6d9e552087410a540030e8637bfbfdd53 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Fri, 20 Oct 2023 07:58:13 +0200 Subject: [PATCH 30/39] Remove check for previous artifacts --- .github/workflows/e2ePerformanceTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 41ef9e62526a8..10351f7cacfdc 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -50,7 +50,7 @@ jobs: run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} - name: Build APK - if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} + # if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} uses: Expensify/App/.github/actions/composite/buildAndroidAPK@main with: ARTIFACT_NAME: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} From 7b245f4df08903e3c2523d55ed347573bdab3ab1 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Fri, 20 Oct 2023 10:29:30 +0200 Subject: [PATCH 31/39] Do not use extended name on generated baseline apk --- .github/workflows/e2ePerformanceTests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 10351f7cacfdc..3c1e499d491b0 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -24,11 +24,11 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Get most recent release version - id: getMostRecentRelease - run: echo "VERSION=$(gh release list --limit 1 | awk '{ print $1 }')" >> "$GITHUB_OUTPUT" - env: - GITHUB_TOKEN: ${{ github.token }} + # - name: Get most recent release version + # id: getMostRecentRelease + # run: echo "VERSION=$(gh release list --limit 1 | awk '{ print $1 }')" >> "$GITHUB_OUTPUT" + # env: + # GITHUB_TOKEN: ${{ github.token }} # - name: Check if there's an existing artifact for this baseline # id: checkForExistingArtifact @@ -53,7 +53,7 @@ jobs: # if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} uses: Expensify/App/.github/actions/composite/buildAndroidAPK@main with: - ARTIFACT_NAME: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} + ARTIFACT_NAME: baseline-apk buildDelta: runs-on: ubuntu-latest-xl From 5a90797bb892992713f2e82397e6e8c884aaf8cd Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Fri, 20 Oct 2023 10:30:31 +0200 Subject: [PATCH 32/39] Simple script to trigger an aws device farm run --- tests/e2e/manually_trigger_aws_df.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100755 tests/e2e/manually_trigger_aws_df.sh diff --git a/tests/e2e/manually_trigger_aws_df.sh b/tests/e2e/manually_trigger_aws_df.sh new file mode 100755 index 0000000000000..bf0356a179038 --- /dev/null +++ b/tests/e2e/manually_trigger_aws_df.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +set -ex + +PROJECT_ARN=arn:aws:devicefarm:us-west-2:015174472939:project:741d1dac-84e7-4c6f-84ed-b41a2209319d +DEVICE_POOL_ARN=arn:aws:devicefarm:us-west-2:015174472939:devicepool:741d1dac-84e7-4c6f-84ed-b41a2209319d/efa4b3bb-85ef-45f2-a063-14393eb4d2c2 +UPLOAD_ARN=arn:aws:devicefarm:us-west-2:015174472939:upload:741d1dac-84e7-4c6f-84ed-b41a2209319d/e65b711b-9dba-45dd-aeb4-e7c0449bccc8 +TEST_SPEC_ARN=arn:aws:devicefarm:us-west-2:015174472939:upload:741d1dac-84e7-4c6f-84ed-b41a2209319d/8e694a23-1dbb-40ff-a0ef-a8077dbfa729 +TEST_PACKAGE_ARN=arn:aws:devicefarm:us-west-2:015174472939:upload:741d1dac-84e7-4c6f-84ed-b41a2209319d/6d61e606-5450-43f2-be94-0bee759569e5 + +aws devicefarm schedule-run --project-arn "${PROJECT_ARN}" --app-arn "${UPLOAD_ARN}" --device-pool-arn "${DEVICE_POOL_ARN}" --name "Test run" --test type=APPIUM_NODE,testPackageArn="${TEST_PACKAGE_ARN}",testSpecArn="${TEST_SPEC_ARN}" +# aws devicefarm list-uploads --arn "${PROJECT_ARN}" +# +# aws devicefarm create-upload --name TestSpecMain.yml --type APPIUM_NODE_TEST_SPEC --project-arn "${PROJECT_ARN}" \ No newline at end of file From bbcad6641c828a30daf2eed13178f62ce3d0bb90 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Fri, 20 Oct 2023 13:29:53 +0200 Subject: [PATCH 33/39] Remove logging on replaced paths --- metro.config.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/metro.config.js b/metro.config.js index 818fbf5ad2274..62ca2a25c6b24 100644 --- a/metro.config.js +++ b/metro.config.js @@ -7,13 +7,10 @@ require('dotenv').config(); const defaultConfig = getDefaultConfig(__dirname); const isUsingMockAPI = process.env.E2E_TESTING === 'true'; -// eslint-disable-next-line no-console -console.log(typeof process.env.E2E_TESTING); -// eslint-disable-next-line no-console -console.log(process.env.E2E_TESTING); + if (isUsingMockAPI) { // eslint-disable-next-line no-console - console.log('⚠️ Using mock API'); + console.log('⚠️⚠️⚠️⚠️ Using mock API ⚠️⚠️⚠️⚠️'); } /** @@ -28,13 +25,11 @@ const config = { sourceExts: [...defaultSourceExts, 'jsx', 'svg'], resolveRequest: (context, moduleName, platform) => { const resolution = context.resolveRequest(context, moduleName, platform); - // eslint-disable-next-line no-console - console.log(`🟠 resolving module name ${moduleName} original path: ${resolution.filePath}`); if (isUsingMockAPI && moduleName.includes('/API')) { const originalPath = resolution.filePath; const mockPath = originalPath.replace('src/libs/API.ts', 'src/libs/E2E/API.mock.js').replace('/src/libs/API.js/', 'src/libs/E2E/API.mock.js'); // eslint-disable-next-line no-console - console.log('🔴 Replace', originalPath, ' => ', mockPath); + console.log('⚠️⚠️⚠️⚠️ Replacing resolution path', originalPath, ' => ', mockPath); return { ...resolution, From 301221f9158e8159ad820b737bb47640e4744ce9 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Fri, 20 Oct 2023 13:41:15 +0200 Subject: [PATCH 34/39] Fix name of download in baseline apk --- .github/workflows/e2ePerformanceTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 3c1e499d491b0..dca78185c6070 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -135,7 +135,7 @@ jobs: uses: actions/download-artifact@e9ef242655d12993efdcda9058dee2db83a2cb9b id: downloadBaselineAPK with: - name: baseline-apk-${{ needs.buildBaseline.outputs.VERSION }} + name: baseline-apk path: zip # The downloaded artifact will be a file named "app-e2e-release.apk" so we have to rename it From 4fcdc0cf9ffae13596106bde1f129d7bcfa36a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Fri, 20 Oct 2023 15:19:44 +0200 Subject: [PATCH 35/39] correct actions for e2e workflow --- .github/workflows/e2ePerformanceTests.yml | 68 +++++++++++------------ 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index dca78185c6070..74c34c3fa277f 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -24,27 +24,27 @@ jobs: steps: - uses: actions/checkout@v3 - # - name: Get most recent release version - # id: getMostRecentRelease - # run: echo "VERSION=$(gh release list --limit 1 | awk '{ print $1 }')" >> "$GITHUB_OUTPUT" - # env: - # GITHUB_TOKEN: ${{ github.token }} - - # - name: Check if there's an existing artifact for this baseline - # id: checkForExistingArtifact - # uses: xSAVIKx/artifact-exists-action@3c5206b1411c0d2fc0840f56b7140646933d9d6a - # with: - # name: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} - - # - name: Skip build if there's already an existing artifact for the baseline - # if: ${{ fromJSON(steps.checkForExistingArtifact.outputs.exists) }} - # run: echo 'APK for baseline ${{ steps.getMostRecentRelease.outputs.VERSION }} already exists, reusing existing build' - - # - name: Checkout "Baseline" commit (last release) - # if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} - # run: | - # git fetch origin tag ${{ steps.getMostRecentRelease.outputs.VERSION }} --no-tags --depth=1 - # git switch --detach ${{ steps.getMostRecentRelease.outputs.VERSION }} + - name: Get most recent release version + id: getMostRecentRelease + run: echo "VERSION=$(gh release list --limit 1 | awk '{ print $1 }')" >> "$GITHUB_OUTPUT" + env: + GITHUB_TOKEN: ${{ github.token }} + + - name: Check if there's an existing artifact for this baseline + id: checkForExistingArtifact + uses: xSAVIKx/artifact-exists-action@3c5206b1411c0d2fc0840f56b7140646933d9d6a + with: + name: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} + + - name: Skip build if there's already an existing artifact for the baseline + if: ${{ fromJSON(steps.checkForExistingArtifact.outputs.exists) }} + run: echo 'APK for baseline ${{ steps.getMostRecentRelease.outputs.VERSION }} already exists, reusing existing build' + + - name: Checkout "Baseline" commit (last release) + if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} + run: | + git fetch origin tag ${{ steps.getMostRecentRelease.outputs.VERSION }} --no-tags --depth=1 + git switch --detach ${{ steps.getMostRecentRelease.outputs.VERSION }} - name: Configure MapBox SDK run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} @@ -223,18 +223,14 @@ jobs: - name: Print results run: cat "./output.md" - # - name: Print AWS Device Farm verbose run results - # if: ${{ always() && runner.debug != null && fromJSON(runner.debug) }} - # run: cat "./Host_Machine_Files/debug.log" -# TODO: Once tests are more reliable we should uncomment this -# - name: Check if test failed, if so post the results and add the DeployBlocker label -# run: | -# if grep -q '🔴' ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md; then -# gh pr edit ${{ inputs.PR_NUMBER }} --add-label DeployBlockerCash -# gh pr comment ${{ inputs.PR_NUMBER }} -F ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md -# gh pr comment ${{ inputs.PR_NUMBER }} -b "@Expensify/mobile-deployers 📣 Please look into this performance regression as it's a deploy blocker." -# else -# echo '✅ no performance regression detected' -# fi -# env: -# GITHUB_TOKEN: ${{ github.token }} + - name: Check if test failed, if so post the results and add the DeployBlocker label + run: | + if grep -q '🔴' ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md; then + gh pr edit ${{ inputs.PR_NUMBER }} --add-label DeployBlockerCash + gh pr comment ${{ inputs.PR_NUMBER }} -F ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md + gh pr comment ${{ inputs.PR_NUMBER }} -b "@Expensify/mobile-deployers 📣 Please look into this performance regression as it's a deploy blocker." + else + echo '✅ no performance regression detected' + fi + env: + GITHUB_TOKEN: ${{ github.token }} From fd5c6100aadff7a266864e220598a3196ba6b30f Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Mon, 23 Oct 2023 09:01:03 +0200 Subject: [PATCH 36/39] Restore generated artifact name --- .github/workflows/e2ePerformanceTests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 74c34c3fa277f..528dbd4006940 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -53,7 +53,7 @@ jobs: # if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} uses: Expensify/App/.github/actions/composite/buildAndroidAPK@main with: - ARTIFACT_NAME: baseline-apk + ARTIFACT_NAME: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} buildDelta: runs-on: ubuntu-latest-xl From 2e73a3f49e3e81f3668b2d14282b9e329f1b8bb3 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Mon, 23 Oct 2023 09:54:06 +0200 Subject: [PATCH 37/39] ADd version tag to Download baseline APK step --- .github/workflows/e2ePerformanceTests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 528dbd4006940..9b3b269d491fb 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -50,7 +50,7 @@ jobs: run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} - name: Build APK - # if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} + if: ${{ !fromJSON(steps.checkForExistingArtifact.outputs.exists) }} uses: Expensify/App/.github/actions/composite/buildAndroidAPK@main with: ARTIFACT_NAME: baseline-apk-${{ steps.getMostRecentRelease.outputs.VERSION }} @@ -135,7 +135,7 @@ jobs: uses: actions/download-artifact@e9ef242655d12993efdcda9058dee2db83a2cb9b id: downloadBaselineAPK with: - name: baseline-apk + name: baseline-apk-${{ needs.buildBaseline.outputs.VERSION }} path: zip # The downloaded artifact will be a file named "app-e2e-release.apk" so we have to rename it From 5653b5d3c260f3c4170c2e68bf93b6034b329078 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Mon, 23 Oct 2023 19:22:41 +0200 Subject: [PATCH 38/39] PR comments --- .tool-versions | 1 - tests/e2e/config.js | 2 +- tests/e2e/manually_trigger_aws_df.sh | 14 -------------- tests/e2e/utils/execAsync.js | 5 ----- 4 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 .tool-versions delete mode 100755 tests/e2e/manually_trigger_aws_df.sh diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 97ad4f02c2247..0000000000000 --- a/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -nodejs 16.15.1 \ No newline at end of file diff --git a/tests/e2e/config.js b/tests/e2e/config.js index fda993ce68a67..3b1856ab8ad85 100644 --- a/tests/e2e/config.js +++ b/tests/e2e/config.js @@ -31,7 +31,7 @@ module.exports = { SERVER_PORT: 4723, // The amount of times a test should be executed for average performance metrics - RUNS: 30, + RUNS: 60, DEFAULT_BASELINE_BRANCH: 'main', diff --git a/tests/e2e/manually_trigger_aws_df.sh b/tests/e2e/manually_trigger_aws_df.sh deleted file mode 100755 index bf0356a179038..0000000000000 --- a/tests/e2e/manually_trigger_aws_df.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -set -ex - -PROJECT_ARN=arn:aws:devicefarm:us-west-2:015174472939:project:741d1dac-84e7-4c6f-84ed-b41a2209319d -DEVICE_POOL_ARN=arn:aws:devicefarm:us-west-2:015174472939:devicepool:741d1dac-84e7-4c6f-84ed-b41a2209319d/efa4b3bb-85ef-45f2-a063-14393eb4d2c2 -UPLOAD_ARN=arn:aws:devicefarm:us-west-2:015174472939:upload:741d1dac-84e7-4c6f-84ed-b41a2209319d/e65b711b-9dba-45dd-aeb4-e7c0449bccc8 -TEST_SPEC_ARN=arn:aws:devicefarm:us-west-2:015174472939:upload:741d1dac-84e7-4c6f-84ed-b41a2209319d/8e694a23-1dbb-40ff-a0ef-a8077dbfa729 -TEST_PACKAGE_ARN=arn:aws:devicefarm:us-west-2:015174472939:upload:741d1dac-84e7-4c6f-84ed-b41a2209319d/6d61e606-5450-43f2-be94-0bee759569e5 - -aws devicefarm schedule-run --project-arn "${PROJECT_ARN}" --app-arn "${UPLOAD_ARN}" --device-pool-arn "${DEVICE_POOL_ARN}" --name "Test run" --test type=APPIUM_NODE,testPackageArn="${TEST_PACKAGE_ARN}",testSpecArn="${TEST_SPEC_ARN}" -# aws devicefarm list-uploads --arn "${PROJECT_ARN}" -# -# aws devicefarm create-upload --name TestSpecMain.yml --type APPIUM_NODE_TEST_SPEC --project-arn "${PROJECT_ARN}" \ No newline at end of file diff --git a/tests/e2e/utils/execAsync.js b/tests/e2e/utils/execAsync.js index 50ae76b500f54..be80452c8acb0 100644 --- a/tests/e2e/utils/execAsync.js +++ b/tests/e2e/utils/execAsync.js @@ -1,5 +1,4 @@ const {exec} = require('child_process'); -// const _ = require('underscore'); const Logger = require('./logger'); /** @@ -17,10 +16,6 @@ module.exports = (command, env = {}) => { ...env, }; - // if (_.keys(env).length !== 0) { - // Logger.log(`environment variables:`, JSON.stringify(finalEnv, null, 2)); - // } - Logger.important(command); childProcess = exec( From 6c6061ff2aaa53483868925420ddf59fcb8944f5 Mon Sep 17 00:00:00 2001 From: Oscar Franco Date: Mon, 23 Oct 2023 19:29:48 +0200 Subject: [PATCH 39/39] Change path of output file on printing error results to github --- .github/workflows/e2ePerformanceTests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2ePerformanceTests.yml b/.github/workflows/e2ePerformanceTests.yml index 9b3b269d491fb..ff888c135be90 100644 --- a/.github/workflows/e2ePerformanceTests.yml +++ b/.github/workflows/e2ePerformanceTests.yml @@ -225,9 +225,9 @@ jobs: - name: Check if test failed, if so post the results and add the DeployBlocker label run: | - if grep -q '🔴' ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md; then + if grep -q '🔴' ./output.md; then gh pr edit ${{ inputs.PR_NUMBER }} --add-label DeployBlockerCash - gh pr comment ${{ inputs.PR_NUMBER }} -F ./Host_Machine_Files/\$WORKING_DIRECTORY/output.md + gh pr comment ${{ inputs.PR_NUMBER }} -F ./output.md gh pr comment ${{ inputs.PR_NUMBER }} -b "@Expensify/mobile-deployers 📣 Please look into this performance regression as it's a deploy blocker." else echo '✅ no performance regression detected'