Bluesky app fork with some witchin' additions 💫

[Release prep] 1.109.0 E2E fixes (#9216)

* list tests

* fix create account

* get onboarding e2e tests working

* get curate list test working

* Update thread-muting.yml

authored by samuel.fm and committed by GitHub a482dae9 25d44d89

Changed files
+69 -79
__e2e__
docs
src
components
screens
Onboarding
StepFinished
StepSuggestedAccounts
StepSuggestedStarterpacks
+6 -3
__e2e__/flows/create-account.yml
··· 3 3 - runScript: 4 4 file: ../setupServer.js 5 5 env: 6 - SERVER_PATH: "" 6 + SERVER_PATH: "" 7 7 - runFlow: 8 8 file: ../setupApp.yml 9 9 - tapOn: ··· 25 25 - tapOn: 26 26 id: "passwordInput" 27 27 - inputText: "hunter22" 28 - - hideKeyboard 28 + - tapOn: 29 + # hideKeyboard on ios is borked 30 + # https://docs.maestro.dev/troubleshooting/known-issues#hidekeyboard-command-is-flaky 31 + text: "Your account" 29 32 - tapOn: 30 33 id: "nextBtn" 31 34 - tapOn: ··· 34 37 - inputText: "e2e-test" 35 38 - extendedWaitUntil: 36 39 visible: 37 - id: "handleAvailableCheck" 40 + id: "handleAvailableCheck" 38 41 - tapOn: 39 42 id: "nextBtn" 40 43 - assertVisible: "Give your profile a face"
+19 -33
__e2e__/flows/curate-lists.yml
··· 17 17 id: "e2eGotoLists" 18 18 - tapOn: 19 19 id: "newUserListBtn" 20 - - assertVisible: 21 - id: "createOrEditListModal" 20 + - waitForAnimationToEnd 21 + - assertVisible: "Create user list" 22 22 - tapOn: 23 - id: "editNameInput" 23 + id: "editListNameInput" 24 24 - inputText: "Good Ppl" 25 25 - tapOn: 26 - id: "editDescriptionInput" 26 + id: "editListDescriptionInput" 27 27 - inputText: "They good" 28 28 - tapOn: "Save" 29 - - tapOn: "Save" 30 - - assertNotVisible: 31 - id: "createOrEditListModal" 29 + - assertNotVisible: "Create user list" 32 30 - tapOn: "People" 33 31 - assertVisible: "Good Ppl" 34 32 - assertVisible: "They good" 35 33 36 34 - tapOn: 37 - label: "Edit display name and description via the edit curatelist modal" 38 - point: "90%,9%" 35 + id: "moreOptionsBtn" 39 36 - tapOn: "Edit list details" 40 - - assertVisible: 41 - id: "createOrEditListModal" 37 + - assertVisible: "Edit user list" 42 38 - tapOn: 43 - id: "editNameInput" 39 + id: "editListNameInput" 44 40 - eraseText 45 41 - inputText: "Bad Ppl" 46 42 - hideKeyboard 47 43 - tapOn: 48 - id: "editDescriptionInput" 44 + id: "editListDescriptionInput" 49 45 - eraseText 50 46 - inputText: "They bad" 51 47 - tapOn: "Save" 52 - - tapOn: "Save" 53 - - assertNotVisible: 54 - id: "createOrEditListModal" 48 + - assertNotVisible: "Edit user list" 55 49 - assertVisible: Bad Ppl 56 50 - assertVisible: They bad 57 51 58 52 - tapOn: 59 - label: "Remove description via the edit curatelist modal" 60 - point: "90%,9%" 53 + id: "moreOptionsBtn" 61 54 - tapOn: "Edit list details" 62 - - assertVisible: 63 - id: "createOrEditListModal" 55 + - assertVisible: "Edit user list" 64 56 - tapOn: 65 - id: "editDescriptionInput" 57 + id: "editListDescriptionInput" 66 58 - eraseText 67 59 - tapOn: "Save" 68 - - tapOn: "Save" 69 - - assertNotVisible: 70 - id: "createOrEditListModal" 60 + - assertNotVisible: "Edit user list" 71 61 - assertNotVisible: 72 62 id: "listDescription" 73 63 74 64 - tapOn: 75 - label: "Delete the curatelist" 76 - point: "90%,9%" 65 + id: "moreOptionsBtn" 77 66 - tapOn: "Delete List" 78 67 - tapOn: 79 68 id: "confirmBtn" ··· 82 71 id: "newUserListBtn" 83 72 - tapOn: 84 73 id: "newUserListBtn" 85 - - assertVisible: 86 - id: "createOrEditListModal" 74 + - assertVisible: "Create user list" 87 75 - tapOn: 88 - id: "editNameInput" 76 + id: "editListNameInput" 89 77 - inputText: "Good Ppl" 90 78 - tapOn: 91 - id: "editDescriptionInput" 79 + id: "editListDescriptionInput" 92 80 - inputText: "They good" 93 81 - tapOn: "Save" 94 - - tapOn: "Save" 95 - - assertNotVisible: 96 - id: "createOrEditListModal" 82 + - assertNotVisible: "Create user list" 97 83 - tapOn: "People" 98 84 - assertVisible: "Good Ppl" 99 85 - assertVisible: "They good"
+2 -6
__e2e__/flows/mod-lists.yml
··· 19 19 id: "moderationlistsBtn" 20 20 - tapOn: "New list" 21 21 - tapOn: 22 - id: "editNameInput" 22 + id: "editListNameInput" 23 23 - inputText: "Muted Users" 24 24 - tapOn: 25 - id: "editDescriptionInput" 25 + id: "editListDescriptionInput" 26 26 - inputText: "Shhh" 27 27 - tapOn: "Save" 28 - - tapOn: "Save" 29 28 30 29 # view modlist 31 30 - assertVisible: "Muted Users" 32 31 - assertVisible: "Shhh" 33 32 34 - # DOES NOT WORK - THE BUTTON IS NOT ACCESSIBLE 35 - # IGNORING FOR NOW, FIX THE COMPONENTS IN THE NEXT RELEASE 36 - # BECAUSE THIS IS A LEGIT A11Y PROBLEM -sfn 37 33 - tapOn: "Subscribe to this list" 38 34 - tapOn: "Mute accounts" 39 35 - tapOn: "Mute list"
+8 -1
__e2e__/flows/onboarding-avatar-creator.yml
··· 30 30 - assertVisible: "What are your interests?" 31 31 - tapOn: 32 32 id: "onboardingContinue" 33 - - assertVisible: "You're ready to go!" 33 + - assertVisible: "Suggested for you" 34 + # mock server doesn't have suggestions api 35 + - tapOn: "Skip to next step" 36 + - swipe: 37 + direction: "LEFT" 38 + - swipe: 39 + direction: "LEFT" 40 + - assertVisible: "Complete onboarding and start using your account" 34 41 - tapOn: 35 42 id: "onboardingFinish" 36 43 - tapOn:
+10 -2
__e2e__/flows/onboarding.yml
··· 16 16 id: "e2eStartOnboarding" 17 17 - tapOn: "Select an avatar" 18 18 - waitForAnimationToEnd 19 - - assertVisible: "Search your library…" 19 + - assertVisible: "Photos" 20 + - assertVisible: "Collections" 20 21 - tapOn: 21 22 point: "50%,22%" 22 23 - waitForAnimationToEnd ··· 27 28 - assertVisible: "What are your interests?" 28 29 - tapOn: 29 30 id: "onboardingContinue" 30 - - assertVisible: "You're ready to go!" 31 + - assertVisible: "Suggested for you" 32 + # mock server doesn't have suggestions api 33 + - tapOn: "Skip to next step" 34 + - swipe: 35 + direction: "LEFT" 36 + - swipe: 37 + direction: "LEFT" 38 + - assertVisible: "Complete onboarding and start using your account" 31 39 - tapOn: 32 40 id: "onboardingFinish" 33 41 - tapOn:
+4
__e2e__/flows/thread-muting.yml
··· 31 31 id: "viewHeaderHomeFeedPrefsBtn" 32 32 - tapOn: 33 33 id: "replyBtn" 34 + - tapOn: 35 + id: "replyBtn" 34 36 - inputText: "Reply 1" 35 37 - tapOn: 36 38 id: "composerPublishBtn" ··· 67 69 id: "bottomBarProfileBtn" 68 70 - tapOn: 69 71 id: "profilePager-selector-1" 72 + - tapOn: 73 + id: "replyBtn" 70 74 - tapOn: 71 75 id: "replyBtn" 72 76 - inputText: "Reply 2"
+6 -6
__e2e__/setupApp.yml
··· 1 1 appId: xyz.blueskyweb.app 2 2 --- 3 3 - launchApp: 4 - appId: "xyz.blueskyweb.app" 5 - clearState: true 4 + appId: "xyz.blueskyweb.app" 5 + clearState: true 6 6 - waitForAnimationToEnd 7 7 - tapOn: "http://localhost:8081" 8 8 - waitForAnimationToEnd 9 9 - extendedWaitUntil: 10 10 visible: "Continue" 11 11 - swipe: 12 - from: "Bluesky" 13 - direction: DOWN 12 + from: "Bluesky" 13 + direction: DOWN 14 + duration: 100 14 15 - tapOn: 15 - id: e2eProxyHeaderInput 16 + id: e2eProxyHeaderInput 16 17 - inputText: ${output.result} 17 18 - pressKey: Enter 18 - - hideKeyboard
+1 -1
docs/build.md
··· 75 75 76 76 - Start in various console tabs: 77 77 - `yarn e2e:mock-server` 78 - - `yarn e2e:metro` 78 + - `yarn e2e:start` 79 79 - Run once: `yarn e2e:build` 80 80 - Each test run: `yarn e2e:run` 81 81
+1 -1
docs/testing.md
··· 12 12 ### Running Maestro tests 13 13 14 14 - In one tab, run `yarn e2e:mock-server` 15 - - In a second tab, run `yarn e2e:metro` 15 + - In a second tab, run `yarn e2e:build` 16 16 - In a third tab, run `yarn e2e:run` 17 17 18 18 ## Using Flashlight for Performance Testing
+3 -2
package.json
··· 46 46 "lint-native:fix": "swiftlint --fix ./modules && ktlint --format ./modules", 47 47 "typecheck": "tsc --project ./tsconfig.check.json", 48 48 "e2e:mock-server": "NODE_ENV=development ./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts", 49 - "e2e:metro": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios", 50 - "e2e:metro-android": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:android", 49 + "e2e:build": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios", 50 + "e2e:build-android": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:android", 51 + "e2e:start": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo start", 51 52 "e2e:run": "maestro test __e2e__", 52 53 "perf:test": "NODE_ENV=test maestro test", 53 54 "perf:test:run": "NODE_ENV=test maestro test __e2e__/perf-test.yml",
+1 -1
src/components/dialogs/lists/CreateOrEditListDialog.tsx
··· 435 435 multiline 436 436 label={_(msg`Description`)} 437 437 placeholder={descriptionPlaceholder} 438 - testID="editProfileDescriptionInput" 438 + testID="editListDescriptionInput" 439 439 /> 440 440 </TextField.Root> 441 441 {descriptionTooLong && (
+1
src/screens/Onboarding/StepFinished/index.tsx
··· 330 330 </Button> 331 331 )} 332 332 <Button 333 + testID="onboardingFinish" 333 334 disabled={saving} 334 335 key={state.activeStep} // remove focus state on nav 335 336 color="primary"
+3 -10
src/screens/Onboarding/StepSuggestedAccounts/index.tsx
··· 1 - import {useCallback, useContext, useMemo, useState} from 'react' 1 + import {useContext, useMemo, useState} from 'react' 2 2 import {View} from 'react-native' 3 3 import {type ModerationOpts} from '@atproto/api' 4 4 import {msg, Trans} from '@lingui/macro' ··· 15 15 import {useLanguagePrefs} from '#/state/preferences' 16 16 import {useModerationOpts} from '#/state/preferences/moderation-opts' 17 17 import {useAgent, useSession} from '#/state/session' 18 - import {useOnboardingDispatch} from '#/state/shell' 19 18 import {OnboardingControls} from '#/screens/Onboarding/Layout' 20 19 import {Context} from '#/screens/Onboarding/state' 21 20 import {useSuggestedUsers} from '#/screens/Search/util/useSuggestedUsers' ··· 42 41 const queryClient = useQueryClient() 43 42 44 43 const {state, dispatch} = useContext(Context) 45 - const onboardDispatch = useOnboardingDispatch() 46 44 47 45 const [selectedInterest, setSelectedInterest] = useState<string | null>(null) 48 46 // keeping track of who was followed via the follow all button ··· 76 74 const isError = !!error 77 75 const isEmpty = 78 76 !isLoading && suggestedUsers && suggestedUsers.actors.length === 0 79 - 80 - const skipOnboarding = useCallback(() => { 81 - onboardDispatch({type: 'finish'}) 82 - dispatch({type: 'finish'}) 83 - }, [onboardDispatch, dispatch]) 84 77 85 78 const followableDids = 86 79 suggestedUsers?.actors ··· 223 216 <Button 224 217 color="secondary" 225 218 size="large" 226 - label={_(msg`Skip this flow`)} 227 - onPress={skipOnboarding}> 219 + label={_(msg`Skip to next step`)} 220 + onPress={() => dispatch({type: 'next'})}> 228 221 <ButtonText> 229 222 <Trans>Skip</Trans> 230 223 </ButtonText>
+4 -13
src/screens/Onboarding/StepSuggestedStarterpacks/index.tsx
··· 1 - import {useCallback, useContext} from 'react' 1 + import {useContext} from 'react' 2 2 import {View} from 'react-native' 3 3 import {msg, Trans} from '@lingui/macro' 4 4 import {useLingui} from '@lingui/react' 5 5 6 6 import {useModerationOpts} from '#/state/preferences/moderation-opts' 7 7 import {useOnboardingSuggestedStarterPacksQuery} from '#/state/queries/useOnboardingSuggestedStarterPacksQuery' 8 - import {useOnboardingDispatch} from '#/state/shell' 9 8 import {OnboardingControls} from '#/screens/Onboarding/Layout' 10 9 import {Context} from '#/screens/Onboarding/state' 11 10 import {atoms as a, useBreakpoints} from '#/alf' ··· 22 21 const moderationOpts = useModerationOpts() 23 22 24 23 const {state, dispatch} = useContext(Context) 25 - const onboardDispatch = useOnboardingDispatch() 26 24 27 25 const { 28 26 data: suggestedStarterPacks, 29 27 isLoading, 30 - error, 28 + isError, 31 29 isRefetching, 32 30 refetch, 33 31 } = useOnboardingSuggestedStarterPacksQuery({ 34 32 enabled: true, 35 33 overrideInterests: state.interestsStepResults.selectedInterests, 36 34 }) 37 - 38 - const isError = !!error 39 - 40 - const skipOnboarding = useCallback(() => { 41 - onboardDispatch({type: 'finish'}) 42 - dispatch({type: 'finish'}) 43 - }, [onboardDispatch, dispatch]) 44 35 45 36 return ( 46 37 <View style={[a.align_start]} testID="onboardingInterests"> ··· 105 96 <Button 106 97 color="secondary" 107 98 size="large" 108 - label={_(msg`Skip this flow`)} 109 - onPress={skipOnboarding}> 99 + label={_(msg`Skip to next step`)} 100 + onPress={() => dispatch({type: 'next'})}> 110 101 <ButtonText> 111 102 <Trans>Skip</Trans> 112 103 </ButtonText>