attempt to fix flaky tests (#318)

* attempt to fix flaky tests

* another attempt to fix flakiness

* more attempts to fix flakiness
This commit is contained in:
Nolan Lawson 2018-05-24 20:01:34 -07:00 committed by GitHub
parent d79de35603
commit fe12b72293
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 16 deletions

View file

@ -1,14 +1,17 @@
import { Role } from 'testcafe' import { Role } from 'testcafe'
import { import {
addInstanceButton,
authorizeInput, emailInput, getUrl, instanceInput, mastodonLogInButton, authorizeInput, emailInput, getUrl, instanceInput, mastodonLogInButton,
passwordInput passwordInput,
sleep
} from './utils' } from './utils'
import { users } from './users' import { users } from './users'
function login (t, username, password) { async function login (t, username, password) {
return t.typeText(instanceInput, 'localhost:3000', {paste: true}) await sleep(500)
.click(addInstanceButton) await t.typeText(instanceInput, 'localhost:3000', {paste: true})
await sleep(500)
return t
.pressKey('enter')
.expect(getUrl()).eql('http://localhost:3000/auth/sign_in', {timeout: 30000}) .expect(getUrl()).eql('http://localhost:3000/auth/sign_in', {timeout: 30000})
.typeText(emailInput, username, {paste: true}) .typeText(emailInput, username, {paste: true})
.typeText(passwordInput, password, {paste: true}) .typeText(passwordInput, password, {paste: true})

View file

@ -4,7 +4,8 @@ import {
authorizeInput, emailInput, formError, getFirstVisibleStatus, getUrl, instanceInput, logInToInstanceLink, authorizeInput, emailInput, formError, getFirstVisibleStatus, getUrl, instanceInput, logInToInstanceLink,
mastodonLogInButton, mastodonLogInButton,
passwordInput, passwordInput,
settingsButton settingsButton,
sleep
} from '../utils' } from '../utils'
fixture`002-login-spec.js` fixture`002-login-spec.js`
@ -25,6 +26,7 @@ function manualLogin (t, username, password) {
} }
test('Cannot log in to a fake instance', async t => { test('Cannot log in to a fake instance', async t => {
await sleep(500)
await t.click(logInToInstanceLink) await t.click(logInToInstanceLink)
.expect(getUrl()).contains('/settings/instances/add') .expect(getUrl()).contains('/settings/instances/add')
.typeText(instanceInput, 'fake.nolanlawson.com', {paste: true}) .typeText(instanceInput, 'fake.nolanlawson.com', {paste: true})
@ -39,6 +41,7 @@ test('Cannot log in to a fake instance', async t => {
}) })
test('Logs in and logs out of localhost:3000', async t => { test('Logs in and logs out of localhost:3000', async t => {
await sleep(500)
await manualLogin(t, 'foobar@localhost:3000', 'foobarfoobar') await manualLogin(t, 'foobar@localhost:3000', 'foobarfoobar')
.expect(getUrl()).eql('http://localhost:4002/') .expect(getUrl()).eql('http://localhost:4002/')
.hover(getFirstVisibleStatus()) .hover(getFirstVisibleStatus())

View file

@ -37,6 +37,7 @@ test('timeline preserves focus', async t => {
test('timeline link preserves focus', async t => { test('timeline link preserves focus', async t => {
await t.useRole(foobarRole) await t.useRole(foobarRole)
.expect(getNthStatus(0).exists).ok({timeout: 20000})
.click(getNthStatus(0).find('.status-header a')) .click(getNthStatus(0).find('.status-header a'))
.expect(getUrl()).contains('/accounts/') .expect(getUrl()).contains('/accounts/')
.click(goBackButton) .click(goBackButton)
@ -87,6 +88,7 @@ test('thread preserves focus', async t => {
test('reply preserves focus and moves focus to the text input', async t => { test('reply preserves focus and moves focus to the text input', async t => {
await t.useRole(foobarRole) await t.useRole(foobarRole)
.expect(getNthStatus(1).exists).ok({timeout: 20000})
.click(getNthReplyButton(1)) .click(getNthReplyButton(1))
.expect(getActiveElementClass()).contains('compose-box-input') .expect(getActiveElementClass()).contains('compose-box-input')
}) })

View file

@ -14,6 +14,7 @@ test('fills in a status posted while away from timeline', async t => {
await t.useRole(foobarRole) await t.useRole(foobarRole)
.click(localTimelineNavButton) .click(localTimelineNavButton)
.expect(getNthStatus(0).exists).ok({timeout})
.hover(getNthStatus(0)) .hover(getNthStatus(0))
await postAs('admin', 'heyo') await postAs('admin', 'heyo')
await t.expect(getNthStatus(0).innerText).contains('heyo', {timeout}) await t.expect(getNthStatus(0).innerText).contains('heyo', {timeout})

View file

@ -11,11 +11,10 @@ fixture`113-block-unblock.js`
.page`http://localhost:4002` .page`http://localhost:4002`
test('Can block and unblock an account from a status', async t => { test('Can block and unblock an account from a status', async t => {
await t.useRole(foobarRole)
let post = 'a very silly statement that should probably get me blocked' let post = 'a very silly statement that should probably get me blocked'
await postAs('admin', post) await postAs('admin', post)
await t.useRole(foobarRole)
await t.expect(getNthStatus(0).innerText).contains(post, {timeout: 20000}) .expect(getNthStatus(0).innerText).contains(post, {timeout: 30000})
.click(getNthStatusOptionsButton(0)) .click(getNthStatusOptionsButton(0))
.expect(getNthDialogOptionsOption(1).innerText).contains('Unfollow @admin') .expect(getNthDialogOptionsOption(1).innerText).contains('Unfollow @admin')
.expect(getNthDialogOptionsOption(2).innerText).contains('Block @admin') .expect(getNthDialogOptionsOption(2).innerText).contains('Block @admin')

View file

@ -2,7 +2,7 @@ import { ClientFunction as exec, Selector as $ } from 'testcafe'
import * as images from './images' import * as images from './images'
import * as blobUtils from './blobUtils' import * as blobUtils from './blobUtils'
const SCROLL_INTERVAL = 3 const SCROLL_INTERVAL = 1
export const settingsButton = $('nav a[aria-label=Settings]') export const settingsButton = $('nav a[aria-label=Settings]')
export const instanceInput = $('#instanceInput') export const instanceInput = $('#instanceInput')
@ -234,27 +234,29 @@ export function getNthPinnedStatusFavoriteButton (n) {
} }
export async function validateTimeline (t, timeline) { export async function validateTimeline (t, timeline) {
const timeout = 20000
for (let i = 0; i < timeline.length; i++) { for (let i = 0; i < timeline.length; i++) {
let status = timeline[i] let status = timeline[i]
await t.expect(getNthStatus(i).exists).ok({ timeout })
if (status.content) { if (status.content) {
await t.expect(getNthStatus(i).find('.status-content p').innerText) await t.expect(getNthStatus(i).find('.status-content p').innerText)
.contains(status.content) .contains(status.content, { timeout })
} }
if (status.spoiler) { if (status.spoiler) {
await t.expect(getNthStatus(i).find('.status-spoiler p').innerText) await t.expect(getNthStatus(i).find('.status-spoiler p').innerText)
.contains(status.spoiler) .contains(status.spoiler, { timeout })
} }
if (status.followedBy) { if (status.followedBy) {
await t.expect(getNthStatus(i).find('.status-header span').innerText) await t.expect(getNthStatus(i).find('.status-header span').innerText)
.contains(status.followedBy + ' followed you') .contains(status.followedBy + ' followed you', { timeout })
} }
if (status.rebloggedBy) { if (status.rebloggedBy) {
await t.expect(getNthStatus(i).find('.status-header span').innerText) await t.expect(getNthStatus(i).find('.status-header span').innerText)
.contains(status.rebloggedBy + ' boosted your status') .contains(status.rebloggedBy + ' boosted your status', { timeout })
} }
if (status.favoritedBy) { if (status.favoritedBy) {
await t.expect(getNthStatus(i).find('.status-header span').innerText) await t.expect(getNthStatus(i).find('.status-header span').innerText)
.contains(status.favoritedBy + ' favorited your status') .contains(status.favoritedBy + ' favorited your status', { timeout })
} }
// hovering forces TestCafé to scroll to that element: https://git.io/vABV2 // hovering forces TestCafé to scroll to that element: https://git.io/vABV2
@ -291,8 +293,10 @@ export async function scrollToBottomOfTimeline (t) {
} }
export async function scrollToStatus (t, n) { export async function scrollToStatus (t, n) {
let timeout = 20000
for (let i = 0; i <= n; i += SCROLL_INTERVAL) { for (let i = 0; i <= n; i += SCROLL_INTERVAL) {
await t.hover(getNthStatus(i)) await t.expect(getNthStatus(i).exists).ok({timeout})
.hover(getNthStatus(i))
.expect($('.loading-footer').exist).notOk() .expect($('.loading-footer').exist).notOk()
if (i < n) { if (i < n) {
await t.hover(getNthStatus(i).find('.status-toolbar')) await t.hover(getNthStatus(i).find('.status-toolbar'))