Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions backstop.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"id": "bgu",
"viewports": [
{
"label": "iphone5",
"width": 320,
"height": 568
},
{
"label": "desktop",
"width": 1024,
"height": 768
}
],
"onBeforeScript": "puppet/onBefore.js",
"onReadyScript": "puppet/onReady.js",
"scenarios": [
{
"label": "Schedule",
"cookiePath": "backstop_data/engine_scripts/cookies.json",
"url": "http://localhost:5000/36/17844/",
"referenceUrl": "",
"readyEvent": "",
"readySelector": "",
"delay": 0,
"hideSelectors": [],
"removeSelectors": [],
"hoverSelector": "",
"clickSelector": "",
"postInteractionWait": 0,
"selectors": [],
"selectorExpansion": true,
"expect": 0,
"misMatchThreshold": 0.1,
"requireSameDimensions": true
}
],
"paths": {
"bitmaps_reference": "backstop_data/bitmaps_reference",
"bitmaps_test": "backstop_data/bitmaps_test",
"engine_scripts": "backstop_data/engine_scripts",
"html_report": "backstop_data/html_report",
"ci_report": "backstop_data/ci_report"
},
"report": ["browser"],
"engine": "puppeteer",
"engineOptions": {
"args": ["--no-sandbox"]
},
"asyncCaptureLimit": 5,
"asyncCompareLimit": 50,
"debug": false,
"debugWindow": false
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions backstop_data/engine_scripts/casper/clickAndHoverHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var WAIT_TIMEOUT = 5000;

module.exports = function(casper, scenario) {
var waitFor = require('./waitForHelperHelper')(casper, WAIT_TIMEOUT);
var hoverSelector = scenario.hoverSelector;
var clickSelector = scenario.clickSelector;
var postInteractionWait = scenario.postInteractionWait;

if (hoverSelector) {
waitFor(hoverSelector);
casper.then(function() {
casper.mouse.move(hoverSelector);
});
}

if (clickSelector) {
waitFor(clickSelector);
casper.then(function() {
casper.click(clickSelector);
});
}

// TODO: if postInteractionWait === integer then do ==> wait(postInteractionWait) || elsevvv
waitFor(postInteractionWait);
};
20 changes: 20 additions & 0 deletions backstop_data/engine_scripts/casper/loadCookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
var fs = require('fs');

module.exports = function(casper, scenario) {
var cookies = [];
var cookiePath = scenario.cookiePath;

// READ COOKIES FROM FILE IF EXISTS
if (fs.existsSync(cookiePath)) {
cookies = JSON.parse(fs.readFileSync(cookiePath));
}

casper.page.cookies = cookies;
console.log(
'Cookie state restored with cookies:',
JSON.stringify(cookies, null, 2)
);
casper.userAgent(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
);
};
6 changes: 6 additions & 0 deletions backstop_data/engine_scripts/casper/onBefore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(casper, scenario, vp) {
require('./loadCookies')(casper, scenario);
casper.userAgent(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
);
};
5 changes: 5 additions & 0 deletions backstop_data/engine_scripts/casper/onReady.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(casper, scenario, vp) {
console.log('SCENARIO> ' + scenario.label);
require('./clickAndHoverHelper')(casper, scenario);
// add more helpers here...
};
18 changes: 18 additions & 0 deletions backstop_data/engine_scripts/casper/waitForHelperHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var TIMEOUT_DEFAULT = 2000;

module.exports = function(casper, timeout) {
var TIMEOUT = timeout || TIMEOUT_DEFAULT;

return function waitFor(selector) {
if (selector) {
casper.waitForSelector(
selector,
function() {},
function() {
console.error('NOT FOUND > ' + selector);
},
TIMEOUT
);
}
};
};
43 changes: 43 additions & 0 deletions backstop_data/engine_scripts/chromy/clickAndHoverHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module.exports = function(chromy, scenario) {
var hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
var clickSelector = scenario.clickSelectors || scenario.clickSelector;
var keyPressSelector =
scenario.keyPressSelectors || scenario.keyPressSelector;
var scrollToSelector =
scenario.scrollToSelectors || scenario.scrollToSelector;
var postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]

if (keyPressSelector) {
for (const keyPressSelectorItem of [].concat(keyPressSelector)) {
chromy
.wait(keyPressSelectorItem.selector)
.insert(keyPressSelectorItem.selector, keyPressSelectorItem.keyPress);
}
}

if (hoverSelector) {
chromy
.wait(hoverSelector)
.rect(hoverSelector)
.result(function(rect) {
chromy.mouseMoved(rect.left, rect.top);
});
}

if (clickSelector) {
chromy.wait(clickSelector).click(clickSelector);
}

if (postInteractionWait) {
chromy.wait(postInteractionWait);
}

if (scrollToSelector) {
chromy
.wait(scrollToSelector)
.evaluate(`window._scrollToSelector = '${scrollToSelector}'`)
.evaluate(function() {
document.querySelector(window._scrollToSelector).scrollIntoView();
});
}
};
22 changes: 22 additions & 0 deletions backstop_data/engine_scripts/chromy/loadCookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var fs = require('fs');

