[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
This commit is contained in:
Samuel Newman
2025-10-16 17:31:11 +03:00
committed by GitHub
parent 25d44d8939
commit a482dae936
14 changed files with 69 additions and 79 deletions
+4 -1
View File
@@ -25,7 +25,10 @@ appId: xyz.blueskyweb.app
- tapOn: - tapOn:
id: "passwordInput" id: "passwordInput"
- inputText: "hunter22" - inputText: "hunter22"
- hideKeyboard - tapOn:
# hideKeyboard on ios is borked
# https://docs.maestro.dev/troubleshooting/known-issues#hidekeyboard-command-is-flaky
text: "Your account"
- tapOn: - tapOn:
id: "nextBtn" id: "nextBtn"
- tapOn: - tapOn:
+19 -33
View File
@@ -17,63 +17,52 @@ appId: xyz.blueskyweb.app
id: "e2eGotoLists" id: "e2eGotoLists"
- tapOn: - tapOn:
id: "newUserListBtn" id: "newUserListBtn"
- assertVisible: - waitForAnimationToEnd
id: "createOrEditListModal" - assertVisible: "Create user list"
- tapOn: - tapOn:
id: "editNameInput" id: "editListNameInput"
- inputText: "Good Ppl" - inputText: "Good Ppl"
- tapOn: - tapOn:
id: "editDescriptionInput" id: "editListDescriptionInput"
- inputText: "They good" - inputText: "They good"
- tapOn: "Save" - tapOn: "Save"
- tapOn: "Save" - assertNotVisible: "Create user list"
- assertNotVisible:
id: "createOrEditListModal"
- tapOn: "People" - tapOn: "People"
- assertVisible: "Good Ppl" - assertVisible: "Good Ppl"
- assertVisible: "They good" - assertVisible: "They good"
- tapOn: - tapOn:
label: "Edit display name and description via the edit curatelist modal" id: "moreOptionsBtn"
point: "90%,9%"
- tapOn: "Edit list details" - tapOn: "Edit list details"
- assertVisible: - assertVisible: "Edit user list"
id: "createOrEditListModal"
- tapOn: - tapOn:
id: "editNameInput" id: "editListNameInput"
- eraseText - eraseText
- inputText: "Bad Ppl" - inputText: "Bad Ppl"
- hideKeyboard - hideKeyboard
- tapOn: - tapOn:
id: "editDescriptionInput" id: "editListDescriptionInput"
- eraseText - eraseText
- inputText: "They bad" - inputText: "They bad"
- tapOn: "Save" - tapOn: "Save"
- tapOn: "Save" - assertNotVisible: "Edit user list"
- assertNotVisible:
id: "createOrEditListModal"
- assertVisible: Bad Ppl - assertVisible: Bad Ppl
- assertVisible: They bad - assertVisible: They bad
- tapOn: - tapOn:
label: "Remove description via the edit curatelist modal" id: "moreOptionsBtn"
point: "90%,9%"
- tapOn: "Edit list details" - tapOn: "Edit list details"
- assertVisible: - assertVisible: "Edit user list"
id: "createOrEditListModal"
- tapOn: - tapOn:
id: "editDescriptionInput" id: "editListDescriptionInput"
- eraseText - eraseText
- tapOn: "Save" - tapOn: "Save"
- tapOn: "Save" - assertNotVisible: "Edit user list"
- assertNotVisible:
id: "createOrEditListModal"
- assertNotVisible: - assertNotVisible:
id: "listDescription" id: "listDescription"
- tapOn: - tapOn:
label: "Delete the curatelist" id: "moreOptionsBtn"
point: "90%,9%"
- tapOn: "Delete List" - tapOn: "Delete List"
- tapOn: - tapOn:
id: "confirmBtn" id: "confirmBtn"
@@ -82,18 +71,15 @@ appId: xyz.blueskyweb.app
id: "newUserListBtn" id: "newUserListBtn"
- tapOn: - tapOn:
id: "newUserListBtn" id: "newUserListBtn"
- assertVisible: - assertVisible: "Create user list"
id: "createOrEditListModal"
- tapOn: - tapOn:
id: "editNameInput" id: "editListNameInput"
- inputText: "Good Ppl" - inputText: "Good Ppl"
- tapOn: - tapOn:
id: "editDescriptionInput" id: "editListDescriptionInput"
- inputText: "They good" - inputText: "They good"
- tapOn: "Save" - tapOn: "Save"
- tapOn: "Save" - assertNotVisible: "Create user list"
- assertNotVisible:
id: "createOrEditListModal"
- tapOn: "People" - tapOn: "People"
- assertVisible: "Good Ppl" - assertVisible: "Good Ppl"
- assertVisible: "They good" - assertVisible: "They good"
+2 -6
View File
@@ -19,21 +19,17 @@ appId: xyz.blueskyweb.app
id: "moderationlistsBtn" id: "moderationlistsBtn"
- tapOn: "New list" - tapOn: "New list"
- tapOn: - tapOn:
id: "editNameInput" id: "editListNameInput"
- inputText: "Muted Users" - inputText: "Muted Users"
- tapOn: - tapOn:
id: "editDescriptionInput" id: "editListDescriptionInput"
- inputText: "Shhh" - inputText: "Shhh"
- tapOn: "Save" - tapOn: "Save"
- tapOn: "Save"
# view modlist # view modlist
- assertVisible: "Muted Users" - assertVisible: "Muted Users"
- assertVisible: "Shhh" - assertVisible: "Shhh"
# DOES NOT WORK - THE BUTTON IS NOT ACCESSIBLE
# IGNORING FOR NOW, FIX THE COMPONENTS IN THE NEXT RELEASE
# BECAUSE THIS IS A LEGIT A11Y PROBLEM -sfn
- tapOn: "Subscribe to this list" - tapOn: "Subscribe to this list"
- tapOn: "Mute accounts" - tapOn: "Mute accounts"
- tapOn: "Mute list" - tapOn: "Mute list"
+8 -1
View File
@@ -30,7 +30,14 @@ appId: xyz.blueskyweb.app
- assertVisible: "What are your interests?" - assertVisible: "What are your interests?"
- tapOn: - tapOn:
id: "onboardingContinue" id: "onboardingContinue"
- assertVisible: "You're ready to go!" - assertVisible: "Suggested for you"
# mock server doesn't have suggestions api
- tapOn: "Skip to next step"
- swipe:
direction: "LEFT"
- swipe:
direction: "LEFT"
- assertVisible: "Complete onboarding and start using your account"
- tapOn: - tapOn:
id: "onboardingFinish" id: "onboardingFinish"
- tapOn: - tapOn:
+10 -2
View File
@@ -16,7 +16,8 @@ appId: xyz.blueskyweb.app
id: "e2eStartOnboarding" id: "e2eStartOnboarding"
- tapOn: "Select an avatar" - tapOn: "Select an avatar"
- waitForAnimationToEnd - waitForAnimationToEnd
- assertVisible: "Search your library…" - assertVisible: "Photos"
- assertVisible: "Collections"
- tapOn: - tapOn:
point: "50%,22%" point: "50%,22%"
- waitForAnimationToEnd - waitForAnimationToEnd
@@ -27,7 +28,14 @@ appId: xyz.blueskyweb.app
- assertVisible: "What are your interests?" - assertVisible: "What are your interests?"
- tapOn: - tapOn:
id: "onboardingContinue" id: "onboardingContinue"
- assertVisible: "You're ready to go!" - assertVisible: "Suggested for you"
# mock server doesn't have suggestions api
- tapOn: "Skip to next step"
- swipe:
direction: "LEFT"
- swipe:
direction: "LEFT"
- assertVisible: "Complete onboarding and start using your account"
- tapOn: - tapOn:
id: "onboardingFinish" id: "onboardingFinish"
- tapOn: - tapOn:
+4
View File
@@ -31,6 +31,8 @@ appId: xyz.blueskyweb.app
id: "viewHeaderHomeFeedPrefsBtn" id: "viewHeaderHomeFeedPrefsBtn"
- tapOn: - tapOn:
id: "replyBtn" id: "replyBtn"
- tapOn:
id: "replyBtn"
- inputText: "Reply 1" - inputText: "Reply 1"
- tapOn: - tapOn:
id: "composerPublishBtn" id: "composerPublishBtn"
@@ -69,6 +71,8 @@ appId: xyz.blueskyweb.app
id: "profilePager-selector-1" id: "profilePager-selector-1"
- tapOn: - tapOn:
id: "replyBtn" id: "replyBtn"
- tapOn:
id: "replyBtn"
- inputText: "Reply 2" - inputText: "Reply 2"
- tapOn: - tapOn:
id: "composerPublishBtn" id: "composerPublishBtn"
+1 -1
View File
@@ -11,8 +11,8 @@ appId: xyz.blueskyweb.app
- swipe: - swipe:
from: "Bluesky" from: "Bluesky"
direction: DOWN direction: DOWN
duration: 100
- tapOn: - tapOn:
id: e2eProxyHeaderInput id: e2eProxyHeaderInput
- inputText: ${output.result} - inputText: ${output.result}
- pressKey: Enter - pressKey: Enter
- hideKeyboard
+1 -1
View File
@@ -75,7 +75,7 @@ After you do `yarn ios` and `yarn android` once, you can later just run `yarn we
- Start in various console tabs: - Start in various console tabs:
- `yarn e2e:mock-server` - `yarn e2e:mock-server`
- `yarn e2e:metro` - `yarn e2e:start`
- Run once: `yarn e2e:build` - Run once: `yarn e2e:build`
- Each test run: `yarn e2e:run` - Each test run: `yarn e2e:run`
+1 -1
View File
@@ -12,7 +12,7 @@ values.
### Running Maestro tests ### Running Maestro tests
- In one tab, run `yarn e2e:mock-server` - In one tab, run `yarn e2e:mock-server`
- In a second tab, run `yarn e2e:metro` - In a second tab, run `yarn e2e:build`
- In a third tab, run `yarn e2e:run` - In a third tab, run `yarn e2e:run`
## Using Flashlight for Performance Testing ## Using Flashlight for Performance Testing
+3 -2
View File
@@ -46,8 +46,9 @@
"lint-native:fix": "swiftlint --fix ./modules && ktlint --format ./modules", "lint-native:fix": "swiftlint --fix ./modules && ktlint --format ./modules",
"typecheck": "tsc --project ./tsconfig.check.json", "typecheck": "tsc --project ./tsconfig.check.json",
"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", "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",
"e2e:metro": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios", "e2e:build": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios",
"e2e:metro-android": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:android", "e2e:build-android": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:android",
"e2e:start": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo start",
"e2e:run": "maestro test __e2e__", "e2e:run": "maestro test __e2e__",
"perf:test": "NODE_ENV=test maestro test", "perf:test": "NODE_ENV=test maestro test",
"perf:test:run": "NODE_ENV=test maestro test __e2e__/perf-test.yml", "perf:test:run": "NODE_ENV=test maestro test __e2e__/perf-test.yml",
@@ -435,7 +435,7 @@ function DialogInner({
multiline multiline
label={_(msg`Description`)} label={_(msg`Description`)}
placeholder={descriptionPlaceholder} placeholder={descriptionPlaceholder}
testID="editProfileDescriptionInput" testID="editListDescriptionInput"
/> />
</TextField.Root> </TextField.Root>
{descriptionTooLong && ( {descriptionTooLong && (
@@ -330,6 +330,7 @@ function ValueProposition({
</Button> </Button>
)} )}
<Button <Button
testID="onboardingFinish"
disabled={saving} disabled={saving}
key={state.activeStep} // remove focus state on nav key={state.activeStep} // remove focus state on nav
color="primary" color="primary"
@@ -1,4 +1,4 @@
import {useCallback, useContext, useMemo, useState} from 'react' import {useContext, useMemo, useState} from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {type ModerationOpts} from '@atproto/api' import {type ModerationOpts} from '@atproto/api'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
@@ -15,7 +15,6 @@ import {updateProfileShadow} from '#/state/cache/profile-shadow'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
import {useOnboardingDispatch} from '#/state/shell'
import {OnboardingControls} from '#/screens/Onboarding/Layout' import {OnboardingControls} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state' import {Context} from '#/screens/Onboarding/state'
import {useSuggestedUsers} from '#/screens/Search/util/useSuggestedUsers' import {useSuggestedUsers} from '#/screens/Search/util/useSuggestedUsers'
@@ -42,7 +41,6 @@ export function StepSuggestedAccounts() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const {state, dispatch} = useContext(Context) const {state, dispatch} = useContext(Context)
const onboardDispatch = useOnboardingDispatch()
const [selectedInterest, setSelectedInterest] = useState<string | null>(null) const [selectedInterest, setSelectedInterest] = useState<string | null>(null)
// keeping track of who was followed via the follow all button // keeping track of who was followed via the follow all button
@@ -77,11 +75,6 @@ export function StepSuggestedAccounts() {
const isEmpty = const isEmpty =
!isLoading && suggestedUsers && suggestedUsers.actors.length === 0 !isLoading && suggestedUsers && suggestedUsers.actors.length === 0
const skipOnboarding = useCallback(() => {
onboardDispatch({type: 'finish'})
dispatch({type: 'finish'})
}, [onboardDispatch, dispatch])
const followableDids = const followableDids =
suggestedUsers?.actors suggestedUsers?.actors
.filter( .filter(
@@ -223,8 +216,8 @@ export function StepSuggestedAccounts() {
<Button <Button
color="secondary" color="secondary"
size="large" size="large"
label={_(msg`Skip this flow`)} label={_(msg`Skip to next step`)}
onPress={skipOnboarding}> onPress={() => dispatch({type: 'next'})}>
<ButtonText> <ButtonText>
<Trans>Skip</Trans> <Trans>Skip</Trans>
</ButtonText> </ButtonText>
@@ -1,11 +1,10 @@
import {useCallback, useContext} from 'react' import {useContext} from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useOnboardingSuggestedStarterPacksQuery} from '#/state/queries/useOnboardingSuggestedStarterPacksQuery' import {useOnboardingSuggestedStarterPacksQuery} from '#/state/queries/useOnboardingSuggestedStarterPacksQuery'
import {useOnboardingDispatch} from '#/state/shell'
import {OnboardingControls} from '#/screens/Onboarding/Layout' import {OnboardingControls} from '#/screens/Onboarding/Layout'
import {Context} from '#/screens/Onboarding/state' import {Context} from '#/screens/Onboarding/state'
import {atoms as a, useBreakpoints} from '#/alf' import {atoms as a, useBreakpoints} from '#/alf'
@@ -22,12 +21,11 @@ export function StepSuggestedStarterpacks() {
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
const {state, dispatch} = useContext(Context) const {state, dispatch} = useContext(Context)
const onboardDispatch = useOnboardingDispatch()
const { const {
data: suggestedStarterPacks, data: suggestedStarterPacks,
isLoading, isLoading,
error, isError,
isRefetching, isRefetching,
refetch, refetch,
} = useOnboardingSuggestedStarterPacksQuery({ } = useOnboardingSuggestedStarterPacksQuery({
@@ -35,13 +33,6 @@ export function StepSuggestedStarterpacks() {
overrideInterests: state.interestsStepResults.selectedInterests, overrideInterests: state.interestsStepResults.selectedInterests,
}) })
const isError = !!error
const skipOnboarding = useCallback(() => {
onboardDispatch({type: 'finish'})
dispatch({type: 'finish'})
}, [onboardDispatch, dispatch])
return ( return (
<View style={[a.align_start]} testID="onboardingInterests"> <View style={[a.align_start]} testID="onboardingInterests">
<Text style={[a.font_bold, a.text_3xl]}> <Text style={[a.font_bold, a.text_3xl]}>
@@ -105,8 +96,8 @@ export function StepSuggestedStarterpacks() {
<Button <Button
color="secondary" color="secondary"
size="large" size="large"
label={_(msg`Skip this flow`)} label={_(msg`Skip to next step`)}
onPress={skipOnboarding}> onPress={() => dispatch({type: 'next'})}>
<ButtonText> <ButtonText>
<Trans>Skip</Trans> <Trans>Skip</Trans>
</ButtonText> </ButtonText>