Skip to content

Commit

Permalink
Merge pull request #47 from Financial-Times/screenshot
Browse files Browse the repository at this point in the history
Refactor url setup into it's own file
  • Loading branch information
adgad authored Apr 3, 2018
2 parents 6e590d9 + fc4654b commit 438866f
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 101 deletions.
1 change: 1 addition & 0 deletions bin/n-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ program.version(require('../package.json').version);

require('../tasks/smoke')(program);
require('../tasks/open')(program);
//require('../tasks/screenshot')(program);


// Handle unknown commands
Expand Down
24 changes: 13 additions & 11 deletions lib/smoke/get-selenium-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ const browserMap = {

module.exports = (browserName) => {

const config = {};

if (process.env.BROWSERSTACK_USER && process.env.BROWSERSTACK_KEY) {
config.desiredCapabilities = browserMap[browserName] || { browserName };
config.user = process.env.BROWSERSTACK_USER;
config.key = process.env.BROWSERSTACK_KEY;
return {
desiredCapabilities: browserMap[browserName] || { browserName },
user: process.env.BROWSERSTACK_USER,
key: process.env.BROWSERSTACK_KEY
};
} else if(process.env.SAUCE_USER && process.env.SAUCE_KEY) {
config.desiredCapabilities = { browserName };
config.user = process.env.SAUCE_USER;
config.key =process.env.SAUCE_KEY;
config.host = 'ondemand.saucelabs.com';
config.services = ['sauce'];
return {
desiredCapabilities: { browserName },
user: process.env.SAUCE_USER,
key: process.env.SAUCE_KEY,
host: 'ondemand.saucelabs.com',
services: ['sauce']
};
}
return config;

};
35 changes: 7 additions & 28 deletions lib/smoke/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,22 @@ const fs = require('fs');
const puppeteer = require('puppeteer');
const PuppeteerPage = require('./puppeteer-page');
const filterConfigs = require('./filter-configs');
const setupPage = require('./setup-page');

module.exports = async (opts, sets) => {
const configFile = path.join(process.cwd(), opts.config || 'test/smoke.js');
module.exports = async (globalOpts, sets) => {
const configFile = path.join(process.cwd(), globalOpts.config || 'test/smoke.js');
if (!fs.existsSync(configFile)) {
throw new Error(`Config file for smoke test does not exist at ${configFile}. Either create a config file at ./test/smoke.js, or pass in a path using --config.`);
} else {

let host = opts.host || 'http://localhost:3002';
const browser = await puppeteer.launch({ headless: false, devtools: true });
const configsToOpen = await filterConfigs(configFile, sets, true);

configsToOpen.forEach((suiteOpts) => {
Object.keys(suiteOpts.urls).forEach(async (url) => {
let urlOpts = suiteOpts.urls[url];
if (typeof urlOpts !== 'object') {
urlOpts = { status: urlOpts };
}

if (!/https?\:\/\//.test(host)) {
host = 'http://' + host;
}

urlOpts.requestHeaders = Object.assign(urlOpts.headers || {}, suiteOpts.headers || {}, {});
urlOpts.requestHeaderPaths = urlOpts.requestHeaderPaths || suiteOpts.requestHeaderPaths || [];
urlOpts.method = urlOpts.method || suiteOpts.method;
urlOpts.body = urlOpts.body || suiteOpts.body;
urlOpts.user = suiteOpts.user;
urlOpts.https = urlOpts.https || suiteOpts.https;
urlOpts.breakpoint = urlOpts.breakpoint || suiteOpts.breakpoint || opts.breakpoint;

if(urlOpts.user && !host.includes('local')) {
urlOpts.requestHeaders['FT-Test-Host'] = host.replace('https://', '').replace('http://', '');
host = 'https://www.ft.com';
}

const fullUrl = `${host}${url}`;
const puppeteerPage = new PuppeteerPage(fullUrl, urlOpts);
Object.keys(suiteOpts.urls).forEach(async (path) => {
let urlOpts = suiteOpts.urls[path];
const pageOpts = setupPage(path, urlOpts, suiteOpts, globalOpts);
const puppeteerPage = new PuppeteerPage(pageOpts);
await puppeteerPage.init(browser);
});
});
Expand Down
20 changes: 8 additions & 12 deletions lib/smoke/puppeteer-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,18 @@ const DIMENSIONS = {

class PuppeteerPage {

constructor (url, options) {
constructor (options) {
this.browser = null;
this.type = 'Chrome';
this.url = url;
this.host = options.host;

if(options.https) {
this.url = this.url.replace('http:', 'https:');
}
this.url = options.url;
this.host = options.url.host;

this.requestHeaders = Object.assign({}, options.requestHeaders || {});
this.method = options.method || 'GET';
this.postData = options.body || null;
this.dimensions = DIMENSIONS[options.breakpoint] || DIMENSIONS['XL'];
this.user = options.user || null;
this.requestHeaderPaths = [this.url].concat(options.requestHeaderPaths || []);
this.requestHeaderPaths = [this.url.toString()].concat(options.requestHeaderPaths || []);


this.pageErrors = [];
Expand Down Expand Up @@ -64,7 +60,7 @@ class PuppeteerPage {

if (this.user) {
const tokens = await getUserTokens(this.user);
await setSessionCookies(this.page, this.url, tokens);
await setSessionCookies(this.page, this.url.toString(), tokens);
}

this.page.setViewport(this.dimensions);
Expand Down Expand Up @@ -114,7 +110,7 @@ class PuppeteerPage {
}
} else {
//Otherwise apply headers for any URls with the same host
if(new URL(url).host === new URL(this.url).host) {
if(new URL(url).host === this.url.host) {
overrides.headers = Object.assign({}, this.requestHeaders);
}
}
Expand Down Expand Up @@ -144,14 +140,14 @@ class PuppeteerPage {
const request = response.request();
const status = response.status();
const url = request.url();
if(url !== this.url.split('#')[0]) {
if(url !== `${this.url.host}${this.url.path}`) {
this.requests.push({ url, status });
} else if (!this.response) {
this.response = response;
}
});

const gotoResponse = await this.page.goto(this.url, { waitUntil: this.waitUntil });
const gotoResponse = await this.page.goto(this.url.toString(), { waitUntil: this.waitUntil });
this.response = this.response || gotoResponse;

if(this.check.cssCoverage) {
Expand Down
47 changes: 47 additions & 0 deletions lib/smoke/setup-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const { URL } = require('url');

module.exports = (path, urlOpts, suiteOpts, globalOpts) => {
const options = typeof urlOpts === 'object' ? Object.assign({}, urlOpts) : { status: urlOpts };
let host = globalOpts.host || 'http://localhost:3002';

if (!/https?\:\/\//.test(host)) {
host = 'http://' + host;
}

options.requestHeaders = Object.assign({}, globalOpts.headers || {}, suiteOpts.headers || {}, urlOpts.headers || {});
options.requestHeaderPaths = urlOpts.requestHeaderPaths || suiteOpts.requestHeaderPaths || [];

options.method = urlOpts.method || suiteOpts.method;
options.body = urlOpts.body || suiteOpts.body;
options.user = suiteOpts.user;
options.https = urlOpts.https || suiteOpts.https;
options.breakpoint = urlOpts.breakpoint || suiteOpts.breakpoint || globalOpts.breakpoint;

const browsers = urlOpts.browsers || suiteOpts.browsers;
const enabledBrowsers = globalOpts.browsers || ['chrome', 'firefox', 'safari', 'internet explorer', 'MicrosoftEdge'];

options.browsersToRun = ['chrome'];
if(Array.isArray(browsers)) {
options.browsersToRun = browsers.filter(browser => enabledBrowsers.includes(browser));
} else if (browsers === true) {
options.browsersToRun = enabledBrowsers;
}

if(options.user && !host.includes('local')) {
options.requestHeaders['FT-Test-Host'] = host.replace('https://', '').replace('http://', '');
host = 'https://www.ft.com';
} else if (options.user) {
//eslint-disable-next-line
console.warn('Cannot run user based tests on local URLs, as they rely on the FT-Test-Host. To run this locally, please use ngrok');
options.user = false;
}

options.url = new URL(path, host);

if(options.https) {
options.url.protocol = 'https';
}

return options;

};
58 changes: 19 additions & 39 deletions lib/smoke/index.js → lib/smoke/smoke-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const chalk = require('chalk');

const checks = require('./checks');
const filterConfigs = require('./filter-configs');
const verifyUrl = require('./verify-url');
const setupPage = require('./setup-page');
const verifyUrl =require('./verify-url');
const PuppeteerPage = require('./puppeteer-page');
const WebdriverPage = require('./webdriver-page');
const getSeleniumGrid = require('./get-selenium-grid');
Expand All @@ -24,8 +25,6 @@ class SmokeTest {
this.isInteractive = opts.interactive;
this.host = opts.host || 'https://local.ft.com:5050';
//TODO: default should be chrome, browsers will be opt-in
this.enabledBrowsers = opts.browsers || ['chrome', 'firefox', 'safari', 'internet explorer', 'MicrosoftEdge'];
this.canRunCrossBrowser = getSeleniumGrid(this.enabledBrowsers);

if (!/https?\:\/\//.test(this.host)) {
this.host = 'http://' + this.host;
Expand All @@ -44,53 +43,34 @@ class SmokeTest {
const puppetTests = [];
const crossBrowserTests = [];

Object.entries(suiteOpts.urls).forEach(async ([url, urlOpts]) => {
const globalOpts = {
headers: this.globalHeaders,
browsers: this.browsers,
breakpoint: this.breakpoint,
host: this.host
};

if (typeof urlOpts !== 'object') {
urlOpts = { status: urlOpts };
}

urlOpts.requestHeaders = Object.assign({}, this.globalHeaders, urlOpts.headers || {}, suiteOpts.headers || {});
urlOpts.requestHeaderPaths = urlOpts.requestHeaderPaths || suiteOpts.requestHeaderPaths || [];
urlOpts.method = urlOpts.method || suiteOpts.method;
urlOpts.body = urlOpts.body || suiteOpts.body;
urlOpts.https = urlOpts.https || suiteOpts.https;
urlOpts.user = suiteOpts.user;
Object.entries(suiteOpts.urls).forEach(async ([path, urlOpts]) => {

let host = this.host;
const pageOpts = setupPage(path, urlOpts, suiteOpts, globalOpts);

if(urlOpts.user) {
const canRunCrossBrowser = getSeleniumGrid(this.enabledBrowsers);

if(host.includes('local')) {
console.warn('Cannot run user based tests on local URLs, as they rely on the FT-Test-Host. To run this locally, please use ngrok');
return;
}
host = 'https://www.ft.com';
urlOpts.requestHeaders = Object.assign({
'FT-Test-Host': this.host.replace('https://', '').replace('http://', '')
}, urlOpts.requestHeaders);
}
;

const fullUrl = `${host}${url}`;
const browsers = urlOpts.browsers || suiteOpts.browsers;
let browsersToRun = ['chrome'];
if(Array.isArray(browsers)) {
browsersToRun = browsers.filter(browser => this.enabledBrowsers.includes(browser));
} else if (browsers === true) {
browsersToRun = this.enabledBrowsers;
if(pageOpts.browsersToRun.length > 1 && !canRunCrossBrowser) {
console.warn('Please set environment variables for Browserstack or Saucelabs to run cross browser tests.');
}

if(browsersToRun.length > 1 && !this.canRunCrossBrowser) {
console.warn('Please set environment variables for Browserstack or Saucelabs to run cross browser tests.');
if(suiteOpts.user && !pageOpts.user) {
return;
}

browsersToRun.forEach(browser => {
pageOpts.browsersToRun.forEach(browser => {
if(browser === 'chrome') {
const puppeteerPage = new PuppeteerPage(fullUrl, urlOpts);
const puppeteerPage = new PuppeteerPage(pageOpts);
puppetTests.push(verifyUrl(puppeteerPage, this.browser, this.checks));
} else if (urlOpts.elements && this.canRunCrossBrowser) {
const webdriverPage = new WebdriverPage(fullUrl, urlOpts, browser);
} else if (pageOpts.elements && canRunCrossBrowser) {
const webdriverPage = new WebdriverPage(pageOpts, browser);
crossBrowserTests.push(verifyUrl(webdriverPage, null, this.checks));
}
});
Expand Down
2 changes: 1 addition & 1 deletion lib/smoke/verify-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const verifyUrl = (testPage, browser, tests) => async () => {


const checkResults = await Promise.all(checks);
console.log(chalk`{bold Testing URL }({blue ${testPage.type}}): {underline.yellow ${testPage.url}}`);
console.log(chalk`{bold Testing URL }({blue ${testPage.type}}): {underline.yellow ${testPage.url.toString()}}`);
checkResults
.filter(result => !!result)
.forEach((check) => {
Expand Down
12 changes: 4 additions & 8 deletions lib/smoke/webdriver-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,11 @@ const DIMENSIONS = {


class WebdriverPage {
constructor (url, options, browserName) {
constructor (options, browserName) {
this.browserOptions = getSeleniumGrid(browserName);
this.type = browserName;
this.browser = webdriverio.remote(this.browserOptions);
this.url = url;

if(options.https) {
this.url = this.url.replace('http:', 'https:');
}
this.url = options.url;

//TODO: map request headers to cookies where applicable (FTSession, next-flags)
this.requestHeaders = Object.assign({}, options.requestHeaders || {});
Expand Down Expand Up @@ -49,7 +45,7 @@ class WebdriverPage {
if(this.requestHeaders) {

//Webdriver only lets you set cookies on the current page, so visit the page.
await this.browser.url(this.url);
await this.browser.url(this.url.toString());

//Translate request headers into cookies if we know about them
Object.entries(this.requestHeaders).forEach(([key, value]) => {
Expand All @@ -59,7 +55,7 @@ class WebdriverPage {
});
}

await this.browser.url(this.url);
await this.browser.url(this.url.toString());
}

async getVisibleElements (selector) {
Expand Down
Empty file added tasks/screenshot.js
Empty file.
2 changes: 1 addition & 1 deletion tasks/smoke.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const SmokeTests = require('../lib/smoke');
const SmokeTests = require('../lib/smoke/smoke-test');

module.exports = (program) => {

Expand Down
2 changes: 1 addition & 1 deletion test/tasks/smoke.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*globals beforeAll, expect */

const server = require('../server/app');
const SmokeTest = require('../../lib/smoke');
const SmokeTest = require('../../lib/smoke/smoke-test');

describe('Smoke Tests of the Smoke', () => {

Expand Down

0 comments on commit 438866f

Please sign in to comment.