forked from cybrespace/pinafore
		
	test: make tests less flaky (#678)
This commit is contained in:
		
							parent
							
								
									673e7b951c
								
							
						
					
					
						commit
						bae367da7b
					
				
					 6 changed files with 61 additions and 72 deletions
				
			
		| 
						 | 
				
			
			@ -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/')
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue