Files
iNaturalistReactNative/e2e/signedIn.e2e.js
Johannes Klein 0e0a6560ac Vision camera v3 (#1121)
* Bump vision-camera

* Refactor patch

* Move patched orientation into patch functions file

* Update react-native-vision-camera+3.4.1.patch

* Switch to MacOS 13 runner

Vision camera requires XCode 15 to compile.

* Add step to specify XCode 15

* Higher level of logging

* Increase test timeout

* Add comment

* Remove navigation to obs without evidence for signed out user

* Patch for location permission not working on iOS

* Increase setup timeout

* Increase some more timeouts

* Revert back to less logging in CI

* Does it have to do with timeouts?

* Trace log level

* Update README.md

* Disable Homebrew’s auto update and install cleanup

* Setup ruby step

* Install pods only if not cached

* Revert "Install pods only if not cached"

This reverts commit 42a2ea02f9.

* Run simulator in headless mode, record all logs

* Increase timeouts again

* Revert "Remove navigation to obs without evidence for signed out user"

This reverts commit 2b4718f5ce.

* Add boolean to run use effect only once

* Did merge wrong code

* There is one more permission gate when entering obs edit now

* Add permission gate dismissal to signed out user test

* Add comment, rename state

* Lower action timeout

* Update react-native-vision-camera to 3.6, update Reanimated to v3 (#838)

* Bump camera and plugin

* Upgrade Reanimated and libs using it

* Update vision-camera mock

* Remove superfluous patch

* Fix type

* Add mocks for e2e tests because bottom sheet does not work on AOSP

* Update package-lock.json

* Update vision camera

* Bump vision camera

* Update vision camera patch version

* Remove superfluous patch

* Update vision camera

* Update vision-camera and plugin

* Use latest vision plugin = rebased v3

* Run npm clean-start

* No longer needed

* Duplicate prop

* Switch back to v3 code

* Upgrading Detox fixes issue with iOS tests failing

Because of previous lack of permissions.

* Update to latest detox version

* Npm i force

* Vision 3 e2e testing, (#1126)

* Remove jest detox config

* Revert e2e timeout increase

* Revert jest config timeout

* Use macos 14 runner which has XCode 15 per default

* Use latest bottom sheet

* Revert "Use latest bottom sheet"

This reverts commit c66cd09838.

* Adding comma back in

* Remove spaces

* Use latest vision-camera and plugin

* Use release version of vision-camera

* Remove force flag

* Update react-native-worklets-core

* Upgrade reanimated

* Update babel.config to allow nested worklets

* Run frame processor async

* Remove enableGpuBuffers flag

* Remove no longer needed comment

* Update comments about version

* Update vision-camera and plugin

* Code format

* Rename param

* Use latest-plugin

* Remove fps param from camera view

* Change confidenceThreshold to number

* API change for results structure

* Refactor fps to be checked inside hook

As of vision-camera 3.9.1 our camera feed is stuttering when calling the runAtTargetFps function inside the useFrameProcessor hook.
So, what I did here is to track the time and skip the frames that are received before the target fps is reached.

* Remove updates of non-camera related

* Update comment

* Code format

* Snapshot updates

* Revert changes to ios e2e

* Add a log for the average time it takes a frame to be processed

* Use release version of plugin

* Add a patch for runAsync to work in release builds

* Update react-native-worklets-core to 0.4.0

* Use latest plugin version

* Add a shift method to worklet arrays

* Use latest vision-plugin

This makes use of .shift() in worklet array and depends on the previous patch.

* Set result timestamp and show age of result in debug mode

* Fix an error with timestamp being undefined

* Remove log

* Use latest vision plugin

* Change result timestamp to pink

* Comment

---------

Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
2024-03-27 00:47:43 +01:00

169 lines
7.4 KiB
JavaScript

import {
by, device, element, expect, waitFor
} from "detox";
import Config from "react-native-config-node";
import { iNatE2eBeforeAll, iNatE2eBeforeEach } from "./helpers";
describe( "Signed in user", () => {
beforeAll( async ( ) => iNatE2eBeforeAll( device ) );
beforeEach( async ( ) => iNatE2eBeforeEach( device ) );
async function createAndUploadObservation( options = { upload: false } ) {
const addObsButton = element( by.id( "add-obs-button" ) );
await waitFor( addObsButton ).toBeVisible().withTimeout( 10000 );
await addObsButton.tap();
await expect( element( by.id( "identify-text" ) ) ).toBeVisible();
// Observe without evidence
const obsWithoutEvidenceButton = element(
by.id( "observe-without-evidence-button" )
);
await expect( obsWithoutEvidenceButton ).toBeVisible();
await obsWithoutEvidenceButton.tap();
// Check that the new observation screen is visible
await waitFor( element( by.id( "new-observation-text" ) ) )
.toBeVisible()
.withTimeout( 10000 );
if ( options.upload ) {
// Press Upload now button
const uploadNowButton = element( by.id( "ObsEdit.uploadButton" ) );
await expect( uploadNowButton ).toBeVisible();
await uploadNowButton.tap();
} else {
// Press Save button
const saveButton = element( by.id( "ObsEdit.saveButton" ) );
await expect( saveButton ).toBeVisible();
await saveButton.tap();
}
// Check that the comments count component for the obs we just created is
// visible. Since it just saved and there's an animation the runs before
// this component becomes visible, and there may be other observations in
// the list, we need to wait for the right CommentsCount component to be
// visible
const obsListItem = element( by.id( /MyObservations\.obsListItem\..*/ ) ).atIndex( 0 );
const obsListItemAttributes = await obsListItem.getAttributes( );
const uuid = obsListItemAttributes.elements
? obsListItemAttributes.elements[0].identifier.split( "." ).pop( )
: obsListItemAttributes.identifier.split( "." ).pop( );
if ( options.upload ) {
const commentCount = element(
by.id( "ObsStatus.commentsCount" )
.withAncestor( by.id( `MyObservations.obsListItem.${uuid}` ) )
);
await waitFor( commentCount ).toBeVisible().withTimeout( 10000 );
}
return uuid;
}
async function deleteObservationByUUID( uuid, username, options = { uploaded: false } ) {
const obsListItem = element( by.id( `MyObservations.obsListItem.${uuid}` ) );
await obsListItem.tap();
if ( options.uploaded ) {
const editButton = element( by.id( "ObsDetail.editButton" ) );
await waitFor( editButton ).toBeVisible().withTimeout( 10000 );
// Navigate to the edit screen
await editButton.tap();
}
// Check that the edit screen is visible
await waitFor( element( by.text( "EVIDENCE" ) ) )
.toBeVisible()
.withTimeout( 10000 );
// Press header kebab menu
const headerKebabMenu = element( by.id( "KebabMenu.Button" ) );
await expect( headerKebabMenu ).toBeVisible();
await headerKebabMenu.tap();
// Press delete observation
const deleteObservation = element( by.id( "Header.delete-observation" ) );
await waitFor( deleteObservation ).toBeVisible().withTimeout( 10000 );
await deleteObservation.tap();
// Check that the delete button is visible
const deleteObservationButton = element( by.text( "DELETE" ) );
await waitFor( deleteObservationButton ).toBeVisible().withTimeout( 10000 );
// Press delete observation
await deleteObservationButton.tap();
// Make sure we're back on MyObservations
await waitFor( username ).toBeVisible().withTimeout( 10000 );
}
it( "should create an observation, add a comment, and delete the observation", async () => {
/*
/ 1. Sign in
*/
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();
const usernameInput = element( by.id( "Login.email" ) );
await waitFor( usernameInput ).toBeVisible().withTimeout( 10000 );
await expect( usernameInput ).toBeVisible();
await element( by.id( "Login.email" ) ).tap();
await element( by.id( "Login.email" ) ).typeText( Config.E2E_TEST_USERNAME );
const passwordInput = element( by.id( "Login.password" ) );
await expect( passwordInput ).toBeVisible();
await element( by.id( "Login.password" ) ).tap();
await element( by.id( "Login.password" ) ).typeText( Config.E2E_TEST_PASSWORD );
const loginButton = element( by.id( "Login.loginButton" ) );
await expect( loginButton ).toBeVisible();
await element( by.id( "Login.loginButton" ) ).tap();
const username = element( by.text( `@${Config.E2E_TEST_USERNAME}` ) ).atIndex(
1
);
await waitFor( username ).toBeVisible().withTimeout( 10000 );
await expect( username ).toBeVisible();
// Weird but functional workaround for the fact that the "Save Password"
// prompt in iOS blocks things on the bottom of the screen.
// https://github.com/wix/Detox/issues/3761#issuecomment-1521110131
await device.sendToHome();
await device.launchApp( {
newInstance: false
} );
/*
/ 2. Create two observations
*/
const uuid = await createAndUploadObservation( { upload: true } );
// Create a second b/c later we want to test that the deleted status text
// is visible in the toolbar, and the toolbar will disappear if there are
// zero observations
await createAndUploadObservation( );
/*
/ 3. Update the observation by adding a comment
*/
const obsListItem = element( by.id( `MyObservations.obsListItem.${uuid}` ) );
await obsListItem.tap();
const commentButton = element( by.id( "ObsDetail.commentButton" ) );
await waitFor( commentButton ).toBeVisible().withTimeout( 10000 );
await commentButton.tap();
// Check that the comment modal is visible
const commentModalInput = element( by.id( "ObsEdit.notes" ) );
await waitFor( commentModalInput ).toBeVisible().withTimeout( 10000 );
// Add a comment
await commentModalInput.tap();
await commentModalInput.typeText( "This is a comment" );
const commentModalSubmitButton = element( by.id( "ObsEdit.confirm" ) );
await commentModalSubmitButton.tap();
// Check that the comment is visible
await element( by.id( `ObsDetails.${uuid}` ) ).scrollTo( "bottom" );
const comment = element( by.text( "This is a comment" ) );
await waitFor( comment ).toBeVisible().withTimeout( 10000 );
await element( by.label( "Navigate back" ) ).tap( );
await waitFor( username ).toBeVisible( ).withTimeout( 10000 );
/*
/ 4. Delete the observations
*/
await deleteObservationByUUID( uuid, username, { uploaded: true } );
// TODO test to make sure the exact observation we created was deleted.
// Testing for the empty list UI isn't adequate because other test runs
// happening in parallel might cause other observations to be there
const deletedObservationText = element( by.text( /1 observation deleted/ ) );
await waitFor( deletedObservationText ).toBeVisible().withTimeout( 10000 );
} );
} );