Half way in improving e2e test infrastructure and refactoring tests to the enhanced (un)subscription process

This commit is contained in:
Tomas Bures 2017-05-23 04:15:32 +02:00
parent 62cc881fd4
commit 328034bae0
16 changed files with 482 additions and 153 deletions

View file

@ -1,21 +0,0 @@
'use strict';
const page = require('./page');
module.exports = driver => Object.assign(page(driver), {
elementToWaitFor: 'alert',
elements: {
alert: 'div.alert:not(.js-warning)'
},
getText() {
return this.element('alert').getText();
},
clear() {
return this.driver.executeScript(`
var elements = document.getElementsByClassName('alert');
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
`);
}
});

View file

@ -1,6 +1,6 @@
'use strict';
const page = require('./page');
const page = require('./web');
module.exports = driver => Object.assign(page(driver), {
url: '/',

View file

@ -0,0 +1,19 @@
'use strict';
const config = require('../helpers/config');
const page = require('./page');
module.exports = (driver, ...extras) => page(driver, {
async fetchMail(address) {
await this.driver.sleep(1000);
await this.driver.navigate().to(`${config.mailUrl}/${address}`);
await this.waitUntilVisible();
},
async ensureUrl(path) {
throw new Error('Unsupported method.');
},
}, ...extras);

View file

@ -4,52 +4,78 @@ const config = require('../helpers/config');
const webdriver = require('selenium-webdriver');
const By = webdriver.By;
const until = webdriver.until;
const fs = require('fs-extra');
module.exports = driver => ({
module.exports = (driver, ...extras) => Object.assign({
driver,
elements: {},
element(key) {
return this.driver.findElement(By.css(this.elements[key] || key));
async element(key) {
return await this.driver.findElement(By.css(this.elements[key] || key));
},
navigate(path) {
this.driver.navigate().to(config.baseUrl + (path || this.url));
return this.waitUntilVisible();
},
async waitUntilVisible(selector) {
// This is left here to ease debugging
// await this.sleep(2000);
// await this.takeScreenshot('image.png');
// console.log(await this.source());
waitUntilVisible() {
let selector = this.elements[this.elementToWaitFor];
if (!selector && this.url) {
selector = 'body.page--' + (this.url.substring(1).replace(/\//g, '--') || 'home');
const sel = selector || this.elements[this.elementToWaitFor] || 'body';
await this.driver.wait(until.elementLocated(By.css(sel)), 10000);
if (this.url) {
await this.ensureUrl();
}
return selector ? this.driver.wait(until.elementLocated(By.css(selector))) : this.driver.sleep(1000);
},
submit() {
return this.element('submitButton').click();
async link(key) {
const elem = await this.element(key);
return await elem.getAttribute('href');
},
click(key) {
return this.element(key).click();
async submit() {
const submitButton = await this.element('submitButton');
await submitButton.click();
},
getText(key) {
return this.element(key).getText();
async click(key) {
const elem = await this.element(key);
await elem.click();
},
getValue(key) {
return this.element(key).getAttribute('value');
async getText(key) {
const elem = await this.element(key);
return await elem.getText();
},
setValue(key, value) {
return this.element(key).sendKeys(value);
async getValue(key) {
const elem = await this.element(key);
return await elem.getAttribute('value');
},
containsText(str) {
// let text = await driver.findElement({ css: 'body' }).getText();
return this.driver.executeScript(`
async setValue(key, value) {
const elem = await this.element(key);
await elem.sendKeys(value);
},
async containsText(str) {
return await this.driver.executeScript(`
return (document.documentElement.textContent || document.documentElement.innerText).indexOf('${str}') > -1;
`);
},
async source() {
return await this.driver.getPageSource();
},
async takeScreenshot(destPath) {
const pngData = await this.driver.takeScreenshot();
const buf = new Buffer(pngData, 'base64');
await fs.writeFile(destPath, buf);
},
async sleep(ms) {
await this.driver.sleep(ms);
}
});
}, ...extras);

View file

@ -1,84 +1,94 @@
'use strict';
const config = require('../helpers/config');
const page = require('./page');
const webBase = require('./web');
const mailBase = require('./mail');
const web = {
enterEmail(value) {
this.element('emailInput').clear();
return this.element('emailInput').sendKeys(value);
}
module.exports = (driver, 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);
return {
webSubscribe: web({
url: `/subscription/${list.cid}`,
elementToWaitFor: 'form',
elements: {
form: `form[action="/subscription/${list.cid}/subscribe"]`,
emailInput: '#main-form input[name="email"]',
submitButton: 'a[href="#submit"]'
}
}),
webConfirmSubscriptionNotice: web({
url: `/subscription/${list.cid}/confirm-subscription-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
mailConfirmSubscription: mail({
elementToWaitFor: 'confirmLink',
elements: {
confirmLink: `a[href^="${config.settings['service-url']}subscription/confirm/subscribe/"]`
}
}),
webSubscribedNotice: web({
url: `/subscription/${list.cid}/subscribed-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
mailSubscriptionConfirmed: mail({
elementToWaitFor: 'unsubscribeLink',
elements: {
unsubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}/unsubscribe/"]`,
manageLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}/manage/"]`
}
}),
/*
webUnsubscribe: web({ // FIXME
elementToWaitFor: 'submitButton',
elements: {
submitButton: 'a[href="#submit"]'
}
}),
*/
webUnsubscribedNotice: web({
url: `/subscription/${list.cid}/unsubscribed-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
mailUnsubscriptionConfirmed: mail({
elementToWaitFor: 'resubscribeLink',
elements: {
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']}"]`
}
}),
*/
};
};
const mail = {
navigate(address) {
this.driver.sleep(100);
this.driver.navigate().to(`http://localhost:${config.app.testserver.mailboxserverport}/${address}`);
return this.waitUntilVisible();
}
};
module.exports = (driver, list) => ({
webSubscribe: Object.assign(page(driver), web, {
url: `/subscription/${list.cid}`,
elementToWaitFor: 'form',
elements: {
form: `form[action="/subscription/${list.cid}/subscribe"]`,
emailInput: '#main-form input[name="email"]',
submitButton: 'a[href="#submit"]'
}
}),
webConfirmSubscriptionNotice: Object.assign(page(driver), web, {
url: `/subscription/${list.cid}/confirm-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
mailConfirmSubscription: Object.assign(page(driver), mail, {
elementToWaitFor: 'confirmLink',
elements: {
confirmLink: `a[href^="${config.settings['service-url']}subscription/subscribe/"]`
}
}),
webSubscribedNotice: Object.assign(page(driver), web, {
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: 'a[href^="https://mailtrain.org"]'
}
}),
mailSubscriptionConfirmed: Object.assign(page(driver), mail, {
elementToWaitFor: 'unsubscribeLink',
elements: {
unsubscribeLink: 'a[href*="/unsubscribe/"]',
manageLink: 'a[href*="/manage/"]'
}
}),
webUnsubscribe: Object.assign(page(driver), web, {
elementToWaitFor: 'submitButton',
elements: {
submitButton: 'a[href="#submit"]'
}
}),
webUnsubscribedNotice: Object.assign(page(driver), web, {
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: 'a[href^="https://mailtrain.org"]'
}
}),
mailUnsubscriptionConfirmed: Object.assign(page(driver), mail, {
elementToWaitFor: 'resubscribeLink',
elements: {
resubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}"]`
}
})
});

View file

@ -1,6 +1,6 @@
'use strict';
const page = require('./page');
const page = require('./web');
module.exports = driver => ({

View file

@ -0,0 +1,44 @@
'use strict';
const config = require('../helpers/config');
const By = require('selenium-webdriver').By;
const url = require('url');
const page = require('./page');
module.exports = (driver, ...extras) => page(driver, {
async navigate(path) {
await this.driver.navigate().to(config.baseUrl + (path || this.url));
await this.waitUntilVisible();
},
async ensureUrl(path) {
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}`) {
throw new Error(`Unexpected URL. Expecting ${config.baseUrl}${this.url} got ${currentUrl.protocol}//${currentUrl.host}/${currentUrl.pathname}`);
}
}
},
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)'));
return await elem.getText();
},
async clearFlash() {
await this.driver.executeScript(`
var elements = document.getElementsByClassName('alert');
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
`);
}
}, ...extras);