This is the template project that's checked out and configured when you run the bando-up command from ljsthw-bandolier. This is where the code really lives.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bandolier-template/lib/testing.js

137 lines
3.6 KiB

import playwright from 'playwright';
import faker from 'faker';
import random from 'random';
import assert from "assert";
import { v4 as uuid } from "uuid";
import fs from "fs";
import url from "url";
import path from "path";
import { User } from "./models.js";
const WAIT_TIME = 5000;
const HEADLESS = !process.env.PLAYVIEW;
const COVERAGE = process.env.NODE_V8_COVERAGE;
export const tid = (name) => `[data-testid="${name}"]`;
export const form = async (page, fields, button_id) => {
for(const [key, value] of Object.entries(fields)) {
if(typeof value === "boolean") {
if(value) {
await page.check(key);
} else {
await page.uncheck(key);
}
} else {
// it's another input to fill
await page.fill(key, value);
}
}
if(button_id) {
await page.click(button_id);
}
}
export const playstart = async (url) => {
if(!HEADLESS) console.log("Running playwright in visible mode (not HEADLESS).");
if(COVERAGE) console.log(`Coverage reports going to ${COVERAGE}.`);
const browser = await playwright['chromium'].launch({headless: HEADLESS});
const context = await browser.newContext();
const p = await context.newPage();
if(COVERAGE) {
await p.coverage.startJSCoverage();
}
p.on('console', async msg => {
console.debug(`CONSOLE ${msg.type()}>>`, msg)
});
await p.goto(url);
return {browser, context, p};
}
export const playstop = async (browser, p) => {
if(COVERAGE) {
const coverage = await p.coverage.stopJSCoverage();
for(const entry of coverage) {
entry.url = path.join(process.cwd(), "public", url.parse(entry.url).pathname);
}
const v8out = {result: coverage, timestamp: Date.now()};
fs.writeFileSync(`${COVERAGE}/${uuid()}.json`, JSON.stringify(v8out));
}
await browser.close();
}
export const wait = async (p, css_id) => {
try {
await p.waitForSelector(css_id, { timeout: WAIT_TIME });
} catch(error) {
console.error(error, `!!!!!!!!!!!!!!!!!!!!!!!!!!!! Failed waiting for id ${css_id}`);
throw error;
}
}
export const expect = async (t, p, css_id) => {
await wait(p, css_id);
let tag = await p.$(css_id);
let text = tag ? await tag.textContent() : "NULL!";
t.true(text !== null);
return text;
}
export const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
}
export const random_user = () => {
let email = faker.internet.email();
let rnd = random.int(0, 10 * 1000);
email = email.replace('@', `${rnd}@`);
let full_name = faker.name.findName();
let initials = full_name.split(' ').map(x => x[0]).join('');
let password = faker.internet.password();
assert(password, "Looks like faker is failing at passwords again.");
return {
email,
full_name,
initials,
password
}
}
export const register_user = async (is_admin=false) => {
const rando = random_user();
rando.password_repeat = rando.password;
// copy it to keep the original password
const user = await User.register({...rando});
if(is_admin) {
// make this user an admin
user.admin = true;
await User.update({id: user.id}, {admin: true});
}
// then replace it so we can use it later
user.raw_password = rando.password;
return user;
}
/* A helper function for other tests to use logins. */
export const login = async (t, p, with_user) => {
const user = with_user ? with_user : await register_user();
await expect(t, p, tid("login-form"));
// fill out correct form, and redirect to watch
await p.fill('#email', user.email);
await p.fill("#password", user.raw_password);
await p.click(tid('login-button'));
await sleep(1000);
return user;
}