Prefilter the mergefeed to ensure a better mix of following and custom feeds (#1498)

* Prefilter the mergefeed to ensure a better mix of following and custom feeds

* Test suite improvements & tests for the mergefeed (#1499)

* Disable invite codes test for now

* Update test sim to latest iphone

* Introduce TestCtrls driver

* Add mergefeed tests
This commit is contained in:
Paul Frazee 2023-09-20 19:47:56 -07:00 committed by GitHub
parent 68dd3210d1
commit 5a945c2024
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 518 additions and 164 deletions

View file

@ -1,18 +1,17 @@
/* eslint-env detox/detox */
import {openApp, login, createServer, sleep} from '../util'
import {openApp, loginAsAlice, createServer, sleep} from '../util'
describe('Composer', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users')
await createServer('?users')
await openApp({
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
})
})
it('Login', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('homeScreenFeedTabs-Following')).tap()
})

View file

@ -1,16 +1,15 @@
/* eslint-env detox/detox */
import {openApp, login, createServer} from '../util'
import {openApp, loginAsAlice, createServer} from '../util'
describe('Home screen', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users&follows&posts')
await createServer('?users&follows&posts')
await openApp({permissions: {notifications: 'YES'}})
})
it('Login', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('homeScreenFeedTabs-Following')).tap()
})

View file

