diff --git a/e2e/sharedFlows/closeOnboarding.js b/e2e/sharedFlows/closeOnboarding.js index e263f3b19..8cc393978 100644 --- a/e2e/sharedFlows/closeOnboarding.js +++ b/e2e/sharedFlows/closeOnboarding.js @@ -7,7 +7,7 @@ import { const VISIBILITY_TIMEOUT = 10_000; export default async function closeOnboarding( ) { - const loginText = element( by.id( "log-in-to-iNaturalist-button.text" ) ); + const loginText = element( by.id( "use-iNaturalist-intro-text" ) ); await waitFor( loginText ).toExist().withTimeout( VISIBILITY_TIMEOUT ); // If we can see MyObs, we don't need to close the onboarding if ( loginText.visible ) { diff --git a/e2e/sharedFlows/signIn.js b/e2e/sharedFlows/signIn.js index 3bd73de08..1d15ed6ce 100644 --- a/e2e/sharedFlows/signIn.js +++ b/e2e/sharedFlows/signIn.js @@ -4,12 +4,19 @@ import { import Config from "react-native-config-node"; export default async function signIn() { - const loginText = element( by.id( "log-in-to-iNaturalist-button.text" ) ); - // 10000 timeout is for github actions, which was failing with a - // shorter timeout period - await waitFor( loginText ).toBeVisible().withTimeout( 10000 ); - await expect( loginText ).toBeVisible(); - await element( by.id( "log-in-to-iNaturalist-button.text" ) ).tap(); + // Find the Menu item from tabs + const openDrawerMenuItem = element( by.id( "OPEN_DRAWER" ) ); + await waitFor( openDrawerMenuItem ).toBeVisible().withTimeout( 10000 ); + await expect( openDrawerMenuItem ).toBeVisible(); + await element( by.id( "OPEN_DRAWER" ) ).tap(); + // Tap the Log-In menu item + // TODO: consider this a temporary solution as it only checks for the drawer-top-banner + // which can be a login prompt or the logged in user's details. If the user is already + // logged in, this should fail instead. + const loginMenuItem = element( by.id( "drawer-top-banner" ) ); + await waitFor( loginMenuItem ).toBeVisible().withTimeout( 10000 ); + await expect( loginMenuItem ).toBeVisible(); + await element( by.id( "drawer-top-banner" ) ).tap(); const usernameInput = element( by.id( "Login.email" ) ); await waitFor( usernameInput ).toBeVisible().withTimeout( 10000 ); await expect( usernameInput ).toBeVisible(); diff --git a/e2e/signedOut.e2e.js b/e2e/signedOut.e2e.js index be50192c6..b771792ff 100644 --- a/e2e/signedOut.e2e.js +++ b/e2e/signedOut.e2e.js @@ -15,7 +15,7 @@ describe( "Signed out user", () => { it( "should start at My Observations with log in text", async () => { await closeOnboarding( ); - const loginText = element( by.id( "log-in-to-iNaturalist-button.text" ) ); + const loginText = element( by.id( "use-iNaturalist-intro-text" ) ); await waitFor( loginText ).toBeVisible( ).withTimeout( 10000 ); await expect( loginText ).toBeVisible( ); } ); diff --git a/src/components/MyObservations/MyObservations.js b/src/components/MyObservations/MyObservations.js index 5fd34294e..7609c9e63 100644 --- a/src/components/MyObservations/MyObservations.js +++ b/src/components/MyObservations/MyObservations.js @@ -12,6 +12,7 @@ import { import GradientButton from "components/SharedComponents/Buttons/GradientButton.tsx"; import Modal from "components/SharedComponents/Modal.tsx"; import { View } from "components/styledComponents"; +import Arrow from "images/svg/curved_arrow_down.svg"; import type { Node } from "react"; import React, { useState } from "react"; import { Pressable } from "react-native"; @@ -85,27 +86,26 @@ const MyObservations = ( { showModal={!onboardingShown} closeModal={() => setOnboardingShown( true )} /> - - - - {t( "Identify-an-organism-with-the-iNaturalist-AI-Camera" )} + + {t( "Use-iNaturalist-to-identify-any-living-thing" )} + + {/* $FlowIgnore[not-a-component] */} + + + \n [one] Uploading { $currentUploadCount } observation\n *[other] Uploading { $currentUploadCount } of { $total } observations\n}", + "Use-iNaturalist-to-identify-any-living-thing": "Use iNaturalist to identify any living thing", "Use-iNaturalists-AI-Camera": "Use iNaturalist's AI Camera to identify organisms in real time", "USE-LOCATION": "USE LOCATION", "Use-the-devices-other-camera": "Use the device's other camera.", diff --git a/src/i18n/strings.ftl b/src/i18n/strings.ftl index 167e8fc54..d49003b80 100644 --- a/src/i18n/strings.ftl +++ b/src/i18n/strings.ftl @@ -563,7 +563,6 @@ IDENTIFICATIONS-WITHOUT-NUMBER = Identifiers = Identifiers Identifiers-View = Identifiers View Identify-an-organism = Identify an organism -Identify-an-organism-with-the-iNaturalist-AI-Camera = Identify an organism with the iNaturalist AI Camera # Onboarding message describing one of the reasons to use iNat Identify-record-learn = Identify, record, and learn about every living species on earth using iNaturalist If-an-account-with-that-email-exists = If an account with that email exists, we've sent password reset instructions to your email. @@ -1291,6 +1290,7 @@ Uploading-x-of-y-observations = [one] Uploading { $currentUploadCount } observation *[other] Uploading { $currentUploadCount } of { $total } observations } +Use-iNaturalist-to-identify-any-living-thing = Use iNaturalist to identify any living thing Use-iNaturalists-AI-Camera = Use iNaturalist's AI Camera to identify organisms in real time # Text for a button prompting the user to grant access to location USE-LOCATION = USE LOCATION diff --git a/src/images/svg/curved_arrow_down.svg b/src/images/svg/curved_arrow_down.svg new file mode 100644 index 000000000..26a24e2e1 --- /dev/null +++ b/src/images/svg/curved_arrow_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/navigation/CustomDrawerContent.tsx b/src/navigation/CustomDrawerContent.tsx index 133d88266..83ef010a7 100644 --- a/src/navigation/CustomDrawerContent.tsx +++ b/src/navigation/CustomDrawerContent.tsx @@ -183,6 +183,7 @@ const CustomDrawerContent = ( { state, navigation, descriptors }: Props ) => { const renderTopBanner = useCallback( ( ) => ( { const signedInUsers = realm.objects( "User" ).filtered( "signedIn == true" ); expect( signedInUsers.length ).toEqual( 0 ); renderAppWithComponent( ); - const loginText = i18next.t( "Log-in-to-contribute-your-observations" ); + const loginText = i18next.t( "Use-iNaturalist-to-identify-any-living-thing" ); expect( await screen.findByText( loginText ) ).toBeTruthy( ); // Unpleasant, but without adjusting the timeout it doesn't seem like // all of these requests get caught diff --git a/tests/integration/navigation/PhotoGallery.test.js b/tests/integration/navigation/PhotoGallery.test.js index 91d326bb2..e97664753 100644 --- a/tests/integration/navigation/PhotoGallery.test.js +++ b/tests/integration/navigation/PhotoGallery.test.js @@ -60,7 +60,7 @@ const actor = userEvent.setup( ); const navigateToPhotoImporter = async ( ) => { await waitFor( ( ) => { global.timeTravel( ); - expect( screen.getByText( /Log in to contribute/ ) ).toBeVisible( ); + expect( screen.getByText( /Use iNaturalist to identify/ ) ).toBeVisible( ); } ); const tabBar = await screen.findByTestId( "CustomTabBar" ); const addObsButton = await within( tabBar ).findByLabelText( "Add observations" ); diff --git a/tests/integration/navigation/SoundRecorder.test.js b/tests/integration/navigation/SoundRecorder.test.js index 633fd6c71..f24ffa26c 100644 --- a/tests/integration/navigation/SoundRecorder.test.js +++ b/tests/integration/navigation/SoundRecorder.test.js @@ -49,7 +49,7 @@ describe( "SoundRecorder navigation", ( ) => { renderApp( ); await waitFor( ( ) => { global.timeTravel( ); - expect( screen.getByText( /Log in to contribute/ ) ).toBeVisible( ); + expect( screen.getByText( /Use iNaturalist to identify/ ) ).toBeVisible( ); } ); const tabBar = await screen.findByTestId( "CustomTabBar" ); const addObsButton = await within( tabBar ).findByLabelText( "Add observations" ); @@ -59,7 +59,7 @@ describe( "SoundRecorder navigation", ( ) => { const mediaNavButtons = await screen.findByTestId( "MediaNavButtons" ); const closeButton = await within( mediaNavButtons ).findByLabelText( "Close" ); await actor.press( closeButton ); - expect( await screen.findByText( /Log in to contribute/ ) ).toBeVisible( ); + expect( await screen.findByText( /Use iNaturalist to identify/ ) ).toBeVisible( ); } ); } ); } ); diff --git a/tests/integration/navigation/StandardCamera.test.js b/tests/integration/navigation/StandardCamera.test.js index 1b06d8fd6..092ed36dc 100644 --- a/tests/integration/navigation/StandardCamera.test.js +++ b/tests/integration/navigation/StandardCamera.test.js @@ -47,7 +47,7 @@ const actor = userEvent.setup( ); const navigateToCamera = async ( ) => { await waitFor( ( ) => { global.timeTravel( ); - expect( screen.getByText( /Log in to contribute/ ) ).toBeVisible( ); + expect( screen.getByText( /Use iNaturalist to identify/ ) ).toBeVisible( ); } ); const tabBar = await screen.findByTestId( "CustomTabBar" ); const addObsButton = await within( tabBar ).findByLabelText( "Add observations" ); @@ -68,7 +68,7 @@ describe( "StandardCamera navigation with advanced user layout", ( ) => { await actor.press( closeButton ); await waitFor( ( ) => { global.timeTravel( ); - expect( screen.getByText( /Log in to contribute/ ) ).toBeVisible( ); + expect( screen.getByText( /Use iNaturalist to identify/ ) ).toBeVisible( ); } ); } ); } );