From bae367da7bca5e0a20138bc67617b0badc65ac90 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Wed, 21 Nov 2018 22:08:37 -0800 Subject: [PATCH] test: make tests less flaky (#678) --- tests/spec/009-threads.js | 7 +-- tests/spec/100-favorite-unfavorite.js | 12 +++--- tests/spec/101-reblog-unreblog.js | 62 ++++++++++++++++----------- tests/spec/104-streaming.js | 4 +- tests/spec/117-pin-unpin.js | 9 ++-- tests/utils.js | 39 ++++------------- 6 files changed, 61 insertions(+), 72 deletions(-) diff --git a/tests/spec/009-threads.js b/tests/spec/009-threads.js index ef98c56..ae08179 100644 --- a/tests/spec/009-threads.js +++ b/tests/spec/009-threads.js @@ -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/') diff --git a/tests/spec/100-favorite-unfavorite.js b/tests/spec/100-favorite-unfavorite.js index 39e0b6a..a02703e 100644 --- a/tests/spec/100-favorite-unfavorite.js +++ b/tests/spec/100-favorite-unfavorite.js @@ -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) diff --git a/tests/spec/101-reblog-unreblog.js b/tests/spec/101-reblog-unreblog.js index 9e08ba0..0272287 100644 --- a/tests/spec/101-reblog-unreblog.js +++ b/tests/spec/101-reblog-unreblog.js @@ -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) diff --git a/tests/spec/104-streaming.js b/tests/spec/104-streaming.js index f1b2594..0f309fe 100644 --- a/tests/spec/104-streaming.js +++ b/tests/spec/104-streaming.js @@ -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') diff --git a/tests/spec/117-pin-unpin.js b/tests/spec/117-pin-unpin.js index 5ab8267..24ca283 100644 --- a/tests/spec/117-pin-unpin.js +++ b/tests/spec/117-pin-unpin.js @@ -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 }) diff --git a/tests/utils.js b/tests/utils.js index 44a3b25..64509cc 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -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++) {