module.exports = function(chromy, scenario) {
var cookies = [];
var cookiePath = scenario.cookiePath;

// READ COOKIES FROM FILE IF EXISTS
if (fs.existsSync(cookiePath)) {
cookies = JSON.parse(fs.readFileSync(cookiePath));
}

// MUNGE COOKIE DOMAIN FOR CHROMY USAGE
cookies = cookies.map(cookie => {
cookie.url = 'https://' + cookie.domain;
delete cookie.domain;
return cookie;
});

// SET COOKIES VIA CHROMY
chromy.setCookie(cookies);
console.log('Cookie state restored with:', JSON.stringify(cookies, null, 2));
};
6 changes: 6 additions & 0 deletions backstop_data/engine_scripts/chromy/onBefore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(chromy, scenario, vp) {
require('./loadCookies')(chromy, scenario);

// IGNORE ANY CERT WARNINGS
chromy.ignoreCertificateErrors();
};
5 changes: 5 additions & 0 deletions backstop_data/engine_scripts/chromy/onReady.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(chromy, scenario, vp) {
console.log('SCENARIO > ' + scenario.label);
require('./clickAndHoverHelper')(chromy, scenario);
// add more ready handlers here...
};
14 changes: 14 additions & 0 deletions backstop_data/engine_scripts/cookies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"domain": ".www.yourdomain.com",
"path": "/",
"name": "yourCookieName",
"value": "yourCookieValue",
"expirationDate": 1798790400,
"hostOnly": false,
"httpOnly": false,
"secure": false,
"session": false,
"sameSite": "no_restriction"
}
]
Binary file added backstop_data/engine_scripts/imageStub.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions backstop_data/engine_scripts/puppet/clickAndHoverHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module.exports = async (page, scenario) => {
var hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
var clickSelector = scenario.clickSelectors || scenario.clickSelector;
var keyPressSelector =
scenario.keyPressSelectors || scenario.keyPressSelector;
var scrollToSelector = scenario.scrollToSelector;
var postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]

if (keyPressSelector) {
for (const keyPressSelectorItem of [].concat(keyPressSelector)) {
await page.waitFor(keyPressSelectorItem.selector);
await page.type(
keyPressSelectorItem.selector,
keyPressSelectorItem.keyPress
);
}
}

if (hoverSelector) {
for (const hoverSelectorIndex of [].concat(hoverSelector)) {
await page.waitFor(hoverSelectorIndex);
await page.hover(hoverSelectorIndex);
}
}

if (clickSelector) {
for (const clickSelectorIndex of [].concat(clickSelector)) {
await page.waitFor(clickSelectorIndex);
await page.click(clickSelectorIndex);
}
}

if (postInteractionWait) {
await page.waitFor(postInteractionWait);
}

if (scrollToSelector) {
await page.waitFor(scrollToSelector);
await page.evaluate(scrollToSelector => {
document.querySelector(scrollToSelector).scrollIntoView();
}, scrollToSelector);
}
};
67 changes: 67 additions & 0 deletions backstop_data/engine_scripts/puppet/ignoreCSP.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* IGNORE CSP HEADERS
* Listen to all requests. If a request matches scenario.url
* then fetch the request again manually, strip out CSP headers
* and respond to the original request without CSP headers.
* Allows `ignoreHTTPSErrors: true` BUT... requires `debugWindow: true`
*
* see https://github.com/GoogleChrome/puppeteer/issues/1229#issuecomment-380133332
* this is the workaround until Page.setBypassCSP lands... https://github.com/GoogleChrome/puppeteer/pull/2324
*
* @param {REQUEST} request
* @return {VOID}
*
* Use this in an onBefore script E.G.
```
module.exports = async function(page, scenario) {
require('./removeCSP')(page, scenario);
}
```
*
*/

const fetch = require('node-fetch');
const https = require('https');
const agent = new https.Agent({
rejectUnauthorized: false,
});

module.exports = async function(page, scenario) {
const intercept = async (request, targetUrl) => {
const requestUrl = request.url();

// FIND TARGET URL REQUEST
if (requestUrl === targetUrl) {
const cookiesList = await page.cookies(requestUrl);
const cookies = cookiesList
.map(cookie => `${cookie.name}=${cookie.value}`)
.join('; ');
const headers = Object.assign(request.headers(), { cookie: cookies });
const options = {
headers: headers,
body: request.postData(),
method: request.method(),
follow: 20,
agent,
};

const result = await fetch(requestUrl, options);

const buffer = await result.buffer();
let cleanedHeaders = result.headers._headers || {};
cleanedHeaders['content-security-policy'] = '';
await request.respond({
body: buffer,
headers: cleanedHeaders,
status: result.status,
});
} else {
request.continue();
}
};

await page.setRequestInterception(true);
page.on('request', req => {
intercept(req, scenario.url);
});
};
37 changes: 37 additions & 0 deletions backstop_data/engine_scripts/puppet/interceptImages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* INTERCEPT IMAGES
* Listen to all requests. If a request matches IMAGE_URL_RE
* then stub the image with data from IMAGE_STUB_URL
*
* Use this in an onBefore script E.G.
```
module.exports = async function(page, scenario) {
require('./interceptImages')(page, scenario);
}
```
*
*/

const fs = require('fs');
const path = require('path');

const IMAGE_URL_RE = /\.gif|\.jpg|\.png/i;
const IMAGE_STUB_URL = path.resolve(__dirname, '../../imageStub.jpg');
const IMAGE_DATA_BUFFER = fs.readFileSync(IMAGE_STUB_URL);
const HEADERS_STUB = {};

module.exports = async function(page, scenario) {
const intercept = async (request, targetUrl) => {
if (IMAGE_URL_RE.test(request.url())) {
await request.respond({
body: IMAGE_DATA_BUFFER,
headers: HEADERS_STUB,
status: 200,
});
} else {
request.continue();
}
};
await page.setRequestInterception(true);
page.on('request', intercept);
};
Loading