test: make tests less flaky (#678)

This commit is contained in:
Nolan Lawson 2018-11-21 22:08:37 -08:00 committed by GitHub
parent 673e7b951c
commit bae367da7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 72 deletions

View File

@ -1,7 +1,7 @@
import { Selector as $ } from 'testcafe'
import {
getNthStatus, getUrl, validateTimeline, scrollToBottomOfTimeline, getFirstVisibleStatus,
goBack, forceOffline, forceOnline, searchNavButton, searchInput, getNthSearchResult
getNthStatus, getUrl, validateTimeline, getFirstVisibleStatus,
goBack, forceOffline, forceOnline, searchNavButton, searchInput, getNthSearchResult, scrollToStatus
} from '../utils'
import { loginAsFoobar } from '../roles'
import { bazThreadRelativeTo2, bazThreadRelativeTo2b, bazThreadRelativeTo2B2, quuxThread } from '../fixtures'
@ -14,8 +14,9 @@ test('Shows a thread', async t => {
await t
.click($('a').withText('quux'))
await scrollToBottomOfTimeline(t)
await scrollToStatus(t, 26)
await t
.hover(getNthStatus(26))
.click(getNthStatus(26))
.expect(getUrl()).contains('/statuses/')

View File

@ -1,7 +1,7 @@
import {
getFavoritesCount,
getNthFavoriteButton, getNthFavorited, getNthStatus, getUrl, homeNavButton, notificationsNavButton,
scrollToBottomOfTimeline, scrollToTopOfTimeline
scrollToBottom, scrollToTop, sleep
} from '../utils'
import { loginAsFoobar } from '../roles'
import { indexWhere } from '../../routes/_utils/arrays'
@ -19,8 +19,9 @@ test('favorites a status', async t => {
.expect(getNthFavorited(4)).eql('true')
// scroll down and back up to force an unrender
await scrollToBottomOfTimeline(t)
await scrollToTopOfTimeline(t)
await scrollToBottom()
await sleep(1)
await scrollToTop()
await t
.hover(getNthStatus(4))
.expect(getNthFavorited(4)).eql('true')
@ -45,8 +46,9 @@ test('unfavorites a status', async t => {
.expect(getNthFavorited(1)).eql('false')
// scroll down and back up to force an unrender
await scrollToBottomOfTimeline(t)
await scrollToTopOfTimeline(t)
await scrollToBottom()
await sleep(1)
await scrollToTop()
await t
.expect(getNthFavorited(1)).eql('false')
.click(notificationsNavButton)

View File

@ -1,24 +1,27 @@
import {
getNthReblogButton, getNthReblogged, getNthStatus, getReblogsCount, getUrl, homeNavButton,
notificationsNavButton,
scrollToBottomOfTimeline, scrollToTopOfTimeline
getNthReblogButton, getNthReblogged, getNthStatus, getNthStatusContent, getReblogsCount, getUrl, homeNavButton,
notificationsNavButton, scrollToBottom, scrollToTop, sleep
} from '../utils'
import { loginAsFoobar } from '../roles'
import { postAs, reblogStatusAs } from '../serverActions'
fixture`101-reblog-unreblog.js`
.page`http://localhost:4002`
test('reblogs a status', async t => {
await postAs('foobar', 'hello this should be reblogged')
await loginAsFoobar(t)
await t
.hover(getNthStatus(0))
.expect(getNthStatusContent(0).innerText).contains('should be reblogged')
.expect(getNthReblogged(0)).eql('false')
.click(getNthReblogButton(0))
.expect(getNthReblogged(0)).eql('true')
// scroll down and back up to force an unrender
await scrollToBottomOfTimeline(t)
await scrollToTopOfTimeline(t)
await scrollToBottom()
await sleep(1)
await scrollToTop()
await t
.hover(getNthStatus(0))
.expect(getNthReblogged(0)).eql('true')
@ -35,46 +38,53 @@ test('reblogs a status', async t => {
})
test('unreblogs a status', async t => {
await postAs('foobar', 'woot i wanna reblog this')
await loginAsFoobar(t)
await t
.hover(getNthStatus(3))
.expect(getNthReblogged(3)).eql('false')
.click(getNthReblogButton(3))
.expect(getNthReblogged(3)).eql('true')
.click(getNthReblogButton(3))
.expect(getNthReblogged(3)).eql('false')
.hover(getNthStatus(0))
.expect(getNthStatusContent(0).innerText).contains('woot i wanna')
.expect(getNthReblogged(0)).eql('false')
.click(getNthReblogButton(0))
.expect(getNthReblogged(0)).eql('true')
.click(getNthReblogButton(0))
.expect(getNthReblogged(0)).eql('false')
// scroll down and back up to force an unrender
await scrollToBottomOfTimeline(t)
await scrollToTopOfTimeline(t)
await scrollToBottom()
await sleep(1)
await scrollToTop()
await t
.hover(getNthStatus(3))
.expect(getNthReblogged(3)).eql('false')
.hover(getNthStatus(0))
.expect(getNthReblogged(0)).eql('false')
.click(notificationsNavButton)
.click(homeNavButton)
.expect(getNthReblogged(3)).eql('false')
.expect(getNthReblogged(0)).eql('false')
.click(notificationsNavButton)
.navigateTo('/')
.expect(getNthReblogged(3)).eql('false')
.click(getNthReblogButton(3))
.expect(getNthReblogged(3)).eql('true')
.expect(getNthReblogged(0)).eql('false')
.click(getNthReblogButton(0))
.expect(getNthReblogged(0)).eql('true')
})
test('Keeps the correct reblogs count', async t => {
let { id } = await postAs('foobar', 'this will be reblogged')
await reblogStatusAs('foobar', id)
await reblogStatusAs('admin', id)
await loginAsFoobar(t)
await t
.hover(getNthStatus(3))
.expect(getNthReblogged(3)).eql('true')
.click(getNthStatus(3))
.hover(getNthStatus(0))
.expect(getNthStatusContent(0).innerText).contains('this will be reblogged')
.expect(getNthReblogged(0)).eql('true')
.click(getNthStatus(0))
.expect(getUrl()).contains('/status')
.expect(getNthReblogged(0)).eql('true')
.expect(getReblogsCount()).eql(2)
.click(homeNavButton)
.expect(getUrl()).eql('http://localhost:4002/')
.hover(getNthStatus(3))
.click(getNthReblogButton(3))
.expect(getNthReblogged(3)).eql('false')
.click(getNthStatus(3))
.hover(getNthStatus(0))
.click(getNthReblogButton(0))
.expect(getNthReblogged(0)).eql('false')
.click(getNthStatus(0))
.expect(getUrl()).contains('/status')
.expect(getNthReblogged(0)).eql('false')
.expect(getReblogsCount()).eql(1)

View File

@ -1,6 +1,6 @@
import { loginAsFoobar } from '../roles'
import {
getNthStatus, scrollContainerToTop, showMoreButton, sleep
getNthStatus, scrollToTop, showMoreButton, sleep
} from '../utils'
import { postAs } from '../serverActions'
@ -27,7 +27,7 @@ test('new incoming toots show a button if scrolled down', async t => {
await sleep(4000)
await t.hover(getNthStatus(2))
.hover(getNthStatus(0))
await scrollContainerToTop()
await scrollToTop()
await sleep(1000)
await t
.expect(showMoreButton.innerText).contains('Show 2 more')

View File

@ -3,8 +3,7 @@ import {
avatarInComposeBox, closeDialogButton, composeInput, getNthDialogOptionsOption, getNthPinnedStatus,
getNthPinnedStatusFavoriteButton,
getNthStatus, getNthStatusContent,
getNthStatusOptionsButton, getUrl, homeNavButton, postStatusButton, scrollContainerToTop, scrollToBottomOfTimeline,
scrollToTopOfTimeline,
getNthStatusOptionsButton, getUrl, homeNavButton, postStatusButton, scrollToTop, scrollToBottom,
settingsNavButton, sleep
} from '../utils'
import { users } from '../users'
@ -70,9 +69,9 @@ test('Saved pinned/unpinned state of status', async t => {
.click(closeDialogButton)
// scroll down and back up to force an unrender
await scrollToBottomOfTimeline(t)
await scrollToTopOfTimeline(t)
await scrollContainerToTop() // otherwise the ... button is obscured by the pen button
await scrollToBottom()
await sleep(1)
await scrollToTop()
await t
.expect(getNthStatusContent(0).innerText).contains('hey I am going to pin and unpin this', { timeout })

View File

@ -64,10 +64,6 @@ export const getActiveElementInnerText = exec(() =>
(document.activeElement && document.activeElement.innerText) || ''
)
export const getActiveElementAriaLabel = exec(() =>
(document.activeElement && document.activeElement.getAttribute('aria-label')) || ''
)
export const getActiveElementInsideNthStatus = exec(() => {
let element = document.activeElement
while (element) {
@ -95,10 +91,6 @@ export const getBodyClassList = exec(() => (
Array.prototype.slice.apply(document.body.classList).filter(_ => _ !== 'the-body'))
)
export const scrollContainerToTop = exec(() => {
document.scrollingElement.scrollTop = 0
})
export const uploadKittenImage = i => (exec(() => {
let image = images[`kitten${i}`]
let blob = blobUtils.base64StringToBlob(image.data, 'image/png')
@ -120,6 +112,14 @@ export const focus = (selector) => (exec(() => {
}
}))
export const scrollToBottom = exec(() => {
document.scrollingElement.scrollTop = document.scrollingElement.scrollHeight
})
export const scrollToTop = exec(() => {
document.scrollingElement.scrollTop = 0
})
export function getNthMediaAltInput (n) {
return $(`.compose-box .compose-media:nth-child(${n}) .compose-media-alt input`)
}
@ -281,29 +281,6 @@ export async function validateTimeline (t, timeline) {
}
}
export async function scrollToTopOfTimeline (t) {
let i = await getFirstVisibleStatus().getAttribute('aria-posinset')
while (true) {
await t.hover(getNthStatus(i))
.expect($('.loading-footer').exist).notOk()
if (--i <= 0) {
break
}
}
}
export async function scrollToBottomOfTimeline (t) {
let i = 0
while (true) {
await t.hover(getNthStatus(i))
.expect($('.loading-footer').exist).notOk()
let size = await getNthStatus(i).getAttribute('aria-setsize')
if (++i >= size - 1) {
break
}
}
}
export async function scrollToStatus (t, n) {
let timeout = 20000
for (let i = 0; i <= n; i++) {