Replace all tests with maestro
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: ?users
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
|
||||||
|
# Post an image with the porn label
|
||||||
|
- tapOn:
|
||||||
|
id: "composeFAB"
|
||||||
|
- inputText: "Post with an image"
|
||||||
|
- tapOn:
|
||||||
|
id: "openGalleryBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "labelsBtn"
|
||||||
|
- tapOn:
|
||||||
|
label: "Tap on porn"
|
||||||
|
point: 78%,67%
|
||||||
|
- tapOn:
|
||||||
|
label: "Tap on confirm"
|
||||||
|
point: 51%,92%
|
||||||
|
- tapOn:
|
||||||
|
id: "composerPublishBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eRefreshHome"
|
||||||
|
- assertVisible: "Adult Content"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eOpenLoggedOutView"
|
||||||
|
- tapOn: "Sign in"
|
||||||
|
- tapOn:
|
||||||
|
id: "selectServiceButton"
|
||||||
|
- tapOn: "Custom"
|
||||||
|
- tapOn:
|
||||||
|
id: "customServerTextInput"
|
||||||
|
- inputText: "http://localhost:3000"
|
||||||
|
- tapOn: "Done"
|
||||||
|
- tapOn:
|
||||||
|
id: "loginUsernameInput"
|
||||||
|
- inputText: "Alice"
|
||||||
|
- tapOn:
|
||||||
|
id: "loginPasswordInput"
|
||||||
|
- inputText: "hunter2"
|
||||||
|
- pressKey: Enter
|
||||||
|
- assertVisible: "Following"
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users&follows&labels"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
|
||||||
|
# create a modlist
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eGotoModeration"
|
||||||
|
- tapOn:
|
||||||
|
id: "moderationlistsBtn"
|
||||||
|
- tapOn: "New"
|
||||||
|
- tapOn:
|
||||||
|
id: "editNameInput"
|
||||||
|
- inputText: "Muted Users"
|
||||||
|
- tapOn:
|
||||||
|
id: "editDescriptionInput"
|
||||||
|
- inputText: "Shhh"
|
||||||
|
- tapOn: "Save"
|
||||||
|
- tapOn: "Save"
|
||||||
|
|
||||||
|
# view modlist
|
||||||
|
- assertVisible: "Muted Users"
|
||||||
|
- assertVisible: "Shhh"
|
||||||
|
|
||||||
|
# toggle mute subscription
|
||||||
|
- tapOn:
|
||||||
|
point: "70%,9%"
|
||||||
|
- tapOn: "Mute accounts"
|
||||||
|
- tapOn: "Mute list"
|
||||||
|
- tapOn: "Unmute"
|
||||||
|
|
||||||
|
# toggle block subscription
|
||||||
|
- tapOn:
|
||||||
|
point: "70%,9%"
|
||||||
|
- tapOn: "Block accounts"
|
||||||
|
- tapOn: "Block list"
|
||||||
|
- tapOn: "Unblock"
|
||||||
|
|
||||||
|
# the rest of the behaviors are tested in curate-lists.yml
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users&posts&feeds"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
|
||||||
|
|
||||||
|
# Navigate to my profile
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarProfileBtn"
|
||||||
|
|
||||||
|
# Can see feeds
|
||||||
|
- swipe:
|
||||||
|
from:
|
||||||
|
id: "profilePager-selector"
|
||||||
|
direction: LEFT
|
||||||
|
- tapOn:
|
||||||
|
id: "profilePager-selector-4"
|
||||||
|
- assertVisible:
|
||||||
|
id: "feed-alice-favs"
|
||||||
|
- swipe:
|
||||||
|
from:
|
||||||
|
id: "profilePager-selector"
|
||||||
|
direction: RIGHT
|
||||||
|
- tapOn:
|
||||||
|
id: "profilePager-selector-0"
|
||||||
|
|
||||||
|
# Open and close edit profile modal
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderEditProfileButton"
|
||||||
|
- assertVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileCancelBtn"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
|
||||||
|
# Edit display name and description via the edit profile modal
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderEditProfileButton"
|
||||||
|
- assertVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileDisplayNameInput"
|
||||||
|
- eraseText
|
||||||
|
- inputText: "Alicia"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileDescriptionInput"
|
||||||
|
- eraseText
|
||||||
|
- inputText: "One cool hacker"
|
||||||
|
- tapOn: "Description"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileSaveBtn"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- assertVisible: "Alicia"
|
||||||
|
- assertVisible: "One cool hacker"
|
||||||
|
|
||||||
|
# Remove display name and description via the edit profile modal
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderEditProfileButton"
|
||||||
|
- assertVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileDisplayNameInput"
|
||||||
|
- eraseText
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileDescriptionInput"
|
||||||
|
- eraseText
|
||||||
|
- tapOn: "Description"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileSaveBtn"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- assertVisible: "alice.test"
|
||||||
|
- assertNotVisible: "One cool hacker"
|
||||||
|
|
||||||
|
# Set avi and banner via the edit profile modal
|
||||||
|
- assertVisible:
|
||||||
|
id: "userBannerFallback"
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderEditProfileButton"
|
||||||
|
- assertVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- tapOn:
|
||||||
|
id: "changeBannerBtn"
|
||||||
|
- tapOn: "Upload from Library"
|
||||||
|
- tapOn:
|
||||||
|
id: "changeAvatarBtn"
|
||||||
|
- tapOn: "Upload from Library"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileSaveBtn"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- assertVisible:
|
||||||
|
id: "userBannerImage"
|
||||||
|
|
||||||
|
# # Remove avi and banner via the edit profile modal
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderEditProfileButton"
|
||||||
|
- assertVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- tapOn:
|
||||||
|
id: "changeBannerBtn"
|
||||||
|
- tapOn: "Remove Banner"
|
||||||
|
- tapOn:
|
||||||
|
id: "changeAvatarBtn"
|
||||||
|
- tapOn: "Remove Avatar"
|
||||||
|
- tapOn:
|
||||||
|
id: "editProfileSaveBtn"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "editProfileModal"
|
||||||
|
- assertVisible:
|
||||||
|
id: "userBannerFallback"
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users&posts&feeds"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
|
||||||
|
# Navigate to another user profile
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarSearchBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "searchTextInput"
|
||||||
|
- inputText: "b"
|
||||||
|
- tapOn:
|
||||||
|
id: "searchAutoCompleteResult-bob.test"
|
||||||
|
- assertVisible:
|
||||||
|
id: "profileView"
|
||||||
|
|
||||||
|
# Can follow/unfollow another user
|
||||||
|
- tapOn:
|
||||||
|
id: "followBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "unfollowBtn"
|
||||||
|
|
||||||
|
# Can mute/unmute another user
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderDropdownBtn"
|
||||||
|
- tapOn: "Mute Account"
|
||||||
|
- assertVisible: "Account Muted"
|
||||||
|
- tapOn:
|
||||||
|
id: "profileHeaderDropdownBtn"
|
||||||
|
- tapOn: "Unmute Account"
|
||||||
|
- assertNotVisible: "Account Muted"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
|
||||||
|
# Navigate to another user profile via autocomplete
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarSearchBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "searchTextInput"
|
||||||
|
- inputText: "b"
|
||||||
|
- tapOn:
|
||||||
|
id: "searchAutoCompleteResult-bob.test"
|
||||||
|
- assertVisible:
|
||||||
|
id: "profileView"
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users&follows"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
|
||||||
|
|
||||||
|
# Login, create a thread, and log out
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
- tapOn:
|
||||||
|
id: "composeFAB"
|
||||||
|
- inputText: "Test thread"
|
||||||
|
- tapOn:
|
||||||
|
id: "composerPublishBtn"
|
||||||
|
|
||||||
|
# Login, reply to the thread, and log out
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInBob"
|
||||||
|
- tapOn:
|
||||||
|
id: "replyBtn"
|
||||||
|
- inputText: "Reply 1"
|
||||||
|
- tapOn:
|
||||||
|
id: "composerPublishBtn"
|
||||||
|
|
||||||
|
# Login, confirm notification exists, mute thread, and log out
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarNotificationsBtn"
|
||||||
|
- assertVisible:
|
||||||
|
id: "feedItem-by-bob.test"
|
||||||
|
- tapOn:
|
||||||
|
id: "feedItem-by-bob.test"
|
||||||
|
- tapOn:
|
||||||
|
id: "postDropdownBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-bob.test"
|
||||||
|
- tapOn: "Mute thread"
|
||||||
|
|
||||||
|
# Login, reply to the thread twice, and log out
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInBob"
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarProfileBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "profilePager-selector-1"
|
||||||
|
- tapOn:
|
||||||
|
id: "replyBtn"
|
||||||
|
- inputText: "Reply 2"
|
||||||
|
- tapOn:
|
||||||
|
id: "composerPublishBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "replyBtn"
|
||||||
|
- inputText: "Reply 3"
|
||||||
|
- tapOn:
|
||||||
|
id: "composerPublishBtn"
|
||||||
|
|
||||||
|
|
||||||
|
# Login, confirm notifications dont exist, unmute the thread, confirm notifications exist
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarNotificationsBtn"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "feedItem-by-bob.test"
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarHomeBtn"
|
||||||
|
- tapOn:
|
||||||
|
id: "postDropdownBtn"
|
||||||
|
- tapOn: "Unmute thread"
|
||||||
|
- tapOn:
|
||||||
|
id: "bottomBarNotificationsBtn"
|
||||||
|
- swipe:
|
||||||
|
from:
|
||||||
|
id: "notifsFeed"
|
||||||
|
direction: DOWN
|
||||||
|
- assertVisible:
|
||||||
|
id: "feedItem-by-bob.test"
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
appId: xyz.blueskyweb.app
|
||||||
|
---
|
||||||
|
- runScript:
|
||||||
|
file: ../setupServer.js
|
||||||
|
env:
|
||||||
|
SERVER_PATH: "?users&follows&thread"
|
||||||
|
- runFlow:
|
||||||
|
file: ../setupApp.yml
|
||||||
|
- tapOn:
|
||||||
|
id: "e2eSignInAlice"
|
||||||
|
|
||||||
|
|
||||||
|
# Navigate to thread
|
||||||
|
- tapOn: "Thread root"
|
||||||
|
- assertVisible: "Thread reply"
|
||||||
|
|
||||||
|
# Can like the root post
|
||||||
|
- tapOn:
|
||||||
|
id: "likeBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-bob.test"
|
||||||
|
- assertVisible:
|
||||||
|
id: "likeCount-expanded"
|
||||||
|
- tapOn:
|
||||||
|
id: "likeBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-bob.test"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "likeCount-expanded"
|
||||||
|
|
||||||
|
# Can like a reply post
|
||||||
|
- tapOn:
|
||||||
|
id: "likeBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
- assertVisible:
|
||||||
|
id: "likeCount"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
- tapOn:
|
||||||
|
id: "likeBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "likeCount"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
|
||||||
|
# Can repost the root post
|
||||||
|
- tapOn:
|
||||||
|
id: "repostBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-bob.test"
|
||||||
|
- tapOn: "Repost"
|
||||||
|
- assertVisible:
|
||||||
|
id: "repostCount-expanded"
|
||||||
|
- tapOn:
|
||||||
|
id: "repostBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-bob.test"
|
||||||
|
- tapOn: "Undo repost"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "repostCount-expanded"
|
||||||
|
|
||||||
|
|
||||||
|
# Can repost a reply post
|
||||||
|
- tapOn:
|
||||||
|
id: "repostBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
- tapOn: "Repost"
|
||||||
|
- assertVisible:
|
||||||
|
id: "repostCount"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
- tapOn:
|
||||||
|
id: "repostBtn"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
|
- tapOn: "Undo repost"
|
||||||
|
- assertNotVisible:
|
||||||
|
id: "repostCount"
|
||||||
|
childOf:
|
||||||
|
id: "postThreadItem-by-carla.test"
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/** @type {import('@jest/types').Config.InitialOptions} */
|
|
||||||
module.exports = {
|
|
||||||
rootDir: '..',
|
|
||||||
testMatch: ['<rootDir>/__e2e__/**/*.test.ts'],
|
|
||||||
testTimeout: 120000,
|
|
||||||
maxWorkers: 1,
|
|
||||||
globalSetup: 'detox/runners/jest/globalSetup',
|
|
||||||
globalTeardown: 'detox/runners/jest/globalTeardown',
|
|
||||||
reporters: ['detox/runners/jest/reporter'],
|
|
||||||
testEnvironment: 'detox/runners/jest/testEnvironment',
|
|
||||||
verbose: true,
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
# flow.yaml
|
# flow.yaml
|
||||||
|
|
||||||
appId: xyz.blueskyweb.app
|
appId: xyz.blueskyweb.app
|
||||||
@@ -74,4 +75,3 @@ appId: xyz.blueskyweb.app
|
|||||||
- "scroll"
|
- "scroll"
|
||||||
- "scroll"
|
- "scroll"
|
||||||
- "scroll"
|
- "scroll"
|
||||||
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// eslint-disable-next-line
|
||||||
http.post('http://localhost:1986/' + SERVER_PATH, {
|
http.post('http://localhost:1986/' + SERVER_PATH, {
|
||||||
headers: {'Content-Type': 'text/plain'},
|
headers: {'Content-Type': 'text/plain'},
|
||||||
body: '',
|
body: '',
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {beforeAll, describe, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
|
|
||||||
import {createServer, loginAsAlice, openApp, sleep} from '../util'
|
|
||||||
|
|
||||||
describe('Composer', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users')
|
|
||||||
await openApp({
|
|
||||||
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Post text only', async () => {
|
|
||||||
await element(by.id('composeFAB')).tap()
|
|
||||||
await device.takeScreenshot('1- opened composer')
|
|
||||||
await element(by.id('composerTextInput')).typeText('Post text only')
|
|
||||||
await device.takeScreenshot('2- entered text')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await device.takeScreenshot('3- opened general section')
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Post with an image', async () => {
|
|
||||||
await element(by.id('composeFAB')).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Post with an image')
|
|
||||||
await element(by.id('openGalleryBtn')).tap()
|
|
||||||
await sleep(1e3)
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Post with a link card', async () => {
|
|
||||||
await element(by.id('composeFAB')).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText(
|
|
||||||
'Post with a https://example.com link card',
|
|
||||||
)
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Reply text only', async () => {
|
|
||||||
await element(by.id('e2eRefreshHome')).tap()
|
|
||||||
|
|
||||||
const post = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('replyBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Reply text only')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Reply with an image', async () => {
|
|
||||||
const post = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('replyBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Reply with an image')
|
|
||||||
await element(by.id('openGalleryBtn')).tap()
|
|
||||||
await sleep(1e3)
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Reply with a link card', async () => {
|
|
||||||
const post = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('replyBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText(
|
|
||||||
'Reply with a https://example.com link card',
|
|
||||||
)
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('QP text only', async () => {
|
|
||||||
const post = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await element(by.id('quoteBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('QP text only')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('QP with an image', async () => {
|
|
||||||
const post = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await element(by.id('quoteBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('QP with an image')
|
|
||||||
await element(by.id('openGalleryBtn')).tap()
|
|
||||||
await sleep(1e3)
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('QP with a link card', async () => {
|
|
||||||
const post = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await element(by.id('quoteBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText(
|
|
||||||
'QP with a https://example.com link card',
|
|
||||||
)
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Create account', () => {
|
|
||||||
let service: string
|
|
||||||
beforeAll(async () => {
|
|
||||||
service = await createServer('')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('I can create a new account', async () => {
|
|
||||||
await element(by.id('e2eOpenLoggedOutView')).tap()
|
|
||||||
|
|
||||||
await element(by.id('createAccountButton')).tap()
|
|
||||||
await device.takeScreenshot('1- opened create account screen')
|
|
||||||
await element(by.id('selectServiceButton')).tap()
|
|
||||||
await device.takeScreenshot('2- selected other server')
|
|
||||||
await element(by.id('customSelectBtn')).tap()
|
|
||||||
await element(by.id('customServerTextInput')).typeText(service)
|
|
||||||
await element(by.id('customServerTextInput')).tapReturnKey()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await device.takeScreenshot('3- input test server URL')
|
|
||||||
await element(by.id('emailInput')).typeText('example@test.com')
|
|
||||||
await element(by.id('passwordInput')).typeText('hunter2')
|
|
||||||
await device.takeScreenshot('4- entered account details')
|
|
||||||
|
|
||||||
await element(by.id('nextBtn')).tap()
|
|
||||||
|
|
||||||
await element(by.id('handleInput')).typeText('e2e-test')
|
|
||||||
await device.takeScreenshot('5- entered handle')
|
|
||||||
|
|
||||||
await element(by.id('nextBtn')).tap()
|
|
||||||
|
|
||||||
await expect(element(by.id('onboardingInterests'))).toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {beforeAll, describe, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
|
|
||||||
import {createServer, loginAsAlice, loginAsBob, openApp, sleep} from '../util'
|
|
||||||
|
|
||||||
describe('Curate lists', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users&follows&posts')
|
|
||||||
await openApp({
|
|
||||||
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login and create a curatelists', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('e2eGotoLists')).tap()
|
|
||||||
await element(by.id('newUserListBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editNameInput')).typeText('Good Ppl')
|
|
||||||
await element(by.id('editDescriptionInput')).typeText('They good')
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await element(by.text('About')).tap()
|
|
||||||
await expect(element(by.id('headerTitle'))).toHaveText('Good Ppl')
|
|
||||||
await expect(element(by.id('listDescription'))).toHaveText('They good')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Edit display name and description via the edit curatelist modal', async () => {
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Edit list details')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editNameInput')).clearText()
|
|
||||||
await element(by.id('editNameInput')).typeText('Bad Ppl')
|
|
||||||
await element(by.id('editDescriptionInput')).clearText()
|
|
||||||
await element(by.id('editDescriptionInput')).typeText('They bad')
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('headerTitle'))).toHaveText('Bad Ppl')
|
|
||||||
await expect(element(by.id('listDescription'))).toHaveText('They bad')
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Remove description via the edit curatelist modal', async () => {
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Edit list details')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editDescriptionInput')).clearText()
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('listDescription'))).not.toBeVisible()
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Set avi via the edit curatelist modal', async () => {
|
|
||||||
await expect(element(by.id('userAvatarFallback'))).toExist()
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Edit list details')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('changeAvatarBtn')).tap()
|
|
||||||
await element(by.text('Upload from Library')).tap()
|
|
||||||
await sleep(3e3)
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('userAvatarImage'))).toExist()
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Remove avi via the edit curatelist modal', async () => {
|
|
||||||
await expect(element(by.id('userAvatarImage'))).toExist()
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Edit list details')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('changeAvatarBtn')).tap()
|
|
||||||
await element(by.text('Remove Avatar')).tap()
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('userAvatarFallback'))).toExist()
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Delete the curatelist', async () => {
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Delete List')).tap()
|
|
||||||
await element(by.id('confirmBtn')).tap()
|
|
||||||
await expect(element(by.id('listsEmpty'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Create a new curatelist', async () => {
|
|
||||||
await element(by.id('e2eGotoLists')).tap()
|
|
||||||
await element(by.id('newUserListBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editNameInput')).typeText('Good Ppl')
|
|
||||||
await element(by.id('editDescriptionInput')).typeText('They good')
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await element(by.text('About')).tap()
|
|
||||||
await expect(element(by.id('headerTitle'))).toHaveText('Good Ppl')
|
|
||||||
await expect(element(by.id('listDescription'))).toHaveText('They good')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Adds users on curatelists from the list', async () => {
|
|
||||||
await element(by.text('About')).tap()
|
|
||||||
await element(by.id('addUserBtn')).tap()
|
|
||||||
await expect(element(by.id('listAddUserModal'))).toBeVisible()
|
|
||||||
await element(by.id('searchInput')).typeText('b')
|
|
||||||
await waitFor(element(by.id('user-bob.test-addBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
await element(by.id('user-bob.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('listAddUserModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('user-bob.test'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Shows posts by the users in the list', async () => {
|
|
||||||
await element(by.text('Posts')).tap()
|
|
||||||
await expect(element(by.id('feedItem-by-bob.test'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Pins the list', async () => {
|
|
||||||
await expect(element(by.id('pinBtn'))).toBeVisible()
|
|
||||||
await element(by.id('pinBtn')).tap()
|
|
||||||
await element(by.id('e2eGotoHome')).tap()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Good Ppl')).tap()
|
|
||||||
await expect(element(by.id('feedItem-by-bob.test'))).toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('bottomBarFeedsBtn')).tap()
|
|
||||||
await element(by.id('saved-feed-Good Ppl')).tap()
|
|
||||||
await expect(element(by.id('feedItem-by-bob.test'))).toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('unpinBtn')).tap()
|
|
||||||
await element(by.id('bottomBarHomeBtn')).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('homeScreenFeedTabs-Good Ppl')),
|
|
||||||
).not.toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('e2eGotoLists')).tap()
|
|
||||||
await element(by.id('list-Good Ppl')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Removes users on curatelists from the list', async () => {
|
|
||||||
await element(by.text('About')).tap()
|
|
||||||
await expect(element(by.id('user-bob.test'))).toBeVisible()
|
|
||||||
await element(by.id('user-bob.test-editBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).toBeVisible()
|
|
||||||
await element(by.id('user-bob.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Shows the curatelist on my profile', async () => {
|
|
||||||
await element(by.id('bottomBarProfileBtn')).tap()
|
|
||||||
await element(by.id('profilePager-selector')).swipe('left')
|
|
||||||
await element(by.id('profilePager-selector-5')).tap()
|
|
||||||
await element(by.id('list-Good Ppl')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Adds and removes users on curatelists from the profile', async () => {
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('bob')
|
|
||||||
await element(by.id('searchAutoCompleteResult-bob.test')).tap()
|
|
||||||
await expect(element(by.id('profileView'))).toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
await element(by.text('Add to Lists')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).toBeVisible()
|
|
||||||
await element(by.id('user-bob.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).not.toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
await element(by.text('Add to Lists')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).toBeVisible()
|
|
||||||
await element(by.id('user-bob.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can report a user list', async () => {
|
|
||||||
await element(by.id('e2eGotoSettings')).tap()
|
|
||||||
await element(by.id('signOutBtn')).tap()
|
|
||||||
await loginAsBob()
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('alice')
|
|
||||||
await element(by.id('searchAutoCompleteResult-alice.test')).tap()
|
|
||||||
await element(by.id('profilePager-selector')).swipe('left')
|
|
||||||
await element(by.id('profilePager-selector-3')).tap()
|
|
||||||
await element(by.id('list-Good Ppl')).tap()
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Report List')).tap()
|
|
||||||
await expect(element(by.id('reportModal'))).toBeVisible()
|
|
||||||
await expect(element(by.text('Report List'))).toBeVisible()
|
|
||||||
await element(
|
|
||||||
by.id('reportReasonRadios-com.atproto.moderation.defs#reasonRude'),
|
|
||||||
).tap()
|
|
||||||
await element(by.id('sendReportBtn')).tap()
|
|
||||||
await expect(element(by.id('reportModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {beforeAll, describe, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
|
|
||||||
import {createServer, loginAsAlice, openApp} from '../util'
|
|
||||||
|
|
||||||
describe('Home screen', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users&follows&posts&feeds')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can go to feeds page using feeds button in tab bar', async () => {
|
|
||||||
await element(by.id('homeScreenFeedTabs-Feeds ✨')).tap()
|
|
||||||
await expect(element(by.text('Discover New Feeds'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Feeds button disappears after pinning a feed', async () => {
|
|
||||||
await element(by.id('bottomBarProfileBtn')).tap()
|
|
||||||
await element(by.id('profilePager-selector')).swipe('left')
|
|
||||||
await element(by.id('profilePager-selector-4')).tap()
|
|
||||||
await element(by.id('feed-alice-favs')).tap()
|
|
||||||
await element(by.id('pinBtn')).tap()
|
|
||||||
await element(by.id('bottomBarHomeBtn')).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('homeScreenFeedTabs-Feeds ✨')),
|
|
||||||
).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can like posts', async () => {
|
|
||||||
const carlaPosts = by.id('feedItem-by-carla.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(carlaPosts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('likeBtn').withAncestor(carlaPosts)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(carlaPosts)).atIndex(0),
|
|
||||||
).toHaveText('1')
|
|
||||||
await element(by.id('likeBtn').withAncestor(carlaPosts)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(carlaPosts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can repost posts', async () => {
|
|
||||||
const carlaPosts = by.id('feedItem-by-carla.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(carlaPosts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('repostBtn').withAncestor(carlaPosts)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(carlaPosts)).atIndex(0),
|
|
||||||
).toHaveText('1')
|
|
||||||
await element(by.id('repostBtn').withAncestor(carlaPosts)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(carlaPosts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
// TODO skipping because the test env PDS isnt setup correctly to handle the report -prf
|
|
||||||
// it('Can report posts', async () => {
|
|
||||||
// const carlaPosts = by.id('feedItem-by-carla.test')
|
|
||||||
// await element(by.id('postDropdownBtn').withAncestor(carlaPosts))
|
|
||||||
// .atIndex(0)
|
|
||||||
// .tap()
|
|
||||||
// await element(by.text('Report post')).tap()
|
|
||||||
// await element(by.id('com.atproto.moderation.defs#reasonSpam')).tap()
|
|
||||||
// await element(by.id('sendReportBtn')).tap()
|
|
||||||
// })
|
|
||||||
|
|
||||||
it('Can swipe between feeds', async () => {
|
|
||||||
await element(by.id('homeScreen')).swipe('left', 'fast', 0.75)
|
|
||||||
await expect(element(by.id('customFeedPage'))).toBeVisible()
|
|
||||||
await element(by.id('homeScreen')).swipe('right', 'fast', 0.75)
|
|
||||||
await expect(element(by.id('followingFeedPage'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can tap between feeds', async () => {
|
|
||||||
await element(by.id('homeScreenFeedTabs-alice-favs')).tap()
|
|
||||||
await expect(element(by.id('customFeedPage'))).toBeVisible()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
await expect(element(by.id('followingFeedPage'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can delete posts', async () => {
|
|
||||||
const alicePosts = by.id('feedItem-by-alice.test')
|
|
||||||
await expect(element(alicePosts.withDescendant(by.text('Post')))).toExist()
|
|
||||||
await element(by.id('postDropdownBtn').withAncestor(alicePosts))
|
|
||||||
.atIndex(0)
|
|
||||||
.tap()
|
|
||||||
await element(by.text('Delete post')).tap()
|
|
||||||
await expect(element(by.id('confirmModal'))).toBeVisible()
|
|
||||||
await element(by.id('confirmBtn')).tap()
|
|
||||||
await expect(
|
|
||||||
element(alicePosts.withDescendant(by.text('Post'))),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {beforeAll, describe, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
|
|
||||||
import {createServer, loginAsAlice, openApp} from '../util'
|
|
||||||
|
|
||||||
describe('invite-codes', () => {
|
|
||||||
let service: string
|
|
||||||
let inviteCode = ''
|
|
||||||
beforeAll(async () => {
|
|
||||||
service = await createServer('?users&invite')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('I can fetch invite codes', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('e2eOpenInviteCodesModal')).tap()
|
|
||||||
await expect(element(by.id('inviteCodesModal'))).toBeVisible()
|
|
||||||
const attrs = await element(by.id('inviteCode-0-code')).getAttributes()
|
|
||||||
inviteCode = attrs.text
|
|
||||||
await element(by.id('closeBtn')).tap()
|
|
||||||
await element(by.id('e2eSignOut')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('I can create a new account with the invite code', async () => {
|
|
||||||
await element(by.id('e2eOpenLoggedOutView')).tap()
|
|
||||||
await element(by.id('createAccountButton')).tap()
|
|
||||||
await device.takeScreenshot('1- opened create account screen')
|
|
||||||
await element(by.id('selectServiceButton')).tap()
|
|
||||||
await device.takeScreenshot('2- selected other server')
|
|
||||||
await element(by.id('customSelectBtn')).tap()
|
|
||||||
await element(by.id('customServerTextInput')).typeText(service)
|
|
||||||
await element(by.id('customServerTextInput')).tapReturnKey()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await device.takeScreenshot('3- input test server URL')
|
|
||||||
await element(by.id('inviteCodeInput')).typeText(inviteCode)
|
|
||||||
await element(by.id('emailInput')).typeText('example@test.com')
|
|
||||||
await element(by.id('passwordInput')).typeText('hunter2')
|
|
||||||
await device.takeScreenshot('4- entered account details')
|
|
||||||
await element(by.id('nextBtn')).tap()
|
|
||||||
await element(by.id('handleInput')).typeText('e2e-test')
|
|
||||||
await device.takeScreenshot('4- entered handle')
|
|
||||||
await element(by.id('nextBtn')).tap()
|
|
||||||
await expect(element(by.id('onboardingInterests'))).toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, login, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Login', () => {
|
|
||||||
let service: string
|
|
||||||
beforeAll(async () => {
|
|
||||||
service = await createServer('?users')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('As Alice, I can login', async () => {
|
|
||||||
await element(by.id('e2eOpenLoggedOutView')).tap()
|
|
||||||
|
|
||||||
await expect(element(by.id('signInButton'))).toBeVisible()
|
|
||||||
await login(service, 'alice', 'hunter2', {
|
|
||||||
takeScreenshots: true,
|
|
||||||
})
|
|
||||||
await device.takeScreenshot('5- opened home screen')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, loginAsAlice, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Mergefeed', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?mergefeed')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login', async () => {
|
|
||||||
await element(by.id('e2eOpenLoggedOutView')).tap()
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('e2eToggleMergefeed')).tap()
|
|
||||||
await element(by.id('bottomBarFeedsBtn')).tap()
|
|
||||||
await element(by.id('feed-alice-favs-toggleSave')).tap()
|
|
||||||
await element(by.id('e2eGotoHome')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Sees the expected mix of posts with default filters', async () => {
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'slow',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
// followed users
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-carla.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 9')
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-bob.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 9')
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'up',
|
|
||||||
'fast',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
// feed users
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-dan.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 0')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Sees the expected mix of posts with replies disabled', async () => {
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'fast',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'fast',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
await element(by.id('viewHeaderHomeFeedPrefsBtn')).tap()
|
|
||||||
await element(by.id('toggleRepliesBtn')).tap()
|
|
||||||
await element(by.id('confirmBtn')).tap()
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'slow',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
|
|
||||||
// followed users
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-carla.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 9')
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-bob.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 9')
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'up',
|
|
||||||
'fast',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
|
|
||||||
// feed users
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-dan.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 0')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Sees the expected mix of posts with no follows', async () => {
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'fast',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('bob')
|
|
||||||
await element(by.id('searchAutoCompleteResult-bob.test')).tap()
|
|
||||||
await expect(element(by.id('profileView'))).toBeVisible()
|
|
||||||
await element(by.id('unfollowBtn')).tap()
|
|
||||||
await element(by.id('profileHeaderBackBtn')).tap()
|
|
||||||
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('searchTextInputClearBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
await element(by.id('searchTextInputClearBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('carla')
|
|
||||||
await element(by.id('searchAutoCompleteResult-carla.test')).tap()
|
|
||||||
await expect(element(by.id('profileView'))).toBeVisible()
|
|
||||||
await element(by.id('unfollowBtn')).tap()
|
|
||||||
await element(by.id('profileHeaderBackBtn')).tap()
|
|
||||||
|
|
||||||
await element(by.id('bottomBarHomeBtn')).tap()
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'slow',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
await element(by.id('followingFeedPage-feed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'slow',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
|
|
||||||
// followed users NOT present
|
|
||||||
await expect(element(by.id('feedItem-by-carla.test'))).not.toExist()
|
|
||||||
await expect(element(by.id('feedItem-by-bob.test'))).not.toExist()
|
|
||||||
|
|
||||||
// feed users
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by.id('postText').withAncestor(by.id('feedItem-by-dan.test')),
|
|
||||||
).atIndex(0),
|
|
||||||
).toHaveText('Post 0')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, loginAsAlice, loginAsBob, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Mod lists', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users&follows&labels')
|
|
||||||
await openApp({
|
|
||||||
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login and view my modlists', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('e2eGotoModeration')).tap()
|
|
||||||
await element(by.id('moderationlistsBtn')).tap()
|
|
||||||
await expect(element(by.id('list-Muted Users'))).toBeVisible()
|
|
||||||
await element(by.id('list-Muted Users')).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('user-muted-by-list-account.test')),
|
|
||||||
).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Toggle mute subscription', async () => {
|
|
||||||
await element(by.id('unmuteBtn')).tap()
|
|
||||||
await element(by.id('subscribeBtn')).tap()
|
|
||||||
await element(by.text('Mute accounts')).tap()
|
|
||||||
await element(by.id('confirmBtn')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Edit display name and description via the edit modlist modal', async () => {
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Edit list details')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editNameInput')).clearText()
|
|
||||||
await element(by.id('editNameInput')).typeText('Bad Ppl')
|
|
||||||
await element(by.id('editDescriptionInput')).clearText()
|
|
||||||
await element(by.id('editDescriptionInput')).typeText('They bad')
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('headerTitle'))).toHaveText('Bad Ppl')
|
|
||||||
await expect(element(by.id('listDescription'))).toHaveText('They bad')
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Remove description via the edit modlist modal', async () => {
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Edit list details')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editDescriptionInput')).clearText()
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('listDescription'))).not.toBeVisible()
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
// DISABLED e2e environment is real finicky about avatar uploads -prf
|
|
||||||
// it('Set avi via the edit modlist modal', async () => {
|
|
||||||
// await expect(element(by.id('userAvatarFallback'))).toExist()
|
|
||||||
// await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
// await element(by.text('Edit list details')).tap()
|
|
||||||
// await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
// await element(by.id('changeAvatarBtn')).tap()
|
|
||||||
// await element(by.text('Library')).tap()
|
|
||||||
// await sleep(3e3)
|
|
||||||
// await element(by.id('saveBtn')).tap()
|
|
||||||
// await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
// await expect(element(by.id('userAvatarImage'))).toExist()
|
|
||||||
// // have to wait for the toast to clear
|
|
||||||
// await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
// .toBeVisible()
|
|
||||||
// .withTimeout(5000)
|
|
||||||
// })
|
|
||||||
|
|
||||||
// it('Remove avi via the edit modlist modal', async () => {
|
|
||||||
// await expect(element(by.id('userAvatarImage'))).toExist()
|
|
||||||
// await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
// await element(by.text('Edit list details')).tap()
|
|
||||||
// await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
// await element(by.id('changeAvatarBtn')).tap()
|
|
||||||
// await element(by.text('Remove')).tap()
|
|
||||||
// await element(by.id('saveBtn')).tap()
|
|
||||||
// await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
// await expect(element(by.id('userAvatarFallback'))).toExist()
|
|
||||||
// // have to wait for the toast to clear
|
|
||||||
// await waitFor(element(by.id('headerDropdownBtn')))
|
|
||||||
// .toBeVisible()
|
|
||||||
// .withTimeout(5000)
|
|
||||||
// })
|
|
||||||
|
|
||||||
it('Delete the modlist', async () => {
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Delete List')).tap()
|
|
||||||
await element(by.id('confirmBtn')).tap()
|
|
||||||
await expect(element(by.id('listsEmpty'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Create a new modlist', async () => {
|
|
||||||
await element(by.id('newModListBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).toBeVisible()
|
|
||||||
await element(by.id('editNameInput')).typeText('Bad Ppl')
|
|
||||||
await element(by.id('editDescriptionInput')).typeText('They bad')
|
|
||||||
await element(by.id('saveBtn')).tap()
|
|
||||||
await expect(element(by.id('createOrEditListModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('headerTitle'))).toHaveText('Bad Ppl')
|
|
||||||
await expect(element(by.id('listDescription'))).toHaveText('They bad')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Adds and removes users on modlists from the list', async () => {
|
|
||||||
await element(by.id('addUserBtn')).tap()
|
|
||||||
await expect(element(by.id('listAddUserModal'))).toBeVisible()
|
|
||||||
await waitFor(element(by.id('user-warn-posts.test-addBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
await element(by.id('user-warn-posts.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('listAddUserModal'))).not.toBeVisible()
|
|
||||||
await element(by.id('listItems-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'slow',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
await expect(element(by.id('user-warn-posts.test'))).toBeVisible()
|
|
||||||
await element(by.id('user-warn-posts.test-editBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).toBeVisible()
|
|
||||||
await element(by.id('user-warn-posts.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Shows the modlist on my profile', async () => {
|
|
||||||
await element(by.id('bottomBarProfileBtn')).tap()
|
|
||||||
await element(by.id('profilePager-selector')).swipe('left')
|
|
||||||
await element(by.id('profilePager-selector-5')).tap()
|
|
||||||
await element(by.id('list-Bad Ppl')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Adds and removes users on modlists from the profile', async () => {
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('bob')
|
|
||||||
await element(by.id('searchAutoCompleteResult-bob.test')).tap()
|
|
||||||
await expect(element(by.id('profileView'))).toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
await element(by.text('Add to Lists')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).toBeVisible()
|
|
||||||
await element(by.id('user-bob.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).not.toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
await element(by.text('Add to Lists')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).toBeVisible()
|
|
||||||
await element(by.id('user-bob.test-addBtn')).tap()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
await expect(element(by.id('userAddRemoveListsModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can report a mute list', async () => {
|
|
||||||
await element(by.id('e2eGotoSettings')).tap()
|
|
||||||
await element(by.id('signOutBtn')).tap()
|
|
||||||
await loginAsBob()
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('alice')
|
|
||||||
await element(by.id('searchAutoCompleteResult-alice.test')).tap()
|
|
||||||
await element(by.id('profilePager-selector')).swipe('left')
|
|
||||||
await element(by.id('profilePager-selector-3')).tap()
|
|
||||||
await element(by.id('list-Bad Ppl')).tap()
|
|
||||||
await element(by.id('headerDropdownBtn')).tap()
|
|
||||||
await element(by.text('Report List')).tap()
|
|
||||||
await expect(element(by.id('reportModal'))).toBeVisible()
|
|
||||||
await expect(element(by.text('Report List'))).toBeVisible()
|
|
||||||
await element(
|
|
||||||
by.id('reportReasonRadios-com.atproto.moderation.defs#reasonRude'),
|
|
||||||
).tap()
|
|
||||||
await element(by.id('sendReportBtn')).tap()
|
|
||||||
await expect(element(by.id('reportModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,196 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {beforeAll, describe, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
|
|
||||||
import {createServer, loginAsAlice, openApp, sleep} from '../util'
|
|
||||||
|
|
||||||
describe('Profile screen', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users&posts&feeds')
|
|
||||||
await openApp({
|
|
||||||
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login and navigate to my profile', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('bottomBarProfileBtn')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can see feeds', async () => {
|
|
||||||
await element(by.id('profilePager-selector')).swipe('left')
|
|
||||||
await element(by.id('profilePager-selector-4')).tap()
|
|
||||||
await expect(element(by.id('feed-alice-favs'))).toBeVisible()
|
|
||||||
await element(by.id('profilePager-selector')).swipe('right')
|
|
||||||
await element(by.id('profilePager-selector-0')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Open and close edit profile modal', async () => {
|
|
||||||
await element(by.id('profileHeaderEditProfileButton')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).toBeVisible()
|
|
||||||
await element(by.id('editProfileCancelBtn')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Edit display name and description via the edit profile modal', async () => {
|
|
||||||
await element(by.id('profileHeaderEditProfileButton')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).toBeVisible()
|
|
||||||
await element(by.id('editProfileDisplayNameInput')).clearText()
|
|
||||||
await element(by.id('editProfileDisplayNameInput')).typeText('Alicia')
|
|
||||||
await element(by.id('editProfileDescriptionInput')).clearText()
|
|
||||||
await element(by.id('editProfileDescriptionInput')).typeText(
|
|
||||||
'One cool hacker',
|
|
||||||
)
|
|
||||||
await element(by.id('editProfileSaveBtn')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('profileHeaderDisplayName'))).toHaveText(
|
|
||||||
'Alicia',
|
|
||||||
)
|
|
||||||
await expect(element(by.id('profileHeaderDescription'))).toHaveText(
|
|
||||||
'One cool hacker',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Remove display name and description via the edit profile modal', async () => {
|
|
||||||
await element(by.id('profileHeaderEditProfileButton')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).toBeVisible()
|
|
||||||
await element(by.id('editProfileDisplayNameInput')).clearText()
|
|
||||||
await element(by.id('editProfileDescriptionInput')).clearText()
|
|
||||||
await element(by.id('editProfileSaveBtn')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('profileHeaderDisplayName'))).toHaveText(
|
|
||||||
'alice.test',
|
|
||||||
)
|
|
||||||
await expect(element(by.id('profileHeaderDescription'))).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Set avi and banner via the edit profile modal', async () => {
|
|
||||||
await expect(element(by.id('userBannerFallback'))).toExist()
|
|
||||||
await expect(element(by.id('userAvatarFallback'))).toExist()
|
|
||||||
await element(by.id('profileHeaderEditProfileButton')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).toBeVisible()
|
|
||||||
await element(by.id('changeBannerBtn')).tap()
|
|
||||||
await element(by.text('Upload from Library')).tap()
|
|
||||||
await sleep(3e3)
|
|
||||||
await element(by.id('changeAvatarBtn')).tap()
|
|
||||||
await element(by.text('Upload from Library')).tap()
|
|
||||||
await sleep(3e3)
|
|
||||||
await element(by.id('editProfileSaveBtn')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('userBannerImage'))).toExist()
|
|
||||||
await expect(element(by.id('userAvatarImage'))).toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Remove avi and banner via the edit profile modal', async () => {
|
|
||||||
await expect(element(by.id('userBannerImage'))).toExist()
|
|
||||||
await expect(element(by.id('userAvatarImage'))).toExist()
|
|
||||||
await element(by.id('profileHeaderEditProfileButton')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).toBeVisible()
|
|
||||||
await element(by.id('changeBannerBtn')).tap()
|
|
||||||
await element(by.text('Remove Banner')).tap()
|
|
||||||
await element(by.id('changeAvatarBtn')).tap()
|
|
||||||
await element(by.text('Remove Avatar')).tap()
|
|
||||||
await element(by.id('editProfileSaveBtn')).tap()
|
|
||||||
await expect(element(by.id('editProfileModal'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('userBannerFallback'))).toExist()
|
|
||||||
await expect(element(by.id('userAvatarFallback'))).toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Navigate to another user profile', async () => {
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('searchTextInput')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
await element(by.id('searchTextInput')).typeText('bob')
|
|
||||||
await element(by.id('searchAutoCompleteResult-bob.test')).tap()
|
|
||||||
await expect(element(by.id('profileView'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can follow/unfollow another user', async () => {
|
|
||||||
await element(by.id('followBtn')).tap()
|
|
||||||
await expect(element(by.id('unfollowBtn'))).toBeVisible()
|
|
||||||
await element(by.id('unfollowBtn')).tap()
|
|
||||||
await expect(element(by.id('followBtn'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can mute/unmute another user', async () => {
|
|
||||||
await expect(element(by.id('profileHeaderAlert'))).not.toExist()
|
|
||||||
await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
await element(by.text('Mute Account')).tap()
|
|
||||||
await expect(element(by.id('profileHeaderAlert'))).toBeVisible()
|
|
||||||
await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
await element(by.text('Unmute Account')).tap()
|
|
||||||
await expect(element(by.id('profileHeaderAlert'))).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
// TODO skipping because the test env PDS isnt setup correctly to handle the report -prf
|
|
||||||
// it('Can report another user', async () => {
|
|
||||||
// await element(by.id('profileHeaderDropdownBtn')).tap()
|
|
||||||
// await element(by.text('Report Account')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).toBeVisible()
|
|
||||||
// await element(
|
|
||||||
// by.id('reportReasonRadios-com.atproto.moderation.defs#reasonSpam'),
|
|
||||||
// ).tap()
|
|
||||||
// await element(by.id('sendReportBtn')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).not.toBeVisible()
|
|
||||||
// })
|
|
||||||
|
|
||||||
it('Can like posts', async () => {
|
|
||||||
await element(by.id('postsFeed-flatlist')).swipe(
|
|
||||||
'down',
|
|
||||||
'slow',
|
|
||||||
1,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
)
|
|
||||||
|
|
||||||
const posts = by.id('feedItem-by-bob.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(posts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('likeBtn').withAncestor(posts)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(posts)).atIndex(0),
|
|
||||||
).toHaveText('1')
|
|
||||||
await element(by.id('likeBtn').withAncestor(posts)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(posts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can repost posts', async () => {
|
|
||||||
const posts = by.id('feedItem-by-bob.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(posts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('repostBtn').withAncestor(posts)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(posts)).atIndex(0),
|
|
||||||
).toHaveText('1')
|
|
||||||
await element(by.id('repostBtn').withAncestor(posts)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(posts)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
// TODO skipping because the test env PDS isnt setup correctly to handle the report -prf
|
|
||||||
// it('Can report posts', async () => {
|
|
||||||
// const posts = by.id('feedItem-by-bob.test')
|
|
||||||
// await element(by.id('postDropdownBtn').withAncestor(posts)).atIndex(0).tap()
|
|
||||||
// await element(by.text('Report post')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).toBeVisible()
|
|
||||||
// await element(
|
|
||||||
// by.id('reportReasonRadios-com.atproto.moderation.defs#reasonSpam'),
|
|
||||||
// ).tap()
|
|
||||||
// await element(by.id('sendReportBtn')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).not.toBeVisible()
|
|
||||||
// })
|
|
||||||
})
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, loginAsAlice, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Search screen', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users')
|
|
||||||
await openApp({
|
|
||||||
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Navigate to another user profile via autocomplete', async () => {
|
|
||||||
await element(by.id('bottomBarSearchBtn')).tap()
|
|
||||||
await element(by.id('searchTextInput')).typeText('bob')
|
|
||||||
await element(by.id('searchAutoCompleteResult-bob.test')).tap()
|
|
||||||
await expect(element(by.id('profileView'))).toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, loginAsAlice, createServer, sleep} from '../util'
|
|
||||||
|
|
||||||
describe('Self-labeling', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users')
|
|
||||||
await openApp({
|
|
||||||
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Post an image with the porn label', async () => {
|
|
||||||
await element(by.id('composeFAB')).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Post with an image')
|
|
||||||
await element(by.id('openGalleryBtn')).tap()
|
|
||||||
await sleep(3e3)
|
|
||||||
await element(by.id('labelsBtn')).tap()
|
|
||||||
await element(by.id('pornLabelBtn')).tap()
|
|
||||||
await element(by.id('confirmBtn')).tap()
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
const posts = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('e2eRefreshHome')).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('contentHider-embed').withAncestor(posts)).atIndex(0),
|
|
||||||
).toExist()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {openApp, loginAsAlice, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Shell', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can swipe the shelf open', async () => {
|
|
||||||
await element(by.id('homeScreen')).swipe('right', 'fast', 0.75)
|
|
||||||
await expect(element(by.id('drawer'))).toBeVisible()
|
|
||||||
await element(by.id('drawer')).swipe('left', 'fast', 0.75)
|
|
||||||
await expect(element(by.id('drawer'))).not.toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can open the shelf by pressing the header avi', async () => {
|
|
||||||
await element(by.id('viewHeaderDrawerBtn')).tap()
|
|
||||||
await expect(element(by.id('drawer'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can navigate using the shelf', async () => {
|
|
||||||
await element(by.id('menuItemButton-Notifications')).tap()
|
|
||||||
await expect(element(by.id('drawer'))).not.toBeVisible()
|
|
||||||
await expect(element(by.id('notificationsScreen'))).toBeVisible()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {describe, beforeAll, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
import {openApp, loginAsAlice, loginAsBob, createServer} from '../util'
|
|
||||||
|
|
||||||
describe('Thread muting', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users&follows')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login, create a thread, and log out', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
await element(by.id('composeFAB')).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Test thread')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login, reply to the thread, and log out', async () => {
|
|
||||||
await loginAsBob()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
const alicePosts = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('replyBtn').withAncestor(alicePosts)).atIndex(0).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Reply 1')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login, confirm notification exists, mute thread, and log out', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('bottomBarNotificationsBtn')).tap()
|
|
||||||
const bobNotifs = by.id('feedItem-by-bob.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('postText').withAncestor(bobNotifs)).atIndex(0),
|
|
||||||
).toHaveText('Reply 1')
|
|
||||||
await element(by.id('postDropdownBtn').withAncestor(bobNotifs))
|
|
||||||
.atIndex(0)
|
|
||||||
.tap()
|
|
||||||
await element(by.text('Mute thread')).tap()
|
|
||||||
// have to wait for the toast to clear
|
|
||||||
await waitFor(element(by.id('viewHeaderDrawerBtn')))
|
|
||||||
.toBeVisible()
|
|
||||||
.withTimeout(5000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login, reply to the thread twice, and log out', async () => {
|
|
||||||
await loginAsBob()
|
|
||||||
|
|
||||||
await element(by.id('bottomBarProfileBtn')).tap()
|
|
||||||
await element(by.id('profilePager-selector-1')).tap()
|
|
||||||
const bobPosts = by.id('feedItem-by-bob.test')
|
|
||||||
await element(by.id('replyBtn').withAncestor(bobPosts)).atIndex(0).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Reply 2')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
|
|
||||||
const alicePosts = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('replyBtn').withAncestor(alicePosts)).atIndex(0).tap()
|
|
||||||
await element(by.id('composerTextInput')).typeText('Reply 3')
|
|
||||||
await element(by.id('composerPublishBtn')).tap()
|
|
||||||
await expect(element(by.id('composeFAB'))).toBeVisible()
|
|
||||||
|
|
||||||
await element(by.id('bottomBarHomeBtn')).tap()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login, confirm notifications dont exist, unmute the thread, confirm notifications exist', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
|
|
||||||
await element(by.id('bottomBarNotificationsBtn')).tap()
|
|
||||||
const bobNotifs = by.id('feedItem-by-bob.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('postText').withAncestor(bobNotifs)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
|
|
||||||
await element(by.id('bottomBarHomeBtn')).tap()
|
|
||||||
const alicePosts = by.id('feedItem-by-alice.test')
|
|
||||||
await element(by.id('postDropdownBtn').withAncestor(alicePosts))
|
|
||||||
.atIndex(0)
|
|
||||||
.tap()
|
|
||||||
await element(by.text('Unmute thread')).tap()
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// the swipe down to trigger PTR isnt working and I dont want to block on this
|
|
||||||
// -prf
|
|
||||||
// await element(by.id('bottomBarNotificationsBtn')).tap()
|
|
||||||
// await element(by.id('notifsFeed')).swipe('down', 'fast')
|
|
||||||
// await waitFor(element(by.id('postText').withAncestor(bobNotifs)))
|
|
||||||
// .toBeVisible()
|
|
||||||
// .withTimeout(5000)
|
|
||||||
// await expect(
|
|
||||||
// element(by.id('postText').withAncestor(bobNotifs)).atIndex(0),
|
|
||||||
// ).toHaveText('Reply 2')
|
|
||||||
// await expect(
|
|
||||||
// element(by.id('postText').withAncestor(bobNotifs)).atIndex(1),
|
|
||||||
// ).toHaveText('Reply 3')
|
|
||||||
// await expect(
|
|
||||||
// element(by.id('postText').withAncestor(bobNotifs)).atIndex(2),
|
|
||||||
// ).toHaveText('Reply 1')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/* eslint-env detox/detox */
|
|
||||||
|
|
||||||
import {beforeAll, describe, it} from '@jest/globals'
|
|
||||||
import {expect} from 'detox'
|
|
||||||
|
|
||||||
import {createServer, loginAsAlice, openApp} from '../util'
|
|
||||||
|
|
||||||
describe('Thread screen', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await createServer('?users&follows&thread')
|
|
||||||
await openApp({permissions: {notifications: 'YES'}})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Login & navigate to thread', async () => {
|
|
||||||
await loginAsAlice()
|
|
||||||
await element(by.id('homeScreenFeedTabs-Following')).tap()
|
|
||||||
await element(by.id('feedItem-by-bob.test')).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by
|
|
||||||
.id('postThreadItem-by-bob.test')
|
|
||||||
.withDescendant(by.text('Thread root')),
|
|
||||||
),
|
|
||||||
).toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(
|
|
||||||
by
|
|
||||||
.id('postThreadItem-by-carla.test')
|
|
||||||
.withDescendant(by.text('Thread reply')),
|
|
||||||
),
|
|
||||||
).toBeVisible()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can like the root post', async () => {
|
|
||||||
const post = by.id('postThreadItem-by-bob.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount-expanded').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('likeBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount-expanded').withAncestor(post)).atIndex(0),
|
|
||||||
).toHaveText('1 like')
|
|
||||||
await element(by.id('likeBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount-expanded').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can like a reply post', async () => {
|
|
||||||
const post = by.id('postThreadItem-by-carla.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('likeBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(post)).atIndex(0),
|
|
||||||
).toHaveText('1')
|
|
||||||
await element(by.id('likeBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(
|
|
||||||
element(by.id('likeCount').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can repost the root post', async () => {
|
|
||||||
const post = by.id('postThreadItem-by-bob.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount-expanded').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount-expanded').withAncestor(post)).atIndex(0),
|
|
||||||
).toHaveText('1 repost')
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount-expanded').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Can repost a reply post', async () => {
|
|
||||||
const post = by.id('postThreadItem-by-carla.test')
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(post)).atIndex(0),
|
|
||||||
).toHaveText('1')
|
|
||||||
await element(by.id('repostBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).toBeVisible()
|
|
||||||
await element(by.id('repostBtn').withAncestor(by.id('repostModal'))).tap()
|
|
||||||
await expect(element(by.id('repostModal'))).not.toBeVisible()
|
|
||||||
await expect(
|
|
||||||
element(by.id('repostCount').withAncestor(post)).atIndex(0),
|
|
||||||
).not.toExist()
|
|
||||||
})
|
|
||||||
|
|
||||||
// TODO skipping because the test env PDS isnt setup correctly to handle the report -prf
|
|
||||||
// it('Can report the root post', async () => {
|
|
||||||
// const post = by.id('postThreadItem-by-bob.test')
|
|
||||||
// await element(by.id('postDropdownBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
// await element(by.text('Report post')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).toBeVisible()
|
|
||||||
// await element(
|
|
||||||
// by.id('reportReasonRadios-com.atproto.moderation.defs#reasonSpam'),
|
|
||||||
// ).tap()
|
|
||||||
// await element(by.id('sendReportBtn')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).not.toBeVisible()
|
|
||||||
// })
|
|
||||||
|
|
||||||
// TODO skipping because the test env PDS isnt setup correctly to handle the report -prf
|
|
||||||
// it('Can report a reply post', async () => {
|
|
||||||
// const post = by.id('postThreadItem-by-carla.test')
|
|
||||||
// await element(by.id('postDropdownBtn').withAncestor(post)).atIndex(0).tap()
|
|
||||||
// await element(by.text('Report post')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).toBeVisible()
|
|
||||||
// await element(
|
|
||||||
// by.id('reportReasonRadios-com.atproto.moderation.defs#reasonSpam'),
|
|
||||||
// ).tap()
|
|
||||||
// await element(by.id('sendReportBtn')).tap()
|
|
||||||
// await expect(element(by.id('reportModal'))).not.toBeVisible()
|
|
||||||
// })
|
|
||||||
})
|
|
||||||
-141
@@ -1,141 +0,0 @@
|
|||||||
import {execSync} from 'child_process'
|
|
||||||
import {resolveConfig} from 'detox/internals'
|
|
||||||
import http from 'http'
|
|
||||||
|
|
||||||
const platform = device.getPlatform()
|
|
||||||
|
|
||||||
export async function openApp(opts: any) {
|
|
||||||
opts = opts || {}
|
|
||||||
const config = await resolveConfig()
|
|
||||||
|
|
||||||
if (device.getPlatform() === 'ios') {
|
|
||||||
// disable password autofill
|
|
||||||
execSync(
|
|
||||||
`plutil -replace restrictedBool.allowPasswordAutoFill.value -bool NO ~/Library/Developer/CoreSimulator/Devices/${device.id}/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles/Library/ConfigurationProfiles/UserSettings.plist`,
|
|
||||||
)
|
|
||||||
execSync(
|
|
||||||
`plutil -replace restrictedBool.allowPasswordAutoFill.value -bool NO ~/Library/Developer/CoreSimulator/Devices/${device.id}/data/Library/UserConfigurationProfiles/EffectiveUserSettings.plist`,
|
|
||||||
)
|
|
||||||
execSync(
|
|
||||||
`plutil -replace restrictedBool.allowPasswordAutoFill.value -bool NO ~/Library/Developer/CoreSimulator/Devices/${device.id}/data/Library/UserConfigurationProfiles/PublicInfo/PublicEffectiveUserSettings.plist`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (config.configurationName.split('.').includes('debug')) {
|
|
||||||
return await openAppForDebugBuild(platform, opts)
|
|
||||||
} else {
|
|
||||||
return await device.launchApp({
|
|
||||||
...opts,
|
|
||||||
newInstance: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function isVisible(id: string) {
|
|
||||||
try {
|
|
||||||
await expect(element(by.id(id))).toBeVisible()
|
|
||||||
return true
|
|
||||||
} catch (e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function login(
|
|
||||||
service: string,
|
|
||||||
username: string,
|
|
||||||
password: string,
|
|
||||||
{takeScreenshots} = {takeScreenshots: false},
|
|
||||||
) {
|
|
||||||
await element(by.id('signInButton')).tap()
|
|
||||||
if (takeScreenshots) {
|
|
||||||
await device.takeScreenshot('1- opened sign-in screen')
|
|
||||||
}
|
|
||||||
if (await isVisible('chooseAccountForm')) {
|
|
||||||
await element(by.id('chooseNewAccountBtn')).tap()
|
|
||||||
}
|
|
||||||
await element(by.id('selectServiceButton')).tap()
|
|
||||||
if (takeScreenshots) {
|
|
||||||
await device.takeScreenshot('2- opened service selector')
|
|
||||||
}
|
|
||||||
await element(by.id('customSelectBtn')).tap()
|
|
||||||
await element(by.id('customServerTextInput')).typeText(service)
|
|
||||||
await element(by.id('customServerTextInput')).tapReturnKey()
|
|
||||||
await element(by.id('doneBtn')).tap()
|
|
||||||
if (takeScreenshots) {
|
|
||||||
await device.takeScreenshot('3- input custom service')
|
|
||||||
}
|
|
||||||
await element(by.id('loginUsernameInput')).typeText(username)
|
|
||||||
await element(by.id('loginPasswordInput')).typeText(password)
|
|
||||||
if (takeScreenshots) {
|
|
||||||
await device.takeScreenshot('4- entered username and password')
|
|
||||||
}
|
|
||||||
await element(by.id('loginNextButton')).tap()
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function loginAsAlice() {
|
|
||||||
await element(by.id('e2eSignInAlice')).tap()
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function loginAsBob() {
|
|
||||||
await element(by.id('e2eSignInBob')).tap()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function openAppForDebugBuild(platform: string, opts: any) {
|
|
||||||
const deepLinkUrl = // Local testing with packager
|
|
||||||
/*process.env.EXPO_USE_UPDATES
|
|
||||||
? // Testing latest published EAS update for the test_debug channel
|
|
||||||
getDeepLinkUrl(getLatestUpdateUrl())
|
|
||||||
: */ getDeepLinkUrl(getDevLauncherPackagerUrl(platform))
|
|
||||||
|
|
||||||
if (platform === 'ios') {
|
|
||||||
await device.launchApp({
|
|
||||||
...opts,
|
|
||||||
newInstance: true,
|
|
||||||
})
|
|
||||||
sleep(3000)
|
|
||||||
await device.openURL({
|
|
||||||
url: deepLinkUrl,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
await device.launchApp({
|
|
||||||
...opts,
|
|
||||||
newInstance: true,
|
|
||||||
url: deepLinkUrl,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
await sleep(3000)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createServer(path = ''): Promise<string> {
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
var req = http.request(
|
|
||||||
{
|
|
||||||
method: 'POST',
|
|
||||||
host: 'localhost',
|
|
||||||
port: 1986,
|
|
||||||
path: `/${path}`,
|
|
||||||
},
|
|
||||||
function (res) {
|
|
||||||
const body: Buffer[] = []
|
|
||||||
res.on('data', chunk => body.push(chunk))
|
|
||||||
res.on('end', function () {
|
|
||||||
try {
|
|
||||||
resolve(Buffer.concat(body).toString())
|
|
||||||
} catch (e) {
|
|
||||||
reject(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
req.on('error', reject)
|
|
||||||
req.end()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const getDeepLinkUrl = (url: string) =>
|
|
||||||
`expo+bluesky://expo-development-client/?url=${encodeURIComponent(url)}`
|
|
||||||
|
|
||||||
const getDevLauncherPackagerUrl = (platform: string) =>
|
|
||||||
`http://localhost:8081/index.bundle?platform=${platform}&dev=true&minify=false&disableOnboarding=1`
|
|
||||||
|
|
||||||
export const sleep = (t: number) => new Promise(res => setTimeout(res, t))
|
|
||||||
+2
-2
@@ -32,9 +32,9 @@
|
|||||||
"typecheck": "tsc --project ./tsconfig.check.json",
|
"typecheck": "tsc --project ./tsconfig.check.json",
|
||||||
"e2e:mock-server": "./jest/dev-infra/with-test-redis-and-db.sh ts-node --project tsconfig.e2e.json __e2e__/mock-server.ts",
|
"e2e:mock-server": "./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:metro": "EXPO_PUBLIC_ENV=e2e NODE_ENV=test RN_SRC_EXT=e2e.ts,e2e.tsx expo run:ios",
|
||||||
"e2e:run": "maestro test .maestro",
|
"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__/maestro/scroll.yaml",
|
"perf:test:run": "NODE_ENV=test maestro test __e2e__/perf-test.yml",
|
||||||
"perf:test:measure": "NODE_ENV=test flashlight test --bundleId xyz.blueskyweb.app --testCommand \"yarn perf:test\" --duration 150000 --resultsFilePath .perf/results.json",
|
"perf:test:measure": "NODE_ENV=test flashlight test --bundleId xyz.blueskyweb.app --testCommand \"yarn perf:test\" --duration 150000 --resultsFilePath .perf/results.json",
|
||||||
"perf:test:results": "NODE_ENV=test flashlight report .perf/results.json",
|
"perf:test:results": "NODE_ENV=test flashlight report .perf/results.json",
|
||||||
"perf:measure": "NODE_ENV=test flashlight measure",
|
"perf:measure": "NODE_ENV=test flashlight measure",
|
||||||
|
|||||||
Reference in New Issue
Block a user