-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathdefaultScenario.js
94 lines (87 loc) · 3.1 KB
/
defaultScenario.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { defaultWaitForPageIdle } from './puppeteerUtil.js'
import { ono } from 'ono'
import { getCustomWaitForPageIdle } from './customWaitForPageIdle.js'
function urlsAreEqual (url1, url2) {
for (const prop of ['protocol', 'hostname', 'port', 'pathname', 'search']) {
let value1 = url1[prop]
let value2 = url2[prop]
if (prop === 'pathname') {
// ignore trailing slashes, most of the time these are effectively the same URL
value1 = value1.replace(/\/+$/g, '')
value2 = value2.replace(/\/+$/g, '')
}
if (value1 !== value2) {
return false
}
}
return true
}
async function clickFirstVisible (page, selector) {
const element = await page.evaluateHandle((selector) => {
return [...document.querySelectorAll(selector)].filter(el => {
// avoid links that open in a new tab
return el.target === '' &&
// quick and dirty visibility check
window.getComputedStyle(el).getPropertyValue('display') !== 'none' &&
window.getComputedStyle(el).getPropertyValue('visibility') !== 'hidden' &&
el.offsetHeight > 0 &&
el.offsetWidth > 0
})[0]
}, selector)
try {
try {
await element.click()
} catch (err) {
throw ono(err, `Element ${selector} is not clickable or is not an in-page SPA navigation`)
}
} finally {
await element.dispose()
}
}
export async function createTests (page) {
const location = await page.evaluate('window.location.href')
const baseUrl = new URL(location)
const hrefs = await page.$$eval('a[href]', elements => {
return elements
.filter(el => {
// avoid links that open in a new tab
return el.target === '' &&
// quick and dirty visibility check
window.getComputedStyle(el).getPropertyValue('display') !== 'none' &&
window.getComputedStyle(el).getPropertyValue('visibility') !== 'hidden' &&
el.offsetHeight > 0 &&
el.offsetWidth > 0
})
.map(el => el.getAttribute('href'))
})
// Find unique links, dedup based on full url
const fullLinksToLinks = new Map()
for (const href of hrefs) {
const url = new URL(href, location)
// origin may be the same for blob: URLs, but the protocol is different
// https://developer.mozilla.org/en-US/docs/Web/API/URL/origin
const isInternalLink = url.origin === baseUrl.origin &&
url.protocol === baseUrl.protocol &&
!urlsAreEqual(url, baseUrl) // ignore links to this very page
if (isInternalLink && !fullLinksToLinks.has(url.href)) {
fullLinksToLinks.set(url.href, href)
}
}
return [...fullLinksToLinks.entries()].map(([fullHref, originalHref]) => {
const url = new URL(fullHref)
return {
data: {
href: originalHref,
fullHref
},
description: `Go to ${url.pathname + url.search + url.hash} and back`
}
})
}
export async function iteration (page, { href }) {
const doWaitForIdle = getCustomWaitForPageIdle() || defaultWaitForPageIdle
await clickFirstVisible(page, `a[href=${JSON.stringify(href)}]`)
await doWaitForIdle(page)
await page.goBack()
await doWaitForIdle(page)
}