Added waitUntilVisibleAfterRefresh and textsToWaitFor - both discussed with @witzig.

Page objects refactored to exploit textsToWaitFor if relevant.

Login tests refactored for the newer API.

Some additional tests in subscription. The rest at least included as "pending".
This commit is contained in:
Tomas Bures 2017-05-26 00:13:40 +02:00
parent ccd37ac792
commit bb2b3da9dd
14 changed files with 446 additions and 393 deletions

View file

@ -1,11 +1,7 @@
'use strict';
const page = require('./web');
const web = require('../lib/web');
module.exports = driver => Object.assign(page(driver), {
url: '/',
elementToWaitFor: 'body',
elements: {
body: 'body.page--home'
}
module.exports = web({
url: '/'
});

View file

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

View file

@ -1,88 +0,0 @@
'use strict';
const config = require('../helpers/config');
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 = (...extras) => Object.assign({
elements: {},
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) {
const sel = selector || this.elements[this.elementToWaitFor] || 'body';
await driver.wait(until.elementLocated(By.css(sel)), 10000);
if (this.url) {
await this.ensureUrl();
}
},
async click(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.getElement(key);
return await elem.getText();
},
async getValue(key) {
const elem = await this.getElement(key);
return await elem.getAttribute('value');
},
async containsText(str) {
return await driver.executeScript(`
return (document.documentElement.textContent || document.documentElement.innerText).indexOf('${str}') > -1;
`);
},
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 driver.takeScreenshot();
const buf = new Buffer(pngData, 'base64');
await fs.writeFile(destPath, buf);
},
async sleep(ms) {
await driver.sleep(ms);
}
}, ...extras);

View file