@ -1,6 +1,11 @@
/* eslint-env detox/detox */
import {openApp, login, createServer} from '../util'
/**
* This test is being skipped until we can resolve the detox crash issue
* with the side drawer.
*/
import {openApp, loginAsAlice, createServer} from '../util'
describe('invite-codes', () => {
let service: string
@ -12,7 +17,7 @@ describe('invite-codes', () => {
it('I can fetch invite codes', async () => {
await expect(element(by.id('signInButton'))).toBeVisible()
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('viewHeaderDrawerBtn')).tap()
await expect(element(by.id('drawer'))).toBeVisible()
await element(by.id('menuItemInviteCodes')).tap()
@ -47,15 +52,10 @@ describe('invite-codes', () => {
await expect(element(by.id('recommendedFeedsOnboarding'))).toBeVisible()
await element(by.id('continueBtn')).tap()
await expect(element(by.id('homeScreen'))).toBeVisible()
await element(by.id('viewHeaderDrawerBtn')).tap()
await element(by.id('menuItemButton-Settings')).tap()
await element(by.id('signOutBtn')).tap()
})
it('I get a notification for the new user', async () => {
await expect(element(by.id('signInButton'))).toBeVisible()
await login(service, 'alice', 'hunter2')
await element(by.id('viewHeaderDrawerBtn')).tap()
await loginAsAlice()
await element(by.id('menuItemButton-Notifications')).tap()
await expect(element(by.id('invitedUser'))).toBeVisible()
})

View file

@ -0,0 +1,157 @@
/* eslint-env detox/detox */
import {openApp, loginAsAlice, createServer} from '../util'
describe('Mergefeed', () => {
beforeAll(async () => {
await createServer('?mergefeed')
await openApp({permissions: {notifications: 'YES'}})
})
it('Login', async () => {
await loginAsAlice()
await element(by.id('e2eToggleMergefeed')).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')
})
})

View file

@ -1,11 +1,10 @@
/* eslint-env detox/detox */
import {openApp, login, createServer, sleep} from '../util'
import {openApp, loginAsAlice, loginAsBob, createServer, sleep} from '../util'
describe('Mute lists', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users&follows&labels')
await createServer('?users&follows&labels')
await openApp({
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
})
@ -13,10 +12,8 @@ describe('Mute lists', () => {
it('Login and view my mutelists', async () => {
await expect(element(by.id('signInButton'))).toBeVisible()
await login(service, 'alice', 'hunter2')
await element(by.id('viewHeaderDrawerBtn')).tap()
await expect(element(by.id('drawer'))).toBeVisible()
await element(by.id('menuItemButton-Moderation')).tap()
await loginAsAlice()
await element(by.id('e2eGotoModeration')).tap()
await element(by.id('mutelistsBtn')).tap()
await expect(element(by.id('list-Muted Users'))).toBeVisible()
await element(by.id('list-Muted Users')).tap()
@ -141,19 +138,9 @@ describe('Mute lists', () => {
})
it('Can report a mute list', async () => {
await element(by.id('bottomBarHomeBtn')).tap()
// Last test leaves us in the list view so we are going back 1 screen to the lists list screen
await element(by.id('viewHeaderDrawerBtn')).tap()
// then to the moderation screen
await element(by.id('viewHeaderDrawerBtn')).tap()
// then to the home screen
await element(by.id('viewHeaderDrawerBtn')).tap()
// then open the drawer to go to settings
await element(by.id('viewHeaderDrawerBtn')).tap()
await element(by.id('menuItemButton-Settings')).tap()
await element(by.id('e2eGotoSettings')).tap()
await element(by.id('signOutBtn')).tap()
await expect(element(by.id('signInButton'))).toBeVisible()
await login(service, 'bob.test', 'hunter2')
await loginAsBob()
await element(by.id('bottomBarSearchBtn')).tap()
await element(by.id('searchTextInput')).typeText('alice')
await element(by.id('searchAutoCompleteResult-alice.test')).tap()

View file

@ -1,11 +1,10 @@
/* eslint-env detox/detox */
import {openApp, login, createServer, sleep} from '../util'
import {openApp, loginAsAlice, createServer, sleep} from '../util'
describe('Profile screen', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users&posts&feeds')
await createServer('?users&posts&feeds')
await openApp({
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
})
@ -13,7 +12,7 @@ describe('Profile screen', () => {
it('Login and navigate to my profile', async () => {
await expect(element(by.id('signInButton'))).toBeVisible()
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('bottomBarProfileBtn')).tap()
})

View file

@ -1,18 +1,17 @@
/* eslint-env detox/detox */
import {openApp, login, createServer} from '../util'
import {openApp, loginAsAlice, createServer} from '../util'
describe('Search screen', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users')
await createServer('?users')
await openApp({
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
})
})
it('Login', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
})
it('Navigate to another user profile via autocomplete', async () => {

View file

@ -1,18 +1,17 @@
/* eslint-env detox/detox */
import {openApp, login, createServer, sleep} from '../util'
import {openApp, loginAsAlice, createServer, sleep} from '../util'
describe('Self-labeling', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users')
await createServer('?users')
await openApp({
permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'},
})
})
it('Login', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('homeScreenFeedTabs-Following')).tap()
})

View file

@ -1,16 +1,15 @@
/* eslint-env detox/detox */
import {openApp, login, createServer} from '../util'
import {openApp, loginAsAlice, createServer} from '../util'
describe('Shell', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users')
await createServer('?users')
await openApp({permissions: {notifications: 'YES'}})
})
it('Login', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('homeScreenFeedTabs-Following')).tap()
})

View file

@ -1,42 +1,34 @@
/* eslint-env detox/detox */
import {openApp, login, createServer} from '../util'
import {openApp, loginAsAlice, loginAsBob, createServer} from '../util'
describe('Thread muting', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users&follows')
await createServer('?users&follows')
await openApp({permissions: {notifications: 'YES'}})
})
it('Login, create a thread, and log out', async () => {
await login(service, 'alice', 'hunter2')
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()
await element(by.id('viewHeaderDrawerBtn')).tap()
await element(by.id('menuItemButton-Settings')).tap()
await element(by.id('signOutBtn')).tap()
})
it('Login, reply to the thread, and log out', async () => {
await login(service, 'bob', 'hunter2')
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()
await element(by.id('viewHeaderDrawerBtn')).tap()
await element(by.id('menuItemButton-Settings')).tap()
await element(by.id('signOutBtn')).tap()
})
it('Login, confirm notification exists, mute thread, and log out', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('bottomBarNotificationsBtn')).tap()
const bobNotifs = by.id('feedItem-by-bob.test')
await expect(
@ -50,14 +42,10 @@ describe('Thread muting', () => {
await waitFor(element(by.id('viewHeaderDrawerBtn')))
.toBeVisible()
.withTimeout(5000)
await element(by.id('viewHeaderDrawerBtn')).tap()
await element(by.id('menuItemButton-Settings')).tap()
await element(by.id('signOutBtn')).tap()
})
it('Login, reply to the thread twice, and log out', async () => {
await login(service, 'bob', 'hunter2')
await loginAsBob()
await element(by.id('bottomBarProfileBtn')).tap()
await element(by.id('selector-1')).tap()
@ -74,13 +62,10 @@ describe('Thread muting', () => {
await expect(element(by.id('composeFAB'))).toBeVisible()
await element(by.id('bottomBarHomeBtn')).tap()
await element(by.id('viewHeaderDrawerBtn')).tap()
await element(by.id('menuItemButton-Settings')).tap()
await element(by.id('signOutBtn')).tap()
})
it('Login, confirm notifications dont exist, unmute the thread, confirm notifications exist', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('bottomBarNotificationsBtn')).tap()
const bobNotifs = by.id('feedItem-by-bob.test')
@ -93,7 +78,7 @@ describe('Thread muting', () => {
await element(by.id('postDropdownBtn').withAncestor(alicePosts))
.atIndex(0)
.tap()
await element(by.text('Mute thread')).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

View file

@ -1,16 +1,15 @@
/* eslint-env detox/detox */
import {openApp, login, createServer} from '../util'
import {openApp, loginAsAlice, createServer} from '../util'
describe('Thread screen', () => {
let service: string
beforeAll(async () => {
service = await createServer('?users&follows&thread')
await createServer('?users&follows&thread')
await openApp({permissions: {notifications: 'YES'}})
})
it('Login & navigate to thread', async () => {
await login(service, 'alice', 'hunter2')
await loginAsAlice()
await element(by.id('homeScreenFeedTabs-Following')).tap()
await element(by.id('feedItem-by-bob.test')).atIndex(0).tap()
await expect(