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,7 +1,7 @@
'use strict';
require('./helpers/exit-unless-test');
const { mocha, driver } = require('./helpers/mocha-e2e');
require('./lib/exit-unless-test');
const { mocha, driver } = require('./lib/mocha-e2e');
const path = require('path');
global.USE_SHARED_DRIVER = true;
@ -11,8 +11,7 @@ const skip = 'skip';
let tests = [
'login',
'subscription',
['subscription-uc', only]
'subscription'
];
tests = tests.map(testSpec => (testSpec.constructor === Array ? testSpec : [testSpec]));

View file

@ -1,7 +1,7 @@
'use strict';
const config = require('../helpers/config');
const driver = require('../helpers/mocha-e2e').driver;
const config = require('./config');
const driver = require('./mocha-e2e').driver;
const page = require('./page');
module.exports = (...extras) => page({

View file

@ -1,14 +1,16 @@
'use strict';
const config = require('../helpers/config');
const config = require('./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 driver = require('./mocha-e2e').driver;
const url = require('url');
const UrlPattern = require('url-pattern');
const waitTimeout = 10000;
module.exports = (...extras) => Object.assign({
elements: {},
@ -32,13 +34,36 @@ module.exports = (...extras) => Object.assign({
},
async waitUntilVisible(selector) {
const sel = selector || this.elements[this.elementToWaitFor] || 'body';
await driver.wait(until.elementLocated(By.css('body')), waitTimeout);
await driver.wait(until.elementLocated(By.css(sel)), 10000);
for (const elem of (this.elementsToWaitFor || [])) {
const sel = this.elements[elem];
if (!sel) {
throw new Error(`Element "${elem}" not found.`);
}
await driver.wait(until.elementLocated(By.css(sel)), waitTimeout);
}
for (const text of (this.textsToWaitFor || [])) {
await driver.wait(new webdriver.Condition(`for text "${text}"`, async (driver) => {
return await this.containsText(text);
}), waitTimeout);
}
if (this.url) {
await this.ensureUrl();
}
await driver.executeScript('document.mailTrainRefreshAcknowledged = true;');
},
async waitUntilVisibleAfterRefresh(selector) {
await driver.wait(new webdriver.Condition('for refresh', async (driver) => {
const val = await driver.executeScript('return document.mailTrainRefreshAcknowledged;');
return !val;
}), waitTimeout);
await this.waitUntilVisible(selector);
},
async click(key) {
@ -63,7 +88,7 @@ module.exports = (...extras) => Object.assign({
async containsText(str) {
return await driver.executeScript(`
return (document.documentElement.textContent || document.documentElement.innerText).indexOf('${str}') > -1;
return (document.documentElement.innerText || document.documentElement.textContent).indexOf('${str}') > -1;
`);
},
@ -76,12 +101,21 @@ module.exports = (...extras) => Object.assign({
await fs.writeFile(destPath, src);
},
async takeScreenshot(destPath) {
async saveScreenshot(destPath) {
const pngData = await driver.takeScreenshot();
const buf = new Buffer(pngData, 'base64');
await fs.writeFile(destPath, buf);
},
async saveSnapshot(destPathBase) {
destPathBase = destPathBase || 'last-failed-e2e-test';
const currentUrl = await driver.getCurrentUrl();
const info = `URL: ${currentUrl}`;
await fs.writeFile(destPathBase + '.info', info);
await this.saveSource(destPathBase + '.html');
await this.saveScreenshot(destPathBase + '.png');
},
async sleep(ms) {
await driver.sleep(ms);
}

View file

@ -1,10 +1,10 @@
'use strict';
const config = require('../helpers/config');
const config = require('./config');
const By = require('selenium-webdriver').By;
const url = require('url');
const UrlPattern = require('url-pattern');
const driver = require('../helpers/mocha-e2e').driver;
const driver = require('./mocha-e2e').driver;
const page = require('./page');
module.exports = (...extras) => page({
@ -14,7 +14,7 @@ module.exports = (...extras) => page({
if (typeof pathOrParams === 'string') {
path = pathOrParams;
} else {
const urlPattern = new UrlPattern(this.url);
const urlPattern = new UrlPattern(this.requestUrl || this.url);
path = urlPattern.stringify(pathOrParams)
}
@ -54,7 +54,7 @@ module.exports = (...extras) => page({
await this.waitUntilVisible('div.alert:not(.js-warning)');
},
async flash() {
async getFlash() {
const elem = await driver.findElement(By.css('div.alert:not(.js-warning)'));
return await elem.getText();
},

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,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,55 +1,68 @@
'use strict';
const config = require('../helpers/config');
const config = require('../lib/config');
const { useCase, step, driver } = require('../lib/mocha-e2e');
const expect = require('chai').expect;
const driver = require('../helpers/driver');
const home = require('../page-objects/home')(driver);
const flash = require('../page-objects/flash')(driver);
const {
login,
account
} = require('../page-objects/users')(driver);
describe('login', function() {
const page = require('../page-objects/user');
const home = require('../page-objects/home');
suite('Login use-cases', function() {
before(() => driver.manage().deleteAllCookies());
it('can access home page', async () => {
test('User can access home page', async () => {
await home.navigate();
});
it('can not access restricted content', async () => {
driver.navigate().to(config.baseUrl + '/settings');
flash.waitUntilVisible();
expect(await flash.getText()).to.contain('Need to be logged in to access restricted content');
await flash.clear();
test('Anonymous user cannot access restricted content', async () => {
await driver.navigate().to(config.baseUrl + '/settings');
await page.login.waitUntilVisible();
await page.login.waitForFlash();
expect(await page.login.getFlash()).to.contain('Need to be logged in to access restricted content');
});
it('can not login with false credentials', async () => {
login.enterUsername(config.users.admin.username);
login.enterPassword('invalid');
login.submit();
flash.waitUntilVisible();
expect(await flash.getText()).to.contain('Incorrect username or password');
await flash.clear();
useCase('Login (invalid credential)', async () => {
await step('User navigates to the login page.', async () => {
await page.login.navigate();
});
await step('User fills in the user name and incorrect password.', async () => {
await page.login.setValue('usernameInput', config.users.admin.username);
await page.login.setValue('passwordInput', 'invalid');
await page.login.submit();
});
await step('System shows a flash notice that credentials are invalid.', async () => {
await page.login.waitForFlash();
expect(await page.login.getFlash()).to.contain('Incorrect username or password');
});
});
it('can login as admin', async () => {
login.enterUsername(config.users.admin.username);
login.enterPassword(config.users.admin.password);
login.submit();
flash.waitUntilVisible();
expect(await flash.getText()).to.contain('Logged in as admin');
});
useCase('Login and logout', async () => {
await step('User navigates to the login page.', async () => {
await page.login.navigate();
});
it('can access account page as admin', async () => {
await account.navigate();
});
await step('User fills in the user name and password.', async () => {
await page.login.setValue('usernameInput', config.users.admin.username);
await page.login.setValue('passwordInput', config.users.admin.password);
await page.login.submit();
});
it('can logout', async () => {
driver.navigate().to(config.baseUrl + '/users/logout');
flash.waitUntilVisible();
expect(await flash.getText()).to.contain('logged out');
});
await step('System shows the home page and a flash notice that user has been logged in.', async () => {
await home.waitUntilVisibleAfterRefresh();
await home.waitForFlash();
expect(await home.getFlash()).to.contain('Logged in as admin');
});
after(() => driver.quit());
await step('User navigates to its account.', async () => {
await page.account.navigate();
});
await step('User logs out.', async () => {
await page.logout.navigate();
await home.waitForFlash();
expect(await home.getFlash()).to.contain('logged out');
});
});
});

View file

@ -1,150 +0,0 @@
'use strict';
const config = require('../helpers/config');
const { useCase, step, driver } = require('../helpers/mocha-e2e');
const shortid = require('shortid');
const expect = require('chai').expect;
const page = require('../page-objects/subscription')(config.lists.one);
function generateEmail() {
return 'keep.' + shortid.generate() + '@mailtrain.org';
}
async function subscribe(subscription) {
await step('User navigates to list subscription page.', async () => {
await page.webSubscribe.navigate();
});
await step('User submits a valid email and other subscription info.', async () => {
await page.webSubscribe.setValue('emailInput', subscription.email);
if (subscription.firstName) {
await page.webSubscribe.setValue('firstNameInput', subscription.firstName);
}
if (subscription.lastName) {
await page.webSubscribe.setValue('lastNameInput', subscription.lastName);
}
await page.webSubscribe.submit();
});
await step('System shows a notice that further instructions are in the email.', async () => {
await page.webConfirmSubscriptionNotice.waitUntilVisible();
});
await step('System sends an email with a link to confirm the subscription.', async () => {
await page.mailConfirmSubscription.fetchMail(subscription.email);
});
await step('User clicks confirm subscription in the email', async () => {
await page.mailConfirmSubscription.click('confirmLink');
});
await step('System shows a notice that subscription has been confirmed.', async () => {
await page.webSubscribedNotice.waitUntilVisible();
});
await step('System sends an email with subscription confirmation.', async () => {
await page.mailSubscriptionConfirmed.fetchMail(subscription.email);
subscription.unsubscribeLink = await page.mailSubscriptionConfirmed.getHref('unsubscribeLink');
subscription.manageLink = await page.mailSubscriptionConfirmed.getHref('manageLink');
const unsubscribeParams = await page.mailSubscriptionConfirmed.getLinkParams('unsubscribeLink');
const manageParams = await page.mailSubscriptionConfirmed.getLinkParams('manageLink');
console.log(unsubscribeParams);
console.log(manageParams);
expect(unsubscribeParams.ucid).to.equal(manageParams.ucid);
subscription.ucid = unsubscribeParams.ucid;
});
return subscription;
}
suite('Subscription use-cases', function() {
before(() => driver.manage().deleteAllCookies());
useCase('Subscription to a public list (main scenario)', async () => {
await subscribe({
email: generateEmail()
});
});
useCase('Subscription to a public list (invalid email)', async () => {
await step('User navigates to list subscribe page', async () => {
await page.webSubscribe.navigate();
});
await step('User submits an invalid email.', async () => {
await page.webSubscribe.setValue('emailInput', 'foo@bar.nope');
await page.webSubscribe.submit();
});
await step('System shows a flash notice that email is invalid.', async () => {
await page.webSubscribe.waitForFlash();
expect(await page.webSubscribe.getFlash()).to.contain('Invalid email address');
});
});
useCase('Unsubscription from list #1 (one-step, no form).', async () => {
const subscription = await subscribe({
email: generateEmail()
});
await step('User clicks the unsubscribe button.', async () => {
await page.mailSubscriptionConfirmed.click('unsubscribeLink');
});
await step('System show a notice that confirms unsubscription.', async () => {
await page.webUnsubscribedNotice.waitUntilVisible();
});
await step('System sends an email that confirms unsubscription.', async () => {
await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email);
});
});
useCase.only('Change email in list #1 (one-step, no form)', async () => {
const subscription = await subscribe({
email: generateEmail(),
firstName: 'John',
lastName: 'Doe'
});
await step('User clicks the manage subscription button.', async () => {
await page.mailSubscriptionConfirmed.click('manageLink');
});
await step('Systems shows a form to change subscription details. The form contains data entered during subscription.', async () => {
await page.webManage.waitUntilVisible();
expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email);
expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName);
expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName);
});
await step('User enters another name and submits the form.', async () => {
subscription.firstName = 'Adam';
subscription.lastName = 'B';
await page.webManage.setValue('firstNameInput', subscription.firstName);
await page.webManage.setValue('lastNameInput', subscription.lastName);
await page.webManage.submit();
});
await step('Systems shows a notice that profile has been updated.', async () => {
await page.webUpdatedNotice.waitUntilVisible();
});
await step('User navigates to manage subscription again.', async () => {
await page.webManage.navigate(subscription.manageLink);
// await page.webManage.navigate({ ucid: subscription.ucid });
});
await step('Systems shows a form with the changes made previously.', async () => {
expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email);
expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName);
expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName);
});
});
});

View file

@ -1,101 +1,239 @@
'use strict';
const config = require('../helpers/config');
const config = require('../lib/config');
const { useCase, step, driver } = require('../lib/mocha-e2e');
const shortid = require('shortid');
const expect = require('chai').expect;
const driver = require('../helpers/driver');
const page = require('../page-objects/web')(driver);
const flash = require('../page-objects/flash')(driver);
const page = require('../page-objects/subscription')(config.lists.one);
const {
webSubscribe,
webConfirmSubscriptionNotice,
mailConfirmSubscription,
webSubscribedNotice,
mailSubscriptionConfirmed,
webUnsubscribe,
webUnsubscribedNotice,
mailUnsubscriptionConfirmed
} = require('../page-objects/subscription')(driver, config.lists.one);
function generateEmail() {
return 'keep.' + shortid.generate() + '@mailtrain.org';
}
const testuser = {
email: 'keep.' + shortid.generate() + '@mailtrain.org'
};
async function subscribe(subscription) {
await step('User navigates to list subscription page.', async () => {
await page.webSubscribe.navigate();
});
// console.log(testuser.email);
await step('User submits a valid email and other subscription info.', async () => {
await page.webSubscribe.setValue('emailInput', subscription.email);
describe('subscribe (list one)', function() {
this.timeout(10000);
if (subscription.firstName) {
await page.webSubscribe.setValue('firstNameInput', subscription.firstName);
}
if (subscription.lastName) {
await page.webSubscribe.setValue('lastNameInput', subscription.lastName);
}
await page.webSubscribe.submit();
});
await step('System shows a notice that further instructions are in the email.', async () => {
await page.webConfirmSubscriptionNotice.waitUntilVisibleAfterRefresh();
});
await step('System sends an email with a link to confirm the subscription.', async () => {
await page.mailConfirmSubscription.fetchMail(subscription.email);
});
await step('User clicks confirm subscription in the email', async () => {
await page.mailConfirmSubscription.click('confirmLink');
});
await step('System shows a notice that subscription has been confirmed.', async () => {
await page.webSubscribedNotice.waitUntilVisibleAfterRefresh();
});
await step('System sends an email with subscription confirmation.', async () => {
await page.mailSubscriptionConfirmed.fetchMail(subscription.email);
subscription.unsubscribeLink = await page.mailSubscriptionConfirmed.getHref('unsubscribeLink');
subscription.manageLink = await page.mailSubscriptionConfirmed.getHref('manageLink');
const unsubscribeParams = await page.mailSubscriptionConfirmed.getLinkParams('unsubscribeLink');
const manageParams = await page.mailSubscriptionConfirmed.getLinkParams('manageLink');
expect(unsubscribeParams.ucid).to.equal(manageParams.ucid);
subscription.ucid = unsubscribeParams.ucid;
});
return subscription;
}
suite('Subscription use-cases', function() {
before(() => driver.manage().deleteAllCookies());
it('visits web-subscribe', async () => {
await webSubscribe.navigate();
useCase('Subscription to a public list (main scenario)', async () => {
await subscribe({
email: generateEmail()
});
});
it('submits invalid email (error)', async () => {
webSubscribe.enterEmail('foo@bar.nope');
webSubscribe.submit();
flash.waitUntilVisible();
expect(await flash.getText()).to.contain('Invalid email address');
useCase('Subscription to a public list (invalid email)', async () => {
await step('User navigates to list subscribe page', async () => {
await page.webSubscribe.navigate();
});
await step('User submits an invalid email.', async () => {
await page.webSubscribe.setValue('emailInput', 'foo@bar.nope');
await page.webSubscribe.submit();
});
await step('System shows a flash notice that email is invalid.', async () => {
await page.webSubscribe.waitForFlash();
expect(await page.webSubscribe.getFlash()).to.contain('Invalid email address');
});
});
it('submits valid email', async () => {
webSubscribe.enterEmail(testuser.email);
await webSubscribe.submit();
useCase('Subscription to a public list (email already registered)', async () => {
const subscription = await subscribe({
email: generateEmail()
});
await step('User navigates to list subscribe page', async () => {
await page.webSubscribe.navigate();
});
await step('User submits the email which has been already registered.', async () => {
await page.webSubscribe.setValue('emailInput', subscription.email);
await page.webSubscribe.submit();
});
await step('System shows a notice that further instructions are in the email.', async () => {
await page.webConfirmSubscriptionNotice.waitUntilVisibleAfterRefresh();
});
await step('System sends an email informing that the address has been already registered.', async () => {
await page.mailAlreadySubscribed.fetchMail(subscription.email);
});
});
it('sees web-confirm-subscription-notice', async () => {
webConfirmSubscriptionNotice.waitUntilVisible();
expect(await page.containsText('Almost Finished')).to.be.true;
useCase('Subscription to a non-public list');
useCase('Change profile info', async () => {
const subscription = await subscribe({
email: generateEmail(),
firstName: 'John',
lastName: 'Doe'
});
await step('User clicks the manage subscription button.', async () => {
await page.mailSubscriptionConfirmed.click('manageLink');
});
await step('Systems shows a form to change subscription details. The form contains data entered during subscription.', async () => {
await page.webManage.waitUntilVisibleAfterRefresh();
expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email);
expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName);
expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName);
});
await step('User enters another name and submits the form.', async () => {
subscription.firstName = 'Adam';
subscription.lastName = 'B';
await page.webManage.setValue('firstNameInput', subscription.firstName);
await page.webManage.setValue('lastNameInput', subscription.lastName);
await page.webManage.submit();
});
await step('Systems shows a notice that profile has been updated.', async () => {
await page.webUpdatedNotice.waitUntilVisibleAfterRefresh();
});
await step('User navigates to manage subscription again.', async () => {
// await page.webManage.navigate(subscription.manageLink);
await page.webManage.navigate({ ucid: subscription.ucid });
});
await step('Systems shows a form with the changes made previously.', async () => {
expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email);
expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName);
expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName);
});
});
it('receives mail-confirm-subscription', async () => {
mailConfirmSubscription.navigate(testuser.email);
expect(await page.containsText('Please Confirm Subscription')).to.be.true;
useCase('Change email', async () => {
const subscription = await subscribe({
email: generateEmail(),
firstName: 'John',
lastName: 'Doe'
});
await step('User clicks the manage subscription button.', async () => {
await page.mailSubscriptionConfirmed.click('manageLink');
});
await step('Systems shows a form to change subscription details. The form contains data entered during subscription.', async () => {
await page.webManage.waitUntilVisibleAfterRefresh();
expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email);
expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName);
expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName);
});
await step('User clicks the change address button.', async () => {
await page.webManage.click('manageAddressLink');
});
await step('Systems shows a form to change email.', async () => {
await page.webManageAddress.waitUntilVisibleAfterRefresh();
});
await step('User fills in a new email address and submits the form.', async () => {
subscription.email = generateEmail();
await page.webManageAddress.setValue('emailNewInput', subscription.email);
await page.webManageAddress.submit();
});
await step('System goes back to the profile form and shows a flash notice that further instructions are in the email.', async () => {
await page.webManage.waitUntilVisibleAfterRefresh();
await page.webManage.waitForFlash();
expect(await page.webManage.getFlash()).to.contain('An email with further instructions has been sent to the provided address');
});
await step('System sends an email with a link to confirm the address change.', async () => {
await page.mailConfirmAddressChange.fetchMail(subscription.email);
});
await step('User clicks confirm subscription in the email', async () => {
await page.mailConfirmAddressChange.click('confirmLink');
});
await step('System shows the profile form with a flash notice that address has been changed.', async () => {
await page.webManage.waitUntilVisibleAfterRefresh();
await page.webManage.waitForFlash();
expect(await page.webManage.getFlash()).to.contain('Email address changed');
expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email);
});
await step('System sends an email with subscription confirmation.', async () => {
await page.mailSubscriptionConfirmed.fetchMail(subscription.email);
});
});
it('clicks confirm subscription', async () => {
await mailConfirmSubscription.click('confirmLink');
useCase('Unsubscription from list #1 (one-step, no form).', async () => {
const subscription = await subscribe({
email: generateEmail()
});
await step('User clicks the unsubscribe button.', async () => {
await page.mailSubscriptionConfirmed.click('unsubscribeLink');
});
await step('System shows a notice that confirms unsubscription.', async () => {
await page.webUnsubscribedNotice.waitUntilVisibleAfterRefresh();
});
await step('System sends an email that confirms unsubscription.', async () => {
await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email);
});
});
it('sees web-subscribed-notice', async () => {
webSubscribedNotice.waitUntilVisible();
expect(await page.containsText('Subscription Confirmed')).to.be.true;
});
useCase('Unsubscription from list #2 (one-step, with form).');
it('receives mail-subscription-confirmed', async () => {
mailSubscriptionConfirmed.navigate(testuser.email);
expect(await page.containsText('Subscription Confirmed')).to.be.true;
});
});
describe('unsubscribe (list one)', function() {
this.timeout(10000);
it('clicks unsubscribe', async () => {
await mailSubscriptionConfirmed.click('unsubscribeLink');
});
it('sees web-unsubscribe', async () => {
webUnsubscribe.waitUntilVisible();
expect(await page.containsText('Unsubscribe')).to.be.true;
});
it('clicks confirm unsubscription', async () => {
await webUnsubscribe.submit();
});
it('sees web-unsubscribed-notice', async () => {
webUnsubscribedNotice.waitUntilVisible();
expect(await page.containsText('Unsubscribe Successful')).to.be.true;
});
it('receives mail-unsubscription-confirmed', async () => {
mailUnsubscriptionConfirmed.navigate(testuser.email);
expect(await page.containsText('You Are Now Unsubscribed')).to.be.true;
});
after(() => driver.quit());
useCase('Unsubscription from list #3 (two-step, no form).');
useCase('Unsubscription from list #4 (two-step, with form).');
useCase('Unsubscription from list #5 (manual unsubscribe).');
});