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.
137 lines
3.6 KiB
137 lines
3.6 KiB
2 years ago
|
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;
|
||
|
}
|