@ -1,106 +1,132 @@
'use strict';
const config = require('../helpers/config');
const webBase = require('./web');
const mailBase = require('./mail');
const config = require('../lib/config');
const web = require('../lib/web');
const mail = require('../lib/mail');
module.exports = list => {
module.exports = list => ({
const web = params => webBase(params);
const mail = params => mailBase(params);
webSubscribe: web({
url: `/subscription/${list.cid}`,
elementsToWaitFor: ['form'],
textsToWaitFor: ['Subscribe to 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"]'
}
}),
return {
webSubscribe: web({
url: `/subscription/${list.cid}`,
elementToWaitFor: 'form',
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"]'
}
}),
webConfirmSubscriptionNotice: web({
url: `/subscription/${list.cid}/confirm-subscription-notice`,
textsToWaitFor: ['We need to confirm your email address']
}),
webConfirmSubscriptionNotice: web({
url: `/subscription/${list.cid}/confirm-subscription-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
mailConfirmSubscription: mail({
elementsToWaitFor: ['confirmLink'],
textsToWaitFor: ['Please Confirm Subscription'],
elements: {
confirmLink: `a[href^="${config.settings['service-url']}subscription/confirm/subscribe/"]`
}
}),
mailConfirmSubscription: mail({
elementToWaitFor: 'confirmLink',
elements: {
confirmLink: `a[href^="${config.settings['service-url']}subscription/confirm/subscribe/"]`
}
}),
mailAlreadySubscribed: mail({
elementsToWaitFor: ['unsubscribeLink'],
textsToWaitFor: ['Email address already registered'],
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`
}
}),
webSubscribedNotice: web({
url: `/subscription/${list.cid}/subscribed-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
webSubscribedNotice: web({
url: `/subscription/${list.cid}/subscribed-notice`,
textsToWaitFor: ['Subscription Confirmed']
}),
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/"]`
},
links: {
unsubscribeLink: `/subscription/${list.cid}/unsubscribe/:ucid`,
manageLink: `/subscription/${list.cid}/manage/:ucid`
}
}),
mailSubscriptionConfirmed: mail({
elementsToWaitFor: ['unsubscribeLink'],
textsToWaitFor: ['Subscription Confirmed'],
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"]'
}
}),
webManage: web({
url: `/subscription/${list.cid}/manage/:ucid`,
elementsToWaitFor: ['form'],
textsToWaitFor: ['Update Your Preferences'],
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"]',
manageAddressLink: `a[href^="/subscription/${list.cid}/manage-address/"]`
},
links: {
manageAddressLink: `/subscription/${list.cid}/manage-address/:ucid`
}
}),
webUpdatedNotice: web({
url: `/subscription/${list.cid}/updated-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
webManageAddress: web({
url: `/subscription/${list.cid}/manage-address/:ucid`,
elementsToWaitFor: ['form'],
textsToWaitFor: ['Update Your Email Address'],
elements: {
form: `form[action="/subscription/${list.cid}/manage-address"]`,
emailInput: '#main-form input[name="email"]',
emailNewInput: '#main-form input[name="email-new"]',
submitButton: 'a[href="#submit"]',
}
}),
/*
webUnsubscribe: web({ // FIXME
elementToWaitFor: 'submitButton',
elements: {
submitButton: 'a[href="#submit"]'
}
}),
mailConfirmAddressChange: mail({
elementsToWaitFor: ['confirmLink'],
textsToWaitFor: ['Please Confirm Subscription Address Change'],
elements: {
confirmLink: `a[href^="${config.settings['service-url']}subscription/confirm/change-address/"]`
}
}),
webUnsubscribedNotice: web({
url: `/subscription/${list.cid}/unsubscribed-notice`,
elementToWaitFor: 'homepageButton',
elements: {
homepageButton: `a[href="${config.settings['default-homepage']}"]`
}
}),
webUpdatedNotice: web({
url: `/subscription/${list.cid}/updated-notice`,
textsToWaitFor: ['Profile Updated'],
}),
mailUnsubscriptionConfirmed: mail({
elementToWaitFor: 'resubscribeLink',
elements: {
resubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}"]`
}
}),
*/
webUnsubscribedNotice: web({
url: `/subscription/${list.cid}/unsubscribed-notice`,
textsToWaitFor: ['Unsubscribe Successful'],
}),
mailUnsubscriptionConfirmed: mail({
elementsToWaitFor: ['resubscribeLink'],
textsToWaitFor: ['You Are Now Unsubscribed'],
elements: {
resubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}"]`
}
}),
/*
webUnsubscribe: web({ // FIXME
elementsToWaitFor: ['submitButton'],
elements: {
submitButton: 'a[href="#submit"]'
}
}),
*/
});
};
};

View file

@ -1,32 +1,29 @@
'use strict';
const page = require('./web');
const web = require('../lib/web');
module.exports = driver => ({
login: Object.assign(page(driver), {
module.exports = {
login: web({
url: '/users/login',
elementToWaitFor: 'submitButton',
elementsToWaitFor: ['submitButton'],
elements: {
usernameInput: 'form[action="/users/login"] input[name="username"]',
passwordInput: 'form[action="/users/login"] input[name="password"]',
submitButton: 'form[action="/users/login"] [type=submit]'
},
enterUsername(value) {
// this.element('usernameInput').clear();
return this.element('usernameInput').sendKeys(value);
},
enterPassword(value) {
return this.element('passwordInput').sendKeys(value);
}
}),
account: Object.assign(page(driver), {
logout: web({
requestUrl: '/users/logout',
url: '/'
}),
account: web({
url: '/users/account',
elementToWaitFor: 'emailInput',
elementsToWaitFor: ['form'],
elements: {
form: `form[action="/users/account"]`,
emailInput: 'form[action="/users/account"] input[name="email"]'
}
})
});
}),
};

View file

@ -1,77 +0,0 @@
'use strict';
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 = (...extras) => page({
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();
},
async ensureUrl(path) {
const desiredUrl = path || this.url;
if (desiredUrl) {
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 flash() {
const elem = await driver.findElement(By.css('div.alert:not(.js-warning)'));
return await elem.getText();
},
async clearFlash() {
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);