From cc78f06b04fd5ebdbc5dca0178d252c6cc7c47cb Mon Sep 17 00:00:00 2001 From: Amanda Bullington <35536439+albullington@users.noreply.github.com> Date: Thu, 25 May 2023 17:13:31 -0700 Subject: [PATCH] Add activity indicator to fetch location (#639) * Add activity indicator to fetch location * Add e2e location mock (#643) Adds a mock for fetchUserLocation intended to be used with e2e tests. `MOCK_MODE=e2e` must be in the ENV for this to work. --------- Co-authored-by: Ken-ichi Ueda --------- Co-authored-by: Johannes Klein Co-authored-by: Ken-ichi Ueda --- .detoxrc.js | 4 ++-- .github/workflows/e2e_android.yml | 2 +- .github/workflows/e2e_ios.yml | 7 +++++- fastlane/Fastfile | 11 ++++++++++ metro.config.js | 5 ++++- package.json | 8 +++---- src/components/ObsEdit/DatePicker.js | 8 ++++--- src/components/ObsEdit/EvidenceSection.js | 22 ++++++++++++++----- .../fetchUserLocation.e2e-mock.js | 17 ++++++++++++++ 9 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 src/sharedHelpers/fetchUserLocation.e2e-mock.js diff --git a/.detoxrc.js b/.detoxrc.js index 9a24b14ba..681f7ace5 100644 --- a/.detoxrc.js +++ b/.detoxrc.js @@ -34,14 +34,14 @@ module.exports = { binaryPath: `android/app/build/outputs/apk/debug/${apkFilenamePrefix}-debug.apk`, testBinaryPath: `android/app/build/outputs/apk/androidTest/debug/${apkFilenamePrefix}-debug-androidTest.apk`, build: - "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", + "(cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug)", }, "android.release": { type: "android.apk", binaryPath: `android/app/build/outputs/apk/release/${apkFilenamePrefix}-release.apk`, testBinaryPath: `android/app/build/outputs/apk/androidTest/release/${apkFilenamePrefix}-release-androidTest.apk`, build: - "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", + "(cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release)", }, }, devices: { diff --git a/.github/workflows/e2e_android.yml b/.github/workflows/e2e_android.yml index fed851e2b..59b920140 100644 --- a/.github/workflows/e2e_android.yml +++ b/.github/workflows/e2e_android.yml @@ -127,7 +127,7 @@ jobs: # Start the Android e2e tests with extensive logging and screen captures for failing tests - name: Android Detox - run: npm run e2e:test:android -- --debug-synchronization 500 --take-screenshots failing --record-videos failing -l trace + run: npm run e2e:test:android -- --take-screenshots failing --record-videos failing -l debug # The artifacts for the failing tests are available for download on github.com on the page of the individual actions run - name: Store Detox artifacts on test failure diff --git a/.github/workflows/e2e_ios.yml b/.github/workflows/e2e_ios.yml index 95e4f4429..8160c6b7b 100644 --- a/.github/workflows/e2e_ios.yml +++ b/.github/workflows/e2e_ios.yml @@ -88,6 +88,11 @@ jobs: JWT_ANONYMOUS_API_SECRET: ${{ secrets.JWT_ANONYMOUS_API_SECRET }} run: printf 'API_URL=https://stagingapi.inaturalist.org/v2\nOAUTH_API_URL=https://staging.inaturalist.org\nJWT_ANONYMOUS_API_SECRET=%s\nOAUTH_CLIENT_ID=%s\nOAUTH_CLIENT_SECRET=%s\nE2E_TEST_USERNAME=%s\nE2E_TEST_PASSWORD=%s\n' "JWT_ANONYMOUS_API_SECRET" "$OAUTH_CLIENT_ID" "$OAUTH_CLIENT_SECRET" "$E2E_TEST_USERNAME" "$E2E_TEST_PASSWORD" > .env + # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable + # This will be available for all subsequent steps + - name: Set MOCK_MODE to e2e + run: echo "MOCK_MODE=e2e" >> "$GITHUB_ENV" + # Install prerequisites for detox and build app, and test - run: brew tap wix/brew - run: brew install applesimutils @@ -96,7 +101,7 @@ jobs: run: npm run e2e:build:ios - name: Run e2e test - run: npm run e2e:test:ios -- --cleanup --debug-synchronization 200 --take-screenshots failing --record-videos failing -l trace + run: npm run e2e:test:ios -- --cleanup --take-screenshots failing --record-videos failing -l debug # The artifacts for the failing tests are available for download on github.com on the page of the individual actions run - name: Store Detox artifacts on test failure diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 4cbe7b587..8c61180ef 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -10,6 +10,17 @@ unless File.exist?( appfile_path ) NO_APPFILE_ERROR end +forbidden_env_vars = [ + "MOCK_MODE" +] +forbidden_env_vars.each do | env_var | + next unless ENV[env_var].to_s.size.positive? + + UI.abort_with_message! <<~NO_ENV_ERROR.gsub( /\s+/, " " ).strip + ENV is set #{env_var}. Remove the value from your ENV before running fastlane. + NO_ENV_ERROR +end + required_env_vars = [ "IOS_PROVISIONING_PROFILE_NAME", "IOS_SHARE_BUNDLE_ID", diff --git a/metro.config.js b/metro.config.js index e6b69f210..2b7954087 100644 --- a/metro.config.js +++ b/metro.config.js @@ -25,7 +25,10 @@ module.exports = ( async () => { }, resolver: { assetExts: assetExts.filter( ext => ext !== "svg" ), - sourceExts: [...sourceExts, "svg"] + sourceExts: + process.env.MOCK_MODE === "e2e" + ? ["e2e-mock.js", ...sourceExts, "svg"] + : [...sourceExts, "svg"] } }; } )(); diff --git a/package.json b/package.json index dc0247eef..1c0aceb6c 100644 --- a/package.json +++ b/package.json @@ -15,12 +15,12 @@ "postinstall": "husky install && patch-package", "translate": "node src/i18n/i18ncli.js build", "e2e:android": "npm run e2e:build:android && npm run e2e:test:android", - "e2e:build:android": "npx detox build --configuration android.release", - "e2e:build:ios": "npx detox build --configuration ios.release", + "e2e:build:android": "MOCK_MODE=e2e npx detox build --configuration android.release", + "e2e:build:ios": "MOCK_MODE=e2e npx detox build --configuration ios.release", "e2e:build": "npm run e2e:build:ios && npm run e2e:build:android", "e2e:ios": "npm run e2e:build:ios && npm run e2e:test:ios", - "e2e:test:android": "npx detox test --configuration android.release", - "e2e:test:ios": "npx detox test --configuration ios.release", + "e2e:test:android": "MOCK_MODE=e2e npx detox test --configuration android.release", + "e2e:test:ios": "MOCK_MODE=e2e npx detox test --configuration ios.release", "e2e:test": "npm run e2e:test:ios && npm run e2e:test:android", "e2e": "npm run e2e:build && npm run e2e:test", "icons": "./scripts/update-icon-font.sh" diff --git a/src/components/ObsEdit/DatePicker.js b/src/components/ObsEdit/DatePicker.js index 5260264c1..866f33d84 100644 --- a/src/components/ObsEdit/DatePicker.js +++ b/src/components/ObsEdit/DatePicker.js @@ -1,7 +1,7 @@ // @flow import { Body3, DateTimePicker, INatIcon } from "components/SharedComponents"; -import { Pressable } from "components/styledComponents"; +import { Pressable, View } from "components/styledComponents"; import { ObsEditContext } from "providers/contexts"; import type { Node } from "react"; import React, { useContext, useState } from "react"; @@ -45,9 +45,11 @@ const DatePicker = ( { currentObservation }: Props ): Node => { onPress={openModal} className="flex-row flex-nowrap items-center" > - + + + {/* $FlowIgnore */} - + {displayDate( ) || t( "Add-Date-Time" )} diff --git a/src/components/ObsEdit/EvidenceSection.js b/src/components/ObsEdit/EvidenceSection.js index 857c1c335..915ce67fb 100644 --- a/src/components/ObsEdit/EvidenceSection.js +++ b/src/components/ObsEdit/EvidenceSection.js @@ -17,7 +17,7 @@ import React, { useCallback, useContext, useEffect, useRef, useState } from "react"; -import { useTheme } from "react-native-paper"; +import { ActivityIndicator, useTheme } from "react-native-paper"; import Photo from "realmModels/Photo"; import useLocationFetching from "sharedHooks/useLocationFetching"; import useTranslation from "sharedHooks/useTranslation"; @@ -179,9 +179,18 @@ const EvidenceSection = ( ): Node => { photoUris={photoUris} handleAddEvidence={handleAddEvidence} /> - - - + + + {shouldFetchLocation && } + + + + + {displayPlaceName( ) && ( {displayPlaceName( )} @@ -191,8 +200,9 @@ const EvidenceSection = ( ): Node => { {displayLocation( )} - - + + + ); diff --git a/src/sharedHelpers/fetchUserLocation.e2e-mock.js b/src/sharedHelpers/fetchUserLocation.e2e-mock.js new file mode 100644 index 000000000..82fe93a68 --- /dev/null +++ b/src/sharedHelpers/fetchUserLocation.e2e-mock.js @@ -0,0 +1,17 @@ +type UserLocation = { + latitude: number, + longitude: number, + positional_accuracy: number, + place_guess: string + +} +const fetchUserLocation = async ( ): Promise => new Promise( resolve => { + setTimeout( ( ) => resolve( { + place_guess: "San Francisco", + latitude: -122.4194, + longitude: 37.7749, + positional_accuracy: 5 + } ), 1000 ); +} ); + +export default fetchUserLocation;