Using object composition instead of class inheritance for page objects
This commit is contained in:
parent
f106cd2850
commit
c3e9781dc4
6 changed files with 60 additions and 80 deletions
|
@ -1,11 +1,15 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Page = require('./page');
|
const page = require('./page');
|
||||||
|
|
||||||
class Flash extends Page {
|
module.exports = driver => Object.assign(page(driver), {
|
||||||
|
elementToWaitFor: 'alert',
|
||||||
|
elements: {
|
||||||
|
alert: 'div.alert:not(.js-warning)'
|
||||||
|
},
|
||||||
getText() {
|
getText() {
|
||||||
return this.element('alert').getText();
|
return this.element('alert').getText();
|
||||||
}
|
},
|
||||||
clear() {
|
clear() {
|
||||||
return this.driver.executeScript(`
|
return this.driver.executeScript(`
|
||||||
var elements = document.getElementsByClassName('alert');
|
var elements = document.getElementsByClassName('alert');
|
||||||
|
@ -14,11 +18,4 @@ class Flash extends Page {
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = driver => new Flash(driver, {
|
|
||||||
elementToWaitFor: 'alert',
|
|
||||||
elements: {
|
|
||||||
alert: 'div.alert:not(.js-warning)'
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Page = require('./page');
|
const page = require('./page');
|
||||||
|
|
||||||
module.exports = driver => new Page(driver, {
|
module.exports = driver => Object.assign(page(driver), {
|
||||||
url: '/',
|
url: '/',
|
||||||
elementToWaitFor: 'body',
|
elementToWaitFor: 'body',
|
||||||
elements: {
|
elements: {
|
||||||
|
|
|
@ -5,50 +5,47 @@ const webdriver = require('selenium-webdriver');
|
||||||
const By = webdriver.By;
|
const By = webdriver.By;
|
||||||
const until = webdriver.until;
|
const until = webdriver.until;
|
||||||
|
|
||||||
class Page {
|
module.exports = driver => ({
|
||||||
constructor(driver, props) {
|
driver,
|
||||||
this.driver = driver;
|
url: '/',
|
||||||
this.props = props || {
|
elements: {},
|
||||||
elements: {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
element(key) {
|
element(key) {
|
||||||
return this.driver.findElement(By.css(this.props.elements[key] || key));
|
return this.driver.findElement(By.css(this.elements[key] || key));
|
||||||
}
|
},
|
||||||
|
|
||||||
navigate() {
|
navigate() {
|
||||||
this.driver.navigate().to(config.baseUrl + this.props.url);
|
this.driver.navigate().to(config.baseUrl + this.url);
|
||||||
return this.waitUntilVisible();
|
return this.waitUntilVisible();
|
||||||
}
|
},
|
||||||
|
|
||||||
waitUntilVisible() {
|
waitUntilVisible() {
|
||||||
let selector = this.props.elements[this.props.elementToWaitFor];
|
let selector = this.elements[this.elementToWaitFor];
|
||||||
if (!selector && this.props.url) {
|
if (!selector && this.url) {
|
||||||
selector = 'body.page--' + (this.props.url.substring(1).replace(/\//g, '--') || 'home');
|
selector = 'body.page--' + (this.url.substring(1).replace(/\//g, '--') || 'home');
|
||||||
}
|
}
|
||||||
return selector ? this.driver.wait(until.elementLocated(By.css(selector))) : this.driver.sleep(1000);
|
return selector ? this.driver.wait(until.elementLocated(By.css(selector))) : this.driver.sleep(1000);
|
||||||
}
|
},
|
||||||
|
|
||||||
submit() {
|
submit() {
|
||||||
return this.element('submitButton').click();
|
return this.element('submitButton').click();
|
||||||
}
|
},
|
||||||
|
|
||||||
click(key) {
|
click(key) {
|
||||||
return this.element(key).click();
|
return this.element(key).click();
|
||||||
}
|
},
|
||||||
|
|
||||||
getText(key) {
|
getText(key) {
|
||||||
return this.element(key).getText();
|
return this.element(key).getText();
|
||||||
}
|
},
|
||||||
|
|
||||||
getValue(key) {
|
getValue(key) {
|
||||||
return this.element(key).getAttribute('value');
|
return this.element(key).getAttribute('value');
|
||||||
}
|
},
|
||||||
|
|
||||||
setValue(key, value) {
|
setValue(key, value) {
|
||||||
return this.element(key).sendKeys(value);
|
return this.element(key).sendKeys(value);
|
||||||
}
|
},
|
||||||
|
|
||||||
containsText(str) {
|
containsText(str) {
|
||||||
// let text = await driver.findElement({ css: 'body' }).getText();
|
// let text = await driver.findElement({ css: 'body' }).getText();
|
||||||
|
@ -56,6 +53,4 @@ class Page {
|
||||||
return (document.documentElement.textContent || document.documentElement.innerText).indexOf('${str}') > -1;
|
return (document.documentElement.textContent || document.documentElement.innerText).indexOf('${str}') > -1;
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
module.exports = Page;
|
|
||||||
|
|
|
@ -1,45 +1,36 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const config = require('../helpers/config');
|
const config = require('../helpers/config');
|
||||||
const Page = require('./page');
|
const page = require('./page');
|
||||||
|
|
||||||
class Web extends Page {
|
const web = {
|
||||||
enterEmail(value) {
|
enterEmail(value) {
|
||||||
this.element('emailInput').clear();
|
this.element('emailInput').clear();
|
||||||
return this.element('emailInput').sendKeys(value);
|
return this.element('emailInput').sendKeys(value);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
class Mail extends Page {
|
const mail = {
|
||||||
navigate(address) {
|
navigate(address) {
|
||||||
this.driver.sleep(100);
|
this.driver.sleep(100);
|
||||||
this.driver.navigate().to(`http://localhost:${config.app.testserver.mailboxserverport}/${address}`);
|
this.driver.navigate().to(`http://localhost:${config.app.testserver.mailboxserverport}/${address}`);
|
||||||
return this.waitUntilVisible();
|
return this.waitUntilVisible();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
class WebSubscribe extends Web {
|
|
||||||
constructor(driver, list) {
|
|
||||||
super(driver, {
|
|
||||||
url: `/subscription/${list.cid}`,
|
|
||||||
elementToWaitFor: 'form',
|
|
||||||
elements: {
|
|
||||||
form: `form[action="/subscription/${list.cid}/subscribe"]`,
|
|
||||||
emailInput: '#main-form input[name="email"]',
|
|
||||||
submitButton: 'a[href="#submit"]'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
foo() {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = (driver, list) => ({
|
module.exports = (driver, list) => ({
|
||||||
|
|
||||||
webSubscribe: new WebSubscribe(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: new Web(driver, {
|
webConfirmSubscriptionNotice: Object.assign(page(driver), web, {
|
||||||
url: `/subscription/${list.cid}/confirm-notice`,
|
url: `/subscription/${list.cid}/confirm-notice`,
|
||||||
elementToWaitFor: 'homepageButton',
|
elementToWaitFor: 'homepageButton',
|
||||||
elements: {
|
elements: {
|
||||||
|
@ -47,21 +38,21 @@ module.exports = (driver, list) => ({
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mailConfirmSubscription: new Mail(driver, {
|
mailConfirmSubscription: Object.assign(page(driver), mail, {
|
||||||
elementToWaitFor: 'confirmLink',
|
elementToWaitFor: 'confirmLink',
|
||||||
elements: {
|
elements: {
|
||||||
confirmLink: `a[href^="${config.settings['service-url']}subscription/subscribe/"]`
|
confirmLink: `a[href^="${config.settings['service-url']}subscription/subscribe/"]`
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
webSubscribedNotice: new Web(driver, {
|
webSubscribedNotice: Object.assign(page(driver), web, {
|
||||||
elementToWaitFor: 'homepageButton',
|
elementToWaitFor: 'homepageButton',
|
||||||
elements: {
|
elements: {
|
||||||
homepageButton: 'a[href^="https://mailtrain.org"]'
|
homepageButton: 'a[href^="https://mailtrain.org"]'
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mailSubscriptionConfirmed: new Mail(driver, {
|
mailSubscriptionConfirmed: Object.assign(page(driver), mail, {
|
||||||
elementToWaitFor: 'unsubscribeLink',
|
elementToWaitFor: 'unsubscribeLink',
|
||||||
elements: {
|
elements: {
|
||||||
unsubscribeLink: 'a[href*="/unsubscribe/"]',
|
unsubscribeLink: 'a[href*="/unsubscribe/"]',
|
||||||
|
@ -69,21 +60,21 @@ module.exports = (driver, list) => ({
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
webUnsubscribe: new Web(driver, {
|
webUnsubscribe: Object.assign(page(driver), web, {
|
||||||
elementToWaitFor: 'submitButton',
|
elementToWaitFor: 'submitButton',
|
||||||
elements: {
|
elements: {
|
||||||
submitButton: 'a[href="#submit"]'
|
submitButton: 'a[href="#submit"]'
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
webUnsubscribedNotice: new Web(driver, {
|
webUnsubscribedNotice: Object.assign(page(driver), web, {
|
||||||
elementToWaitFor: 'homepageButton',
|
elementToWaitFor: 'homepageButton',
|
||||||
elements: {
|
elements: {
|
||||||
homepageButton: 'a[href^="https://mailtrain.org"]'
|
homepageButton: 'a[href^="https://mailtrain.org"]'
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mailUnsubscriptionConfirmed: new Mail(driver, {
|
mailUnsubscriptionConfirmed: Object.assign(page(driver), mail, {
|
||||||
elementToWaitFor: 'resubscribeLink',
|
elementToWaitFor: 'resubscribeLink',
|
||||||
elements: {
|
elements: {
|
||||||
resubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}"]`
|
resubscribeLink: `a[href^="${config.settings['service-url']}subscription/${list.cid}"]`
|
||||||
|
|
|
@ -1,30 +1,27 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Page = require('./page');
|
const page = require('./page');
|
||||||
|
|
||||||
class Login extends Page {
|
|
||||||
enterUsername(value) {
|
|
||||||
// this.element('usernameInput').clear();
|
|
||||||
return this.element('usernameInput').sendKeys(value);
|
|
||||||
}
|
|
||||||
enterPassword(value) {
|
|
||||||
return this.element('passwordInput').sendKeys(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = driver => ({
|
module.exports = driver => ({
|
||||||
|
|
||||||
login: new Login(driver, {
|
login: Object.assign(page(driver), {
|
||||||
url: '/users/login',
|
url: '/users/login',
|
||||||
elementToWaitFor: 'submitButton',
|
elementToWaitFor: 'submitButton',
|
||||||
elements: {
|
elements: {
|
||||||
usernameInput: 'form[action="/users/login"] input[name="username"]',
|
usernameInput: 'form[action="/users/login"] input[name="username"]',
|
||||||
passwordInput: 'form[action="/users/login"] input[name="password"]',
|
passwordInput: 'form[action="/users/login"] input[name="password"]',
|
||||||
submitButton: 'form[action="/users/login"] [type=submit]'
|
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: new Page(driver, {
|
account: Object.assign(page(driver), {
|
||||||
url: '/users/account',
|
url: '/users/account',
|
||||||
elementToWaitFor: 'emailInput',
|
elementToWaitFor: 'emailInput',
|
||||||
elements: {
|
elements: {
|
||||||
|
|
|
@ -4,10 +4,10 @@ const config = require('../helpers/config');
|
||||||
const shortid = require('shortid');
|
const shortid = require('shortid');
|
||||||
const expect = require('chai').expect;
|
const expect = require('chai').expect;
|
||||||
const driver = require('../helpers/driver');
|
const driver = require('../helpers/driver');
|
||||||
const Page = require('../page-objects/page');
|
|
||||||
|
|
||||||
const page = new Page(driver);
|
const page = require('../page-objects/page')(driver);
|
||||||
const flash = require('../page-objects/flash')(driver);
|
const flash = require('../page-objects/flash')(driver);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
webSubscribe,
|
webSubscribe,
|
||||||
webConfirmSubscriptionNotice,
|
webConfirmSubscriptionNotice,
|
||||||
|
|
Loading…
Reference in a new issue