Improve e2e tests (#8927)

* get e2e image picker working

* verify create account actually reaches onboarding

* wait for image to actually be attached before posting

* wait until login finishes before moving on

* sign out before switch accounts then wait until logged in

* disable onboarding experiments in e2e

* add testId to handle availability checkmark

* fix too long username

* update thread muting test to reflect current behaviour

* hackfix for the british english translation

* unflake the onboarding tests

* fix curate list flow

* admit defeat on the most list one
This commit is contained in:
Samuel Newman
2025-08-29 18:15:05 +03:00
committed by GitHub
parent 541502c7ee
commit d6dc52b6ea
24 changed files with 200 additions and 92 deletions
+17
View File
@@ -7,6 +7,7 @@ import ExpoImageCropTool, {type OpenCropperOptions} from 'expo-image-crop-tool'
import {compressIfNeeded} from './manip'
import {type PickerImage} from './picker.shared'
import {ImagePickerResult} from 'expo-image-picker'
async function getFile() {
const imagesDir = documentDirectory!
@@ -38,6 +39,22 @@ export async function openPicker(): Promise<PickerImage[]> {
return [await getFile()]
}
export async function openUnifiedPicker(): Promise<ImagePickerResult> {
const file = await getFile()
return {
assets: [
{
type: 'image',
uri: file.path,
mimeType: file.mime,
...file,
},
],
canceled: false,
}
}
export async function openCamera(): Promise<PickerImage> {
return await getFile()
}
+22
View File
@@ -1,11 +1,14 @@
import {
type ImagePickerOptions,
launchImageLibraryAsync,
UIImagePickerPreferredAssetRepresentationMode,
} from 'expo-image-picker'
import {t} from '@lingui/macro'
import {isIOS, isWeb} from '#/platform/detection'
import {type ImageMeta} from '#/state/gallery'
import * as Toast from '#/view/com/util/Toast'
import {VIDEO_MAX_DURATION_MS} from '../constants'
import {getDataUriSize} from './util'
export type PickerImage = ImageMeta & {
@@ -36,3 +39,22 @@ export async function openPicker(opts?: ImagePickerOptions) {
size: getDataUriSize(image.uri),
}))
}
export async function openUnifiedPicker({
selectionCountRemaining,
}: {
selectionCountRemaining: number
}) {
return await launchImageLibraryAsync({
exif: false,
mediaTypes: ['images', 'videos'],
quality: 1,
allowsMultipleSelection: true,
legacy: true,
base64: isWeb,
selectionLimit: isIOS ? selectionCountRemaining : undefined,
preferredAssetRepresentationMode:
UIImagePickerPreferredAssetRepresentationMode.Current,
videoMaxDuration: VIDEO_MAX_DURATION_MS / 1000,
})
}
+5 -1
View File
@@ -1,7 +1,11 @@
import ExpoImageCropTool, {type OpenCropperOptions} from 'expo-image-crop-tool'
import {type ImagePickerOptions, launchCameraAsync} from 'expo-image-picker'
export {openPicker, type PickerImage as RNImage} from './picker.shared'
export {
openPicker,
openUnifiedPicker,
type PickerImage as RNImage,
} from './picker.shared'
export async function openCamera(customOpts: ImagePickerOptions) {
const opts: ImagePickerOptions = {
+1 -1
View File
@@ -3,7 +3,7 @@ import {type OpenCropperOptions} from 'expo-image-crop-tool'
import {type PickerImage} from './picker.shared'
import {type CameraOpts} from './types'
export {openPicker} from './picker.shared'
export {openPicker, openUnifiedPicker} from './picker.shared'
export async function openCamera(_opts: CameraOpts): Promise<PickerImage> {
throw new Error('openCamera is not supported on web')
+1
View File
@@ -580,6 +580,7 @@ function LegacyFinalStep({
<OnboardingControls.Portal>
<Button
testID="onboardingFinish"
disabled={saving}
key={state.activeStep} // remove focus state on nav
color="primary"
@@ -244,6 +244,7 @@ export function StepInterests() {
) : (
<Button
disabled={saving || !data}
testID="onboardingContinue"
variant="solid"
color="primary"
size="large"
@@ -268,6 +268,7 @@ export function StepProfile() {
<OnboardingControls.Portal>
<View style={[a.gap_md, gtMobile && a.flex_row_reverse]}>
<Button
testID="onboardingContinue"
variant="solid"
color="primary"
size="large"
@@ -279,6 +280,7 @@ export function StepProfile() {
<ButtonIcon icon={ChevronRight} position="right" />
</Button>
<Button
testID="onboardingAvatarCreator"
variant="ghost"
color="primary"
size="large"
+4 -2
View File
@@ -13,13 +13,15 @@ import {StepFinished} from '#/screens/Onboarding/StepFinished'
import {StepInterests} from '#/screens/Onboarding/StepInterests'
import {StepProfile} from '#/screens/Onboarding/StepProfile'
import {Portal} from '#/components/Portal'
import {ENV} from '#/env'
import {StepSuggestedAccounts} from './StepSuggestedAccounts'
export function Onboarding() {
const {_} = useLingui()
const gate = useGate()
const showValueProp = gate('onboarding_value_prop')
const showSuggestedAccounts = gate('onboarding_suggested_accounts')
const showValueProp = ENV !== 'e2e' && gate('onboarding_value_prop')
const showSuggestedAccounts =
ENV !== 'e2e' && gate('onboarding_suggested_accounts')
const [state, dispatch] = useReducer(reducer, {
...initialState,
totalSteps: showSuggestedAccounts ? 4 : 3,
+4 -1
View File
@@ -168,7 +168,10 @@ export function StepHandle() {
</TextField.GhostText>
)}
{isHandleAvailable?.available && (
<CheckIcon style={[{color: t.palette.positive_600}, a.z_20]} />
<CheckIcon
testID="handleAvailableCheck"
style={[{color: t.palette.positive_600}, a.z_20]}
/>
)}
</TextField.Root>
</View>
+4 -18
View File
@@ -1,10 +1,6 @@
import {useCallback} from 'react'
import {Keyboard} from 'react-native'
import {
type ImagePickerAsset,
launchImageLibraryAsync,
UIImagePickerPreferredAssetRepresentationMode,
} from 'expo-image-picker'
import {type ImagePickerAsset} from 'expo-image-picker'
import {msg, plural} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -13,8 +9,9 @@ import {
usePhotoLibraryPermission,
useVideoLibraryPermission,
} from '#/lib/hooks/usePermissions'
import {openUnifiedPicker} from '#/lib/media/picker'
import {extractDataUriMime} from '#/lib/media/util'
import {isIOS, isNative, isWeb} from '#/platform/detection'
import {isNative, isWeb} from '#/platform/detection'
import {MAX_IMAGES} from '#/view/com/composer/state/composer'
import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
@@ -448,18 +445,7 @@ export function SelectMediaButton({
}
const {assets, canceled} = await sheetWrapper(
launchImageLibraryAsync({
exif: false,
mediaTypes: ['images', 'videos'],
quality: 1,
allowsMultipleSelection: true,
legacy: true,
base64: isWeb,
selectionLimit: isIOS ? selectionCountRemaining : undefined,
preferredAssetRepresentationMode:
UIImagePickerPreferredAssetRepresentationMode.Current,
videoMaxDuration: VIDEO_MAX_DURATION_MS / 1000,
}),
openUnifiedPicker({selectionCountRemaining}),
)
if (canceled) return