test: cases for PJAX

This commit is contained in:
EnixCoda 2020-11-24 21:46:48 +08:00
parent 17c4becff2
commit 5fe3b566f0
No known key found for this signature in database
GPG key ID: 0C1A07377913A1DD
7 changed files with 171 additions and 5 deletions

View file

@ -0,0 +1,23 @@
import { expectToFind, expectToNotFind, sleep, waitForLegacyPJAXRedirect } from '../utils'
describe(`in Gitako project page`, () => {
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/commits/develop'))
it('should not break go back in history', async () => {
for (let i = 0; i < 3; i++) {
const commitLinks = await page.$$(
`#js-repo-pjax-container .TimelineItem-body ol li > div:nth-child(1) a[href*="/commit/"]`,
)
if (commitLinks.length < 2) throw new Error(`No enough commits`)
commitLinks[i].click()
await waitForLegacyPJAXRedirect()
await expectToFind('div.commit')
await sleep(1000)
page.goBack()
await sleep(1000)
// The selector for file content
await expectToNotFind('div.commit')
}
})
})

View file

@ -0,0 +1,23 @@
import { expectToFind, expectToNotFind, sleep, waitForLegacyPJAXRedirect } from '../utils'
describe(`in Gitako project page`, () => {
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/tree/develop/src'))
it('should not break go back in history', async () => {
for (let i = 0; i < 3; i++) {
const commitLinks = await page.$$(
`.js-details-container div[role="row"] div[role="rowheader"] a[title*="."]`,
)
if (commitLinks.length < 2) throw new Error(`No enough files`)
await commitLinks[i].click()
await waitForLegacyPJAXRedirect()
await expectToFind('table.js-file-line-container')
await sleep(1000)
page.goBack()
await sleep(1000)
// The selector for file content
await expectToNotFind('table.js-file-line-container')
}
})
})

View file

@ -0,0 +1,29 @@
import {
expectToFind,
expectToNotFind,
patientClick,
selectFileTreeItem,
sleep,
waitForPJAXAPIRedirect,
} from '../utils'
describe(`in Gitako project page`, () => {
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako'))
it('should work with PJAX', async () => {
await sleep(3000)
await patientClick(page, selectFileTreeItem('.babelrc'))
await waitForPJAXAPIRedirect()
// The selector for file content
await expectToFind('table.js-file-line-container')
page.goBack()
await waitForPJAXAPIRedirect()
// The selector for file content
await expectToNotFind('table.js-file-line-container')
// await waitForPJAXAPIRedirect()
})
})

View file

@ -0,0 +1,30 @@
import { patientClick, selectFileTreeItem, sleep, waitForLegacyPJAXRedirect } from '../utils'
describe(`in Gitako project page`, () => {
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako/src'))
it('should work with PJAX', async () => {
await sleep(3000)
await patientClick(page, selectFileTreeItem('src/analytics.ts'))
await waitForLegacyPJAXRedirect()
await page.click('a[data-tab-item="issues-tab"]')
await waitForLegacyPJAXRedirect()
await page.click('a[data-tab-item="pull-requests-tab"]')
await waitForLegacyPJAXRedirect()
page.goBack()
await sleep(1000)
page.goBack()
await sleep(1000)
expect(
await page.evaluate(
() => document.querySelector('.final-path')?.textContent === 'analytics.ts',
),
).toBe(true)
})
})

View file

@ -1,4 +1,4 @@
import { expectToFind, expectToNotFind, scroll } from '../utils'
import { expectToFind, expectToNotFind, scroll, selectFileTreeItem } from '../utils'
describe(`in Gitako project page`, () => {
beforeAll(() => page.goto('https://github.com/EnixCoda/Gitako'))
@ -14,14 +14,14 @@ describe(`in Gitako project page`, () => {
it('should render while scroll', async () => {
const filesEle = await page.waitForSelector('.gitako-side-bar .files')
// node of tsconfig.json should NOT be rendered before scroll down
await expectToNotFind('.gitako-side-bar .files a[title="tsconfig.json"]')
await expectToNotFind(selectFileTreeItem('tsconfig.json'))
const box = await filesEle.boundingBox()
if (box) {
await page.mouse.move(box.x + 40, box.y + 40)
await scroll({ totalDistance: 100, duration: 5000 })
await scroll({ totalDistance: 100, duration: 1000 })
// node of tsconfig.json should be rendered now
await expectToFind('.gitako-side-bar .files a[title="tsconfig.json"]')
await expectToFind(selectFileTreeItem('tsconfig.json'))
}
})
})

View file

@ -1,3 +1,5 @@
import { Page } from 'puppeteer'
export async function expectToFind(selector: string) {
await expect(page.waitForSelector(selector)).resolves.not.toBeNull()
}
@ -25,3 +27,62 @@ export async function scroll({
await sleep((duration * step) / totalDistance)
}
}
export function assert(condition: boolean, err?: Error | string) {
if (!condition) throw typeof err === 'string' ? new Error(err) : err
}
let counter = 0
export async function listenTo<Args extends any[] = any[]>(
event: string,
target: 'document' | 'window',
callback: (...args: Args) => void,
oneTime?: boolean,
) {
const callbackName = 'onEvent' + ++counter
await page.exposeFunction(callbackName, callback)
await page.evaluate(
(event, target, callbackName, oneTime) => {
const t = target === 'document' ? document : window
const onEvent = (...args: any[]): void => {
;((window[callbackName as any] as any) as (...args: any[]) => void)(...args)
if (oneTime) t.removeEventListener(event, onEvent)
}
t.addEventListener(event, onEvent)
},
event,
target,
callbackName,
oneTime || false,
)
}
export function once(event: string, target: 'document' | 'window') {
return new Promise(resolve => {
listenTo(
event,
target,
(...args) => {
resolve(args)
},
true,
)
})
}
export function waitForLegacyPJAXRedirect() {
return once('pjax:end', 'document')
}
export function waitForPJAXAPIRedirect() {
return once('pjax:ready', 'document')
}
export function selectFileTreeItem(path: string): string {
return `.gitako-side-bar .files a[title="${path}"]`
}
export async function patientClick(page: Page, selector: string) {
await page.waitForSelector(selector)
await page.click(selector)
}

View file

@ -61,7 +61,7 @@ module.exports = {
// globals: {},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
maxWorkers: 1, // more than 1 workers may make tabs in background and never renders Gitako's file items.
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [