2020-05-15 19:27:29 +02:00
|
|
|
const path = require('path');
|
2020-05-15 16:02:16 +02:00
|
|
|
const puppeteer = require('puppeteer');
|
2020-05-29 15:36:32 +02:00
|
|
|
const assert = require("assert");
|
2020-05-15 16:02:16 +02:00
|
|
|
|
|
|
|
class CommonUtils {
|
|
|
|
constructor() {
|
|
|
|
this.browser = null;
|
2020-05-15 19:27:29 +02:00
|
|
|
this.screenshot_id = 0;
|
2020-05-29 15:36:32 +02:00
|
|
|
this.realm_url = "http://zulip.zulipdev.com:9981/";
|
2020-05-15 16:02:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async ensure_browser() {
|
|
|
|
if (this.browser === null) {
|
|
|
|
this.browser = await puppeteer.launch({
|
|
|
|
args: [
|
|
|
|
'--window-size=1400,1024',
|
|
|
|
'--no-sandbox', '--disable-setuid-sandbox',
|
|
|
|
],
|
|
|
|
defaultViewport: { width: 1280, height: 1024 },
|
|
|
|
headless: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async get_page(url = null) {
|
|
|
|
await this.ensure_browser();
|
|
|
|
|
|
|
|
const page = await this.browser.newPage();
|
|
|
|
if (url !== null) {
|
|
|
|
await page.goto(url);
|
|
|
|
}
|
|
|
|
|
|
|
|
return page;
|
|
|
|
}
|
2020-05-15 17:38:25 +02:00
|
|
|
|
2020-05-15 19:27:29 +02:00
|
|
|
async screenshot(page, name = null) {
|
|
|
|
if (name === null) {
|
|
|
|
name = `${this.screenshot_id}`;
|
|
|
|
this.screenshot_id += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const root_dir = path.resolve(__dirname, '../../');
|
|
|
|
const screenshot_path = path.join(root_dir, 'var/puppeteer', `${name}.png`);
|
|
|
|
await page.screenshot({
|
|
|
|
path: screenshot_path,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-05-29 20:46:35 +02:00
|
|
|
/**
|
|
|
|
* This function takes a params object whose fields
|
|
|
|
* are referenced by name attribute of an input field and
|
|
|
|
* the input as a key.
|
|
|
|
*
|
|
|
|
* For example to fill:
|
|
|
|
* <form id="#demo">
|
|
|
|
* <input type="text" name="username">
|
|
|
|
* <input type="checkbox" name="terms">
|
|
|
|
* </form>
|
|
|
|
*
|
|
|
|
* You can call:
|
|
|
|
* common.fill_form(page, '#demo', {
|
|
|
|
* username: 'Iago',
|
|
|
|
* terms: true
|
|
|
|
* });
|
|
|
|
*/
|
|
|
|
async fill_form(page, form_selector, params) {
|
|
|
|
for (const name of Object.keys(params)) {
|
|
|
|
const name_selector = `${form_selector} [name="${name}"]`;
|
|
|
|
const value = params[name];
|
|
|
|
if (typeof value === "boolean") {
|
|
|
|
await page.$eval(name_selector, (el, value) => {
|
|
|
|
if (el.checked !== value) {
|
|
|
|
el.click();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
await page.type(name_selector, params[name]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:36:32 +02:00
|
|
|
async log_in(page, credentials) {
|
|
|
|
console.log("Logging in");
|
|
|
|
await page.goto(this.realm_url + 'login/');
|
|
|
|
assert.equal(this.realm_url + 'login/', page.url());
|
2020-05-29 20:46:35 +02:00
|
|
|
// fill login form
|
|
|
|
const params = {
|
|
|
|
username: credentials.username,
|
|
|
|
password: credentials.password,
|
|
|
|
};
|
|
|
|
await this.fill_form(page, '#login_form', params);
|
2020-05-29 15:36:32 +02:00
|
|
|
await page.$eval('#login_form', form => form.submit());
|
|
|
|
}
|
|
|
|
|
|
|
|
async log_out(page) {
|
|
|
|
await page.goto(this.realm_url);
|
|
|
|
const menu_selector = '#settings-dropdown';
|
|
|
|
const logout_selector = 'a[href="#logout"]';
|
|
|
|
console.log("Loggin out");
|
|
|
|
await page.waitForSelector(menu_selector, {visible: true});
|
|
|
|
await page.click(menu_selector);
|
|
|
|
await page.waitForSelector(logout_selector);
|
|
|
|
await page.click(logout_selector);
|
|
|
|
|
|
|
|
// Wait for a email input in login page so we know login
|
|
|
|
// page is loaded. Then check that we are at the login url.
|
|
|
|
await page.waitForSelector('input[name="username"]');
|
|
|
|
assert(page.url().includes('/login/'));
|
|
|
|
}
|
|
|
|
|
2020-05-15 17:38:25 +02:00
|
|
|
async run_test(test_function) {
|
2020-05-16 19:14:31 +02:00
|
|
|
// Pass a page instance to test so we can take
|
|
|
|
// a screenshot of it when the test fails.
|
|
|
|
const page = await this.get_page();
|
2020-05-15 17:38:25 +02:00
|
|
|
try {
|
2020-05-16 19:14:31 +02:00
|
|
|
await test_function(page);
|
2020-05-15 17:38:25 +02:00
|
|
|
} catch (e) {
|
|
|
|
console.log(e);
|
2020-05-16 19:14:31 +02:00
|
|
|
|
|
|
|
// Take a screenshot, and increment the screenshot_id.
|
|
|
|
await this.screenshot(page, `failure-${this.screenshot_id}`);
|
|
|
|
this.screenshot_id += 1;
|
|
|
|
|
2020-05-15 17:38:25 +02:00
|
|
|
await this.browser.close();
|
|
|
|
process.exit(1);
|
|
|
|
} finally {
|
|
|
|
this.browser.close();
|
|
|
|
}
|
|
|
|
}
|
2020-05-15 16:02:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const common = new CommonUtils();
|
|
|
|
module.exports = common;
|