mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2026-06-21 05:58:37 -04:00
* 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 commit42a2ea02f9. * Run simulator in headless mode, record all logs * Increase timeouts again * Revert "Remove navigation to obs without evidence for signed out user" This reverts commit2b4718f5ce. * 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 commitc66cd09838. * 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>
169 lines
7.4 KiB
JavaScript
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 );
|
|
} );
|
|
} );
|