diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-03-31 13:17:26 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-31 13:17:26 -0500 |
commit | a3334a01a221877d3e06e02f960fda441f3460bd (patch) | |
tree | 64cdbb1232d1a3c00750c346b6e3ae529b51d1b0 /__e2e__/tests | |
parent | 19f3a2fa92a61ddb785fc4e42d73792c1d0e772c (diff) | |
download | voidsky-a3334a01a221877d3e06e02f960fda441f3460bd.tar.zst |
Lex refactor (#362)
* Remove the hackcheck for upgrades * Rename the PostEmbeds folder to match the codebase style * Updates to latest lex refactor * Update to use new bsky agent * Update to use api package's richtext library * Switch to upsertProfile * Add TextEncoder/TextDecoder polyfill * Add Intl.Segmenter polyfill * Update composer to calculate lengths by grapheme * Fix detox * Fix login in e2e * Create account e2e passing * Implement an e2e mocking framework * Don't use private methods on mobx models as mobx can't track them * Add tooling for e2e-specific builds and add e2e media-picker mock * Add some tests and fix some bugs around profile editing * Add shell tests * Add home screen tests * Add thread screen tests * Add tests for other user profile screens * Add search screen tests * Implement profile imagery change tools and tests * Update to new embed behaviors * Add post tests * Fix to profile-screen test * Fix session resumption * Update web composer to new api * 1.11.0 * Fix pagination cursor parameters * Add quote posts to notifications * Fix embed layouts * Remove youtube inline player and improve tap handling on link cards * Reset minimal shell mode on all screen loads and feed swipes (close #299) * Update podfile.lock * Improve post notfound UI (close #366) * Bump atproto packages
Diffstat (limited to '__e2e__/tests')
-rw-r--r-- | __e2e__/tests/composer.test.ts | 108 | ||||
-rw-r--r-- | __e2e__/tests/create-account.test.ts | 31 | ||||
-rw-r--r-- | __e2e__/tests/home-screen.test.ts | 92 | ||||
-rw-r--r-- | __e2e__/tests/login.test.ts | 19 | ||||
-rw-r--r-- | __e2e__/tests/profile-screen.test.ts | 173 | ||||
-rw-r--r-- | __e2e__/tests/search-screen.test.ts | 24 | ||||
-rw-r--r-- | __e2e__/tests/shell.test.ts | 34 | ||||
-rw-r--r-- | __e2e__/tests/thread-screen.test.ts | 123 |
8 files changed, 604 insertions, 0 deletions
diff --git a/__e2e__/tests/composer.test.ts b/__e2e__/tests/composer.test.ts new file mode 100644 index 000000000..afc23cc13 --- /dev/null +++ b/__e2e__/tests/composer.test.ts @@ -0,0 +1,108 @@ +/* eslint-env detox/detox */ + +import {openApp, login, createServer, sleep} from '../util' + +describe('Composer', () => { + let service: string + beforeAll(async () => { + service = await createServer('?users') + await openApp({ + permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'}, + }) + }) + + it('Login', async () => { + await login(service, 'alice', 'hunter2') + 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('addLinkCardBtn')).tap() + await element(by.id('composerPublishBtn')).tap() + await expect(element(by.id('composeFAB'))).toBeVisible() + }) + + it('Reply text only', 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 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('addLinkCardBtn')).tap() + 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('addLinkCardBtn')).tap() + await element(by.id('composerPublishBtn')).tap() + await expect(element(by.id('composeFAB'))).toBeVisible() + }) +}) diff --git a/__e2e__/tests/create-account.test.ts b/__e2e__/tests/create-account.test.ts new file mode 100644 index 000000000..7b2e00fb5 --- /dev/null +++ b/__e2e__/tests/create-account.test.ts @@ -0,0 +1,31 @@ +/* eslint-env detox/detox */ + +import {openApp, createServer} from '../util' + +describe('Create account', () => { + let service: string + beforeAll(async () => { + service = await createServer('mock0') + await openApp({permissions: {notifications: 'YES'}}) + }) + + it('I can create a new account', async () => { + await element(by.id('createAccountButton')).tap() + await device.takeScreenshot('1- opened create account screen') + await element(by.id('otherServerBtn')).tap() + await device.takeScreenshot('2- selected other server') + await element(by.id('customServerInput')).clearText() + await element(by.id('customServerInput')).typeText(service) + await device.takeScreenshot('3- input test server URL') + await element(by.id('nextBtn')).tap() + await element(by.id('emailInput')).typeText('example@test.com') + await element(by.id('passwordInput')).typeText('hunter2') + await element(by.id('is13Input')).tap() + 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('homeScreen'))).toBeVisible() + }) +}) diff --git a/__e2e__/tests/home-screen.test.ts b/__e2e__/tests/home-screen.test.ts new file mode 100644 index 000000000..1ec1774f3 --- /dev/null +++ b/__e2e__/tests/home-screen.test.ts @@ -0,0 +1,92 @@ +/* eslint-env detox/detox */ + +import {openApp, login, createServer} from '../util' + +describe('Home screen', () => { + let service: string + beforeAll(async () => { + service = await createServer('?users&follows&posts') + await openApp({permissions: {notifications: 'YES'}}) + }) + + it('Login', async () => { + await login(service, 'alice', 'hunter2') + await element(by.id('homeScreenFeedTabs-Following')).tap() + }) + + it('Can like posts', async () => { + const carlaPosts = by.id('feedItem-by-carla.test') + await expect( + element(by.id('likeCount').withAncestor(carlaPosts)).atIndex(0), + ).toHaveText('0') + 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), + ).toHaveText('0') + }) + + it('Can repost posts', async () => { + const carlaPosts = by.id('feedItem-by-carla.test') + await expect( + element(by.id('repostCount').withAncestor(carlaPosts)).atIndex(0), + ).toHaveText('0') + 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), + ).toHaveText('0') + }) + + 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.id('postDropdownReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).toBeVisible() + await element(by.id('reportPostRadios-spam')).tap() + await element(by.id('sendReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).not.toBeVisible() + }) + + it('Can swipe between feeds', async () => { + await element(by.id('homeScreen')).swipe('left', 'fast', 0.75) + await expect(element(by.id('whatshotFeedPage'))).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-What's hot")).tap() + await expect(element(by.id('whatshotFeedPage'))).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.id('postDropdownDeleteBtn')).tap() + await expect(element(by.id('confirmModal'))).toBeVisible() + await element(by.id('confirmBtn')).tap() + await expect( + element(alicePosts.withDescendant(by.text('Post'))), + ).not.toExist() + }) +}) diff --git a/__e2e__/tests/login.test.ts b/__e2e__/tests/login.test.ts new file mode 100644 index 000000000..788016db6 --- /dev/null +++ b/__e2e__/tests/login.test.ts @@ -0,0 +1,19 @@ +/* eslint-env detox/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 expect(element(by.id('signInButton'))).toBeVisible() + await login(service, 'alice', 'hunter2', { + takeScreenshots: true, + }) + await device.takeScreenshot('5- opened home screen') + }) +}) diff --git a/__e2e__/tests/profile-screen.test.ts b/__e2e__/tests/profile-screen.test.ts new file mode 100644 index 000000000..e1b6dcaf4 --- /dev/null +++ b/__e2e__/tests/profile-screen.test.ts @@ -0,0 +1,173 @@ +/* eslint-env detox/detox */ + +import {openApp, login, createServer, sleep} from '../util' + +describe('Profile screen', () => { + let service: string + beforeAll(async () => { + service = await createServer('?users&posts') + await openApp({ + permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'}, + }) + }) + + it('Login and navigate to my profile', async () => { + await expect(element(by.id('signInButton'))).toBeVisible() + await login(service, 'alice', 'hunter2') + await element(by.id('bottomBarProfileBtn')).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'))).toHaveText('') + }) + + 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.id('changeBannerLibraryBtn')).tap() + await sleep(3e3) + await element(by.id('changeAvatarBtn')).tap() + await element(by.id('changeAvatarLibraryBtn')).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.id('changeBannerRemoveBtn')).tap() + await element(by.id('changeAvatarBtn')).tap() + await element(by.id('changeAvatarRemoveBtn')).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(2000) + 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('profileHeaderMutedNotice'))).not.toExist() + await element(by.id('profileHeaderDropdownBtn')).tap() + await element(by.id('profileHeaderDropdownMuteBtn')).tap() + await expect(element(by.id('profileHeaderMutedNotice'))).toBeVisible() + await element(by.id('profileHeaderDropdownBtn')).tap() + await element(by.id('profileHeaderDropdownMuteBtn')).tap() + await expect(element(by.id('profileHeaderMutedNotice'))).not.toExist() + }) + + it('Can report another user', async () => { + await element(by.id('profileHeaderDropdownBtn')).tap() + await element(by.id('profileHeaderDropdownReportBtn')).tap() + await expect(element(by.id('reportAccountModal'))).toBeVisible() + await element(by.id('reportAccountRadios-spam')).tap() + await element(by.id('sendReportBtn')).tap() + await expect(element(by.id('reportAccountModal'))).not.toBeVisible() + }) + + it('Can like posts', async () => { + const posts = by.id('feedItem-by-bob.test') + await expect( + element(by.id('likeCount').withAncestor(posts)).atIndex(0), + ).toHaveText('0') + 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), + ).toHaveText('0') + }) + + it('Can repost posts', async () => { + const posts = by.id('feedItem-by-bob.test') + await expect( + element(by.id('repostCount').withAncestor(posts)).atIndex(0), + ).toHaveText('0') + 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), + ).toHaveText('0') + }) + + 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.id('postDropdownReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).toBeVisible() + await element(by.id('reportPostRadios-spam')).tap() + await element(by.id('sendReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).not.toBeVisible() + }) +}) diff --git a/__e2e__/tests/search-screen.test.ts b/__e2e__/tests/search-screen.test.ts new file mode 100644 index 000000000..093d97c89 --- /dev/null +++ b/__e2e__/tests/search-screen.test.ts @@ -0,0 +1,24 @@ +/* eslint-env detox/detox */ + +import {openApp, login, createServer} from '../util' + +describe('Search screen', () => { + let service: string + beforeAll(async () => { + service = await createServer('?users') + await openApp({ + permissions: {notifications: 'YES', medialibrary: 'YES', photos: 'YES'}, + }) + }) + + it('Login', async () => { + await login(service, 'alice', 'hunter2') + }) + + 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() + }) +}) diff --git a/__e2e__/tests/shell.test.ts b/__e2e__/tests/shell.test.ts new file mode 100644 index 000000000..5cfd4277f --- /dev/null +++ b/__e2e__/tests/shell.test.ts @@ -0,0 +1,34 @@ +/* eslint-env detox/detox */ + +import {openApp, login, createServer} from '../util' + +describe('Shell', () => { + let service: string + beforeAll(async () => { + service = await createServer('?users') + await openApp({permissions: {notifications: 'YES'}}) + }) + + it('Login', async () => { + await login(service, 'alice', 'hunter2') + 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() + }) +}) diff --git a/__e2e__/tests/thread-screen.test.ts b/__e2e__/tests/thread-screen.test.ts new file mode 100644 index 000000000..f84c339ce --- /dev/null +++ b/__e2e__/tests/thread-screen.test.ts @@ -0,0 +1,123 @@ +/* eslint-env detox/detox */ + +import {openApp, login, createServer} from '../util' + +describe('Thread screen', () => { + let service: string + beforeAll(async () => { + service = await createServer('?users&follows&thread') + await openApp({permissions: {notifications: 'YES'}}) + }) + + it('Login & navigate to thread', async () => { + await login(service, 'alice', 'hunter2') + 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').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 like') + await element(by.id('likeBtn').withAncestor(post)).atIndex(0).tap() + await expect( + element(by.id('likeCount').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), + ).toHaveText('0') + 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), + ).toHaveText('0') + }) + + it('Can repost the root post', async () => { + const post = by.id('postThreadItem-by-bob.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 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').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), + ).toHaveText('0') + 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), + ).toHaveText('0') + }) + + 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.id('postDropdownReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).toBeVisible() + await element(by.id('reportPostRadios-spam')).tap() + await element(by.id('sendReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).not.toBeVisible() + }) + + 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.id('postDropdownReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).toBeVisible() + await element(by.id('reportPostRadios-spam')).tap() + await element(by.id('sendReportBtn')).tap() + await expect(element(by.id('reportPostModal'))).not.toBeVisible() + }) +}) |