Files
bee-dashboard/ui-test/library.js
T
Cafe137 186d0352cf fix: correct website upload path (#483)
* test(wip): add ui tests

* fix: correct website upload path

* fix: use includes

* test: rewrite ui tests

* build: remove concurrently

* ci: run puppeteer in headless

* test: add regression tests

* test: add website regression 03 test

* test: add react test website

* chore: revert newlines

Co-authored-by: Cafe137 <aron@aronsoos.com>
2022-07-25 11:24:32 +02:00

153 lines
4.7 KiB
JavaScript

const puppeteer = require('puppeteer')
const SLEEP_MS = 500
const SLEEP_ITERATIONS = 20
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} selector XPath selector
*/
async function waitForElementXPath(page, selector) {
for (let i = 0; i < SLEEP_ITERATIONS; i++) {
const [element] = await page.$x(selector)
if (element) {
return element
}
await sleep(SLEEP_MS)
}
return null
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} selector CSS selector
*/
async function waitForElementCss(page, selector) {
for (let i = 0; i < SLEEP_ITERATIONS; i++) {
const element = await page.$(selector)
if (element) {
return element
}
await sleep(SLEEP_MS)
}
return null
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} elementType HTML tag name, e.g. `a`, `button`, `div`,
* @param {string} text e.g. `"Submit"`
*/
function waitForEnabledStateXPath(page, elementType, text) {
return waitForElementXPath(page, `//${elementType}[contains(., '${text}')][not(@disabled)]`)
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} elementType HTML tag name, e.g. `a`, `button`, `div`,
* @param {string} text e.g. `"Submit"`
*/
async function clickElementWithText(page, elementType, text) {
const element = await waitForElementXPath(page, `//${elementType}[contains(., '${text}')]`)
if (!element) {
throw Error(`clickElementWithText: Could not find <${elementType}> containing "${text}"`)
}
if (element) {
await element.click()
}
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} elementType HTML tag name, e.g. `a`, `button`, `div`,
* @param {string} text e.g. `"Submit"`
* @param {string} filePath e.g. `"test-data/text.txt"`
*/
async function clickElementWithTextAndUpload(page, elementType, text, filePath) {
const [fileChooser] = await Promise.all([page.waitForFileChooser(), clickElementWithText(page, elementType, text)])
await fileChooser.accept([filePath])
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} elementType HTML tag name, e.g. `a`, `button`, `div`,
* @param {string} cssClass CSS class with the dot, e.g. '.MuiSelect-select'
*/
async function clickElementWithClass(page, elementType, cssClass) {
const element = await waitForElementCss(page, `${elementType}${cssClass}`)
if (!element) {
throw Error(`clickElementWithClass: Could not find <${elementType}> with class ${cssClass}`)
}
if (element) {
await element.click()
}
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} elementType HTML tag name, e.g. `a`, `button`, `div`,
* @param {string} text e.g. `"Submit"`
*/
async function assertElementWithTextExists(page, elementType, text) {
const element = await waitForElementXPath(page, `//${elementType}[contains(., '${text}')]`)
if (!element) {
throw Error(`assertElementWithTextExists: Could not find <${elementType}> containing "${text}"`)
}
return true
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} elementType HTML tag name, e.g. `a`, `button`, `div`,
* @param {string} attribute HTML attribute, e.g. `alt` or `id`
* @param {string} value Expected value of the attribute
* @param {string} property Property to return from the queried HTML element
* @returns {Promise<string>}
*/
async function queryElementPropertyByAttribute(page, elementType, attribute, value, property) {
const element = await waitForElementXPath(page, `//${elementType}[contains(@${attribute}, "${value}")]`)
return page.evaluate((element, property) => element[property], element, property)
}
/**
* @param {puppeteer.Page} page Puppeteer Page object returned by `browser.newPage()`
* @param {string} alt `<img>` `alt` to look for
*/
function queryImgSrcByAlt(page, alt) {
return queryElementPropertyByAttribute(page, 'img', 'alt', alt, 'src')
}
module.exports = {
sleep,
Assert: {
elementWithTextExists: assertElementWithTextExists,
},
Click: {
elementWithText: clickElementWithText,
elementWithClass: clickElementWithClass,
elementWithTextAndUpload: clickElementWithTextAndUpload,
},
Query: {
elementPropertyByAttribute: queryElementPropertyByAttribute,
imgSrcByAlt: queryImgSrcByAlt,
},
Wait: {
forElementCss: waitForElementCss,
forElementXPath: waitForElementXPath,
forEnabledStateXPath: waitForEnabledStateXPath,
},
}