Polishing e2e test API. Added option to parse links and extract parameters from them. Added option to construct parameterizedlinks in "navigate".
This commit is contained in:
parent
328034bae0
commit
ccd37ac792
12 changed files with 308 additions and 147 deletions
|
@ -1,14 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const config = require('../helpers/config');
|
||||
|
||||
const driver = require('../helpers/mocha-e2e').driver;
|
||||
const page = require('./page');
|
||||
|
||||
module.exports = (driver, ...extras) => page(driver, {
|
||||
module.exports = (...extras) => page({
|
||||
|
||||
async fetchMail(address) {
|
||||
await this.driver.sleep(1000);
|
||||
await this.driver.navigate().to(`${config.mailUrl}/${address}`);
|
||||
await driver.sleep(1000);
|
||||
await driver.navigate().to(`${config.mailUrl}/${address}`);
|
||||
await this.waitUntilVisible();
|
||||
},
|
||||
|
||||
|
|
|
@ -5,77 +5,84 @@ const webdriver = require('selenium-webdriver');
|
|||
const By = webdriver.By;
|
||||
const until = webdriver.until;
|
||||
const fs = require('fs-extra');
|
||||
const driver = require('../helpers/mocha-e2e').driver;
|
||||
const url = require('url');
|
||||
const UrlPattern = require('url-pattern');
|
||||
|
||||
module.exports = (driver, ...extras) => Object.assign({
|
||||
driver,
|
||||
|
||||
module.exports = (...extras) => Object.assign({
|
||||
elements: {},
|
||||
|
||||
async element(key) {
|
||||
return await this.driver.findElement(By.css(this.elements[key] || key));
|
||||
async getElement(key) {
|
||||
return await driver.findElement(By.css(this.elements[key]));
|
||||
},
|
||||
|
||||
async getLinkParams(key) {
|
||||
const elem = await driver.findElement(By.css(this.elements[key]));
|
||||
|
||||
const linkUrl = await elem.getAttribute('href');
|
||||
const linkPath = url.parse(linkUrl).path;
|
||||
|
||||
const urlPattern = new UrlPattern(this.links[key]);
|
||||
|
||||
const params = urlPattern.match(linkPath);
|
||||
if (!params) {
|
||||
throw new Error(`Cannot match URL pattern ${this.links[key]}`);
|
||||
}
|
||||
return params;
|
||||
},
|
||||
|
||||
async waitUntilVisible(selector) {
|
||||
// This is left here to ease debugging
|
||||
// await this.sleep(2000);
|
||||
// await this.takeScreenshot('image.png');
|
||||
// console.log(await this.source());
|
||||
|
||||
const sel = selector || this.elements[this.elementToWaitFor] || 'body';
|
||||
await this.driver.wait(until.elementLocated(By.css(sel)), 10000);
|
||||
|
||||
await driver.wait(until.elementLocated(By.css(sel)), 10000);
|
||||
|
||||
if (this.url) {
|
||||
await this.ensureUrl();
|
||||
}
|
||||
},
|
||||
|
||||
async link(key) {
|
||||
const elem = await this.element(key);
|
||||
return await elem.getAttribute('href');
|
||||
},
|
||||
|
||||
async submit() {
|
||||
const submitButton = await this.element('submitButton');
|
||||
await submitButton.click();
|
||||
},
|
||||
|
||||
async click(key) {
|
||||
const elem = await this.element(key);
|
||||
const elem = await this.getElement(key);
|
||||
await elem.click();
|
||||
},
|
||||
|
||||
async getHref(key) {
|
||||
const elem = await this.getElement(key);
|
||||
return await elem.getAttribute('href');
|
||||
},
|
||||
|
||||
async getText(key) {
|
||||
const elem = await this.element(key);
|
||||
const elem = await this.getElement(key);
|
||||
return await elem.getText();
|
||||
},
|
||||
|
||||
async getValue(key) {
|
||||
const elem = await this.element(key);
|
||||
const elem = await this.getElement(key);
|
||||
return await elem.getAttribute('value');
|
||||
},
|
||||
|
||||
async setValue(key, value) {
|
||||
const elem = await this.element(key);
|
||||
await elem.sendKeys(value);
|
||||
},
|
||||
|
||||
async containsText(str) {
|
||||
return await this.driver.executeScript(`
|
||||
return await driver.executeScript(`
|
||||
return (document.documentElement.textContent || document.documentElement.innerText).indexOf('${str}') > -1;
|
||||
`);
|
||||
},
|
||||
|
||||
async source() {
|
||||
return await this.driver.getPageSource();
|
||||
async getSource() {
|
||||
return await driver.getPageSource();
|
||||
},
|
||||
|
||||
async saveSource(destPath) {
|
||||
const src = await this.getSource();
|
||||
await fs.writeFile(destPath, src);
|
||||
},
|
||||
|
||||
async takeScreenshot(destPath) {
|
||||
const pngData = await this.driver.takeScreenshot();
|
||||
const pngData = await driver.takeScreenshot();
|
||||
const buf = new Buffer(pngData, 'base64');
|
||||
await fs.writeFile(destPath, buf);
|
||||
},
|
||||
|
||||
async sleep(ms) {
|
||||
await this.driver.sleep(ms);
|
||||
await driver.sleep(ms);
|
||||
}
|
||||
}, ...extras);
|
||||
|
|
|
@ -4,17 +4,10 @@ const config = require('../helpers/config');
|
|||
const webBase = require('./web');
|
||||
const mailBase = require('./mail');
|
||||
|
||||
module.exports = (driver, list) => {
|
||||
module.exports = list => {
|
||||
|
||||
const web = params => webBase(driver, {
|
||||
async enterEmail(value) {
|
||||
const emailInput = await this.element('emailInput');
|
||||
await emailInput.clear();
|
||||
await emailInput.sendKeys(value);
|
||||
},
|
||||
}, params);
|
||||
|
||||
const mail = params => mailBase(driver, params);
|
||||
const web = params => webBase(params);
|
||||
const mail = params => mailBase(params);
|
||||
|
||||
return {
|
||||
webSubscribe: web({
|
||||
|
@ -23,6 +16,8 @@ module.exports = (driver, list) => {
|
|||
elements: {
|
||||
form: `form[action="/subscription/${list.cid}/subscribe"]`,
|
||||
emailInput: '#main-form input[name="email"]',
|
||||
firstNameInput: '#main-form input[name="first-name"]',
|
||||
lastNameInput: '#main-form input[name="last-name"]',
|
||||
submitButton: 'a[href="#submit"]'
|
||||
}
|
||||
}),
|
||||
|
@ -55,17 +50,40 @@ module.exports = (driver, list) => {
|
|||
elements: {
|
||||
unsubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}/unsubscribe/"]`,
|
||||
manageLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}/manage/"]`
|
||||
},
|
||||
links: {
|
||||
unsubscribeLink: `/subscription/${list.cid}/unsubscribe/:ucid`,
|
||||
manageLink: `/subscription/${list.cid}/manage/:ucid`
|
||||
}
|
||||
}),
|
||||
|
||||
/*
|
||||
webManage: web({
|
||||
url: `/subscription/${list.cid}/manage/:ucid`,
|
||||
elementToWaitFor: 'form',
|
||||
elements: {
|
||||
form: `form[action="/subscription/${list.cid}/manage"]`,
|
||||
emailInput: '#main-form input[name="email"]',
|
||||
firstNameInput: '#main-form input[name="first-name"]',
|
||||
lastNameInput: '#main-form input[name="last-name"]',
|
||||
submitButton: 'a[href="#submit"]'
|
||||
}
|
||||
}),
|
||||
|
||||
webUpdatedNotice: web({
|
||||
url: `/subscription/${list.cid}/updated-notice`,
|
||||
elementToWaitFor: 'homepageButton',
|
||||
elements: {
|
||||
homepageButton: `a[href="${config.settings['default-homepage']}"]`
|
||||
}
|
||||
}),
|
||||
|
||||
/*
|
||||
webUnsubscribe: web({ // FIXME
|
||||
elementToWaitFor: 'submitButton',
|
||||
elements: {
|
||||
submitButton: 'a[href="#submit"]'
|
||||
}
|
||||
}),
|
||||
*/
|
||||
|
||||
webUnsubscribedNotice: web({
|
||||
url: `/subscription/${list.cid}/unsubscribed-notice`,
|
||||
|
@ -81,14 +99,8 @@ module.exports = (driver, list) => {
|
|||
resubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}"]`
|
||||
}
|
||||
}),
|
||||
/* TODO
|
||||
webManage: web({
|
||||
url: `/subscription/${list.cid}/manage`,
|
||||
elementToWaitFor: 'homepageButton',
|
||||
elements: {
|
||||
homepageButton: `a[href="${config.settings['default-homepage']}"]`
|
||||
}
|
||||
}),
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -3,13 +3,30 @@
|
|||
const config = require('../helpers/config');
|
||||
const By = require('selenium-webdriver').By;
|
||||
const url = require('url');
|
||||
|
||||
const UrlPattern = require('url-pattern');
|
||||
const driver = require('../helpers/mocha-e2e').driver;
|
||||
const page = require('./page');
|
||||
|
||||
module.exports = (driver, ...extras) => page(driver, {
|
||||
module.exports = (...extras) => page({
|
||||
|
||||
async navigate(path) {
|
||||
await this.driver.navigate().to(config.baseUrl + (path || this.url));
|
||||
async navigate(pathOrParams) {
|
||||
let path;
|
||||
if (typeof pathOrParams === 'string') {
|
||||
path = pathOrParams;
|
||||
} else {
|
||||
const urlPattern = new UrlPattern(this.url);
|
||||
path = urlPattern.stringify(pathOrParams)
|
||||
}
|
||||
|
||||
const parsedUrl = url.parse(path);
|
||||
let absolutePath;
|
||||
if (parsedUrl.host) {
|
||||
absolutePath = path;
|
||||
} else {
|
||||
absolutePath = config.baseUrl + path;
|
||||
}
|
||||
|
||||
await driver.navigate().to(absolutePath);
|
||||
await this.waitUntilVisible();
|
||||
},
|
||||
|
||||
|
@ -17,28 +34,44 @@ module.exports = (driver, ...extras) => page(driver, {
|
|||
const desiredUrl = path || this.url;
|
||||
|
||||
if (desiredUrl) {
|
||||
const currentUrl = url.parse(await this.driver.getCurrentUrl());
|
||||
if (this.url !== currentUrl.pathname || config.baseUrl !== `${currentUrl.protocol}//${currentUrl.host}`) {
|
||||
const currentUrl = url.parse(await driver.getCurrentUrl());
|
||||
const urlPattern = new UrlPattern(desiredUrl);
|
||||
const params = urlPattern.match(currentUrl.pathname);
|
||||
if (!params || config.baseUrl !== `${currentUrl.protocol}//${currentUrl.host}`) {
|
||||
throw new Error(`Unexpected URL. Expecting ${config.baseUrl}${this.url} got ${currentUrl.protocol}//${currentUrl.host}/${currentUrl.pathname}`);
|
||||
}
|
||||
|
||||
this.params = params;
|
||||
}
|
||||
},
|
||||
|
||||
async submit() {
|
||||
const submitButton = await this.getElement('submitButton');
|
||||
await submitButton.click();
|
||||
},
|
||||
|
||||
async waitForFlash() {
|
||||
await this.waitUntilVisible('div.alert:not(.js-warning)');
|
||||
},
|
||||
|
||||
async getFlash() {
|
||||
const elem = await this.driver.findElement(By.css('div.alert:not(.js-warning)'));
|
||||
async flash() {
|
||||
const elem = await driver.findElement(By.css('div.alert:not(.js-warning)'));
|
||||
return await elem.getText();
|
||||
},
|
||||
|
||||
async clearFlash() {
|
||||
await this.driver.executeScript(`
|
||||
await driver.executeScript(`
|
||||
var elements = document.getElementsByClassName('alert');
|
||||
while(elements.length > 0){
|
||||
elements[0].parentNode.removeChild(elements[0]);
|
||||
}
|
||||
`);
|
||||
},
|
||||
|
||||
async setValue(key, value) {
|
||||
const elem = await this.getElement(key);
|
||||
await elem.clear();
|
||||
await elem.sendKeys(value);
|
||||
}
|
||||
|
||||
}, ...extras);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue