From 78cd465e2eae5cc7fc3b39a7cd21811cbf6c4664 Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 10:49:13 +0100 Subject: [PATCH 01/12] init v5 migration --- src/WdioScreenshotLauncher.js | 25 ++++++ src/commands/saveDocumentScreenshot.js | 2 - src/commands/saveElementScreenshot.js | 7 +- src/commands/saveViewportScreenshot.js | 1 - src/index.js | 34 +-------- src/modules/afterScreenshot.js | 38 ++++++---- src/modules/beforeScreenshot.js | 76 ++++++++++--------- src/modules/makeAreaScreenshot.js | 51 ++++++++----- src/modules/makeDocumentScreenshot.js | 12 ++- src/modules/makeElementScreenshot.js | 16 +++- src/modules/makeViewportScreenshot.js | 13 +++- src/scripts/getBoundingRects.js | 3 +- src/scripts/getScreenDimensions.js | 8 +- src/scripts/getScrollPosition.js | 21 ++--- src/scripts/hideElements.js | 13 ++++ src/scripts/modifyElements.js | 17 ++--- src/scripts/pageHeight.js | 1 + src/scripts/scroll.js | 0 src/scripts/scrollbars.js | 1 + src/scripts/triggerResize.js | 1 + src/scripts/virtualScroll.js | 0 src/utils/CropDimension.js | 4 - src/utils/ScreenDimension.js | 23 ++++-- src/utils/ScreenshotStrategyManager.js | 17 +++-- src/utils/generateUUID.js | 0 src/utils/getBase64ImageSize.js | 0 src/utils/groupBoundingRect.js | 24 ++++-- src/utils/image/gm.js | 66 ++++++++-------- src/utils/image/index.js | 4 +- src/utils/image/jimp.js | 27 +++---- src/utils/normalizeScreenshot.js | 56 +++++++++----- src/utils/saveBase64Image.js | 0 src/utils/strategies/BaseStrategy.js | 9 ++- .../strategies/FullpageScreenshotStrategy.js | 3 - .../strategies/MergeScreenshotStrategy.js | 19 +++-- .../TrimAndMergeScreenshotStrategy.js | 27 ++++--- 36 files changed, 359 insertions(+), 260 deletions(-) create mode 100755 src/WdioScreenshotLauncher.js mode change 100644 => 100755 src/commands/saveDocumentScreenshot.js mode change 100644 => 100755 src/commands/saveElementScreenshot.js mode change 100644 => 100755 src/commands/saveViewportScreenshot.js mode change 100644 => 100755 src/modules/afterScreenshot.js mode change 100644 => 100755 src/modules/beforeScreenshot.js mode change 100644 => 100755 src/modules/makeAreaScreenshot.js mode change 100644 => 100755 src/modules/makeDocumentScreenshot.js mode change 100644 => 100755 src/modules/makeElementScreenshot.js mode change 100644 => 100755 src/modules/makeViewportScreenshot.js mode change 100644 => 100755 src/scripts/getBoundingRects.js mode change 100644 => 100755 src/scripts/getScreenDimensions.js mode change 100644 => 100755 src/scripts/getScrollPosition.js create mode 100644 src/scripts/hideElements.js mode change 100644 => 100755 src/scripts/modifyElements.js mode change 100644 => 100755 src/scripts/pageHeight.js mode change 100644 => 100755 src/scripts/scroll.js mode change 100644 => 100755 src/scripts/scrollbars.js mode change 100644 => 100755 src/scripts/triggerResize.js mode change 100644 => 100755 src/scripts/virtualScroll.js mode change 100644 => 100755 src/utils/CropDimension.js mode change 100644 => 100755 src/utils/ScreenDimension.js mode change 100644 => 100755 src/utils/ScreenshotStrategyManager.js mode change 100644 => 100755 src/utils/generateUUID.js mode change 100644 => 100755 src/utils/getBase64ImageSize.js mode change 100644 => 100755 src/utils/groupBoundingRect.js mode change 100644 => 100755 src/utils/image/gm.js mode change 100644 => 100755 src/utils/image/index.js mode change 100644 => 100755 src/utils/image/jimp.js mode change 100644 => 100755 src/utils/normalizeScreenshot.js mode change 100644 => 100755 src/utils/saveBase64Image.js mode change 100644 => 100755 src/utils/strategies/BaseStrategy.js mode change 100644 => 100755 src/utils/strategies/FullpageScreenshotStrategy.js mode change 100644 => 100755 src/utils/strategies/MergeScreenshotStrategy.js mode change 100644 => 100755 src/utils/strategies/TrimAndMergeScreenshotStrategy.js diff --git a/src/WdioScreenshotLauncher.js b/src/WdioScreenshotLauncher.js new file mode 100755 index 0000000..2fcf6f4 --- /dev/null +++ b/src/WdioScreenshotLauncher.js @@ -0,0 +1,25 @@ +import saveDocumentScreenshot from './commands/saveDocumentScreenshot'; +import saveElementScreenshot from './commands/saveElementScreenshot'; +import saveViewportScreenshot from './commands/saveViewportScreenshot'; + +import makeDocumentScreenshot from './modules/makeDocumentScreenshot'; +import makeElementScreenshot from './modules/makeElementScreenshot'; +import makeViewportScreenshot from './modules/makeViewportScreenshot'; + +export default class WdioScreenshot { + constructor(browser, options) { + } + + before() { + // add commands to WebdriverIO instance + browser.addCommand('saveDocumentScreenshot', saveDocumentScreenshot); + browser.addCommand('saveElementScreenshot', saveElementScreenshot); + browser.addCommand('saveViewportScreenshot', saveViewportScreenshot); + } +} + +export { + makeDocumentScreenshot, + makeElementScreenshot, + makeViewportScreenshot, +}; diff --git a/src/commands/saveDocumentScreenshot.js b/src/commands/saveDocumentScreenshot.js old mode 100644 new mode 100755 index f8f6a32..a19079c --- a/src/commands/saveDocumentScreenshot.js +++ b/src/commands/saveDocumentScreenshot.js @@ -10,7 +10,6 @@ import saveBase64Image from '../utils/saveBase64Image'; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, options) { - if (_.isPlainObject(fileName) && _.isUndefined(options)) { options = fileName; fileName = undefined; @@ -18,7 +17,6 @@ export default async function async(fileName, options) { // make screenshot of area const base64Image = await makeDocumentScreenshot(this, options); - if (typeof fileName !== 'undefined') { // store base64 image as real png await saveBase64Image(fileName, base64Image); diff --git a/src/commands/saveElementScreenshot.js b/src/commands/saveElementScreenshot.js old mode 100644 new mode 100755 index 448a141..17e988e --- a/src/commands/saveElementScreenshot.js +++ b/src/commands/saveElementScreenshot.js @@ -11,8 +11,11 @@ import saveBase64Image from '../utils/saveBase64Image'; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, elementSelector, options) { - - if ((_.isString(fileName) || _.isArray(fileName)) && _.isPlainObject(elementSelector) && _.isUndefined(options)) { + if ( + (_.isString(fileName) || _.isArray(fileName)) && + _.isPlainObject(elementSelector) && + _.isUndefined(options) + ) { options = elementSelector; elementSelector = fileName; fileName = undefined; diff --git a/src/commands/saveViewportScreenshot.js b/src/commands/saveViewportScreenshot.js old mode 100644 new mode 100755 index 6dce3d9..189ae0a --- a/src/commands/saveViewportScreenshot.js +++ b/src/commands/saveViewportScreenshot.js @@ -10,7 +10,6 @@ import saveBase64Image from '../utils/saveBase64Image'; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, options) { - if (_.isPlainObject(fileName) && _.isUndefined(options)) { options = fileName; fileName = undefined; diff --git a/src/index.js b/src/index.js index 57680c8..97b2e8d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,33 +1,3 @@ -import saveDocumentScreenshot from './commands/saveDocumentScreenshot'; -import saveElementScreenshot from './commands/saveElementScreenshot'; -import saveViewportScreenshot from './commands/saveViewportScreenshot'; +import WdioScreenshot from './WdioScreenshotLauncher'; -import makeDocumentScreenshot from './modules/makeDocumentScreenshot'; -import makeElementScreenshot from './modules/makeElementScreenshot'; -import makeViewportScreenshot from './modules/makeViewportScreenshot'; - -class WDIOScreenshot { - - constructor(browser, options) { - if (!browser) { - throw new Error('A WebdriverIO instance is needed to initialise wdio-screenshot') - } - - // add commands to WebdriverIO instance - browser.addCommand('saveDocumentScreenshot', saveDocumentScreenshot); - browser.addCommand('saveElementScreenshot', saveElementScreenshot); - browser.addCommand('saveViewportScreenshot', saveViewportScreenshot); - } -} - -// export init function for initialization -export function init(webdriverInstance, options) { - return new WDIOScreenshot(webdriverInstance, options); -} - -// export also helpers for regression lib -export { - makeDocumentScreenshot, - makeElementScreenshot, - makeViewportScreenshot, -}; +module.exports = new WdioScreenshot(); diff --git a/src/modules/afterScreenshot.js b/src/modules/afterScreenshot.js old mode 100644 new mode 100755 index 19d408e..a42c1af --- a/src/modules/afterScreenshot.js +++ b/src/modules/afterScreenshot.js @@ -1,24 +1,30 @@ -import debug from 'debug'; +import debug from "debug"; -import scrollbars from '../scripts/scrollbars'; -import modifyElements from '../scripts/modifyElements'; +import scrollbars from "../scripts/scrollbars"; +import modifyElements from "../scripts/modifyElements"; +import hideElements from "../scripts/hideElements"; const log = debug('wdio-screenshot:afterScreenshot'); export default async function afterScreenshot(browser, options) { - // show elements - if (Array.isArray(options.hide) && options.hide.length) { - log('show the following elements again: %s', options.hide.join(', ')); - await browser.selectorExecute(options.hide, modifyElements, 'opacity', ''); - } + // show elements + if (Array.isArray(options.hide) && options.hide.length) { + log('show the following elements again: %s', options.hide.join(', ')); - // add elements again - if (Array.isArray(options.remove) && options.remove.length) { - log('add the following elements again: %s', options.remove.join(', ')); - await browser.selectorExecute(options.remove, modifyElements, 'display', ''); - } - // show scrollbars - log('show scrollbars again'); - await browser.execute(scrollbars, true); + for (let i = 0; i < options.hide.length; i++) { + let elements = await browser.$$(options.hide[i]); + await browser.execute(hideElements, elements, false); + } + } + + // add elements again + if (Array.isArray(options.remove) && options.remove.length) { + log('add the following elements again: %s', options.remove.join(', ')); + await browser.selectorExecute(options.remove, modifyElements, 'display', ''); + } + + // show scrollbars + log('show scrollbars again'); + await browser.execute(scrollbars, true); } diff --git a/src/modules/beforeScreenshot.js b/src/modules/beforeScreenshot.js old mode 100644 new mode 100755 index 0d656ea..29ad997 --- a/src/modules/beforeScreenshot.js +++ b/src/modules/beforeScreenshot.js @@ -1,40 +1,48 @@ -import debug from 'debug'; +import debug from "debug"; -import scroll from '../scripts/scroll'; -import scrollbars from '../scripts/scrollbars'; -import modifyElements from '../scripts/modifyElements'; -import triggerResize from '../scripts/triggerResize'; +import scroll from "../scripts/scroll"; +import scrollbars from "../scripts/scrollbars"; +import modifyElements from "../scripts/modifyElements"; +import triggerResize from "../scripts/triggerResize"; +import hideElements from "../scripts/hideElements"; const log = debug('wdio-screenshot:beforeScreenshot'); export default async function beforeScreenshot(browser, options) { - // hide scrollbars - log('hide scrollbars'); - await browser.execute(scrollbars, false); - - log('trigger resize event to allow js components to resize properly'); - await browser.execute(triggerResize); - - // hide elements - if (Array.isArray(options.hide) && options.hide.length) { - log('hide the following elements: %s', options.hide.join(', ')); - await browser.selectorExecute(options.hide, modifyElements, 'opacity', '0'); - } - - // remove elements - if (Array.isArray(options.remove) && options.remove.length) { - log('remove the following elements: %s', options.remove.join(', ')); - await browser.selectorExecute(options.remove, modifyElements, 'display', 'none'); - } - - // scroll back to start - const x = 0; - const y = 0; - log('scroll back to start x: %s, y: %s', x, y); - await browser.execute(scroll, x, y); - - // wait a bit for browser render - const pause = 200; - log('wait %s ms for browser render', pause); - await browser.pause(pause); + // hide scrollbars + log('hide scrollbars'); + await browser.execute(scrollbars, false); + + log('trigger resize event to allow js components to resize properly'); + await browser.execute(triggerResize); + + // hide elements + if (Array.isArray(options.hide) && options.hide.length) { + log('hide the following elements: %s', options.hide.join(', ')); + + for (let i = 0; i < options.hide.length; i++) { + let elements = await browser.$$(options.hide[i]); + await browser.execute(hideElements, elements, true); + } + + await browser.pause(15000); + } + + // TODO + // remove elements + if (Array.isArray(options.remove) && options.remove.length) { + log('remove the following elements: %s', options.remove.join(', ')); + await selectorExecute(options.remove, modifyElements, 'display', 'none'); + } + + // scroll back to start + const x = 0; + const y = 0; + log('scroll back to start x: %s, y: %s', x, y); + await browser.execute(scroll, x, y); + + // wait a bit for browser render + const pause = 200; + log('wait %s ms for browser render', pause); + await browser.pause(pause); } diff --git a/src/modules/makeAreaScreenshot.js b/src/modules/makeAreaScreenshot.js old mode 100644 new mode 100755 index 54314f4..278790b --- a/src/modules/makeAreaScreenshot.js +++ b/src/modules/makeAreaScreenshot.js @@ -15,9 +15,25 @@ import normalizeScreenshot from '../utils/normalizeScreenshot'; const log = debug('wdio-screenshot:makeAreaScreenshot'); const tmpDir = path.join(__dirname, '..', '..', '.tmp'); -async function storeScreenshot(browser, screenDimensions, cropDimensions, base64Screenshot, filePath) { - const normalizedBase64Screenshot = await normalizeScreenshot(browser, screenDimensions, base64Screenshot); - log('crop screenshot with width: %s, height: %s, offsetX: %s, offsetY: %s', cropDimensions.getWidth(), cropDimensions.getHeight(), cropDimensions.getX(), cropDimensions.getY()); +async function storeScreenshot( + browser, + screenDimensions, + cropDimensions, + base64Screenshot, + filePath, +) { + const normalizedBase64Screenshot = await normalizeScreenshot( + browser, + screenDimensions, + base64Screenshot, + ); + log( + 'crop screenshot with width: %s, height: %s, offsetX: %s, offsetY: %s', + cropDimensions.getWidth(), + cropDimensions.getHeight(), + cropDimensions.getX(), + cropDimensions.getY(), + ); const croppedBase64Screenshot = await cropImage(normalizedBase64Screenshot, cropDimensions); @@ -25,9 +41,9 @@ async function storeScreenshot(browser, screenDimensions, cropDimensions, base64 } export default async function makeAreaScreenshot(browser, startX, startY, endX, endY) { - log('requested a screenshot for the following area: %j', {startX, startY, endX, endY}); + log('requested a screenshot for the following area: %j', { startX, startY, endX, endY }); - const screenDimensions = (await browser.execute(getScreenDimensions)).value; + const screenDimensions = await browser.execute(getScreenDimensions); log('detected screenDimensions %j', screenDimensions); const screenDimension = new ScreenDimension(screenDimensions, browser); @@ -56,13 +72,17 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, await browser.pause(100); log('take screenshot'); - const base64Screenshot = (await browser.screenshot()).value; + + const cropDimensions = screenshotStrategy.getCropDimensions(); const filePath = path.join(dir, `${indexY}-${indexX}.png`); + const base64Screenshot = await browser.saveScreenshot(filePath); - screenshotPromises.push(storeScreenshot(browser, screenDimension, cropDimensions, base64Screenshot, filePath)); + screenshotPromises.push( + storeScreenshot(browser, screenDimension, cropDimensions, base64Screenshot, filePath), + ); - if(!Array.isArray(cropImages[indexY])) { + if (!Array.isArray(cropImages[indexY])) { cropImages[indexY] = []; } @@ -70,10 +90,10 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, loop = screenshotStrategy.hasNextScrollPosition(); screenshotStrategy.moveToNextScrollPosition(); - } while (loop) + } while (loop); const [mergedBase64Screenshot] = await Promise.all([ - Promise.resolve().then(async() => { + Promise.resolve().then(async () => { await Promise.all(screenshotPromises); log('merge images togehter'); const mergedBase64Screenshot = await mergeImages(cropImages); @@ -81,23 +101,20 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, await fsExtra.remove(dir); return mergedBase64Screenshot; }), - Promise.resolve().then(async() => { + Promise.resolve().then(async () => { log('reset page height'); await browser.execute(pageHeight, ''); log('revert scroll to x: %s, y: %s', 0, 0); await browser.execute(virtualScroll, 0, 0, true); - }) + }), ]); - return mergedBase64Screenshot; - - } catch(e) { + } catch (e) { try { await fsExtra.remove(dir); - } catch(e) {} + } catch (e) {} throw e; } - } diff --git a/src/modules/makeDocumentScreenshot.js b/src/modules/makeDocumentScreenshot.js old mode 100644 new mode 100755 index 60403b6..73ee644 --- a/src/modules/makeDocumentScreenshot.js +++ b/src/modules/makeDocumentScreenshot.js @@ -9,7 +9,6 @@ import ScreenDimension from '../utils/ScreenDimension'; const log = debug('wdio-screenshot:makeDocumentScreenshot'); - export default async function makeDocumentScreenshot(browser, options = {}) { log('start document screenshot'); @@ -17,11 +16,18 @@ export default async function makeDocumentScreenshot(browser, options = {}) { await beforeScreenshot(browser, options); // get screen dimisions to determine document height & width - const screenDimensions = (await browser.execute(getScreenDimensions)).value; + const screenDimensions = await browser.execute(getScreenDimensions); + const screenDimension = new ScreenDimension(screenDimensions, browser); // make screenshot of area - const base64Image = await makeAreaScreenshot(browser, 0, 0, screenDimension.getDocumentWidth(), screenDimension.getDocumentHeight()); + const base64Image = await makeAreaScreenshot( + browser, + 0, + 0, + screenDimension.getDocumentWidth(), + screenDimension.getDocumentHeight(), + ); // show scrollbars, show & add elements await afterScreenshot(browser, options); diff --git a/src/modules/makeElementScreenshot.js b/src/modules/makeElementScreenshot.js old mode 100644 new mode 100755 index 424bad0..c36739d --- a/src/modules/makeElementScreenshot.js +++ b/src/modules/makeElementScreenshot.js @@ -9,7 +9,6 @@ import getBoundingRects from '../scripts/getBoundingRects'; const log = debug('wdio-screenshot:makeElementScreenshot'); - export default async function makeElementScreenshot(browser, elementSelector, options = {}) { log('start element screenshot'); @@ -17,11 +16,22 @@ export default async function makeElementScreenshot(browser, elementSelector, op await beforeScreenshot(browser, options); // get bounding rect of elements - const boundingRects = await browser.selectorExecute(elementSelector, getBoundingRects); + // const boundingRects = await browser.selectorExecute(elementSelector, getBoundingRects); + + const elements = await browser.$$(elementSelector); + + const boundingRects = await browser.execute(getBoundingRects, elements); + const boundingRect = groupBoundingRect(boundingRects); // make screenshot of area - const base64Image = await makeAreaScreenshot(browser, boundingRect.left, boundingRect.top, boundingRect.right, boundingRect.bottom); + const base64Image = await makeAreaScreenshot( + browser, + boundingRect.left, + boundingRect.top, + boundingRect.right, + boundingRect.bottom, + ); // show scrollbars, show & add elements await afterScreenshot(browser, options); diff --git a/src/modules/makeViewportScreenshot.js b/src/modules/makeViewportScreenshot.js old mode 100644 new mode 100755 index 2419bc0..faab9dd --- a/src/modules/makeViewportScreenshot.js +++ b/src/modules/makeViewportScreenshot.js @@ -11,23 +11,28 @@ import ScreenDimension from '../utils/ScreenDimension'; const log = debug('wdio-screenshot:makeViewportScreenshot'); - // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function makeViewportScreenshot(browser, options = {}) { log('start viewport screenshot'); // get current scroll position - const [startX, startY] = (await browser.execute(getScrollPosition)).value; + const [startX, startY] = await browser.execute(getScrollPosition); // hide scrollbars, scroll to start, hide & remove elements, wait for render await beforeScreenshot(browser, options); // get screen dimisions to determine viewport height & width - const screenDimensions = (await browser.execute(getScreenDimensions)).value; + const screenDimensions = await browser.execute(getScreenDimensions); const screenDimension = new ScreenDimension(screenDimensions, browser); // make screenshot of area - const base64Image = await makeAreaScreenshot(browser, startX, startY, screenDimension.getViewportWidth(), screenDimension.getViewportHeight()); + const base64Image = await makeAreaScreenshot( + browser, + startX, + startY, + screenDimension.getViewportWidth(), + screenDimension.getViewportHeight(), + ); // show scrollbars, show & add elements await afterScreenshot(browser, options); diff --git a/src/scripts/getBoundingRects.js b/src/scripts/getBoundingRects.js old mode 100644 new mode 100755 index e1e9f0a..b1b9d3c --- a/src/scripts/getBoundingRects.js +++ b/src/scripts/getBoundingRects.js @@ -1,7 +1,6 @@ - export default function getBoundingRect(elems) { - return elems.map((elem) => { + return elems.map(elem => { const boundingRect = elem.getBoundingClientRect(); return { top: boundingRect.top, diff --git a/src/scripts/getScreenDimensions.js b/src/scripts/getScreenDimensions.js old mode 100644 new mode 100755 index 7228a0d..4efa99c --- a/src/scripts/getScreenDimensions.js +++ b/src/scripts/getScreenDimensions.js @@ -1,5 +1,5 @@ -export default function getScreenDimension() { +export default function getScreenDimension() { const body = document.body; const html = document.documentElement; @@ -14,14 +14,14 @@ export default function getScreenDimension() { }, body: { scrollHeight: body.scrollHeight, - offsetHeight: body.offsetHeight + offsetHeight: body.offsetHeight, }, html: { clientWidth: html.clientWidth, scrollWidth: html.scrollWidth, clientHeight: html.clientHeight, scrollHeight: html.scrollHeight, - offsetHeight: html.offsetHeight - } + offsetHeight: html.offsetHeight, + }, }; } diff --git a/src/scripts/getScrollPosition.js b/src/scripts/getScrollPosition.js old mode 100644 new mode 100755 index 95e1805..1fa17c1 --- a/src/scripts/getScrollPosition.js +++ b/src/scripts/getScrollPosition.js @@ -1,19 +1,14 @@ + export default function getScrollPosition() { if (typeof window.pageYOffset !== 'undefined') { - return [ - window.pageXOffset, - window.pageYOffset - ]; - } else if (typeof document.documentElement.scrollTop !== 'undefined' && document.documentElement.scrollTop > 0) { - return [ - document.documentElement.scrollLeft, - document.documentElement.scrollTop - ]; + return [window.pageXOffset, window.pageYOffset]; + } else if ( + typeof document.documentElement.scrollTop !== 'undefined' && + document.documentElement.scrollTop > 0 + ) { + return [document.documentElement.scrollLeft, document.documentElement.scrollTop]; } else if (typeof document.body.scrollTop !== 'undefined') { - return [ - document.body.scrollLeft, - document.body.scrollTop - ]; + return [document.body.scrollLeft, document.body.scrollTop]; } return [0, 0]; } diff --git a/src/scripts/hideElements.js b/src/scripts/hideElements.js new file mode 100644 index 0000000..45cd14f --- /dev/null +++ b/src/scripts/hideElements.js @@ -0,0 +1,13 @@ + +export default function hideElements(elems, flag = true) { + + if (flag) { + return elems.forEach(ele => { + ele.style.setProperty('opacity', '0.0', 'important'); + }); + } else { + return elems.forEach(ele => { + ele.style.setProperty('opacity', '1.0'); + }); + } +} diff --git a/src/scripts/modifyElements.js b/src/scripts/modifyElements.js old mode 100644 new mode 100755 index 9c5197a..2d016c5 --- a/src/scripts/modifyElements.js +++ b/src/scripts/modifyElements.js @@ -1,21 +1,18 @@ export default function modifyElements() { - const args = Array.prototype.slice.call(arguments).filter(function(n) { - return !!n || n === ''; - }); + const args = Array.prototype.slice.call(arguments).filter(n => !!n || n === ''); const style = args[args.length - 2]; const value = args[args.length - 1]; args.splice(-2); - for (var i = 0; i < args.length; ++i) { - for (var j = 0; j < args[i].length; ++j) { - var element = args[i][j]; + for (let i = 0; i < args.length; ++i) { + for (let j = 0; j < args[i].length; ++j) { + const element = args[i][j]; try { - element.style.setProperty(style, value, 'important'); - } - catch (error) { - element.setAttribute('style', element.style.cssText + style + ':' + value + '!important;'); + element.style.setProperty(style, value, 'important'); + } catch (error) { + element.setAttribute('style', `${element.style.cssText + style}:${value}!important;`); } } } diff --git a/src/scripts/pageHeight.js b/src/scripts/pageHeight.js old mode 100644 new mode 100755 index 6ae6b8f..00aed59 --- a/src/scripts/pageHeight.js +++ b/src/scripts/pageHeight.js @@ -1,3 +1,4 @@ + export default function pageHeight(height) { document.body.style.height = height; } diff --git a/src/scripts/scroll.js b/src/scripts/scroll.js old mode 100644 new mode 100755 diff --git a/src/scripts/scrollbars.js b/src/scripts/scrollbars.js old mode 100644 new mode 100755 index 362ccc4..0ed0548 --- a/src/scripts/scrollbars.js +++ b/src/scripts/scrollbars.js @@ -1,3 +1,4 @@ + export default function scrollbars(enabled) { if (enabled) { document.documentElement.style.overflow = ''; diff --git a/src/scripts/triggerResize.js b/src/scripts/triggerResize.js old mode 100644 new mode 100755 index a053cd4..3c71ff5 --- a/src/scripts/triggerResize.js +++ b/src/scripts/triggerResize.js @@ -1,3 +1,4 @@ + /** * trigger window.resize to relayout js components */ diff --git a/src/scripts/virtualScroll.js b/src/scripts/virtualScroll.js old mode 100644 new mode 100755 diff --git a/src/utils/CropDimension.js b/src/utils/CropDimension.js old mode 100644 new mode 100755 index 0eee37a..b7d46a8 --- a/src/utils/CropDimension.js +++ b/src/utils/CropDimension.js @@ -1,6 +1,4 @@ - export default class CropDimension { - constructor(width, height, x, y, top = true, rotation = 0) { this.width = width; this.height = height; @@ -10,7 +8,6 @@ export default class CropDimension { this.rotation = rotation; } - getWidth() { return this.width; } @@ -34,5 +31,4 @@ export default class CropDimension { getRotation() { return this.rotation; } - } diff --git a/src/utils/ScreenDimension.js b/src/utils/ScreenDimension.js old mode 100644 new mode 100755 index 7a8175a..8cdc734 --- a/src/utils/ScreenDimension.js +++ b/src/utils/ScreenDimension.js @@ -1,7 +1,7 @@ export default class ScreenDimensions { - constructor(options, browser = {}) { const { html, body, window } = options; + const { isIOS } = browser; this.isIOS = isIOS; @@ -9,7 +9,13 @@ export default class ScreenDimensions { this.viewportHeight = window.innerHeight || html.clientHeight || 0; this.documentWidth = html.scrollWidth; - this.documentHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); + this.documentHeight = Math.max( + body.scrollHeight, + body.offsetHeight, + html.clientHeight, + html.scrollHeight, + html.offsetHeight, + ); const screenMax = Math.max(window.screenWidth, window.screenHeight); const screenMin = Math.min(window.screenWidth, window.screenHeight); @@ -26,16 +32,23 @@ export default class ScreenDimensions { this.pixelRatio = window.pixelRatio; this.orientation = window.orientation; - if (this.isIOS && this.isLandscape() && this.getViewportHeight() - 20 === this.getInnerHeight()) { + if ( + this.isIOS && + this.isLandscape() && + this.getViewportHeight() - 20 === this.getInnerHeight() + ) { // iOS 7 has a 20px bug in landscape mode this.viewportHeight = this.getInnerHeight(); } - if (this.isIOS && this.isLandscape() && this.getDocumentHeight() - 20 === this.getInnerHeight()) { + if ( + this.isIOS && + this.isLandscape() && + this.getDocumentHeight() - 20 === this.getInnerHeight() + ) { // iOS 7 has a 20px bug in landscape mode this.documentHeight = this.getInnerHeight(); } - } getViewportWidth() { diff --git a/src/utils/ScreenshotStrategyManager.js b/src/utils/ScreenshotStrategyManager.js old mode 100644 new mode 100755 index 9288845..c17f7a3 --- a/src/utils/ScreenshotStrategyManager.js +++ b/src/utils/ScreenshotStrategyManager.js @@ -10,30 +10,31 @@ const regexPhantomjs = /phantomjs/i; const log = debug('wdio-screenshot:ScreenshotStrategyManager'); function matchBrowserName(browser, regex) { - return browser.desiredCapabilities && browser.desiredCapabilities.browserName && regex.test(browser.desiredCapabilities.browserName); + return ( + browser.desiredCapabilities && + browser.desiredCapabilities.browserName && + regex.test(browser.desiredCapabilities.browserName) + ); } function isPhantomjs(browser) { return matchBrowserName(browser, regexPhantomjs); } - export default class ScreenshotStrategyManager { - static getStrategy(browser, screenDimensions) { if (isPhantomjs(browser)) { - log('use full page strategy') + log('use full page strategy'); return new FullpageScreenshotStrategy(screenDimensions); } - + const { isIOS } = browser; if (isIOS) { - log('use iOS Trim and Merge viewport strategy') + log('use iOS Trim and Merge viewport strategy'); return new TrimAndMergeViewportStrategy(screenDimensions); } - log('use merge viewport strategy') + log('use merge viewport strategy'); return new MergeViewportStrategy(screenDimensions); } - } diff --git a/src/utils/generateUUID.js b/src/utils/generateUUID.js old mode 100644 new mode 100755 diff --git a/src/utils/getBase64ImageSize.js b/src/utils/getBase64ImageSize.js old mode 100644 new mode 100755 diff --git a/src/utils/groupBoundingRect.js b/src/utils/groupBoundingRect.js old mode 100644 new mode 100755 index df826d2..1e400d3 --- a/src/utils/groupBoundingRect.js +++ b/src/utils/groupBoundingRect.js @@ -1,20 +1,30 @@ - - export default function groupBoundingRect(boundingRects) { - return boundingRects.reduce((groupedBoundingRect, boundingRect ) => { - if (typeof groupedBoundingRect.top === 'undefined' || groupedBoundingRect.top > boundingRect.top) { + return boundingRects.reduce((groupedBoundingRect, boundingRect) => { + if ( + typeof groupedBoundingRect.top === 'undefined' || + groupedBoundingRect.top > boundingRect.top + ) { groupedBoundingRect.top = boundingRect.top; } - if (typeof groupedBoundingRect.right === 'undefined' || groupedBoundingRect.right < boundingRect.right) { + if ( + typeof groupedBoundingRect.right === 'undefined' || + groupedBoundingRect.right < boundingRect.right + ) { groupedBoundingRect.right = boundingRect.right; } - if (typeof groupedBoundingRect.bottom === 'undefined' || groupedBoundingRect.bottom < boundingRect.bottom) { + if ( + typeof groupedBoundingRect.bottom === 'undefined' || + groupedBoundingRect.bottom < boundingRect.bottom + ) { groupedBoundingRect.bottom = boundingRect.bottom; } - if (typeof groupedBoundingRect.left === 'undefined' || groupedBoundingRect.left > boundingRect.left) { + if ( + typeof groupedBoundingRect.left === 'undefined' || + groupedBoundingRect.left > boundingRect.left + ) { groupedBoundingRect.left = boundingRect.left; } diff --git a/src/utils/image/gm.js b/src/utils/image/gm.js old mode 100644 new mode 100755 index 4ee32b9..ba486c6 --- a/src/utils/image/gm.js +++ b/src/utils/image/gm.js @@ -7,7 +7,6 @@ import CropDimension from '../CropDimension'; const tmpDir = path.join(__dirname, '../../../.tmp'); - /** * Crops an image * @param {string} base64Screenshot image to crop @@ -15,27 +14,31 @@ const tmpDir = path.join(__dirname, '../../../.tmp'); * @return {string} cropped image */ export async function cropImage(base64Screenshot, cropDimensions) { - - if (!(cropDimensions instanceof CropDimension )) { + if (!(cropDimensions instanceof CropDimension)) { throw new Error('Please provide a valid instance of CropDimension!'); } - const image = gm(new Buffer(base64Screenshot, 'base64')) + const image = gm(new Buffer(base64Screenshot, 'base64')); if (cropDimensions.getRotation() !== 0) { image.rotate('white', cropDimensions.getRotation()); } image.gravity(cropDimensions.getGravity()); - image.crop(cropDimensions.getWidth(), cropDimensions.getHeight(), cropDimensions.getX(), cropDimensions.getY()); + image.crop( + cropDimensions.getWidth(), + cropDimensions.getHeight(), + cropDimensions.getX(), + cropDimensions.getY(), + ); return new Promise((resolve, reject) => { - image.toBuffer('PNG',function (err, buffer) { + image.toBuffer('PNG', (err, buffer) => { if (err) { return reject(err); } return resolve(buffer.toString('base64')); - }) + }); }); } @@ -54,23 +57,21 @@ export async function scaleImage(base64Screenshot, scaleFactor) { image.resize(percent, percent, '%'); return new Promise((resolve, reject) => { - image.toBuffer('PNG',function (err, buffer) { + image.toBuffer('PNG', (err, buffer) => { if (err) { return reject(err); } return resolve(buffer.toString('base64')); - }) + }); }); } - /** * Merges mulidimensional array of images to a single image: * @param {string[][]} images array of images * @return {string} screenshot */ export async function mergeImages(images) { - const uuid = generateUUID(); const dir = path.join(tmpDir, uuid); @@ -78,54 +79,51 @@ export async function mergeImages(images) { await fsExtra.ensureDir(dir); // merge all horizintal screens - const rowImagesPromises = images.map(((colImages, key) => { + const rowImagesPromises = images.map((colImages, key) => { const firstImage = colImages.shift(); const rowImage = gm(firstImage); if (colImages.length) { colImages.push(true); - rowImage.append.apply(rowImage, colImages); + rowImage.append(...colImages); } return new Promise((resolve, reject) => { const file = path.join(dir, `${key}.png`); - rowImage.write(file, function (err) { + rowImage.write(file, err => { if (err) { return reject(err); } return resolve(file); }); }); - })); + }); // merge all vertical screens - const base64Screenshot = await Promise - .all(rowImagesPromises) - .then((rowImages) => { - const firstImage = rowImages.shift(); - const mergedImage = gm(firstImage); - - if (rowImages.length) { - mergedImage.append.apply(mergedImage, rowImages); - } - - return new Promise((resolve, reject) => { - mergedImage.toBuffer('PNG',function (err, buffer) { - if (err) { - return reject(err); - } - return resolve(buffer.toString('base64')); - }); + const base64Screenshot = await Promise.all(rowImagesPromises).then(rowImages => { + const firstImage = rowImages.shift(); + const mergedImage = gm(firstImage); + + if (rowImages.length) { + mergedImage.append(...rowImages); + } + + return new Promise((resolve, reject) => { + mergedImage.toBuffer('PNG', (err, buffer) => { + if (err) { + return reject(err); + } + return resolve(buffer.toString('base64')); }); }); + }); await fsExtra.remove(dir); return base64Screenshot; - } catch (e) { try { await fsExtra.remove(dir); - } catch(e) {} + } catch (e) {} throw e; } diff --git a/src/utils/image/index.js b/src/utils/image/index.js old mode 100644 new mode 100755 index 40dc006..15e4242 --- a/src/utils/image/index.js +++ b/src/utils/image/index.js @@ -2,16 +2,16 @@ import * as jimp from './jimp'; import * as gm from './gm'; import which from 'which'; import debug from 'debug'; + const log = debug('wdio-screenshot:image'); let gmInstalled = false; try { gmInstalled = !!which.sync('gm'); -} catch(e) {} +} catch (e) {} log(`Use image processing library: ${gmInstalled ? 'GraphicsMagick' : 'Jimp'}`); - const { cropImage, mergeImages, scaleImage } = gmInstalled ? gm : jimp; export { cropImage, scaleImage, mergeImages }; diff --git a/src/utils/image/jimp.js b/src/utils/image/jimp.js old mode 100644 new mode 100755 index e072683..37e38de --- a/src/utils/image/jimp.js +++ b/src/utils/image/jimp.js @@ -8,21 +8,19 @@ import CropDimension from '../CropDimension'; * @return {string} cropped image */ export async function cropImage(base64Screenshot, cropDimensions) { - - if (!(cropDimensions instanceof CropDimension )) { + if (!(cropDimensions instanceof CropDimension)) { throw new Error('Please provide a valid instance of CropDimension!'); } const image = await Jimp.read(new Buffer(base64Screenshot, 'base64')); - if (cropDimensions.getRotation() !== 0) { image.rotate(cropDimensions.getRotation()); } const { height } = image.bitmap; - let x = cropDimensions.getX(); + const x = cropDimensions.getX(); let y = cropDimensions.getY(); if (cropDimensions.getGravity() === 'SouthWest') { @@ -34,12 +32,12 @@ export async function cropImage(base64Screenshot, cropDimensions) { image.crop(x, y, cropDimensions.getWidth(), cropDimensions.getHeight()); return new Promise((resolve, reject) => { - image.getBuffer(Jimp.MIME_PNG,function (err, buffer) { + image.getBuffer(Jimp.MIME_PNG, (err, buffer) => { if (err) { return reject(err); } return resolve(buffer.toString('base64')); - }) + }); }); } @@ -50,37 +48,34 @@ export async function cropImage(base64Screenshot, cropDimensions) { * @returns {string} screenshot */ export async function scaleImage(base64Screenshot, scaleFactor) { - const image = await Jimp.read(new Buffer(base64Screenshot, 'base64')); image.scale(scaleFactor); return new Promise((resolve, reject) => { - image.getBuffer(Jimp.MIME_PNG,function (err, buffer) { + image.getBuffer(Jimp.MIME_PNG, (err, buffer) => { if (err) { return reject(err); } return resolve(buffer.toString('base64')); - }) + }); }); } - /** * Merges mulidimensional array of images to a single image: * @param {string[][]} images array of images * @return {string} screenshot */ export async function mergeImages(images) { - let imageWidth = 0; let imageHeight = 0; // merge horizontal - const rowImagePromises = images.map(async function(row) { + const rowImagePromises = images.map(async row => { let width = 0; let height = 0; - const colImagesPromises = row.map(async function(colImage) { + const colImagesPromises = row.map(async colImage => { const image = await Jimp.read(colImage); width += image.bitmap.width; height = image.bitmap.height; @@ -94,7 +89,7 @@ export async function mergeImages(images) { let x = 0; for (const colImage of colImages) { image.blit(colImage, x, 0); - x += colImage.bitmap.width + x += colImage.bitmap.width; } imageWidth = image.bitmap.width; @@ -116,12 +111,12 @@ export async function mergeImages(images) { // finally get screenshot const base64Screenshot = await new Promise((resolve, reject) => { - image.getBuffer(Jimp.MIME_PNG,function (err, buffer) { + image.getBuffer(Jimp.MIME_PNG, (err, buffer) => { if (err) { return reject(err); } return resolve(buffer.toString('base64')); - }) + }); }); return base64Screenshot; } diff --git a/src/utils/normalizeScreenshot.js b/src/utils/normalizeScreenshot.js old mode 100644 new mode 100755 index cc9727d..540ce26 --- a/src/utils/normalizeScreenshot.js +++ b/src/utils/normalizeScreenshot.js @@ -3,19 +3,26 @@ import getBase64ImageSize from './getBase64ImageSize'; import { cropImage, scaleImage } from './image'; async function normalizeRetinaScreenshot(browser, screenDimensions, base64Screenshot) { - // check if image dimensions are different to viewport as browsers like firefox scales images automatically down - const size = getBase64ImageSize(base64Screenshot); - const imageSizeMax = Math.max(size.width, size.height); - const imageSizeMin = Math.min(size.width, size.height); - const viewportSizeMax = screenDimensions.applyScaleFactor(Math.max(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); - const viewportSizeMin = screenDimensions.applyScaleFactor(Math.min(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); - const isImageScaled = imageSizeMax !== viewportSizeMax && imageSizeMin !== viewportSizeMin; + // check if image dimensions are different to viewport as browsers like firefox scales images automatically down + const size = getBase64ImageSize(base64Screenshot); + const imageSizeMax = Math.max(size.width, size.height); + const imageSizeMin = Math.min(size.width, size.height); + const viewportSizeMax = screenDimensions.applyScaleFactor( + Math.max(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight()), + ); + const viewportSizeMin = screenDimensions.applyScaleFactor( + Math.min(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight()), + ); + const isImageScaled = imageSizeMax !== viewportSizeMax && imageSizeMin !== viewportSizeMin; - if (isImageScaled) { - const normalizedScreenshot = await scaleImage(base64Screenshot, 1 / screenDimensions.getPixelRatio()); - return normalizedScreenshot; - } - return base64Screenshot; + if (isImageScaled) { + const normalizedScreenshot = await scaleImage( + base64Screenshot, + 1 / screenDimensions.getPixelRatio(), + ); + return normalizedScreenshot; + } + return base64Screenshot; } async function normalizeIOSScreenshot(browser, screenDimensions, base64Screenshot) { @@ -26,7 +33,8 @@ async function normalizeIOSScreenshot(browser, screenDimensions, base64Screensho const viewportWidth = screenDimensions.applyScaleFactor(screenDimensions.getViewportWidth()); // all iPad's have 1024.. - const isIpad = screenDimensions.getScreenHeight() === 1024 || screenDimensions.getScreenWidth() === 1024; + const isIpad = + screenDimensions.getScreenHeight() === 1024 || screenDimensions.getScreenWidth() === 1024; const isIphone = !isIpad; // detect if status bar + navigation bar is shown @@ -50,7 +58,14 @@ async function normalizeIOSScreenshot(browser, screenDimensions, base64Screensho if (barsHeight > 0 || rotation > 0) { // crop only when necessary - const cropDimensions = new CropDimension(viewportWidth, viewportHeight, 0, barsHeight, true, rotation); + const cropDimensions = new CropDimension( + viewportWidth, + viewportHeight, + 0, + barsHeight, + true, + rotation, + ); const croppedBase64Screenshot = await cropImage(base64Screenshot, cropDimensions); return croppedBase64Screenshot; } @@ -58,18 +73,25 @@ async function normalizeIOSScreenshot(browser, screenDimensions, base64Screensho return base64Screenshot; } - export default async function normalizeSreenshot(browser, screenDimensions, base64Screenshot) { let normalizedScreenshot = base64Screenshot; // check if we could have a retina image if (screenDimensions.getPixelRatio() > 1) { - normalizedScreenshot = await normalizeRetinaScreenshot(browser, screenDimensions, normalizedScreenshot); + normalizedScreenshot = await normalizeRetinaScreenshot( + browser, + screenDimensions, + normalizedScreenshot, + ); } // check if we have to crop navigation- & toolbar for iOS if (browser.isMobile && browser.isIOS) { - normalizedScreenshot = await normalizeIOSScreenshot(browser, screenDimensions, normalizedScreenshot); + normalizedScreenshot = await normalizeIOSScreenshot( + browser, + screenDimensions, + normalizedScreenshot, + ); } return normalizedScreenshot; } diff --git a/src/utils/saveBase64Image.js b/src/utils/saveBase64Image.js old mode 100644 new mode 100755 diff --git a/src/utils/strategies/BaseStrategy.js b/src/utils/strategies/BaseStrategy.js old mode 100644 new mode 100755 index 45cd03a..c0fe9b5 --- a/src/utils/strategies/BaseStrategy.js +++ b/src/utils/strategies/BaseStrategy.js @@ -1,7 +1,6 @@ import CropDimension from '../CropDimension'; export default class BaseStrategy { - constructor(screenDimensions) { this.screenDimensions = screenDimensions; @@ -10,7 +9,12 @@ export default class BaseStrategy { y: 0, }; - this.setScrollArea(0, 0, this.screenDimensions.getDocumentWidth(), this.screenDimensions.getDocumentHeight()); + this.setScrollArea( + 0, + 0, + this.screenDimensions.getDocumentWidth(), + this.screenDimensions.getDocumentHeight(), + ); } setScrollArea(startX, startY, endX, endY) { @@ -69,5 +73,4 @@ export default class BaseStrategy { const adjustedHeight = this.screenDimensions.applyScaleFactor(height); return new CropDimension(adjustedWidth, adjustedHeight, x, y, top, rotation); } - } diff --git a/src/utils/strategies/FullpageScreenshotStrategy.js b/src/utils/strategies/FullpageScreenshotStrategy.js old mode 100644 new mode 100755 index f13be89..3603e36 --- a/src/utils/strategies/FullpageScreenshotStrategy.js +++ b/src/utils/strategies/FullpageScreenshotStrategy.js @@ -1,7 +1,6 @@ import BaseStrategy from './BaseStrategy'; export default class FullpageScreenshotStrategy extends BaseStrategy { - hasNextHorizontalScrollPosition() { return false; } @@ -27,6 +26,4 @@ export default class FullpageScreenshotStrategy extends BaseStrategy { return this.createCropDimensions(width, height, 0, 0, true, 0); } - - } diff --git a/src/utils/strategies/MergeScreenshotStrategy.js b/src/utils/strategies/MergeScreenshotStrategy.js old mode 100644 new mode 100755 index 533a6c0..499fc57 --- a/src/utils/strategies/MergeScreenshotStrategy.js +++ b/src/utils/strategies/MergeScreenshotStrategy.js @@ -1,15 +1,22 @@ import BaseStrategy from './BaseStrategy'; export default class MergeScreenshotStrategy extends BaseStrategy { - hasNextHorizontalScrollPosition() { const width = this.area.endX - this.area.startX; - return width > this.index.x * this.screenDimensions.getViewportWidth() + this.screenDimensions.getViewportWidth(); + return ( + width > + this.index.x * this.screenDimensions.getViewportWidth() + + this.screenDimensions.getViewportWidth() + ); } hasNextVerticalScrollPosition() { const height = this.area.endY - this.area.startY; - return height > this.index.y * this.screenDimensions.getViewportHeight() + this.screenDimensions.getViewportHeight(); + return ( + height > + this.index.y * this.screenDimensions.getViewportHeight() + + this.screenDimensions.getViewportHeight() + ); } getScrollPosition() { @@ -17,8 +24,8 @@ export default class MergeScreenshotStrategy extends BaseStrategy { const viewportHeight = this.screenDimensions.getViewportHeight(); return { - x: this.area.startX + (this.index.x * viewportWidth), - y: this.area.startY + (this.index.y * viewportHeight), + x: this.area.startX + this.index.x * viewportWidth, + y: this.area.startY + this.index.y * viewportHeight, indexX: this.index.x, indexY: this.index.y, }; @@ -40,6 +47,4 @@ export default class MergeScreenshotStrategy extends BaseStrategy { return this.createCropDimensions(width, height, 0, 0, true, 0); } - - } diff --git a/src/utils/strategies/TrimAndMergeScreenshotStrategy.js b/src/utils/strategies/TrimAndMergeScreenshotStrategy.js old mode 100644 new mode 100755 index f605b00..fc0a5df --- a/src/utils/strategies/TrimAndMergeScreenshotStrategy.js +++ b/src/utils/strategies/TrimAndMergeScreenshotStrategy.js @@ -7,19 +7,26 @@ const NAV_SHADOW_CONST_COMBINED = NAV_SHADOW_CONST * 2; exports.consts = { NAV_SHADOW_CONST, - NAV_SHADOW_CONST_COMBINED + NAV_SHADOW_CONST_COMBINED, }; export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { - hasNextHorizontalScrollPosition() { const width = this.area.endX - this.area.startX; - return width > this.index.x * this.screenDimensions.getViewportWidth() + this.screenDimensions.getViewportWidth(); + return ( + width > + this.index.x * this.screenDimensions.getViewportWidth() + + this.screenDimensions.getViewportWidth() + ); } hasNextVerticalScrollPosition() { const height = this.area.endY - this.area.startY; - return height > this.index.y * this.screenDimensions.getViewportHeight() + this.screenDimensions.getViewportHeight(); + return ( + height > + this.index.y * this.screenDimensions.getViewportHeight() + + this.screenDimensions.getViewportHeight() + ); } getScrollPosition() { @@ -28,11 +35,10 @@ export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { if (this.index.y === 0 && !this.hasNextVerticalScrollPosition()) { viewportHeight = this.screenDimensions.getViewportHeight(); } - return { - x: this.area.startX + (this.index.x * viewportWidth), - y: this.area.startY + (this.index.y * viewportHeight), + x: this.area.startX + this.index.x * viewportWidth, + y: this.area.startY + this.index.y * viewportHeight, indexX: this.index.x, indexY: this.index.y, }; @@ -49,10 +55,10 @@ export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { const wantedWidth = endX - startX - x * viewportWidth; const width = wantedWidth > viewportWidth ? viewportWidth : wantedWidth; - const viewPortHeightMinusNavs = (viewportHeight - NAV_SHADOW_CONST_COMBINED); + const viewPortHeightMinusNavs = viewportHeight - NAV_SHADOW_CONST_COMBINED; const wantedHeight = endY - startY - y * viewPortHeightMinusNavs; const height = wantedHeight > viewPortHeightMinusNavs ? viewportHeight : wantedHeight; - + let finalHeight, topTrim; if (y === 0 && !this.hasNextVerticalScrollPosition()) { // First AND Last @@ -75,8 +81,7 @@ export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { topTrim = NAV_SHADOW_CONST; finalHeight = height - NAV_SHADOW_CONST_COMBINED; } - + return this.createCropDimensions(width, finalHeight, 0, topTrim, true, 0); } - } From 9dae59ae394088af655958d9e7cac94c70eb055a Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 11:34:53 +0100 Subject: [PATCH 02/12] Fix styling --- src/commands/saveDocumentScreenshot.js | 2 ++ src/commands/saveElementScreenshot.js | 12 +++---- src/commands/saveViewportScreenshot.js | 1 + src/modules/afterScreenshot.js | 8 +++-- src/modules/beforeScreenshot.js | 10 +++--- src/modules/makeAreaScreenshot.js | 36 +++++-------------- src/modules/makeDocumentScreenshot.js | 8 +---- src/modules/makeElementScreenshot.js | 11 ++---- src/modules/makeViewportScreenshot.js | 8 +---- src/scripts/getBoundingRects.js | 3 +- src/scripts/getScreenDimensions.js | 9 +++-- src/scripts/getScrollPosition.js | 20 +++++++---- src/scripts/hideElements.js | 1 - src/scripts/modifyElements.js | 19 ---------- src/scripts/pageHeight.js | 1 - src/scripts/removeElements.js | 12 +++++++ src/scripts/scroll.js | 1 - src/scripts/scrollbars.js | 1 - src/scripts/triggerResize.js | 1 - src/scripts/virtualScroll.js | 1 - src/utils/CropDimension.js | 1 + src/utils/ScreenDimension.js | 21 +++-------- src/utils/ScreenshotStrategyManager.js | 13 +++---- src/utils/groupBoundingRect.js | 20 +++-------- src/utils/image/gm.js | 11 +++--- src/utils/image/jimp.js | 3 +- src/utils/normalizeScreenshot.js | 29 ++++----------- src/utils/strategies/BaseStrategy.js | 8 ++--- .../strategies/FullpageScreenshotStrategy.js | 1 + .../strategies/MergeScreenshotStrategy.js | 13 ++++--- .../TrimAndMergeScreenshotStrategy.js | 23 +++++------- 31 files changed, 107 insertions(+), 201 deletions(-) delete mode 100755 src/scripts/modifyElements.js create mode 100644 src/scripts/removeElements.js diff --git a/src/commands/saveDocumentScreenshot.js b/src/commands/saveDocumentScreenshot.js index a19079c..f8f6a32 100755 --- a/src/commands/saveDocumentScreenshot.js +++ b/src/commands/saveDocumentScreenshot.js @@ -10,6 +10,7 @@ import saveBase64Image from '../utils/saveBase64Image'; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, options) { + if (_.isPlainObject(fileName) && _.isUndefined(options)) { options = fileName; fileName = undefined; @@ -17,6 +18,7 @@ export default async function async(fileName, options) { // make screenshot of area const base64Image = await makeDocumentScreenshot(this, options); + if (typeof fileName !== 'undefined') { // store base64 image as real png await saveBase64Image(fileName, base64Image); diff --git a/src/commands/saveElementScreenshot.js b/src/commands/saveElementScreenshot.js index 17e988e..1062b1c 100755 --- a/src/commands/saveElementScreenshot.js +++ b/src/commands/saveElementScreenshot.js @@ -1,6 +1,6 @@ -import _ from 'lodash'; -import makeElementScreenshot from '../modules/makeElementScreenshot'; -import saveBase64Image from '../utils/saveBase64Image'; +import _ from "lodash"; +import makeElementScreenshot from "../modules/makeElementScreenshot"; +import saveBase64Image from "../utils/saveBase64Image"; /** * @alias browser.saveElementScreenshot @@ -11,11 +11,7 @@ import saveBase64Image from '../utils/saveBase64Image'; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, elementSelector, options) { - if ( - (_.isString(fileName) || _.isArray(fileName)) && - _.isPlainObject(elementSelector) && - _.isUndefined(options) - ) { + if ((_.isString(fileName) || _.isArray(fileName)) && _.isPlainObject(elementSelector) && _.isUndefined(options)) { options = elementSelector; elementSelector = fileName; fileName = undefined; diff --git a/src/commands/saveViewportScreenshot.js b/src/commands/saveViewportScreenshot.js index 189ae0a..6dce3d9 100755 --- a/src/commands/saveViewportScreenshot.js +++ b/src/commands/saveViewportScreenshot.js @@ -10,6 +10,7 @@ import saveBase64Image from '../utils/saveBase64Image'; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, options) { + if (_.isPlainObject(fileName) && _.isUndefined(options)) { options = fileName; fileName = undefined; diff --git a/src/modules/afterScreenshot.js b/src/modules/afterScreenshot.js index a42c1af..239720c 100755 --- a/src/modules/afterScreenshot.js +++ b/src/modules/afterScreenshot.js @@ -1,7 +1,7 @@ import debug from "debug"; import scrollbars from "../scripts/scrollbars"; -import modifyElements from "../scripts/modifyElements"; +import removeElements from "../scripts/removeElements"; import hideElements from "../scripts/hideElements"; const log = debug('wdio-screenshot:afterScreenshot'); @@ -21,7 +21,11 @@ export default async function afterScreenshot(browser, options) { // add elements again if (Array.isArray(options.remove) && options.remove.length) { log('add the following elements again: %s', options.remove.join(', ')); - await browser.selectorExecute(options.remove, modifyElements, 'display', ''); + + for (let i = 0; i < options.hide.length; i++) { + let elements = await browser.$$(options.remove[i]); + await browser.execute(removeElements, elements, false); + } } // show scrollbars diff --git a/src/modules/beforeScreenshot.js b/src/modules/beforeScreenshot.js index 29ad997..b321b0d 100755 --- a/src/modules/beforeScreenshot.js +++ b/src/modules/beforeScreenshot.js @@ -2,7 +2,7 @@ import debug from "debug"; import scroll from "../scripts/scroll"; import scrollbars from "../scripts/scrollbars"; -import modifyElements from "../scripts/modifyElements"; +import removeElements from "../scripts/removeElements"; import triggerResize from "../scripts/triggerResize"; import hideElements from "../scripts/hideElements"; @@ -24,15 +24,17 @@ export default async function beforeScreenshot(browser, options) { let elements = await browser.$$(options.hide[i]); await browser.execute(hideElements, elements, true); } - - await browser.pause(15000); } // TODO // remove elements if (Array.isArray(options.remove) && options.remove.length) { log('remove the following elements: %s', options.remove.join(', ')); - await selectorExecute(options.remove, modifyElements, 'display', 'none'); + + for (let i = 0; i < options.hide.length; i++) { + let elements = await browser.$$(options.remove[i]); + await browser.execute(removeElements, elements, true); + } } // scroll back to start diff --git a/src/modules/makeAreaScreenshot.js b/src/modules/makeAreaScreenshot.js index 278790b..92a2bb2 100755 --- a/src/modules/makeAreaScreenshot.js +++ b/src/modules/makeAreaScreenshot.js @@ -15,25 +15,9 @@ import normalizeScreenshot from '../utils/normalizeScreenshot'; const log = debug('wdio-screenshot:makeAreaScreenshot'); const tmpDir = path.join(__dirname, '..', '..', '.tmp'); -async function storeScreenshot( - browser, - screenDimensions, - cropDimensions, - base64Screenshot, - filePath, -) { - const normalizedBase64Screenshot = await normalizeScreenshot( - browser, - screenDimensions, - base64Screenshot, - ); - log( - 'crop screenshot with width: %s, height: %s, offsetX: %s, offsetY: %s', - cropDimensions.getWidth(), - cropDimensions.getHeight(), - cropDimensions.getX(), - cropDimensions.getY(), - ); +async function storeScreenshot(browser, screenDimensions, cropDimensions, base64Screenshot, filePath) { + const normalizedBase64Screenshot = await normalizeScreenshot(browser, screenDimensions, base64Screenshot); + log('crop screenshot with width: %s, height: %s, offsetX: %s, offsetY: %s', cropDimensions.getWidth(), cropDimensions.getHeight(), cropDimensions.getX(), cropDimensions.getY()); const croppedBase64Screenshot = await cropImage(normalizedBase64Screenshot, cropDimensions); @@ -41,7 +25,7 @@ async function storeScreenshot( } export default async function makeAreaScreenshot(browser, startX, startY, endX, endY) { - log('requested a screenshot for the following area: %j', { startX, startY, endX, endY }); + log('requested a screenshot for the following area: %j', { startX, startY, endX, endY}); const screenDimensions = await browser.execute(getScreenDimensions); log('detected screenDimensions %j', screenDimensions); @@ -73,14 +57,11 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, log('take screenshot'); - const cropDimensions = screenshotStrategy.getCropDimensions(); const filePath = path.join(dir, `${indexY}-${indexX}.png`); const base64Screenshot = await browser.saveScreenshot(filePath); - screenshotPromises.push( - storeScreenshot(browser, screenDimension, cropDimensions, base64Screenshot, filePath), - ); + screenshotPromises.push(storeScreenshot(browser, screenDimension, cropDimensions, base64Screenshot, filePath)); if (!Array.isArray(cropImages[indexY])) { cropImages[indexY] = []; @@ -90,10 +71,10 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, loop = screenshotStrategy.hasNextScrollPosition(); screenshotStrategy.moveToNextScrollPosition(); - } while (loop); + } while (loop) const [mergedBase64Screenshot] = await Promise.all([ - Promise.resolve().then(async () => { + Promise.resolve().then(async() => { await Promise.all(screenshotPromises); log('merge images togehter'); const mergedBase64Screenshot = await mergeImages(cropImages); @@ -107,9 +88,10 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, log('revert scroll to x: %s, y: %s', 0, 0); await browser.execute(virtualScroll, 0, 0, true); - }), + }) ]); return mergedBase64Screenshot; + } catch (e) { try { await fsExtra.remove(dir); diff --git a/src/modules/makeDocumentScreenshot.js b/src/modules/makeDocumentScreenshot.js index 73ee644..70d8520 100755 --- a/src/modules/makeDocumentScreenshot.js +++ b/src/modules/makeDocumentScreenshot.js @@ -21,13 +21,7 @@ export default async function makeDocumentScreenshot(browser, options = {}) { const screenDimension = new ScreenDimension(screenDimensions, browser); // make screenshot of area - const base64Image = await makeAreaScreenshot( - browser, - 0, - 0, - screenDimension.getDocumentWidth(), - screenDimension.getDocumentHeight(), - ); + const base64Image = await makeAreaScreenshot(browser, 0, 0, screenDimension.getDocumentWidth(), screenDimension.getDocumentHeight()); // show scrollbars, show & add elements await afterScreenshot(browser, options); diff --git a/src/modules/makeElementScreenshot.js b/src/modules/makeElementScreenshot.js index c36739d..8563f54 100755 --- a/src/modules/makeElementScreenshot.js +++ b/src/modules/makeElementScreenshot.js @@ -9,6 +9,7 @@ import getBoundingRects from '../scripts/getBoundingRects'; const log = debug('wdio-screenshot:makeElementScreenshot'); + export default async function makeElementScreenshot(browser, elementSelector, options = {}) { log('start element screenshot'); @@ -16,22 +17,14 @@ export default async function makeElementScreenshot(browser, elementSelector, op await beforeScreenshot(browser, options); // get bounding rect of elements - // const boundingRects = await browser.selectorExecute(elementSelector, getBoundingRects); const elements = await browser.$$(elementSelector); - const boundingRects = await browser.execute(getBoundingRects, elements); const boundingRect = groupBoundingRect(boundingRects); // make screenshot of area - const base64Image = await makeAreaScreenshot( - browser, - boundingRect.left, - boundingRect.top, - boundingRect.right, - boundingRect.bottom, - ); + const base64Image = await makeAreaScreenshot(browser, boundingRect.left, boundingRect.top, boundingRect.right, boundingRect.bottom); // show scrollbars, show & add elements await afterScreenshot(browser, options); diff --git a/src/modules/makeViewportScreenshot.js b/src/modules/makeViewportScreenshot.js index faab9dd..a4b52c9 100755 --- a/src/modules/makeViewportScreenshot.js +++ b/src/modules/makeViewportScreenshot.js @@ -26,13 +26,7 @@ export default async function makeViewportScreenshot(browser, options = {}) { const screenDimension = new ScreenDimension(screenDimensions, browser); // make screenshot of area - const base64Image = await makeAreaScreenshot( - browser, - startX, - startY, - screenDimension.getViewportWidth(), - screenDimension.getViewportHeight(), - ); + const base64Image = await makeAreaScreenshot(browser, startX, startY, screenDimension.getViewportWidth(), screenDimension.getViewportHeight()); // show scrollbars, show & add elements await afterScreenshot(browser, options); diff --git a/src/scripts/getBoundingRects.js b/src/scripts/getBoundingRects.js index b1b9d3c..779a101 100755 --- a/src/scripts/getBoundingRects.js +++ b/src/scripts/getBoundingRects.js @@ -1,6 +1,5 @@ - export default function getBoundingRect(elems) { - return elems.map(elem => { + return elems.map((elem) => { const boundingRect = elem.getBoundingClientRect(); return { top: boundingRect.top, diff --git a/src/scripts/getScreenDimensions.js b/src/scripts/getScreenDimensions.js index 4efa99c..f67f87c 100755 --- a/src/scripts/getScreenDimensions.js +++ b/src/scripts/getScreenDimensions.js @@ -1,4 +1,3 @@ - export default function getScreenDimension() { const body = document.body; const html = document.documentElement; @@ -10,18 +9,18 @@ export default function getScreenDimension() { pixelRatio: typeof window.devicePixelRatio === 'undefined' ? 1 : window.devicePixelRatio, orientation: typeof window.orientation === 'undefined' ? 0 : Math.abs(window.orientation), screenWidth: window.screen.width, - screenHeight: window.screen.height, + screenHeight: window.screen.height }, body: { scrollHeight: body.scrollHeight, - offsetHeight: body.offsetHeight, + offsetHeight: body.offsetHeight }, html: { clientWidth: html.clientWidth, scrollWidth: html.scrollWidth, clientHeight: html.clientHeight, scrollHeight: html.scrollHeight, - offsetHeight: html.offsetHeight, - }, + offsetHeight: html.offsetHeight + } }; } diff --git a/src/scripts/getScrollPosition.js b/src/scripts/getScrollPosition.js index 1fa17c1..864ef0f 100755 --- a/src/scripts/getScrollPosition.js +++ b/src/scripts/getScrollPosition.js @@ -1,14 +1,20 @@ - export default function getScrollPosition() { if (typeof window.pageYOffset !== 'undefined') { - return [window.pageXOffset, window.pageYOffset]; + return [ + window.pageXOffset, + window.pageYOffset + ]; } else if ( - typeof document.documentElement.scrollTop !== 'undefined' && - document.documentElement.scrollTop > 0 - ) { - return [document.documentElement.scrollLeft, document.documentElement.scrollTop]; + typeof document.documentElement.scrollTop !== 'undefined' && document.documentElement.scrollTop > 0) { + return [ + document.documentElement.scrollLeft, + document.documentElement.scrollTop + ]; } else if (typeof document.body.scrollTop !== 'undefined') { - return [document.body.scrollLeft, document.body.scrollTop]; + return [ + document.body.scrollLeft, + document.body.scrollTop + ]; } return [0, 0]; } diff --git a/src/scripts/hideElements.js b/src/scripts/hideElements.js index 45cd14f..58fba9c 100644 --- a/src/scripts/hideElements.js +++ b/src/scripts/hideElements.js @@ -1,4 +1,3 @@ - export default function hideElements(elems, flag = true) { if (flag) { diff --git a/src/scripts/modifyElements.js b/src/scripts/modifyElements.js deleted file mode 100755 index 2d016c5..0000000 --- a/src/scripts/modifyElements.js +++ /dev/null @@ -1,19 +0,0 @@ - -export default function modifyElements() { - const args = Array.prototype.slice.call(arguments).filter(n => !!n || n === ''); - const style = args[args.length - 2]; - const value = args[args.length - 1]; - - args.splice(-2); - for (let i = 0; i < args.length; ++i) { - for (let j = 0; j < args[i].length; ++j) { - const element = args[i][j]; - - try { - element.style.setProperty(style, value, 'important'); - } catch (error) { - element.setAttribute('style', `${element.style.cssText + style}:${value}!important;`); - } - } - } -} diff --git a/src/scripts/pageHeight.js b/src/scripts/pageHeight.js index 00aed59..6ae6b8f 100755 --- a/src/scripts/pageHeight.js +++ b/src/scripts/pageHeight.js @@ -1,4 +1,3 @@ - export default function pageHeight(height) { document.body.style.height = height; } diff --git a/src/scripts/removeElements.js b/src/scripts/removeElements.js new file mode 100644 index 0000000..44a1c95 --- /dev/null +++ b/src/scripts/removeElements.js @@ -0,0 +1,12 @@ +export default function hideElements(elems, flag = true) { + + if (flag) { + return elems.forEach(ele => { + ele.style.setProperty('display', 'none', 'important'); + }); + } else { + return elems.forEach(ele => { + ele.style.setProperty('display', ''); + }); + } +} diff --git a/src/scripts/scroll.js b/src/scripts/scroll.js index f2c3f35..f1601bc 100755 --- a/src/scripts/scroll.js +++ b/src/scripts/scroll.js @@ -1,4 +1,3 @@ - export default function scroll(x, y) { window.scrollTo(x, y); } diff --git a/src/scripts/scrollbars.js b/src/scripts/scrollbars.js index 0ed0548..362ccc4 100755 --- a/src/scripts/scrollbars.js +++ b/src/scripts/scrollbars.js @@ -1,4 +1,3 @@ - export default function scrollbars(enabled) { if (enabled) { document.documentElement.style.overflow = ''; diff --git a/src/scripts/triggerResize.js b/src/scripts/triggerResize.js index 3c71ff5..a053cd4 100755 --- a/src/scripts/triggerResize.js +++ b/src/scripts/triggerResize.js @@ -1,4 +1,3 @@ - /** * trigger window.resize to relayout js components */ diff --git a/src/scripts/virtualScroll.js b/src/scripts/virtualScroll.js index 02313ae..015bedf 100755 --- a/src/scripts/virtualScroll.js +++ b/src/scripts/virtualScroll.js @@ -1,4 +1,3 @@ - export default function virtualScroll(x, y, remove) { const w = x === 0 ? 0 : -1 * x; const h = y === 0 ? 0 : -1 * y; diff --git a/src/utils/CropDimension.js b/src/utils/CropDimension.js index b7d46a8..08c1ef2 100755 --- a/src/utils/CropDimension.js +++ b/src/utils/CropDimension.js @@ -31,4 +31,5 @@ export default class CropDimension { getRotation() { return this.rotation; } + } diff --git a/src/utils/ScreenDimension.js b/src/utils/ScreenDimension.js index 8cdc734..3909e7f 100755 --- a/src/utils/ScreenDimension.js +++ b/src/utils/ScreenDimension.js @@ -9,13 +9,7 @@ export default class ScreenDimensions { this.viewportHeight = window.innerHeight || html.clientHeight || 0; this.documentWidth = html.scrollWidth; - this.documentHeight = Math.max( - body.scrollHeight, - body.offsetHeight, - html.clientHeight, - html.scrollHeight, - html.offsetHeight, - ); + this.documentHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); const screenMax = Math.max(window.screenWidth, window.screenHeight); const screenMin = Math.min(window.screenWidth, window.screenHeight); @@ -32,23 +26,16 @@ export default class ScreenDimensions { this.pixelRatio = window.pixelRatio; this.orientation = window.orientation; - if ( - this.isIOS && - this.isLandscape() && - this.getViewportHeight() - 20 === this.getInnerHeight() - ) { + if (this.isIOS && this.isLandscape() && this.getViewportHeight() - 20 === this.getInnerHeight()) { // iOS 7 has a 20px bug in landscape mode this.viewportHeight = this.getInnerHeight(); } - if ( - this.isIOS && - this.isLandscape() && - this.getDocumentHeight() - 20 === this.getInnerHeight() - ) { + if (this.isIOS && this.isLandscape() && this.getDocumentHeight() - 20 === this.getInnerHeight()) { // iOS 7 has a 20px bug in landscape mode this.documentHeight = this.getInnerHeight(); } + } getViewportWidth() { diff --git a/src/utils/ScreenshotStrategyManager.js b/src/utils/ScreenshotStrategyManager.js index c17f7a3..ad18203 100755 --- a/src/utils/ScreenshotStrategyManager.js +++ b/src/utils/ScreenshotStrategyManager.js @@ -10,11 +10,7 @@ const regexPhantomjs = /phantomjs/i; const log = debug('wdio-screenshot:ScreenshotStrategyManager'); function matchBrowserName(browser, regex) { - return ( - browser.desiredCapabilities && - browser.desiredCapabilities.browserName && - regex.test(browser.desiredCapabilities.browserName) - ); + return (browser.desiredCapabilities && browser.desiredCapabilities.browserName && regex.test(browser.desiredCapabilities.browserName)); } function isPhantomjs(browser) { @@ -22,19 +18,20 @@ function isPhantomjs(browser) { } export default class ScreenshotStrategyManager { + static getStrategy(browser, screenDimensions) { if (isPhantomjs(browser)) { - log('use full page strategy'); + log('use full page strategy') return new FullpageScreenshotStrategy(screenDimensions); } const { isIOS } = browser; if (isIOS) { - log('use iOS Trim and Merge viewport strategy'); + log('use iOS Trim and Merge viewport strategy') return new TrimAndMergeViewportStrategy(screenDimensions); } - log('use merge viewport strategy'); + log('use merge viewport strategy') return new MergeViewportStrategy(screenDimensions); } } diff --git a/src/utils/groupBoundingRect.js b/src/utils/groupBoundingRect.js index 1e400d3..5e8e402 100755 --- a/src/utils/groupBoundingRect.js +++ b/src/utils/groupBoundingRect.js @@ -1,30 +1,18 @@ export default function groupBoundingRect(boundingRects) { return boundingRects.reduce((groupedBoundingRect, boundingRect) => { - if ( - typeof groupedBoundingRect.top === 'undefined' || - groupedBoundingRect.top > boundingRect.top - ) { + if (typeof groupedBoundingRect.top === 'undefined' || groupedBoundingRect.top > boundingRect.top) { groupedBoundingRect.top = boundingRect.top; } - if ( - typeof groupedBoundingRect.right === 'undefined' || - groupedBoundingRect.right < boundingRect.right - ) { + if (typeof groupedBoundingRect.right === 'undefined' || groupedBoundingRect.right < boundingRect.right) { groupedBoundingRect.right = boundingRect.right; } - if ( - typeof groupedBoundingRect.bottom === 'undefined' || - groupedBoundingRect.bottom < boundingRect.bottom - ) { + if (typeof groupedBoundingRect.bottom === 'undefined' || groupedBoundingRect.bottom < boundingRect.bottom) { groupedBoundingRect.bottom = boundingRect.bottom; } - if ( - typeof groupedBoundingRect.left === 'undefined' || - groupedBoundingRect.left > boundingRect.left - ) { + if (typeof groupedBoundingRect.left === 'undefined' || groupedBoundingRect.left > boundingRect.left) { groupedBoundingRect.left = boundingRect.left; } diff --git a/src/utils/image/gm.js b/src/utils/image/gm.js index ba486c6..e2959fc 100755 --- a/src/utils/image/gm.js +++ b/src/utils/image/gm.js @@ -7,6 +7,7 @@ import CropDimension from '../CropDimension'; const tmpDir = path.join(__dirname, '../../../.tmp'); + /** * Crops an image * @param {string} base64Screenshot image to crop @@ -14,23 +15,19 @@ const tmpDir = path.join(__dirname, '../../../.tmp'); * @return {string} cropped image */ export async function cropImage(base64Screenshot, cropDimensions) { + if (!(cropDimensions instanceof CropDimension)) { throw new Error('Please provide a valid instance of CropDimension!'); } - const image = gm(new Buffer(base64Screenshot, 'base64')); + const image = gm(new Buffer(base64Screenshot, 'base64')) if (cropDimensions.getRotation() !== 0) { image.rotate('white', cropDimensions.getRotation()); } image.gravity(cropDimensions.getGravity()); - image.crop( - cropDimensions.getWidth(), - cropDimensions.getHeight(), - cropDimensions.getX(), - cropDimensions.getY(), - ); + image.crop(cropDimensions.getWidth(), cropDimensions.getHeight(), cropDimensions.getX(), cropDimensions.getY()); return new Promise((resolve, reject) => { image.toBuffer('PNG', (err, buffer) => { diff --git a/src/utils/image/jimp.js b/src/utils/image/jimp.js index 37e38de..520b7a7 100755 --- a/src/utils/image/jimp.js +++ b/src/utils/image/jimp.js @@ -8,6 +8,7 @@ import CropDimension from '../CropDimension'; * @return {string} cropped image */ export async function cropImage(base64Screenshot, cropDimensions) { + if (!(cropDimensions instanceof CropDimension)) { throw new Error('Please provide a valid instance of CropDimension!'); } @@ -20,7 +21,7 @@ export async function cropImage(base64Screenshot, cropDimensions) { const { height } = image.bitmap; - const x = cropDimensions.getX(); + let x = cropDimensions.getX(); let y = cropDimensions.getY(); if (cropDimensions.getGravity() === 'SouthWest') { diff --git a/src/utils/normalizeScreenshot.js b/src/utils/normalizeScreenshot.js index 540ce26..cc69c7f 100755 --- a/src/utils/normalizeScreenshot.js +++ b/src/utils/normalizeScreenshot.js @@ -7,19 +7,12 @@ async function normalizeRetinaScreenshot(browser, screenDimensions, base64Screen const size = getBase64ImageSize(base64Screenshot); const imageSizeMax = Math.max(size.width, size.height); const imageSizeMin = Math.min(size.width, size.height); - const viewportSizeMax = screenDimensions.applyScaleFactor( - Math.max(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight()), - ); - const viewportSizeMin = screenDimensions.applyScaleFactor( - Math.min(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight()), - ); + const viewportSizeMax = screenDimensions.applyScaleFactor(Math.max(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); + const viewportSizeMin = screenDimensions.applyScaleFactor(Math.min(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); const isImageScaled = imageSizeMax !== viewportSizeMax && imageSizeMin !== viewportSizeMin; if (isImageScaled) { - const normalizedScreenshot = await scaleImage( - base64Screenshot, - 1 / screenDimensions.getPixelRatio(), - ); + const normalizedScreenshot = await scaleImage(base64Screenshot, 1 / screenDimensions.getPixelRatio()); return normalizedScreenshot; } return base64Screenshot; @@ -33,8 +26,7 @@ async function normalizeIOSScreenshot(browser, screenDimensions, base64Screensho const viewportWidth = screenDimensions.applyScaleFactor(screenDimensions.getViewportWidth()); // all iPad's have 1024.. - const isIpad = - screenDimensions.getScreenHeight() === 1024 || screenDimensions.getScreenWidth() === 1024; + const isIpad = screenDimensions.getScreenHeight() === 1024 || screenDimensions.getScreenWidth() === 1024; const isIphone = !isIpad; // detect if status bar + navigation bar is shown @@ -73,25 +65,18 @@ async function normalizeIOSScreenshot(browser, screenDimensions, base64Screensho return base64Screenshot; } + export default async function normalizeSreenshot(browser, screenDimensions, base64Screenshot) { let normalizedScreenshot = base64Screenshot; // check if we could have a retina image if (screenDimensions.getPixelRatio() > 1) { - normalizedScreenshot = await normalizeRetinaScreenshot( - browser, - screenDimensions, - normalizedScreenshot, - ); + normalizedScreenshot = await normalizeRetinaScreenshot(browser, screenDimensions, normalizedScreenshot); } // check if we have to crop navigation- & toolbar for iOS if (browser.isMobile && browser.isIOS) { - normalizedScreenshot = await normalizeIOSScreenshot( - browser, - screenDimensions, - normalizedScreenshot, - ); + normalizedScreenshot = await normalizeIOSScreenshot(browser, screenDimensions, normalizedScreenshot); } return normalizedScreenshot; } diff --git a/src/utils/strategies/BaseStrategy.js b/src/utils/strategies/BaseStrategy.js index c0fe9b5..4a59939 100755 --- a/src/utils/strategies/BaseStrategy.js +++ b/src/utils/strategies/BaseStrategy.js @@ -1,6 +1,7 @@ import CropDimension from '../CropDimension'; export default class BaseStrategy { + constructor(screenDimensions) { this.screenDimensions = screenDimensions; @@ -9,12 +10,7 @@ export default class BaseStrategy { y: 0, }; - this.setScrollArea( - 0, - 0, - this.screenDimensions.getDocumentWidth(), - this.screenDimensions.getDocumentHeight(), - ); + this.setScrollArea(0, 0, this.screenDimensions.getDocumentWidth(), this.screenDimensions.getDocumentHeight()); } setScrollArea(startX, startY, endX, endY) { diff --git a/src/utils/strategies/FullpageScreenshotStrategy.js b/src/utils/strategies/FullpageScreenshotStrategy.js index 3603e36..af1e2f6 100755 --- a/src/utils/strategies/FullpageScreenshotStrategy.js +++ b/src/utils/strategies/FullpageScreenshotStrategy.js @@ -1,6 +1,7 @@ import BaseStrategy from './BaseStrategy'; export default class FullpageScreenshotStrategy extends BaseStrategy { + hasNextHorizontalScrollPosition() { return false; } diff --git a/src/utils/strategies/MergeScreenshotStrategy.js b/src/utils/strategies/MergeScreenshotStrategy.js index 499fc57..b51c889 100755 --- a/src/utils/strategies/MergeScreenshotStrategy.js +++ b/src/utils/strategies/MergeScreenshotStrategy.js @@ -1,6 +1,7 @@ import BaseStrategy from './BaseStrategy'; export default class MergeScreenshotStrategy extends BaseStrategy { + hasNextHorizontalScrollPosition() { const width = this.area.endX - this.area.startX; return ( @@ -12,11 +13,7 @@ export default class MergeScreenshotStrategy extends BaseStrategy { hasNextVerticalScrollPosition() { const height = this.area.endY - this.area.startY; - return ( - height > - this.index.y * this.screenDimensions.getViewportHeight() + - this.screenDimensions.getViewportHeight() - ); + return (height > this.index.y * this.screenDimensions.getViewportHeight() + this.screenDimensions.getViewportHeight()); } getScrollPosition() { @@ -24,8 +21,8 @@ export default class MergeScreenshotStrategy extends BaseStrategy { const viewportHeight = this.screenDimensions.getViewportHeight(); return { - x: this.area.startX + this.index.x * viewportWidth, - y: this.area.startY + this.index.y * viewportHeight, + x: this.area.startX + (this.index.x * viewportWidth), + y: this.area.startY + (this.index.y * viewportHeight), indexX: this.index.x, indexY: this.index.y, }; @@ -47,4 +44,6 @@ export default class MergeScreenshotStrategy extends BaseStrategy { return this.createCropDimensions(width, height, 0, 0, true, 0); } + + } diff --git a/src/utils/strategies/TrimAndMergeScreenshotStrategy.js b/src/utils/strategies/TrimAndMergeScreenshotStrategy.js index fc0a5df..be48df3 100755 --- a/src/utils/strategies/TrimAndMergeScreenshotStrategy.js +++ b/src/utils/strategies/TrimAndMergeScreenshotStrategy.js @@ -7,26 +7,19 @@ const NAV_SHADOW_CONST_COMBINED = NAV_SHADOW_CONST * 2; exports.consts = { NAV_SHADOW_CONST, - NAV_SHADOW_CONST_COMBINED, + NAV_SHADOW_CONST_COMBINED }; export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { + hasNextHorizontalScrollPosition() { const width = this.area.endX - this.area.startX; - return ( - width > - this.index.x * this.screenDimensions.getViewportWidth() + - this.screenDimensions.getViewportWidth() - ); + return width > this.index.x * this.screenDimensions.getViewportWidth() + this.screenDimensions.getViewportWidth(); } hasNextVerticalScrollPosition() { const height = this.area.endY - this.area.startY; - return ( - height > - this.index.y * this.screenDimensions.getViewportHeight() + - this.screenDimensions.getViewportHeight() - ); + return height > this.index.y * this.screenDimensions.getViewportHeight() + this.screenDimensions.getViewportHeight(); } getScrollPosition() { @@ -36,9 +29,10 @@ export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { viewportHeight = this.screenDimensions.getViewportHeight(); } + return { - x: this.area.startX + this.index.x * viewportWidth, - y: this.area.startY + this.index.y * viewportHeight, + x: this.area.startX + (this.index.x * viewportWidth), + y: this.area.startY + (this.index.y * viewportHeight), indexX: this.index.x, indexY: this.index.y, }; @@ -55,7 +49,7 @@ export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { const wantedWidth = endX - startX - x * viewportWidth; const width = wantedWidth > viewportWidth ? viewportWidth : wantedWidth; - const viewPortHeightMinusNavs = viewportHeight - NAV_SHADOW_CONST_COMBINED; + const viewPortHeightMinusNavs = (viewportHeight - NAV_SHADOW_CONST_COMBINED); const wantedHeight = endY - startY - y * viewPortHeightMinusNavs; const height = wantedHeight > viewPortHeightMinusNavs ? viewportHeight : wantedHeight; @@ -84,4 +78,5 @@ export default class TrimAndMergeScreenshotStrategy extends BaseStrategy { return this.createCropDimensions(width, finalHeight, 0, topTrim, true, 0); } + } From 47bfa521e758234dd0b20fabf0429e7ea7b73919 Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 11:59:11 +0100 Subject: [PATCH 03/12] Formating fixing for better PR --- src/commands/saveElementScreenshot.js | 7 +- src/modules/afterScreenshot.js | 8 +- src/modules/beforeScreenshot.js | 74 +++++++++---------- src/modules/makeAreaScreenshot.js | 7 +- src/modules/makeDocumentScreenshot.js | 2 +- src/scripts/getScrollPosition.js | 3 +- src/scripts/scroll.js | 1 + src/scripts/virtualScroll.js | 1 + src/utils/CropDimension.js | 3 + src/utils/ScreenDimension.js | 1 + src/utils/ScreenshotStrategyManager.js | 4 +- src/utils/image/jimp.js | 13 ++-- src/utils/normalizeScreenshot.js | 30 ++++---- src/utils/strategies/BaseStrategy.js | 1 + .../strategies/FullpageScreenshotStrategy.js | 2 + .../strategies/MergeScreenshotStrategy.js | 10 +-- 16 files changed, 89 insertions(+), 78 deletions(-) diff --git a/src/commands/saveElementScreenshot.js b/src/commands/saveElementScreenshot.js index 1062b1c..448a141 100755 --- a/src/commands/saveElementScreenshot.js +++ b/src/commands/saveElementScreenshot.js @@ -1,6 +1,6 @@ -import _ from "lodash"; -import makeElementScreenshot from "../modules/makeElementScreenshot"; -import saveBase64Image from "../utils/saveBase64Image"; +import _ from 'lodash'; +import makeElementScreenshot from '../modules/makeElementScreenshot'; +import saveBase64Image from '../utils/saveBase64Image'; /** * @alias browser.saveElementScreenshot @@ -11,6 +11,7 @@ import saveBase64Image from "../utils/saveBase64Image"; // Note: function name must be async to signalize WebdriverIO that this function returns a promise export default async function async(fileName, elementSelector, options) { + if ((_.isString(fileName) || _.isArray(fileName)) && _.isPlainObject(elementSelector) && _.isUndefined(options)) { options = elementSelector; elementSelector = fileName; diff --git a/src/modules/afterScreenshot.js b/src/modules/afterScreenshot.js index 239720c..bc0f4f1 100755 --- a/src/modules/afterScreenshot.js +++ b/src/modules/afterScreenshot.js @@ -1,8 +1,8 @@ -import debug from "debug"; +import debug from 'debug'; -import scrollbars from "../scripts/scrollbars"; -import removeElements from "../scripts/removeElements"; -import hideElements from "../scripts/hideElements"; +import scrollbars from '../scripts/scrollbars'; +import removeElements from '../scripts/removeElements'; +import hideElements from '../scripts/hideElements'; const log = debug('wdio-screenshot:afterScreenshot'); diff --git a/src/modules/beforeScreenshot.js b/src/modules/beforeScreenshot.js index b321b0d..81faec3 100755 --- a/src/modules/beforeScreenshot.js +++ b/src/modules/beforeScreenshot.js @@ -1,50 +1,50 @@ -import debug from "debug"; +import debug from 'debug'; -import scroll from "../scripts/scroll"; -import scrollbars from "../scripts/scrollbars"; -import removeElements from "../scripts/removeElements"; -import triggerResize from "../scripts/triggerResize"; -import hideElements from "../scripts/hideElements"; +import scroll from '../scripts/scroll'; +import scrollbars from '../scripts/scrollbars'; +import removeElements from '../scripts/removeElements'; +import triggerResize from '../scripts/triggerResize'; +import hideElements from '../scripts/hideElements'; const log = debug('wdio-screenshot:beforeScreenshot'); export default async function beforeScreenshot(browser, options) { - // hide scrollbars - log('hide scrollbars'); - await browser.execute(scrollbars, false); + // hide scrollbars + log('hide scrollbars'); + await browser.execute(scrollbars, false); - log('trigger resize event to allow js components to resize properly'); - await browser.execute(triggerResize); + log('trigger resize event to allow js components to resize properly'); + await browser.execute(triggerResize); - // hide elements - if (Array.isArray(options.hide) && options.hide.length) { - log('hide the following elements: %s', options.hide.join(', ')); + // hide elements + if (Array.isArray(options.hide) && options.hide.length) { + log('hide the following elements: %s', options.hide.join(', ')); - for (let i = 0; i < options.hide.length; i++) { - let elements = await browser.$$(options.hide[i]); - await browser.execute(hideElements, elements, true); - } + for (let i = 0; i < options.hide.length; i++) { + let elements = await browser.$$(options.hide[i]); + await browser.execute(hideElements, elements, true); } + } - // TODO - // remove elements - if (Array.isArray(options.remove) && options.remove.length) { - log('remove the following elements: %s', options.remove.join(', ')); + // TODO + // remove elements + if (Array.isArray(options.remove) && options.remove.length) { + log('remove the following elements: %s', options.remove.join(', ')); - for (let i = 0; i < options.hide.length; i++) { - let elements = await browser.$$(options.remove[i]); - await browser.execute(removeElements, elements, true); - } + for (let i = 0; i < options.hide.length; i++) { + let elements = await browser.$$(options.remove[i]); + await browser.execute(removeElements, elements, true); } - - // scroll back to start - const x = 0; - const y = 0; - log('scroll back to start x: %s, y: %s', x, y); - await browser.execute(scroll, x, y); - - // wait a bit for browser render - const pause = 200; - log('wait %s ms for browser render', pause); - await browser.pause(pause); + } + + // scroll back to start + const x = 0; + const y = 0; + log('scroll back to start x: %s, y: %s', x, y); + await browser.execute(scroll, x, y); + + // wait a bit for browser render + const pause = 200; + log('wait %s ms for browser render', pause); + await browser.pause(pause); } diff --git a/src/modules/makeAreaScreenshot.js b/src/modules/makeAreaScreenshot.js index 92a2bb2..38de7d3 100755 --- a/src/modules/makeAreaScreenshot.js +++ b/src/modules/makeAreaScreenshot.js @@ -63,7 +63,7 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, screenshotPromises.push(storeScreenshot(browser, screenDimension, cropDimensions, base64Screenshot, filePath)); - if (!Array.isArray(cropImages[indexY])) { + if(!Array.isArray(cropImages[indexY])) { cropImages[indexY] = []; } @@ -92,11 +92,12 @@ export default async function makeAreaScreenshot(browser, startX, startY, endX, ]); return mergedBase64Screenshot; - } catch (e) { + } catch(e) { try { await fsExtra.remove(dir); - } catch (e) {} + } catch(e) {} throw e; } + } diff --git a/src/modules/makeDocumentScreenshot.js b/src/modules/makeDocumentScreenshot.js index 70d8520..4867550 100755 --- a/src/modules/makeDocumentScreenshot.js +++ b/src/modules/makeDocumentScreenshot.js @@ -9,6 +9,7 @@ import ScreenDimension from '../utils/ScreenDimension'; const log = debug('wdio-screenshot:makeDocumentScreenshot'); + export default async function makeDocumentScreenshot(browser, options = {}) { log('start document screenshot'); @@ -17,7 +18,6 @@ export default async function makeDocumentScreenshot(browser, options = {}) { // get screen dimisions to determine document height & width const screenDimensions = await browser.execute(getScreenDimensions); - const screenDimension = new ScreenDimension(screenDimensions, browser); // make screenshot of area diff --git a/src/scripts/getScrollPosition.js b/src/scripts/getScrollPosition.js index 864ef0f..95e1805 100755 --- a/src/scripts/getScrollPosition.js +++ b/src/scripts/getScrollPosition.js @@ -4,8 +4,7 @@ export default function getScrollPosition() { window.pageXOffset, window.pageYOffset ]; - } else if ( - typeof document.documentElement.scrollTop !== 'undefined' && document.documentElement.scrollTop > 0) { + } else if (typeof document.documentElement.scrollTop !== 'undefined' && document.documentElement.scrollTop > 0) { return [ document.documentElement.scrollLeft, document.documentElement.scrollTop diff --git a/src/scripts/scroll.js b/src/scripts/scroll.js index f1601bc..f2c3f35 100755 --- a/src/scripts/scroll.js +++ b/src/scripts/scroll.js @@ -1,3 +1,4 @@ + export default function scroll(x, y) { window.scrollTo(x, y); } diff --git a/src/scripts/virtualScroll.js b/src/scripts/virtualScroll.js index 015bedf..02313ae 100755 --- a/src/scripts/virtualScroll.js +++ b/src/scripts/virtualScroll.js @@ -1,3 +1,4 @@ + export default function virtualScroll(x, y, remove) { const w = x === 0 ? 0 : -1 * x; const h = y === 0 ? 0 : -1 * y; diff --git a/src/utils/CropDimension.js b/src/utils/CropDimension.js index 08c1ef2..0eee37a 100755 --- a/src/utils/CropDimension.js +++ b/src/utils/CropDimension.js @@ -1,4 +1,6 @@ + export default class CropDimension { + constructor(width, height, x, y, top = true, rotation = 0) { this.width = width; this.height = height; @@ -8,6 +10,7 @@ export default class CropDimension { this.rotation = rotation; } + getWidth() { return this.width; } diff --git a/src/utils/ScreenDimension.js b/src/utils/ScreenDimension.js index 3909e7f..b5edfbd 100755 --- a/src/utils/ScreenDimension.js +++ b/src/utils/ScreenDimension.js @@ -1,4 +1,5 @@ export default class ScreenDimensions { + constructor(options, browser = {}) { const { html, body, window } = options; diff --git a/src/utils/ScreenshotStrategyManager.js b/src/utils/ScreenshotStrategyManager.js index ad18203..33b334b 100755 --- a/src/utils/ScreenshotStrategyManager.js +++ b/src/utils/ScreenshotStrategyManager.js @@ -10,13 +10,14 @@ const regexPhantomjs = /phantomjs/i; const log = debug('wdio-screenshot:ScreenshotStrategyManager'); function matchBrowserName(browser, regex) { - return (browser.desiredCapabilities && browser.desiredCapabilities.browserName && regex.test(browser.desiredCapabilities.browserName)); + return browser.desiredCapabilities && browser.desiredCapabilities.browserName && regex.test(browser.desiredCapabilities.browserName); } function isPhantomjs(browser) { return matchBrowserName(browser, regexPhantomjs); } + export default class ScreenshotStrategyManager { static getStrategy(browser, screenDimensions) { @@ -34,4 +35,5 @@ export default class ScreenshotStrategyManager { log('use merge viewport strategy') return new MergeViewportStrategy(screenDimensions); } + } diff --git a/src/utils/image/jimp.js b/src/utils/image/jimp.js index 520b7a7..2b8ee94 100755 --- a/src/utils/image/jimp.js +++ b/src/utils/image/jimp.js @@ -9,12 +9,13 @@ import CropDimension from '../CropDimension'; */ export async function cropImage(base64Screenshot, cropDimensions) { - if (!(cropDimensions instanceof CropDimension)) { + if (!(cropDimensions instanceof CropDimension )) { throw new Error('Please provide a valid instance of CropDimension!'); } const image = await Jimp.read(new Buffer(base64Screenshot, 'base64')); + if (cropDimensions.getRotation() !== 0) { image.rotate(cropDimensions.getRotation()); } @@ -38,7 +39,7 @@ export async function cropImage(base64Screenshot, cropDimensions) { return reject(err); } return resolve(buffer.toString('base64')); - }); + }) }); } @@ -49,6 +50,7 @@ export async function cropImage(base64Screenshot, cropDimensions) { * @returns {string} screenshot */ export async function scaleImage(base64Screenshot, scaleFactor) { + const image = await Jimp.read(new Buffer(base64Screenshot, 'base64')); image.scale(scaleFactor); @@ -58,10 +60,11 @@ export async function scaleImage(base64Screenshot, scaleFactor) { return reject(err); } return resolve(buffer.toString('base64')); - }); + }) }); } + /** * Merges mulidimensional array of images to a single image: * @param {string[][]} images array of images @@ -90,7 +93,7 @@ export async function mergeImages(images) { let x = 0; for (const colImage of colImages) { image.blit(colImage, x, 0); - x += colImage.bitmap.width; + x += colImage.bitmap.width } imageWidth = image.bitmap.width; @@ -117,7 +120,7 @@ export async function mergeImages(images) { return reject(err); } return resolve(buffer.toString('base64')); - }); + }) }); return base64Screenshot; } diff --git a/src/utils/normalizeScreenshot.js b/src/utils/normalizeScreenshot.js index cc69c7f..8a8ab46 100755 --- a/src/utils/normalizeScreenshot.js +++ b/src/utils/normalizeScreenshot.js @@ -1,21 +1,21 @@ -import CropDimension from './CropDimension'; -import getBase64ImageSize from './getBase64ImageSize'; -import { cropImage, scaleImage } from './image'; +import CropDimension from "./CropDimension"; +import getBase64ImageSize from "./getBase64ImageSize"; +import {cropImage, scaleImage} from "./image"; async function normalizeRetinaScreenshot(browser, screenDimensions, base64Screenshot) { - // check if image dimensions are different to viewport as browsers like firefox scales images automatically down - const size = getBase64ImageSize(base64Screenshot); - const imageSizeMax = Math.max(size.width, size.height); - const imageSizeMin = Math.min(size.width, size.height); - const viewportSizeMax = screenDimensions.applyScaleFactor(Math.max(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); - const viewportSizeMin = screenDimensions.applyScaleFactor(Math.min(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); - const isImageScaled = imageSizeMax !== viewportSizeMax && imageSizeMin !== viewportSizeMin; + // check if image dimensions are different to viewport as browsers like firefox scales images automatically down + const size = getBase64ImageSize(base64Screenshot); + const imageSizeMax = Math.max(size.width, size.height); + const imageSizeMin = Math.min(size.width, size.height); + const viewportSizeMax = screenDimensions.applyScaleFactor(Math.max(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); + const viewportSizeMin = screenDimensions.applyScaleFactor(Math.min(screenDimensions.getViewportWidth(), screenDimensions.getViewportHeight())); + const isImageScaled = imageSizeMax !== viewportSizeMax && imageSizeMin !== viewportSizeMin; - if (isImageScaled) { - const normalizedScreenshot = await scaleImage(base64Screenshot, 1 / screenDimensions.getPixelRatio()); - return normalizedScreenshot; - } - return base64Screenshot; + if (isImageScaled) { + const normalizedScreenshot = await scaleImage(base64Screenshot, 1 / screenDimensions.getPixelRatio()); + return normalizedScreenshot; + } + return base64Screenshot; } async function normalizeIOSScreenshot(browser, screenDimensions, base64Screenshot) { diff --git a/src/utils/strategies/BaseStrategy.js b/src/utils/strategies/BaseStrategy.js index 4a59939..45cd03a 100755 --- a/src/utils/strategies/BaseStrategy.js +++ b/src/utils/strategies/BaseStrategy.js @@ -69,4 +69,5 @@ export default class BaseStrategy { const adjustedHeight = this.screenDimensions.applyScaleFactor(height); return new CropDimension(adjustedWidth, adjustedHeight, x, y, top, rotation); } + } diff --git a/src/utils/strategies/FullpageScreenshotStrategy.js b/src/utils/strategies/FullpageScreenshotStrategy.js index af1e2f6..f13be89 100755 --- a/src/utils/strategies/FullpageScreenshotStrategy.js +++ b/src/utils/strategies/FullpageScreenshotStrategy.js @@ -27,4 +27,6 @@ export default class FullpageScreenshotStrategy extends BaseStrategy { return this.createCropDimensions(width, height, 0, 0, true, 0); } + + } diff --git a/src/utils/strategies/MergeScreenshotStrategy.js b/src/utils/strategies/MergeScreenshotStrategy.js index b51c889..533a6c0 100755 --- a/src/utils/strategies/MergeScreenshotStrategy.js +++ b/src/utils/strategies/MergeScreenshotStrategy.js @@ -4,16 +4,12 @@ export default class MergeScreenshotStrategy extends BaseStrategy { hasNextHorizontalScrollPosition() { const width = this.area.endX - this.area.startX; - return ( - width > - this.index.x * this.screenDimensions.getViewportWidth() + - this.screenDimensions.getViewportWidth() - ); + return width > this.index.x * this.screenDimensions.getViewportWidth() + this.screenDimensions.getViewportWidth(); } hasNextVerticalScrollPosition() { const height = this.area.endY - this.area.startY; - return (height > this.index.y * this.screenDimensions.getViewportHeight() + this.screenDimensions.getViewportHeight()); + return height > this.index.y * this.screenDimensions.getViewportHeight() + this.screenDimensions.getViewportHeight(); } getScrollPosition() { @@ -45,5 +41,5 @@ export default class MergeScreenshotStrategy extends BaseStrategy { return this.createCropDimensions(width, height, 0, 0, true, 0); } - + } From b97f0810f55f1941a968377897bab0b7ac5e586e Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 12:07:28 +0100 Subject: [PATCH 04/12] Fix --- src/utils/image/gm.js | 42 +++++++++++++++++--------------- src/utils/image/index.js | 3 ++- src/utils/image/jimp.js | 1 + src/utils/normalizeScreenshot.js | 15 +++--------- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/utils/image/gm.js b/src/utils/image/gm.js index e2959fc..0e8967d 100755 --- a/src/utils/image/gm.js +++ b/src/utils/image/gm.js @@ -16,7 +16,7 @@ const tmpDir = path.join(__dirname, '../../../.tmp'); */ export async function cropImage(base64Screenshot, cropDimensions) { - if (!(cropDimensions instanceof CropDimension)) { + if (!(cropDimensions instanceof CropDimension )) { throw new Error('Please provide a valid instance of CropDimension!'); } @@ -35,7 +35,7 @@ export async function cropImage(base64Screenshot, cropDimensions) { return reject(err); } return resolve(buffer.toString('base64')); - }); + }) }); } @@ -59,16 +59,18 @@ export async function scaleImage(base64Screenshot, scaleFactor) { return reject(err); } return resolve(buffer.toString('base64')); - }); + }) }); } + /** * Merges mulidimensional array of images to a single image: * @param {string[][]} images array of images * @return {string} screenshot */ export async function mergeImages(images) { + const uuid = generateUUID(); const dir = path.join(tmpDir, uuid); @@ -94,25 +96,27 @@ export async function mergeImages(images) { return resolve(file); }); }); - }); + }) // merge all vertical screens - const base64Screenshot = await Promise.all(rowImagesPromises).then(rowImages => { - const firstImage = rowImages.shift(); - const mergedImage = gm(firstImage); - - if (rowImages.length) { - mergedImage.append(...rowImages); - } - - return new Promise((resolve, reject) => { - mergedImage.toBuffer('PNG', (err, buffer) => { - if (err) { - return reject(err); - } - return resolve(buffer.toString('base64')); + const base64Screenshot = await Promise + .all(rowImagesPromises) + .then(rowImages => { + const firstImage = rowImages.shift(); + const mergedImage = gm(firstImage); + + if (rowImages.length) { + mergedImage.append(...rowImages); + } + + return new Promise((resolve, reject) => { + mergedImage.toBuffer('PNG', (err, buffer) => { + if (err) { + return reject(err); + } + return resolve(buffer.toString('base64')); + }); }); - }); }); await fsExtra.remove(dir); diff --git a/src/utils/image/index.js b/src/utils/image/index.js index 15e4242..10c7728 100755 --- a/src/utils/image/index.js +++ b/src/utils/image/index.js @@ -3,13 +3,14 @@ import * as gm from './gm'; import which from 'which'; import debug from 'debug'; + const log = debug('wdio-screenshot:image'); let gmInstalled = false; try { gmInstalled = !!which.sync('gm'); -} catch (e) {} +} catch(e) {} log(`Use image processing library: ${gmInstalled ? 'GraphicsMagick' : 'Jimp'}`); diff --git a/src/utils/image/jimp.js b/src/utils/image/jimp.js index 2b8ee94..4b5249f 100755 --- a/src/utils/image/jimp.js +++ b/src/utils/image/jimp.js @@ -71,6 +71,7 @@ export async function scaleImage(base64Screenshot, scaleFactor) { * @return {string} screenshot */ export async function mergeImages(images) { + let imageWidth = 0; let imageHeight = 0; diff --git a/src/utils/normalizeScreenshot.js b/src/utils/normalizeScreenshot.js index 8a8ab46..d7283b8 100755 --- a/src/utils/normalizeScreenshot.js +++ b/src/utils/normalizeScreenshot.js @@ -1,6 +1,6 @@ -import CropDimension from "./CropDimension"; -import getBase64ImageSize from "./getBase64ImageSize"; -import {cropImage, scaleImage} from "./image"; +import CropDimension from './CropDimension'; +import getBase64ImageSize from './getBase64ImageSize'; +import {cropImage, scaleImage} from './image'; async function normalizeRetinaScreenshot(browser, screenDimensions, base64Screenshot) { // check if image dimensions are different to viewport as browsers like firefox scales images automatically down @@ -50,14 +50,7 @@ async function normalizeIOSScreenshot(browser, screenDimensions, base64Screensho if (barsHeight > 0 || rotation > 0) { // crop only when necessary - const cropDimensions = new CropDimension( - viewportWidth, - viewportHeight, - 0, - barsHeight, - true, - rotation, - ); + const cropDimensions = new CropDimension(viewportWidth, viewportHeight, 0, barsHeight, true, rotation); const croppedBase64Screenshot = await cropImage(base64Screenshot, cropDimensions); return croppedBase64Screenshot; } From a57a8c55dd35d4163d16004b81346da53ce3af1f Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 12:11:48 +0100 Subject: [PATCH 05/12] Update README & wdio peer dependency --- README.md | 7 ++++--- package.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bf82996..8473bae 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status][build-badge]][build] [![Build Status Windows][build-windows-badge]][build-windows] [![npm package][npm-badge]][npm] +Working properly with WebdriverIO > 5.0.0 ## Browser Support [![Build Status](https://saucelabs.com/open_sauce/build_matrix/zinserjan.svg)](https://saucelabs.com/u/zinserjan) @@ -30,12 +31,12 @@ Note: If you want to improve performance, you can [install GraphicsMagick](#use- Setup wdio-screenshot by adding a `wdio-screenshot` key to the plugins section of your WebdriverIO config. ```js +const WdioScreenshot = require('wdio-screenshot'); + // wdio.conf.js exports.config = { // ... - plugins: { - 'wdio-screenshot': {} - }, + services: [..., [WdioScreenshot]] // ... }; ``` diff --git a/package.json b/package.json index b122ce3..5f24c11 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "author": "Jan-André Zinser", "license": "MIT", "peerDependencies": { - "webdriverio": "^4.0.7" + "webdriverio": "^5.7.6" }, "dependencies": { "babel-runtime": "^6.9.0", From e4e42e643b45e75617ab25183ee826b34b0131ed Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 12:13:21 +0100 Subject: [PATCH 06/12] README fix --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8473bae..4c616ca 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ Instructions on how to install `WebdriverIO` can be found [here.](http://webdriv Note: If you want to improve performance, you can [install GraphicsMagick](#use-graphicsmagick). ## Configuration -Setup wdio-screenshot by adding a `wdio-screenshot` key to the plugins section of your WebdriverIO config. +Setup wdio-screenshot by adding a `wdio-screenshot` key to the service section of your WebdriverIO config. +More information [Custom Services](https://webdriver.io/docs/customservices.html) ```js const WdioScreenshot = require('wdio-screenshot'); From eeeacad91af777cb137629ae99e70dc481d0895c Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 16:26:00 +0100 Subject: [PATCH 07/12] Test refactor init --- appveyor.yml | 4 +- package.json | 15 +- src/WdioScreenshotLauncher.js | 9 +- src/modules/afterScreenshot.js | 2 +- src/modules/beforeScreenshot.js | 2 +- test/helper/compareImages.js | 1 + test/wdio/specs/desktop-capture.test.js | 4 +- test/wdio/specs/desktop.test.js | 1032 ++++++++++++----------- test/wdio/specs/ios-capture.test.js | 2 +- test/wdio/specs/mobile.test.js | 2 +- test/wdio/wdio.appveyor-conf.js | 2 +- test/wdio/wdio.local-conf.js | 21 +- test/wdio/wdio.sauce-conf.js | 2 +- 13 files changed, 559 insertions(+), 539 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3cd1ebb..c52affc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,8 +11,8 @@ environment: # Install scripts. (runs after repo cloning) install: # Install GraphicsMagick - - if %GRAPHICSMAGICK%==true appveyor-retry appveyor DownloadFile http://downloads.sourceforge.net/graphicsmagick/GraphicsMagick-1.3.20-Q8-win32-dll.exe - - if %GRAPHICSMAGICK%==true GraphicsMagick-1.3.20-Q8-win32-dll.exe /SP /VERYSILENT /NORESTART /NOICONS /DIR=%CD%\gm + - if %GRAPHICSMAGICK%==true appveyor-retry appveyor DownloadFile http://downloads.sourceforge.net/graphicsmagick/GraphicsMagick-1.3.31-Q8-win32-dll.exe + - if %GRAPHICSMAGICK%==true GraphicsMagick-1.3.31-Q8-win32-dll.exe /SP /VERYSILENT /NORESTART /NOICONS /DIR=%CD%\gm - if %GRAPHICSMAGICK%==true set PATH=%CD%\gm;%PATH% # Get the wanted version of Node - ps: Install-Product node $env:nodejs_version diff --git a/package.json b/package.json index 5f24c11..d9828f8 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "clean": "npm run clean-lib && npm run clean-tmp", "build": "npm run clean && babel ./src -d lib", "test": "npm run clean && mocha --compilers js:babel-register --timeout 15000 --recursive test/unit", - "test:local": "npm run clean && wdio ./test/wdio/wdio.local-conf.js", + "test:local": "npm run build && wdio ./test/wdio/wdio.local-conf.js", "test:sauce": "npm run clean && wdio ./test/wdio/wdio.sauce-conf.js", "test:appveyor": "npm run clean && wdio ./test/wdio/wdio.appveyor-conf.js", "test:standalone": "npm run clean && npm run selenium-install && mocha --compilers js:babel-register --timeout 30000 --recursive test/standalone", @@ -48,6 +48,12 @@ "which": "^1.2.10" }, "devDependencies": { + "@wdio/cli": "^5.7.6", + "@wdio/local-runner": "^5.7.6", + "@wdio/mocha-framework": "^5.7.6", + "@wdio/selenium-standalone-service": "^5.7.2", + "@wdio/spec-reporter": "^5.7.2", + "@wdio/sync": "^5.7.6", "babel-cli": "^6.9.0", "babel-plugin-lodash": "^3.2.9", "babel-plugin-syntax-async-functions": "^6.8.0", @@ -56,7 +62,7 @@ "babel-plugin-transform-runtime": "^6.9.0", "babel-preset-es2015": "^6.9.0", "babel-register": "^6.9.0", - "chai": "^3.5.0", + "chai": "^4.2.0", "gh-pages": "^0.11.0", "glob": "^7.1.0", "http-server": "^0.9.0", @@ -66,10 +72,7 @@ "rimraf": "^2.5.2", "selenium-standalone": "^6.4.1", "sinon": "^1.17.6", - "wdio-mocha-framework": "^0.3.2", - "wdio-sauce-service": "^0.4.0", - "wdio-selenium-standalone-service": "0.0.8", - "webdriverio": "~4.8.0" + "webdriverio": "^5.7.6" }, "engines": { "node": ">=4" diff --git a/src/WdioScreenshotLauncher.js b/src/WdioScreenshotLauncher.js index 2fcf6f4..a2f2d3e 100755 --- a/src/WdioScreenshotLauncher.js +++ b/src/WdioScreenshotLauncher.js @@ -7,7 +7,10 @@ import makeElementScreenshot from './modules/makeElementScreenshot'; import makeViewportScreenshot from './modules/makeViewportScreenshot'; export default class WdioScreenshot { - constructor(browser, options) { + constructor(browser = {}, options = {}) { + if (!browser) { + throw new Error('A WebdriverIO instance is needed to initialise wdio-screenshot') + } } before() { @@ -18,6 +21,10 @@ export default class WdioScreenshot { } } +export function init(webdriverInstance, options) { + return new WdioScreenshot(webdriverInstance, options); +} + export { makeDocumentScreenshot, makeElementScreenshot, diff --git a/src/modules/afterScreenshot.js b/src/modules/afterScreenshot.js index bc0f4f1..c807c88 100755 --- a/src/modules/afterScreenshot.js +++ b/src/modules/afterScreenshot.js @@ -22,7 +22,7 @@ export default async function afterScreenshot(browser, options) { if (Array.isArray(options.remove) && options.remove.length) { log('add the following elements again: %s', options.remove.join(', ')); - for (let i = 0; i < options.hide.length; i++) { + for (let i = 0; i < options.remove.length; i++) { let elements = await browser.$$(options.remove[i]); await browser.execute(removeElements, elements, false); } diff --git a/src/modules/beforeScreenshot.js b/src/modules/beforeScreenshot.js index 81faec3..afd25c9 100755 --- a/src/modules/beforeScreenshot.js +++ b/src/modules/beforeScreenshot.js @@ -31,7 +31,7 @@ export default async function beforeScreenshot(browser, options) { if (Array.isArray(options.remove) && options.remove.length) { log('remove the following elements: %s', options.remove.join(', ')); - for (let i = 0; i < options.hide.length; i++) { + for (let i = 0; i < options.remove.length; i++) { let elements = await browser.$$(options.remove[i]); await browser.execute(removeElements, elements, true); } diff --git a/test/helper/compareImages.js b/test/helper/compareImages.js index d80fec4..2c9ecc9 100644 --- a/test/helper/compareImages.js +++ b/test/helper/compareImages.js @@ -7,6 +7,7 @@ export default function compareImages(image1, image2, misMatchPercentage = 0.2) return new Promise((resolve) => { const image = resemble(image1).compareTo(image2); image.onComplete((data) => { + console.log(data); assert.isTrue(data.isSameDimensions, `different dimensions, see "${image1}" and "${image2}"`); assert.closeTo(Number(data.misMatchPercentage), 0, misMatchPercentage, `different images, see "${image1}" and "${image2}"`); resolve(); diff --git a/test/wdio/specs/desktop-capture.test.js b/test/wdio/specs/desktop-capture.test.js index 3ae8fe7..bded78a 100644 --- a/test/wdio/specs/desktop-capture.test.js +++ b/test/wdio/specs/desktop-capture.test.js @@ -10,7 +10,7 @@ const groupName = 'MacbookPro'; function getSpecificFile(page, type, file) { - const { browserName } = browser.desiredCapabilities; + const { browserName } = browser.capabilities; const folder = path.join(groupName, browserName, file); return path.join(screenshotDir, folder); @@ -29,7 +29,7 @@ describe('capture screenshots & dimensions for unit tests', function () { beforeEach(async function () { this.page = 'empty'; await browser.url(`${this.page}.html`); - await browser.setViewportSize({width: 500, height: 500}); + await browser.setWindowSize( 500, 500); await browser.pause(5000); }); diff --git a/test/wdio/specs/desktop.test.js b/test/wdio/specs/desktop.test.js index 806efc0..c1c4ebd 100644 --- a/test/wdio/specs/desktop.test.js +++ b/test/wdio/specs/desktop.test.js @@ -1,8 +1,8 @@ -import path from 'path'; -import {assert} from 'chai'; +import path from "path"; +import {assert} from "chai"; -import generateUUID from '../../../src/utils/generateUUID'; -import compareImages from '../../helper/compareImages'; +import generateUUID from "../../../src/utils/generateUUID"; +import compareImages from "../../helper/compareImages"; const tmpDir = path.join(process.cwd(), '.tmp'); @@ -48,7 +48,7 @@ const screenElementModifierRemoveViewport480 = getBrowserSpecificFile(path.join( const screenElementModifierRemoveElement480 = getBrowserSpecificFile(path.join(screenshotDir, 'desktop-element-modifier-remove-element-480.png')); function isIE() { - const { browserName } = browser.desiredCapabilities; + const {browserName} = browser.capabilities; return browserName === 'internet explorer'; } @@ -75,7 +75,7 @@ describe('integration tests for desktop browsers', function () { it('with window size 480px', async function () { const screenPath = path.join(tmpDir, '/desktop-static-document-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); + await browser.setWindowSize(480, 500); await browser.pause(500); await browser.saveDocumentScreenshot(screenPath); @@ -86,7 +86,7 @@ describe('integration tests for desktop browsers', function () { it('with window size 1600', async function () { const screenPath = path.join(tmpDir, '/desktop-static-document-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); + await browser.setWindowSize(1600, 500); await browser.pause(500); await browser.saveDocumentScreenshot(screenPath); @@ -99,7 +99,7 @@ describe('integration tests for desktop browsers', function () { it('with window size 480px', async function () { const screenPath = path.join(tmpDir, '/desktop-static-element-footer', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); + await browser.setWindowSize(480, 500); await browser.pause(500); await browser.saveElementScreenshot(screenPath, '.footer'); @@ -109,7 +109,7 @@ describe('integration tests for desktop browsers', function () { it('with window size 1600px', async function () { const screenPath = path.join(tmpDir, '/desktop-static-element-footer', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); + await browser.setWindowSize(1600, 500); await browser.pause(500); await browser.saveElementScreenshot(screenPath, '.footer'); @@ -122,7 +122,8 @@ describe('integration tests for desktop browsers', function () { it('with window size 480px', async function () { const screenPath = path.join(tmpDir, '/desktop-static-viewport-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); + + await browser.setWindowSize(480, 560); await browser.pause(500); await browser.saveViewportScreenshot(screenPath); @@ -132,7 +133,8 @@ describe('integration tests for desktop browsers', function () { it('with window size 1600', async function () { const screenPath = path.join(tmpDir, '/desktop-static-viewport-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); + + await browser.setWindowSize(1600, 580); await browser.pause(500); await browser.saveViewportScreenshot(screenPath); @@ -141,612 +143,612 @@ describe('integration tests for desktop browsers', function () { }); }); - context('responsive sites - responsive.html', function () { - beforeEach(async function () { - await browser.url('responsive.html'); - await browser.pause(3000); - }); +context('responsive sites - responsive.html', function () { + beforeEach(async function () { + await browser.url('responsive.html'); + await browser.pause(3000); + }); - context('saveDocumentScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); + context('saveDocumentScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); + await browser.setWindowSize(480, 500); + await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveDocument480); - }); + await compareImages(screenPath, screenResponsiveDocument480); + }); - it('with window size 1600', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-document-1600', `${generateUUID()}.png`); + it('with window size 1600', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-document-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); - await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.setWindowSize(1600, 500); + await browser.pause(500); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveDocument1600); - }); + await compareImages(screenPath, screenResponsiveDocument1600); }); + }); - context('saveElementScreenshot', function () { + context('saveElementScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveElementScreenshot(screenPath, '.footer'); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveElementScreenshot(screenPath, '.footer'); - await compareImages(screenPath, screenResponsiveElemenentFooter480); - }); + await compareImages(screenPath, screenResponsiveElemenentFooter480); + }); - it('with window size 1600px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-1600', `${generateUUID()}.png`); + it('with window size 1600px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); - await browser.pause(500); - await browser.saveElementScreenshot(screenPath, '.footer'); + await browser.setWindowSize(1600, 500); + await browser.pause(500); + await browser.saveElementScreenshot(screenPath, '.footer'); - await compareImages(screenPath, screenResponsiveElemenentFooter1600); - }); + await compareImages(screenPath, screenResponsiveElemenentFooter1600); }); + }); - context('saveViewportScreenshot', function () { + context('saveViewportScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveViewport480); - }); + await compareImages(screenPath, screenResponsiveViewport480); + }); - it('with window size 1600', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-1600', `${generateUUID()}.png`); + it('with window size 1600', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(1600, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveViewport1600); - }); + await compareImages(screenPath, screenResponsiveViewport1600); }); }); +}); - context('responsive sites with min-width - responsive-min-width.html', function () { - beforeEach(async function () { - await browser.url('responsive-min-width.html'); - await browser.pause(3000); - }); +context('responsive sites with min-width - responsive-min-width.html', function () { + beforeEach(async function () { + await browser.url('responsive-min-width.html'); + await browser.pause(3000); + }); - context('saveDocumentScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-document-480', `${generateUUID()}.png`); + context('saveDocumentScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-document-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); + await browser.setWindowSize(480, 500); + await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveMinWidthDocument480); - }); + await compareImages(screenPath, screenResponsiveMinWidthDocument480); + }); - it('with window size 1600', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-document-1600', `${generateUUID()}.png`); + it('with window size 1600', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-document-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); - await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.setWindowSize(1600, 500); + await browser.pause(500); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveMinWidthDocument1600); - }); + await compareImages(screenPath, screenResponsiveMinWidthDocument1600); }); + }); - context('saveElementScreenshot', function () { + context('saveElementScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-element-footer-480', `${generateUUID()}.png`); + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-element-footer-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveElementScreenshot(screenPath, '.footer'); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveElementScreenshot(screenPath, '.footer'); - await compareImages(screenPath, screenResponsiveMinWidthElemenentFooter); - }); + await compareImages(screenPath, screenResponsiveMinWidthElemenentFooter); + }); - it('with window size 1600px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-element-footer-1600', `${generateUUID()}.png`); + it('with window size 1600px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-element-footer-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); - await browser.pause(500); - await browser.saveElementScreenshot(screenPath, '.footer'); + await browser.setWindowSize(1600, 500); + await browser.pause(500); + await browser.saveElementScreenshot(screenPath, '.footer'); - await compareImages(screenPath, screenResponsiveMinWidthElemenentFooter); - }); + await compareImages(screenPath, screenResponsiveMinWidthElemenentFooter); }); + }); - context('saveViewportScreenshot', function () { + context('saveViewportScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-viewport-480', `${generateUUID()}.png`); + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-viewport-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveMinWidthViewport480); - }); + await compareImages(screenPath, screenResponsiveMinWidthViewport480); + }); - it('with window size 1600', async function () { - const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-viewport-1600', `${generateUUID()}.png`); + it('with window size 1600', async function () { + const screenPath = path.join(tmpDir, '/desktop-responsive-min-width-viewport-1600', `${generateUUID()}.png`); - await browser.setViewportSize({width: 1600, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(1600, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveMinWidthViewport1600); - }); + await compareImages(screenPath, screenResponsiveMinWidthViewport1600); }); }); +}); - context('dynamic size issues - size-dynamic.html', function () { - beforeEach(async function () { - await browser.url('size-dynamic.html'); - await browser.pause(3000); - }); +context('dynamic size issues - size-dynamic.html', function () { + beforeEach(async function () { + await browser.url('size-dynamic.html'); + await browser.pause(3000); + }); - context('saveDocumentScreenshot', function () { + context('saveDocumentScreenshot', function () { - it('resizes elements properly', async function () { - const screenPath = path.join(tmpDir, '/desktop-dynamic-size-document-480', `${generateUUID()}.png`); + it('resizes elements properly', async function () { + const screenPath = path.join(tmpDir, '/desktop-dynamic-size-document-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenDynamicSizeDocument480); - }); + await compareImages(screenPath, screenDynamicSizeDocument480); }); + }); - context('saveViewportScreenshot', function () { + context('saveViewportScreenshot', function () { - it('resizes elements properly', async function () { - const screenPath = path.join(tmpDir, '/desktop-dynamic-size-viewport-480', `${generateUUID()}.png`); + it('resizes elements properly', async function () { + const screenPath = path.join(tmpDir, '/desktop-dynamic-size-viewport-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenDynamicSizeViewport480); - }); + await compareImages(screenPath, screenDynamicSizeViewport480); }); - context('saveElementScreenshot', function () { + }); + context('saveElementScreenshot', function () { - it('resizes elements properly', async function () { - const screenPath = path.join(tmpDir, '/desktop-dynamic-size-element-480', `${generateUUID()}.png`); + it('resizes elements properly', async function () { + const screenPath = path.join(tmpDir, '/desktop-dynamic-size-element-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveElementScreenshot(screenPath, '#dynamic-box'); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveElementScreenshot(screenPath, '#dynamic-box'); - await compareImages(screenPath, screenDynamicSizeElement480); - }); + await compareImages(screenPath, screenDynamicSizeElement480); }); }); +}); - context('overlay - overlay.html', function () { - beforeEach(async function () { - await browser.url('overlay.html'); - await browser.pause(3000); - }); +context('overlay - overlay.html', function () { + beforeEach(async function () { + await browser.url('overlay.html'); + await browser.pause(3000); + }); - context('saveDocumentScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-overlay-document-480', `${generateUUID()}.png`); + context('saveDocumentScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-overlay-document-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenOverlayDocument480); - }); + await compareImages(screenPath, screenOverlayDocument480); }); + }); - context('saveViewportScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-overlay-viewport-480', `${generateUUID()}.png`); + context('saveViewportScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-overlay-viewport-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenOverlayViewport480); - }); + await compareImages(screenPath, screenOverlayViewport480); }); + }); - context('saveElementScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-overlay-element-480', `${generateUUID()}.png`); + context('saveElementScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-overlay-element-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveElementScreenshot(screenPath, '#overlay-content'); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveElementScreenshot(screenPath, '#overlay-content'); - await compareImages(screenPath, screenOverlayElement480); - }); + await compareImages(screenPath, screenOverlayElement480); }); }); +}); - context('fullpage modal - fullpage-modal.html', function () { - beforeEach(async function () { - await browser.url('fullpage-modal.html'); - await browser.pause(3000); - }); +context('fullpage modal - fullpage-modal.html', function () { + beforeEach(async function () { + await browser.url('fullpage-modal.html'); + await browser.pause(3000); + }); - context('saveDocumentScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-fullpage-modal-document-480', `${generateUUID()}.png`); + context('saveDocumentScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-fullpage-modal-document-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveDocumentScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenFullpageModalDocument480); - }); + await compareImages(screenPath, screenFullpageModalDocument480); }); + }); - context('saveViewportScreenshot', function () { - it('with window size 480px', async function () { - const screenPath = path.join(tmpDir, '/desktop-fullpage-modal-viewport-480', `${generateUUID()}.png`); + context('saveViewportScreenshot', function () { + it('with window size 480px', async function () { + const screenPath = path.join(tmpDir, '/desktop-fullpage-modal-viewport-480', `${generateUUID()}.png`); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - await browser.saveViewportScreenshot(screenPath); + await browser.setWindowSize(480, 500); + await browser.pause(500); + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenFullpageModalViewport480); - }); + await compareImages(screenPath, screenFullpageModalViewport480); }); }); +}); - context('element modifier - element-modifier.html', function () { - beforeEach(async function () { - await browser.url('element-modifier.html'); - await browser.pause(3000); - await browser.setViewportSize({width: 480, height: 500}); - await browser.pause(500); - }); - - context('hide', function() { - const options = { - hide: ['.group', '.orange'] - }; +context('element modifier - element-modifier.html', function () { + beforeEach(async function () { + await browser.url('element-modifier.html'); + await browser.pause(3000); + await browser.setWindowSize(480, 500); + await browser.pause(500); + }); - it('saveDocumentScreenshot', async function () { - const screenPath = path.join(tmpDir, '/desktop-element-modifier-hide-document-480', `${generateUUID()}.png`); - await browser.saveDocumentScreenshot(screenPath, options); - await compareImages(screenPath, screenElementModifierHideDocument480); - }); + context('hide', function () { + const options = { + hide: ['.group', '.orange'] + }; - it('saveViewportScreenshot', async function () { - const screenPath = path.join(tmpDir, '/desktop-element-modifier-hide-viewport-480', `${generateUUID()}.png`); - await browser.saveViewportScreenshot(screenPath, options); - await compareImages(screenPath, screenElementModifierHideViewport480); - }); + it('saveDocumentScreenshot', async function () { + const screenPath = path.join(tmpDir, '/desktop-element-modifier-hide-document-480', `${generateUUID()}.png`); + await browser.saveDocumentScreenshot(screenPath, options); + await compareImages(screenPath, screenElementModifierHideDocument480); + }); - it('saveElementScreenshot', async function () { - const screenPath = path.join(tmpDir, '/desktop-element-modifier-hide-element-480', `${generateUUID()}.png`); - await browser.saveElementScreenshot(screenPath, '.wrapper', options); - await compareImages(screenPath, screenElementModifierHideElement480); - }); + it('saveViewportScreenshot', async function () { + const screenPath = path.join(tmpDir, '/desktop-element-modifier-hide-viewport-480', `${generateUUID()}.png`); + await browser.saveViewportScreenshot(screenPath, options); + await compareImages(screenPath, screenElementModifierHideViewport480); }); - context('remove', function() { - const options = { - remove: ['.group', '.orange'] - }; + it('saveElementScreenshot', async function () { + const screenPath = path.join(tmpDir, '/desktop-element-modifier-hide-element-480', `${generateUUID()}.png`); + await browser.saveElementScreenshot(screenPath, '.wrapper', options); + await compareImages(screenPath, screenElementModifierHideElement480); + }); + }); - it('saveDocumentScreenshot', async function () { - const screenPath = path.join(tmpDir, '/desktop-element-modifier-remove-document-480', `${generateUUID()}.png`); - await browser.saveDocumentScreenshot(screenPath, options); - await compareImages(screenPath, screenElementModifierRemoveDocument480); - }); + context('remove', function () { + const options = { + remove: ['.group', '.orange'] + }; - it('saveViewportScreenshot', async function () { - const screenPath = path.join(tmpDir, '/desktop-element-modifier-remove-viewport-480', `${generateUUID()}.png`); - await browser.saveViewportScreenshot(screenPath, options); - await compareImages(screenPath, screenElementModifierRemoveViewport480); - }); + it('saveDocumentScreenshot', async function () { + const screenPath = path.join(tmpDir, '/desktop-element-modifier-remove-document-480', `${generateUUID()}.png`); + await browser.saveDocumentScreenshot(screenPath, options); + await compareImages(screenPath, screenElementModifierRemoveDocument480); + }); - it('saveElementScreenshot', async function () { - const screenPath = path.join(tmpDir, '/desktop-element-modifier-remove-element-480', `${generateUUID()}.png`); - await browser.saveElementScreenshot(screenPath, '.wrapper', options); - await compareImages(screenPath, screenElementModifierRemoveElement480); - }); + it('saveViewportScreenshot', async function () { + const screenPath = path.join(tmpDir, '/desktop-element-modifier-remove-viewport-480', `${generateUUID()}.png`); + await browser.saveViewportScreenshot(screenPath, options); + await compareImages(screenPath, screenElementModifierRemoveViewport480); }); + it('saveElementScreenshot', async function () { + const screenPath = path.join(tmpDir, '/desktop-element-modifier-remove-element-480', `${generateUUID()}.png`); + await browser.saveElementScreenshot(screenPath, '.wrapper', options); + await compareImages(screenPath, screenElementModifierRemoveElement480); + }); }); - // context.only('take screenshots', function () { - // context('responsive sites - responsive.html', function () { - // beforeEach(async function () { - // await browser.url('responsive-min-width.html'); - // await browser.pause(3000); - // }); - // - // context('saveDocumentScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenResponsiveMinWidthDocument480); - // }); - // - // it('with window size 1600', async function () { - // await browser.setViewportSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenResponsiveMinWidthDocument1600); - // }); - // }); - // - // context('saveElementScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveElementScreenshot(screenResponsiveMinWidthElemenentFooter, '.footer'); - // }); - // - // }); - // - // context('saveViewportScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenResponsiveMinWidthViewport480); - // }); - // - // it('with window size 1600', async function () { - // await browser.setViewportSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenResponsiveMinWidthViewport1600); - // }); - // }); - // }); - // - // context('responsive sites - responsive.html', function () { - // beforeEach(async function () { - // await browser.url('responsive.html'); - // await browser.pause(3000); - // }); - // - // context('saveDocumentScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenResponsiveDocument480); - // }); - // - // it('with window size 1600', async function () { - // await browser.setViewportSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenResponsiveDocument1600); - // }); - // }); - // - // context('saveElementScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveElementScreenshot(screenResponsiveElemenentFooter480, '.footer'); - // }); - // - // it('with window size 1600', async function () { - // await browser.windowHandleSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.saveElementScreenshot(screenResponsiveElemenentFooter1600, '.footer'); - // }); - // }); - // - // context('saveViewportScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenResponsiveViewport480); - // }); - // - // it('with window size 1600', async function () { - // await browser.setViewportSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenResponsiveViewport1600); - // }); - // }); - // }); - // - // context('static sites - static.html', function () { - // context('saveDocumentScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.url('static.html'); - // await browser.pause(3000); - // await browser.saveDocumentScreenshot(screenStaticDocument480); - // }); - // - // it('with window size 1600', async function () { - // await browser.setViewportSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.url('static.html'); - // await browser.pause(1000); - // await browser.saveDocumentScreenshot(screenStaticDocument1600); - // }); - // }); - // - // context('saveElementScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.url('static.html'); - // await browser.pause(3000); - // await browser.saveElementScreenshot(screenStaticElemenentFooter, '.footer'); - // }); - // - // }); - // - // context('saveViewportScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.url('static.html'); - // await browser.pause(3000); - // await browser.saveViewportScreenshot(screenStaticViewport480); - // }); - // - // it('with window size 1600', async function () { - // await browser.setViewportSize({width: 1600, height: 500}); - // await browser.pause(500); - // await browser.url('static.html'); - // await browser.pause(1000); - // await browser.saveViewportScreenshot(screenStaticViewport1600); - // }); - // }); - // }); - // - // context('dynamic size issues - size-dynamic.html', function () { - // beforeEach(async function () { - // await browser.url('size-dynamic.html'); - // await browser.pause(3000); - // - // }); - // - // context('saveDocumentScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenDynamicSizeDocument480); - // }); - // }); - // - // context('saveViewportScreenshot', function () { - // - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenDynamicSizeViewport480); - // }); - // }); - // context('saveElementScreenshot', function () { - // - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveElementScreenshot(screenDynamicSizeElement480, '#dynamic-box'); - // }); - // }); - // }); - // - // context('overlay - overlay.html', function () { - // beforeEach(async function () { - // await browser.url('overlay.html'); - // await browser.pause(3000); - // - // }); - // - // context('saveDocumentScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenOverlayDocument480); - // }); - // }); - // - // context('saveViewportScreenshot', function () { - // - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenOverlayViewport480); - // }); - // }); - // context('saveElementScreenshot', function () { - // - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveElementScreenshot(screenOverlayElement480, '#overlay-content'); - // }); - // }); - // }); - // - // context('fullpage modal - fullpage-modal.html', function () { - // beforeEach(async function () { - // await browser.url('fullpage-modal.html'); - // await browser.pause(3000); - // - // }); - // - // context('saveDocumentScreenshot', function () { - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveDocumentScreenshot(screenFullpageModalDocument480); - // }); - // }); - // - // context('saveViewportScreenshot', function () { - // - // it('with window size 480px', async function () { - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // await browser.saveViewportScreenshot(screenFullpageModalViewport480); - // }); - // }); - // }); - // - // context('element modifier - element-modifier.html', function () { - // beforeEach(async function () { - // await browser.url('element-modifier.html'); - // await browser.pause(3000); - // await browser.setViewportSize({width: 480, height: 500}); - // await browser.pause(500); - // }); - // - // context('hide', function() { - // const options = { - // hide: ['.group', '.orange'] - // }; - // - // it('saveDocumentScreenshot', async function () { - // await browser.saveDocumentScreenshot(screenElementModifierHideDocument480, options); - // }); - // - // it('saveViewportScreenshot', async function () { - // await browser.saveViewportScreenshot(screenElementModifierHideViewport480, options); - // }); - // - // it('saveElementScreenshot', async function () { - // await browser.saveElementScreenshot(screenElementModifierHideElement480, '.wrapper', options); - // }); - // }); - // - // context('remove', function() { - // const options = { - // remove: ['.group', '.orange'] - // }; - // - // it('saveDocumentScreenshot', async function () { - // await browser.saveDocumentScreenshot(screenElementModifierRemoveDocument480, options); - // }); - // - // it('saveViewportScreenshot', async function () { - // await browser.saveViewportScreenshot(screenElementModifierRemoveViewport480, options); - // }); - // - // it('saveElementScreenshot', async function () { - // await browser.saveElementScreenshot(screenElementModifierRemoveElement480, '.wrapper', options); - // }); - // }); - // }); - // }); +}); + +// context.only('take screenshots', function () { +// context('responsive sites - responsive.html', function () { +// beforeEach(async function () { +// await browser.url('responsive-min-width.html'); +// await browser.pause(3000); +// }); +// +// context('saveDocumentScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenResponsiveMinWidthDocument480); +// }); +// +// it('with window size 1600', async function () { +// await browser.setViewportSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenResponsiveMinWidthDocument1600); +// }); +// }); +// +// context('saveElementScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveElementScreenshot(screenResponsiveMinWidthElemenentFooter, '.footer'); +// }); +// +// }); +// +// context('saveViewportScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenResponsiveMinWidthViewport480); +// }); +// +// it('with window size 1600', async function () { +// await browser.setViewportSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenResponsiveMinWidthViewport1600); +// }); +// }); +// }); +// +// context('responsive sites - responsive.html', function () { +// beforeEach(async function () { +// await browser.url('responsive.html'); +// await browser.pause(3000); +// }); +// +// context('saveDocumentScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenResponsiveDocument480); +// }); +// +// it('with window size 1600', async function () { +// await browser.setViewportSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenResponsiveDocument1600); +// }); +// }); +// +// context('saveElementScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveElementScreenshot(screenResponsiveElemenentFooter480, '.footer'); +// }); +// +// it('with window size 1600', async function () { +// await browser.windowHandleSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.saveElementScreenshot(screenResponsiveElemenentFooter1600, '.footer'); +// }); +// }); +// +// context('saveViewportScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenResponsiveViewport480); +// }); +// +// it('with window size 1600', async function () { +// await browser.setViewportSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenResponsiveViewport1600); +// }); +// }); +// }); +// +// context('static sites - static.html', function () { +// context('saveDocumentScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.url('static.html'); +// await browser.pause(3000); +// await browser.saveDocumentScreenshot(screenStaticDocument480); +// }); +// +// it('with window size 1600', async function () { +// await browser.setViewportSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.url('static.html'); +// await browser.pause(1000); +// await browser.saveDocumentScreenshot(screenStaticDocument1600); +// }); +// }); +// +// context('saveElementScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.url('static.html'); +// await browser.pause(3000); +// await browser.saveElementScreenshot(screenStaticElemenentFooter, '.footer'); +// }); +// +// }); +// +// context('saveViewportScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.url('static.html'); +// await browser.pause(3000); +// await browser.saveViewportScreenshot(screenStaticViewport480); +// }); +// +// it('with window size 1600', async function () { +// await browser.setViewportSize({width: 1600, height: 500}); +// await browser.pause(500); +// await browser.url('static.html'); +// await browser.pause(1000); +// await browser.saveViewportScreenshot(screenStaticViewport1600); +// }); +// }); +// }); +// +// context('dynamic size issues - size-dynamic.html', function () { +// beforeEach(async function () { +// await browser.url('size-dynamic.html'); +// await browser.pause(3000); +// +// }); +// +// context('saveDocumentScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenDynamicSizeDocument480); +// }); +// }); +// +// context('saveViewportScreenshot', function () { +// +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenDynamicSizeViewport480); +// }); +// }); +// context('saveElementScreenshot', function () { +// +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveElementScreenshot(screenDynamicSizeElement480, '#dynamic-box'); +// }); +// }); +// }); +// +// context('overlay - overlay.html', function () { +// beforeEach(async function () { +// await browser.url('overlay.html'); +// await browser.pause(3000); +// +// }); +// +// context('saveDocumentScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenOverlayDocument480); +// }); +// }); +// +// context('saveViewportScreenshot', function () { +// +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenOverlayViewport480); +// }); +// }); +// context('saveElementScreenshot', function () { +// +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveElementScreenshot(screenOverlayElement480, '#overlay-content'); +// }); +// }); +// }); +// +// context('fullpage modal - fullpage-modal.html', function () { +// beforeEach(async function () { +// await browser.url('fullpage-modal.html'); +// await browser.pause(3000); +// +// }); +// +// context('saveDocumentScreenshot', function () { +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveDocumentScreenshot(screenFullpageModalDocument480); +// }); +// }); +// +// context('saveViewportScreenshot', function () { +// +// it('with window size 480px', async function () { +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// await browser.saveViewportScreenshot(screenFullpageModalViewport480); +// }); +// }); +// }); +// +// context('element modifier - element-modifier.html', function () { +// beforeEach(async function () { +// await browser.url('element-modifier.html'); +// await browser.pause(3000); +// await browser.setViewportSize({width: 480, height: 500}); +// await browser.pause(500); +// }); +// +// context('hide', function() { +// const options = { +// hide: ['.group', '.orange'] +// }; +// +// it('saveDocumentScreenshot', async function () { +// await browser.saveDocumentScreenshot(screenElementModifierHideDocument480, options); +// }); +// +// it('saveViewportScreenshot', async function () { +// await browser.saveViewportScreenshot(screenElementModifierHideViewport480, options); +// }); +// +// it('saveElementScreenshot', async function () { +// await browser.saveElementScreenshot(screenElementModifierHideElement480, '.wrapper', options); +// }); +// }); +// +// context('remove', function() { +// const options = { +// remove: ['.group', '.orange'] +// }; +// +// it('saveDocumentScreenshot', async function () { +// await browser.saveDocumentScreenshot(screenElementModifierRemoveDocument480, options); +// }); +// +// it('saveViewportScreenshot', async function () { +// await browser.saveViewportScreenshot(screenElementModifierRemoveViewport480, options); +// }); +// +// it('saveElementScreenshot', async function () { +// await browser.saveElementScreenshot(screenElementModifierRemoveElement480, '.wrapper', options); +// }); +// }); +// }); +// }); }); diff --git a/test/wdio/specs/ios-capture.test.js b/test/wdio/specs/ios-capture.test.js index 83e1981..0388306 100644 --- a/test/wdio/specs/ios-capture.test.js +++ b/test/wdio/specs/ios-capture.test.js @@ -10,7 +10,7 @@ import compareImages from '../../helper/compareImages'; const screenshotDir = path.join(process.cwd(), '.tmp'); function getSpecificFile(page, type, file) { - const { deviceName, deviceOrientation, platformName, platformVersion } = browser.desiredCapabilities; + const { deviceName, deviceOrientation, platformName, platformVersion } = browser.capabilities; const folder = path.join(platformName, `v${platformVersion}`, deviceName, `${page}_${type}`.replace(/-/, '_'), file).replace(/\s/, '_'); return path.join(screenshotDir, folder); diff --git a/test/wdio/specs/mobile.test.js b/test/wdio/specs/mobile.test.js index f693641..37863b7 100644 --- a/test/wdio/specs/mobile.test.js +++ b/test/wdio/specs/mobile.test.js @@ -11,7 +11,7 @@ const fixtureDir = path.join(process.cwd(), 'test/fixture'); const screenshotDir = path.join(fixtureDir, '/web/screenshots'); function getBrowserSpecificFile(prefix) { - const { deviceName, deviceOrientation, platformName } = browser.desiredCapabilities; + const { deviceName, deviceOrientation, platformName } = browser.capabilities; // all os versions should produce the same screenshots return `${prefix}_${platformName}_${deviceName}_${deviceOrientation}.png`; diff --git a/test/wdio/wdio.appveyor-conf.js b/test/wdio/wdio.appveyor-conf.js index fda8ee0..c480dd0 100644 --- a/test/wdio/wdio.appveyor-conf.js +++ b/test/wdio/wdio.appveyor-conf.js @@ -27,7 +27,7 @@ exports.config = { ], }, before: function() { - require('../../src').init(browser, {}) + require('../../src/WdioScreenshotLauncher').init(browser, {}) }, services: ['selenium-standalone'], seleniumArgs: { diff --git a/test/wdio/wdio.local-conf.js b/test/wdio/wdio.local-conf.js index 36be070..3700e60 100644 --- a/test/wdio/wdio.local-conf.js +++ b/test/wdio/wdio.local-conf.js @@ -1,3 +1,4 @@ +const WdioScreenshot = require('../../lib'); require("babel-register"); var path = require('path'); @@ -7,7 +8,12 @@ exports.config = { path.join(__dirname, '/specs/desktop.test.js') ], capabilities: [{ - browserName: 'chrome' + browserName: 'chrome', + 'goog:chromeOptions': { + args: [ + 'disable-infobars', + ], + }, }, { browserName: 'firefox' }], @@ -26,15 +32,16 @@ exports.config = { 'js:babel-register' ], }, - before: function () { - require('../../src').init(browser, {}) - }, - services: ['selenium-standalone'], + reporters: ['spec'], + // before: function () { + // require('../../src/WdioScreenshotLauncher').init(browser, {}) + // }, + services: ['selenium-standalone', [WdioScreenshot]], seleniumArgs: { - version: '3.0.1' + version: '3.8.1' }, seleniumInstallArgs: { - version: '3.0.1', + version: '3.8.1', logger: console.log } }; diff --git a/test/wdio/wdio.sauce-conf.js b/test/wdio/wdio.sauce-conf.js index 287f328..24ad327 100644 --- a/test/wdio/wdio.sauce-conf.js +++ b/test/wdio/wdio.sauce-conf.js @@ -243,7 +243,7 @@ exports.config = { ], }, before: function() { - require('../../src').init(browser, {}) + require('../../src/WdioScreenshotLauncher').init(browser, {}) }, services: ['sauce'], user: process.env.SAUCE_USERNAME, From d0d9776b102aa481686b1337d8cf71d3f8664015 Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 16:38:47 +0100 Subject: [PATCH 08/12] Add Wdio Screenshot service to test wdio config --- test/helper/compareImages.js | 1 - test/wdio/wdio.appveyor-conf.js | 9 +++++---- test/wdio/wdio.sauce-conf.js | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/test/helper/compareImages.js b/test/helper/compareImages.js index 2c9ecc9..d80fec4 100644 --- a/test/helper/compareImages.js +++ b/test/helper/compareImages.js @@ -7,7 +7,6 @@ export default function compareImages(image1, image2, misMatchPercentage = 0.2) return new Promise((resolve) => { const image = resemble(image1).compareTo(image2); image.onComplete((data) => { - console.log(data); assert.isTrue(data.isSameDimensions, `different dimensions, see "${image1}" and "${image2}"`); assert.closeTo(Number(data.misMatchPercentage), 0, misMatchPercentage, `different images, see "${image1}" and "${image2}"`); resolve(); diff --git a/test/wdio/wdio.appveyor-conf.js b/test/wdio/wdio.appveyor-conf.js index c480dd0..b96c395 100644 --- a/test/wdio/wdio.appveyor-conf.js +++ b/test/wdio/wdio.appveyor-conf.js @@ -1,3 +1,4 @@ +const WdioScreenshot = require('../../lib'); require("babel-register"); var path = require('path'); @@ -26,10 +27,10 @@ exports.config = { 'js:babel-register' ], }, - before: function() { - require('../../src/WdioScreenshotLauncher').init(browser, {}) - }, - services: ['selenium-standalone'], + // before: function() { + // require('../../src/WdioScreenshotLauncher').init(browser, {}) + // }, + services: ['selenium-standalone', [WdioScreenshot]], seleniumArgs: { javaArgs: [ '-Djna.nosys=true' diff --git a/test/wdio/wdio.sauce-conf.js b/test/wdio/wdio.sauce-conf.js index 24ad327..6dee542 100644 --- a/test/wdio/wdio.sauce-conf.js +++ b/test/wdio/wdio.sauce-conf.js @@ -1,3 +1,4 @@ +const WdioScreenshot = require('../../lib'); require("babel-register"); var path = require('path'); @@ -245,7 +246,7 @@ exports.config = { before: function() { require('../../src/WdioScreenshotLauncher').init(browser, {}) }, - services: ['sauce'], + services: ['sauce', [WdioScreenshot]], user: process.env.SAUCE_USERNAME, key: process.env.SAUCE_ACCESS_KEY, sauceConnect: true, From 4f8bedf3f4ed782a1f0e445db19a8d25872d15f6 Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 19:02:12 +0100 Subject: [PATCH 09/12] Next test fix iteration --- package.json | 6 +- src/WdioScreenshotLauncher.js | 22 ++++--- test/standalone/standalone.test.js | 95 +++++++++++++++++------------- 3 files changed, 71 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index d9828f8..09031be 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "build": "npm run clean && babel ./src -d lib", "test": "npm run clean && mocha --compilers js:babel-register --timeout 15000 --recursive test/unit", "test:local": "npm run build && wdio ./test/wdio/wdio.local-conf.js", - "test:sauce": "npm run clean && wdio ./test/wdio/wdio.sauce-conf.js", - "test:appveyor": "npm run clean && wdio ./test/wdio/wdio.appveyor-conf.js", - "test:standalone": "npm run clean && npm run selenium-install && mocha --compilers js:babel-register --timeout 30000 --recursive test/standalone", + "test:sauce": "npm run build && wdio ./test/wdio/wdio.sauce-conf.js", + "test:appveyor": "npm run build && wdio ./test/wdio/wdio.appveyor-conf.js", + "test:standalone": "npm run build && npm run selenium-install && mocha --compilers js:babel-register --timeout 30000 --recursive test/standalone", "selenium-install": "selenium-standalone install", "server": "http-server test/fixture/web -p 3000", "deploy-integration-tests": "gh-pages -d test/fixture/web", diff --git a/src/WdioScreenshotLauncher.js b/src/WdioScreenshotLauncher.js index a2f2d3e..5c0e9ba 100755 --- a/src/WdioScreenshotLauncher.js +++ b/src/WdioScreenshotLauncher.js @@ -1,16 +1,22 @@ -import saveDocumentScreenshot from './commands/saveDocumentScreenshot'; -import saveElementScreenshot from './commands/saveElementScreenshot'; -import saveViewportScreenshot from './commands/saveViewportScreenshot'; +import saveDocumentScreenshot from "./commands/saveDocumentScreenshot"; +import saveElementScreenshot from "./commands/saveElementScreenshot"; +import saveViewportScreenshot from "./commands/saveViewportScreenshot"; -import makeDocumentScreenshot from './modules/makeDocumentScreenshot'; -import makeElementScreenshot from './modules/makeElementScreenshot'; -import makeViewportScreenshot from './modules/makeViewportScreenshot'; +import makeDocumentScreenshot from "./modules/makeDocumentScreenshot"; +import makeElementScreenshot from "./modules/makeElementScreenshot"; +import makeViewportScreenshot from "./modules/makeViewportScreenshot"; export default class WdioScreenshot { - constructor(browser = {}, options = {}) { + constructor(browser = {}, options = {}, standalone = false) { if (!browser) { throw new Error('A WebdriverIO instance is needed to initialise wdio-screenshot') } + + if (standalone) { + browser.addCommand('saveDocumentScreenshot', saveDocumentScreenshot); + browser.addCommand('saveElementScreenshot', saveElementScreenshot); + browser.addCommand('saveViewportScreenshot', saveViewportScreenshot); + } } before() { @@ -22,7 +28,7 @@ export default class WdioScreenshot { } export function init(webdriverInstance, options) { - return new WdioScreenshot(webdriverInstance, options); + return new WdioScreenshot(webdriverInstance, options, true); } export { diff --git a/test/standalone/standalone.test.js b/test/standalone/standalone.test.js index 3efe366..c0f19e5 100644 --- a/test/standalone/standalone.test.js +++ b/test/standalone/standalone.test.js @@ -1,10 +1,10 @@ -import path from 'path'; -import { remote, multiremote } from 'webdriverio'; -import { start } from 'selenium-standalone'; -import { assert } from 'chai'; -import { init } from '../../src'; -import generateUUID from '../../src/utils/generateUUID'; -import compareImages from '../helper/compareImages'; +import path from "path"; +import {multiremote, remote} from "webdriverio"; +import {start} from "selenium-standalone"; +import {assert} from "chai"; +import {init} from "../../src/WdioScreenshotLauncher"; +import generateUUID from "../../src/utils/generateUUID"; +import compareImages from "../helper/compareImages"; const tmpDir = path.join(process.cwd(), '.tmp'); const fixtureDir = path.join(process.cwd(), 'test/fixture'); @@ -16,7 +16,7 @@ const screenResponsiveViewport480 = path.join(screenshotDir, 'desktop-responsive let selenium; -before(async() => { +before(async () => { selenium = await new Promise((resolve, reject) => { start((err, child) => { err ? reject(err) : resolve(child); @@ -24,7 +24,7 @@ before(async() => { }); }); -after(async() => { +after(async () => { selenium.kill(); }); @@ -35,31 +35,42 @@ describe('standalone', () => { let browser; - before(async() => { - browser = remote({ - desiredCapabilities: { + before(async () => { + + let options = { + capabilities: { browserName: 'chrome' } - }); + }; + + browser = await remote(options); + + // await browser.init(); + + // browser = remote({ + // capabilities: { + // browserName: 'chrome' + // } + // }); // init wdio-screenshot - init(browser); + await init(browser); + - await browser.init(); - await browser.setViewportSize({ width: 480, height: 500 }); + await browser.setWindowSize(480, 500); await browser.pause(1000); }); - after(async() => { - await browser.end(); + after(async () => { + await browser.deleteSession(); }); - beforeEach(async() => { + beforeEach(async () => { await browser.url('http://localhost:3000/integration/responsive.html'); await browser.pause(3000); }); - it('saveDocumentScreenshot should work', async() => { + it('saveDocumentScreenshot should work', async () => { assert.isFunction(browser.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); @@ -68,7 +79,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveDocument480); }); - it('saveViewportScreenshot should work', async() => { + it('saveViewportScreenshot should work', async () => { assert.isFunction(browser.saveViewportScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); @@ -77,7 +88,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveViewport480); }); - it('saveElementScreenshot should work', async() => { + it('saveElementScreenshot should work', async () => { assert.isFunction(browser.saveElementScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); @@ -92,42 +103,44 @@ describe('standalone', () => { let browserB; - before(async() => { - browser = multiremote({ + before(async () => { + browser = await multiremote({ browserA: { - desiredCapabilities: { + capabilities: { browserName: 'chrome' } }, browserB: { - desiredCapabilities: { + capabilities: { browserName: 'chrome' } } }); // init wdio-screenshot - init(browser); - - await browser.init(); + await init(browser); - browserA = browser.select("browserA"); - browserB = browser.select("browserB"); + console.log("TYPE OF BROWSER", browser.constructor.name); + console.log("ALL BROWSER", browser); + browserA = browser.browserA; + console.log("BROWSER A:", browserA); + browserB = browser.browserB; + console.log("BROWSER B:", browserB); - await browser.setViewportSize({ width: 480, height: 500 }); + await browser.setWindowSize(480, 500); await browser.pause(1000); }); - after(async() => { - await browser.end(); + after(async () => { + await browser.deleteSession(); }); - beforeEach(async() => { + beforeEach(async () => { await browser.url('http://localhost:3000/integration/responsive.html'); await browser.pause(3000); }); - it('saveDocumentScreenshot should work on browserA', async() => { + it('saveDocumentScreenshot should work on browserA', async () => { assert.isFunction(browserA.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); @@ -136,7 +149,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveDocument480); }); - it('saveDocumentScreenshot should work on browserB', async() => { + it('saveDocumentScreenshot should work on browserB', async () => { assert.isFunction(browserA.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); @@ -145,7 +158,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveDocument480); }); - it('saveViewportScreenshot should work on browserA', async() => { + it('saveViewportScreenshot should work on browserA', async () => { assert.isFunction(browserA.saveViewportScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); @@ -154,7 +167,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveViewport480); }); - it('saveViewportScreenshot should work on browserB', async() => { + it('saveViewportScreenshot should work on browserB', async () => { assert.isFunction(browserB.saveViewportScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); @@ -163,7 +176,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveViewport480); }); - it('saveElementScreenshot should work on browserA', async() => { + it('saveElementScreenshot should work on browserA', async () => { assert.isFunction(browserA.saveElementScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); @@ -171,7 +184,7 @@ describe('standalone', () => { await compareImages(screenPath, screenResponsiveElemenentFooter480); }); - it('saveElementScreenshot should work on browserB', async() => { + it('saveElementScreenshot should work on browserB', async () => { assert.isFunction(browserB.saveElementScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); From 481e5fae5d243ce06d8c79516e669f2765c3c408 Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Tue, 26 Mar 2019 21:02:44 +0100 Subject: [PATCH 10/12] Bump up node version on CI --- .travis.yml | 6 +++--- appveyor.yml | 4 ++-- test/wdio/wdio.appveyor-conf.js | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index c390b63..ca1aa76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ env: matrix: include: # Node 4 with GraphicsMagick - - node_js: 4 + - node_js: 8 env: GRAPHICSMAGICK=true addons: apt: @@ -34,11 +34,11 @@ matrix: - google-chrome-stable # Node 4 without GraphicsMagick - - node_js: 4 + - node_js: 8 env: GRAPHICSMAGICK=false # Node 6 without GraphicsMagick - - node_js: 6 + - node_js: 8 env: GRAPHICSMAGICK=false before_script: diff --git a/appveyor.yml b/appveyor.yml index c52affc..5440fc4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,9 +3,9 @@ environment: global: DEBUG: "wdio-screenshot:*" matrix: - - nodejs_version: "6" + - nodejs_version: "8" GRAPHICSMAGICK: true - - nodejs_version: "6" + - nodejs_version: "8" GRAPHICSMAGICK: false # Install scripts. (runs after repo cloning) diff --git a/test/wdio/wdio.appveyor-conf.js b/test/wdio/wdio.appveyor-conf.js index b96c395..c675314 100644 --- a/test/wdio/wdio.appveyor-conf.js +++ b/test/wdio/wdio.appveyor-conf.js @@ -9,7 +9,6 @@ exports.config = { capabilities: [ { browserName: 'internet explorer', - version: '11' } ], sync: false, From 60cba7861226215332ac5e9d0b454481e6716e9f Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Wed, 27 Mar 2019 15:50:49 +0100 Subject: [PATCH 11/12] Adding ref screenshot per browser --- src/WdioScreenshotLauncher.js | 17 +++--- ...sktop-dynamic-size-document-480_chrome.png | Bin 0 -> 1817 bytes ...ktop-dynamic-size-document-480_firefox.png | Bin 0 -> 1762 bytes ...esktop-dynamic-size-element-480_chrome.png | Bin 0 -> 1108 bytes ...sktop-dynamic-size-element-480_firefox.png | Bin 0 -> 1035 bytes ...sktop-dynamic-size-viewport-480_chrome.png | Bin 0 -> 1817 bytes ...ktop-dynamic-size-viewport-480_firefox.png | Bin 0 -> 1762 bytes ...ment-modifier-hide-document-480_chrome.png | Bin 0 -> 3944 bytes ...ent-modifier-hide-document-480_firefox.png | Bin 0 -> 3871 bytes ...ement-modifier-hide-element-480_chrome.png | Bin 0 -> 3371 bytes ...ment-modifier-hide-element-480_firefox.png | Bin 0 -> 3298 bytes ...ment-modifier-hide-viewport-480_chrome.png | Bin 0 -> 1830 bytes ...ent-modifier-hide-viewport-480_firefox.png | Bin 0 -> 1781 bytes ...nt-modifier-remove-document-480_chrome.png | Bin 0 -> 2394 bytes ...t-modifier-remove-document-480_firefox.png | Bin 0 -> 2320 bytes ...ent-modifier-remove-element-480_chrome.png | Bin 0 -> 1963 bytes ...nt-modifier-remove-element-480_firefox.png | Bin 0 -> 1889 bytes ...nt-modifier-remove-viewport-480_chrome.png | Bin 0 -> 1883 bytes ...t-modifier-remove-viewport-480_firefox.png | Bin 0 -> 1834 bytes ...top-fullpage-modal-document-480_chrome.png | Bin 0 -> 1826 bytes ...op-fullpage-modal-document-480_firefox.png | Bin 0 -> 1773 bytes ...top-fullpage-modal-viewport-480_chrome.png | Bin 0 -> 1826 bytes ...op-fullpage-modal-viewport-480_firefox.png | Bin 0 -> 1773 bytes .../desktop-overlay-document-480_chrome.png | Bin 0 -> 1876 bytes .../desktop-overlay-document-480_firefox.png | Bin 0 -> 1820 bytes .../desktop-overlay-element-480_chrome.png | Bin 0 -> 1421 bytes .../desktop-overlay-element-480_firefox.png | Bin 0 -> 1345 bytes .../desktop-overlay-viewport-480_chrome.png | Bin 0 -> 1876 bytes .../desktop-overlay-viewport-480_firefox.png | Bin 0 -> 1820 bytes ...esktop-responsive-document-1600_chrome.png | Bin 0 -> 11278 bytes ...sktop-responsive-document-1600_firefox.png | Bin 0 -> 11341 bytes ...desktop-responsive-document-480_chrome.png | Bin 0 -> 5379 bytes ...esktop-responsive-document-480_firefox.png | Bin 0 -> 5431 bytes ...-responsive-element-footer-1600_chrome.png | Bin 0 -> 518 bytes ...responsive-element-footer-1600_firefox.png | Bin 0 -> 445 bytes ...p-responsive-element-footer-480_chrome.png | Bin 0 -> 371 bytes ...-responsive-element-footer-480_firefox.png | Bin 0 -> 298 bytes ...ponsive-min-width-document-1600_chrome.png | Bin 0 -> 11276 bytes ...onsive-min-width-document-1600_firefox.png | Bin 0 -> 11191 bytes ...sponsive-min-width-document-480_chrome.png | Bin 0 -> 9639 bytes ...ponsive-min-width-document-480_firefox.png | Bin 0 -> 9554 bytes ...onsive-min-width-element-footer_chrome.png | Bin 0 -> 541 bytes ...nsive-min-width-element-footer_firefox.png | Bin 0 -> 468 bytes ...ponsive-min-width-viewport-1600_chrome.png | Bin 0 -> 3921 bytes ...onsive-min-width-viewport-1600_firefox.png | Bin 0 -> 3916 bytes ...sponsive-min-width-viewport-480_chrome.png | Bin 0 -> 1884 bytes ...ponsive-min-width-viewport-480_firefox.png | Bin 0 -> 1848 bytes ...esktop-responsive-viewport-1600_chrome.png | Bin 0 -> 3922 bytes ...sktop-responsive-viewport-1600_firefox.png | Bin 0 -> 3982 bytes ...desktop-responsive-viewport-480_chrome.png | Bin 0 -> 1924 bytes ...esktop-responsive-viewport-480_firefox.png | Bin 0 -> 1957 bytes .../desktop-static-document-1600_chrome.png | Bin 0 -> 11276 bytes .../desktop-static-document-1600_firefox.png | Bin 0 -> 11191 bytes .../desktop-static-document-480_chrome.png | Bin 0 -> 9639 bytes .../desktop-static-document-480_firefox.png | Bin 0 -> 9554 bytes .../desktop-static-element-footer_chrome.png | Bin 0 -> 541 bytes .../desktop-static-element-footer_firefox.png | Bin 0 -> 468 bytes .../desktop-static-viewport-1600_chrome.png | Bin 0 -> 4634 bytes .../desktop-static-viewport-1600_firefox.png | Bin 0 -> 4597 bytes .../desktop-static-viewport-480_chrome.png | Bin 0 -> 2136 bytes .../desktop-static-viewport-480_firefox.png | Bin 0 -> 2081 bytes test/helper/compareImages.js | 2 +- test/standalone/standalone.test.js | 52 +++++++++--------- test/wdio/specs/desktop.test.js | 19 +++++++ test/wdio/wdio.appveyor-conf.js | 4 +- test/wdio/wdio.local-conf.js | 24 ++++---- 66 files changed, 69 insertions(+), 49 deletions(-) create mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-element-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-element-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-element-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-element-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-element-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-element-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-fullpage-modal-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-fullpage-modal-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-overlay-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-overlay-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-overlay-element-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-overlay-element-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-overlay-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-overlay-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-document-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-document-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-element-footer-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-element-footer-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-element-footer-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-element-footer-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-document-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-document-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-element-footer_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-element-footer_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-viewport-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-viewport-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-viewport-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-viewport-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-responsive-viewport-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-static-document-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-static-document-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-static-document-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-static-document-480_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-static-element-footer_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-static-element-footer_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-static-viewport-1600_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-static-viewport-1600_firefox.png create mode 100644 test/fixture/web/screenshots/desktop-static-viewport-480_chrome.png create mode 100644 test/fixture/web/screenshots/desktop-static-viewport-480_firefox.png diff --git a/src/WdioScreenshotLauncher.js b/src/WdioScreenshotLauncher.js index 5c0e9ba..345f842 100755 --- a/src/WdioScreenshotLauncher.js +++ b/src/WdioScreenshotLauncher.js @@ -11,12 +11,6 @@ export default class WdioScreenshot { if (!browser) { throw new Error('A WebdriverIO instance is needed to initialise wdio-screenshot') } - - if (standalone) { - browser.addCommand('saveDocumentScreenshot', saveDocumentScreenshot); - browser.addCommand('saveElementScreenshot', saveElementScreenshot); - browser.addCommand('saveViewportScreenshot', saveViewportScreenshot); - } } before() { @@ -27,8 +21,15 @@ export default class WdioScreenshot { } } -export function init(webdriverInstance, options) { - return new WdioScreenshot(webdriverInstance, options, true); +export function init(webdriverInstance) { + // return new WdioScreenshot(webdriverInstance, options, true); + + + webdriverInstance.addCommand('saveDocumentScreenshot', saveDocumentScreenshot); + webdriverInstance.addCommand('saveElementScreenshot', saveElementScreenshot); + webdriverInstance.addCommand('saveViewportScreenshot', saveViewportScreenshot); + + } export { diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-document-480_chrome.png b/test/fixture/web/screenshots/desktop-dynamic-size-document-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd4832ca37234a1cc28a7b0dfbe9d1ab53459c8 GIT binary patch literal 1817 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?OF7tpB1(>`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDKfl)!>0E2)) z0s{w!0Rsz*1OpQj4+A43TSLRB^k}e*CWisZ2I=M7`^o?S literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-element-480_chrome.png b/test/fixture/web/screenshots/desktop-dynamic-size-element-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..0b463d1af156183f63d82bfe5ce914c44dabd78b GIT binary patch literal 1108 zcmeAS@N?(olHy`uVBq!ia0y~yV0-{%f8byPk~d1X?*dXR>5jgR3=A9lx&I`x0{M)^ zLGDfr>(0r%1acITJ%W507^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10 zf-TA0-G$*l2rk&Wd@=(A^8rs6$B>F!Z?A4-WDsCDVBqtweujR@gqRC!i~Eb&7(QHC z#mw-)osEZqk(sTbfsxtaKm(&f!T|;Wg9HW+2?GWe9tj4fQR&fO8BGoYk_}=u7BfGy UKKZX2n7bJ~UHx3vIVCg!0FV97ng9R* literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-element-480_firefox.png b/test/fixture/web/screenshots/desktop-dynamic-size-element-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..8ecf2f7f96989be8a578a5d247b77e0c1c29f614 GIT binary patch literal 1035 zcmeAS@N?(olHy`uVBq!ia0y~yV0-{%f8byPk~d1X?*dY6N#5=*4F5rJ!QSPQ85o!k zc)B=-RNQ)d)sT@vf#<-6#`^OQn&ectewCh`W6W?McsCzIgS?~x0}GD?0}~q$10yqA zLjxnT!+{1yg@gkP0tN{T91^3_qrozo90npA6fmZ3X1=GrV(xWd?q=|G^>bP0l+XkK DiZHoe literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-dynamic-size-viewport-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd4832ca37234a1cc28a7b0dfbe9d1ab53459c8 GIT binary patch literal 1817 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?OF7tpB1(>`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDKfl)!>0E2)) z0s{w!0Rsz*1OpQj4+A43TSLRB^k}e*CWisZ2I=M7`^o?S literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..81c7c244635f46d07067c7ab9687a5a5ebb391ce GIT binary patch literal 3944 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9z`Tuv4JcwT$0ZC%v7|ftIx;Y9?C1WI$O_~$ z76-XIF|0c$^AgBWNcITwWnidMV_;}#VPN_n$sP#gzmc}Kijg6G#^$)uTrt2+9#CvN{rWf1pWy+^{I3nZHKVPv0d0-; zRUOc?fB(ITiD7xg73OUp7)M*f1KCNic*VHeMm~>|;UE81rU5NB2eRrM40anFmsl;w j$PoURnTCDDM*G=^gx|G_3-1N?co{rh{an^LB{Ts51MET? literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_firefox.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..be398545d77ef69054e5d70bd5919a504acac017 GIT binary patch literal 3871 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9z`Tuv4JcwT$0ZC%u_bxCyD1jAnzO zTsjn7VJ?f@f4+)|L4C&d^;L(&>_!W@0WI8%dp5ojWGFBljfa7)WZi8OW^aAP$}lJK zT-CwRTrt2+9$;)tzy96bma##&<{GovN5;`s*+8~NEnYG1{_H=k;Ds51Pp58)ozVsnJ|iw?*nuc=~Ti0S30Wr6vRVc{m>cb}_YUj_Df O89ZJ6T-G@yGywotBrZPy literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-element-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-element-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..305d025ef10794143a0744ed8c2fa49563b345d6 GIT binary patch literal 3371 zcmeAS@N?(olHy`uVBq!ia0y~yV60(aU~b`H1Bxu#*)<(Vv7|ftIx;Y9?C1WI$O_~$ z76-XIF|0c$^AgBWNcITwWnidMV_;}#VPNCcX_ZSXv+SD{~9Axhh7^SEk z1RZaG?>Ku^nZaUS`)C`2M(wAK``3NHD$QWgI2y#XYM*VapErv?V8OT1)(?$ZKlbgK WLh%x;J68icEexKnelF{r5}E)>&zf=o literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-element-480_firefox.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-element-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..d3ab7243fa836d314e6f0771b3c86711e9f05e9d GIT binary patch literal 3298 zcmeAS@N?(olHy`uVBq!ia0y~yV60(aU~b`H1Bxu#*)<(Vu_bxCyDrl literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..397c684fb829020426b63e2e9faa0543d04e3cf2 GIT binary patch literal 1830 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?OF7tpB1(>`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDx;PKn%?K>mfA*~5 zF)4-v%ePfAF#MUw!0h1Az^I^bfI&bYfq{bqsDnjM zT^vIyZoR#}QLx!TfaPHI)SyG^B|llddNn2S>{5=%&$@o*4I_ix*OlxH2c$U-7+6>& z7?_xN7#JDZ8X6dw9UK}M6%-CI2nZxFaBz%Dj|R(Vav049L%4Kk%(s1@_q+V6Fhj)w utNyA(x;CQ)+klq$*=c3AObqv)@z+1$2>y7XNFG>^F?hQAxvXq$Rw2>A7FL!e z-3wivX3Z^UFY0T`U%mUkO!68=hB>d6$}upU_h?{LP&mLKAdtYo!C}C_!Xm-I#KgnE z$jH{vz`*R_K(_ROK>i!4fA75FWSEl>XZMOTdI#A?QRa|Q-H_NlV|Z+pd(Osx$Bh{( z63$f}6w{-2l#hlqN%_d#Hevej>(RE14Z?e_Gn*AMQj*<9!=9wD$5O;uykgv4v%l_| zFoVU>t#TV$xv5nWjz$eRQ3I+!o|b)`&hX%UfG(BmrqLK7DMpHWHog*M_>dDri*^Dm cEmdKI;Vst08YYr0ssI2 literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-document-480_firefox.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..e560ecabf06ec740893dc29f6264f5862e6f5162 GIT binary patch literal 2320 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9z@)~(1{CS;ja&$%*pj^6T^Rm@;DWu&Co?c` z9QAZ@45_&F_WH&^XG0NJ$IhR&0+$#icV;Ut;R<)*eRA&31dW58&*n3}4=WIr-D`O) zf|j0y?|7z6|o7&tf#7+6>&7?_xN7#JDZ8XCx!Zd@$4;qb zzS3traDQPGmFuR_7$GS}o=GHMRc3f_a|bQj39z_$ApU%+z?rGepB@35I1HYyelF{r G5}E*l3u)~D literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-element-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-element-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..279b4923eb661acc656f1fd0b9c8f5b4d195759b GIT binary patch literal 1963 zcmeAS@N?(olHy`uVBq!ia0y~yV5|Y+FC1(@5j&P?^+1Xx-O<;Pfnj4m_n$;oAfK@~ z$lZxy-8q?;K#oGPN02WALzNl>LqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByD%_bn@vou913@MrJsH;fE1&L0?+SmYI)Mk%TWK~n57iOuc|1$O+SVN0XrmGt*r zzhN~C!}HIhX_u;L7s;?~-~U=xGc$;P7!6{iP@!sq-u8IuPX^X3egVZF41!Ig6t#ok aBlAyRerq+O373GCCWEJ|pUXO@geCyRC*ci(0|UF5 zr;B4q#jUs3Hu4^FU|?~S-pOv%rCcl?;==pnT*ix)hw3`#u6(fQ>e|P}J**A;%V*m% zG-PwwIkY@rb{VCp8w6`kOC*2eU^w^u;b_>>D0!{9|JN|BpW#7`+-MS}QT9FZZJ&L5 zKEng1(IBR7@qmc0BV~I`Muq>ZWYww<%n8hGWbkzLb6Mw< G&;$T2bUhgW literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea2a3784852c8ae15dc734ef770a866c5f391ea GIT binary patch literal 1883 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?OF7tpB1(>`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByD%)M-kVHlG)V?OPJF|9JKjX9unQj%B8S) z;Zl}K7voOO2|oDy;??=dJ+%xB?Y~yBGaOJCN?_pNFkoO|kzinA;$dK9WNT<(V0Lh5 zU{p{zz#t$%w)BRp%wad*_g677u+O;eZJWp`PYYWpbK^+T-Dr92#%n?EH~$~=Fx;E5 zIc`G>KeeNLBn2ns8RbA2f5g*D>+8Y{76;0069h-|2Ng>n(vxE2TDc9U?!R0q`QIgL`9vldmvnXfP2Y1-r6~f%+CWWIR;NxKbLh*2~7ZFG%WrA literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480_firefox.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..98ced8285a2891336e26d15e146b20f8971f578c GIT binary patch literal 1834 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?t2o$zBA3Od&j(U$N#5=*4F5rJ!QSPQfdcnE zT^vIyZoR#37|7x%;(9SJ%SPZ)LywGZ%Zdos42AnV&dn^7;)}U0+z-Bf@$G*0+G0kA z=~XM(84lE|9AFR-NMPXLFkoO|kzinA;$dK9WNT<(V0Lh5U{p{bTl&EYb{|Xo_g`5U z^ftuDzv5JmA=@a*95SjK61(4`UaxWQvG{+?nBm94dtaLb^=J|8qoGZ7UUIihICcGZ zuq|T)x6O6twjC5@x6yDXI^1y-aWY>UH0AsAK?PRfYWAK2MoLS-(I}xLN-SP62EQ|} e=VYks&+qupcg=UJtSYebWAJqKb6Mw<&;$ShpdnHK literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-fullpage-modal-document-480_chrome.png b/test/fixture/web/screenshots/desktop-fullpage-modal-document-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..5b3e29212811ffc3839574b3ac950d2fdb7aeb4d GIT binary patch literal 1826 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?OF7tpB1(>`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDfPv-U0R@Kt>t1{mkZIsvcVb=B`@Fj9 z;}z@-A6D;`V_?u0N?_pN04igVU|?e6VPIrrYiM9#c5rB5R8Tm;ARsU*jT|fwDxR$| zXE;z~Ga4+&!7`d!Ml;cHE<73^?|E0n%%F3ed9-vSu~v{@e2MdVm*a9*U|q%F>FVdQ I&MBb@0OY0-NdN!< literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-fullpage-modal-document-480_firefox.png b/test/fixture/web/screenshots/desktop-fullpage-modal-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..3ceab67f73f691eb7cc90f2821bfe777dc186409 GIT binary patch literal 1773 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?t2o$zBA3Od&j(U$N#5=*4F5rJ!QSPQfdY#> zT^vIyZoR#3DA-`Yz;f__0>l4xFFp#$G;pswv99TTUS0L^3U-DMtM|$=FlY-UFmP}H zm9a=LFfs8kFfy_=G%zqbI5aRSC>&rA5Ezw44weTM&(@eT94N9G4Ho2J8BHytnP{XH q9x~5MuS+u|SjvqSo+MTpKNy_dIUkyN)SLm`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDfPv-U0R@Kt>t1{mkZIsvcVb=B`@Fj9 z;}z@-A6D;`V_?u0N?_pN04igVU|?e6VPIrrYiM9#c5rB5R8Tm;ARsU*jT|fwDxR$| zXE;z~Ga4+&!7`d!Ml;cHE<73^?|E0n%%F3ed9-vSu~v{@e2MdVm*a9*U|q%F>FVdQ I&MBb@0OY0-NdN!< literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480_firefox.png b/test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..3ceab67f73f691eb7cc90f2821bfe777dc186409 GIT binary patch literal 1773 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?t2o$zBA3Od&j(U$N#5=*4F5rJ!QSPQfdY#> zT^vIyZoR#3DA-`Yz;f__0>l4xFFp#$G;pswv99TTUS0L^3U-DMtM|$=FlY-UFmP}H zm9a=LFfs8kFfy_=G%zqbI5aRSC>&rA5Ezw44weTM&(@eT94N9G4Ho2J8BHytnP{XH q9x~5MuS+u|SjvqSo+MTpKNy_dIUkyN)SLm`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByD`OOv9OIaKQNl>Ig*~ZxM&^Ta z>#x@CIb->ZfnndPAbkdg{~isD3JM1p1OyToI5-R#SXd+&n3#AN7#Z0b8W@-z9H=UN zE$35^y)45qiOrI)nFw0o@Ll-Y?03K8)-xR7-!*rSydFKANK^k0ZNszo9+;SW`;{oe zgU2!SN-;w_#Auh1sv4EAzYPTCjH+wgG6js(&Z(o}PD=3?@l0m(%otF~)}i$RSg`>katBw`wC#~#^CAd=d#Wzp$Pz1aWPr| literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-overlay-document-480_firefox.png b/test/fixture/web/screenshots/desktop-overlay-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..145471b1d9375670fd96e9b5d342dd82f9ec614b GIT binary patch literal 1820 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?t2o$zBA3Od&j(U$N#5=*4F5rJ!QSPQfdUsj zT^vIyZoR#8koS;*0D~j@QiF1~61VhaEgu|ml+vVje9kVF&(H2PWoVec>nbOZnT}f=c+$@gW<8PW4j1jaN%#u z*M-j?2d-y0z#Vw4U zua0AE;Ewvr#2!QKj7k?z(4>eN5SMS;dMr!rI;db<#04zZ77!>nH>6KqJl~z+0ncc> d5v+Ia1=|UQ7D-?D2CVKFJYD@<);T3K0RZ43A3gv8 literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-overlay-element-480_chrome.png b/test/fixture/web/screenshots/desktop-overlay-element-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..5ed73fd5c17f6fe49ed187fe8d82a8178dab0eb6 GIT binary patch literal 1421 zcmeAS@N?(olHy`uVBq!ia0y~yU|a&k4jgPik{RwbiPH{GB6wyP+?GF;cQ@WWKwXPz~BMo3L$ZCr1Rf@zOzc3!TigtH|_j5 z)uCw{YhW{YAVDIwD3=Aya zJY5_^DsH{KzEP0LP=LkJ_G_c2v4XLYu;z)&4yCu#*O-@HmrCYkuy|8g#lX;`=)vH^ zA;iGh#NyDTz&Js{gFyv}Tku|PU;O&Z(TqPF&!4UPF@eEDK!rhwg|mUhkx9XEluPr_ zXsP~QaIUgSo1y+pJJuLNi?C5Ha`L4#H16zfFRt^;XMMoF_N=u$&RjyNHAoq5)F|Zm nD_CoI?WG{Y17|{o%|mWMTb>5KW1pV`%R~lGS3j3^P6`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByD`OOv9OIaKQNl>Ig*~ZxM&^Ta z>#x@CIb->ZfnndPAbkdg{~isD3JM1p1OyToI5-R#SXd+&n3#AN7#Z0b8W@-z9H=UN zE$35^y)45qiOrI)nFw0o@Ll-Y?03K8)-xR7-!*rSydFKANK^k0ZNszo9+;SW`;{oe zgU2!SN-;w_#Auh1sv4EAzYPTCjH+wgG6js(&Z(o}PD=3?@l0m(%otF~)}i$RSg`>katBw`wC#~#^CAd=d#Wzp$Pz1aWPr| literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-overlay-viewport-480_firefox.png b/test/fixture/web/screenshots/desktop-overlay-viewport-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..145471b1d9375670fd96e9b5d342dd82f9ec614b GIT binary patch literal 1820 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?t2o$zBA3Od&j(U$N#5=*4F5rJ!QSPQfdUsj zT^vIyZoR#8koS;*0D~j@QiF1~61VhaEgu|ml+vVje9kVF&(H2PWoVec>nbOZnT}f=c+$@gW<8PW4j1jaN%#u z*M-j?2d-y0z#Vw4U zua0AE;Ewvr#2!QKj7k?z(4>eN5SMS;dMr!rI;db<#04zZ77!>nH>6KqJl~z+0ncc> d5v+Ia1=|UQ7D-?D2CVKFJYD@<);T3K0RZ43A3gv8 literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-document-1600_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..33fb9f15ca893b0015b1c0540ce746b930156a50 GIT binary patch literal 11278 zcmeHNSxggA6uqsL66;13aH$Q(M2#CngMw086fH!sKqLegs0&duMj9%qv{uF~t`Q9w zmlO(q&=?R@5RE`ZO)TM~)-(cfgCYopNEHf=Rlzs!&-jHOYR8xPxbyCO%*=UrJ@1}L z*d&`YVb%lym=qfmodn<`1>kk~`XEh*ESN%qwA`3 z=0mSOzAh0ICJW7W?X!#-8OhaxomJ0wCq$J8Jl>sN)Y6rmuefuz*eAcQW^Sv0Ur5t2 zb9v5{HmxM`xkPC)*4e)+o8K9A+_VSxN(0erKq;t^R4e_}rF>=uP`8)si*GK@qp^f= zqF{jd>v(iKIMS9P5h$fp&zmcUFLOq^DsKi4WOzOR|KK$dY|i0u@s4%+24N|^07QY1 zAb1dS02qrml-J9(8s799^g93^9ZshfFwNtFiMrtZv4maw6ga0;*HxZ zv6y?d`Fa|IT*K1V5$luWLoCYKmK+UCt#P}!^!rq*v(;!Yt<r+M3~l#c=er2)$T*!hZ$s5^<%`d+$A7eFGLx;`?@fNK^q%Yk9|(@hoSv=xas>#6u) z=Jo9X`*Zi&7qRISq&q?kJ)XflGma}=DWdcG+T88TfltAZM-;A>d{ZzLOO;5sM$9=) znjvh3q=CRNkizZv3pe&RLu_OL845aCtHIXaFnTpG2;YrmK#5HFF_8Ts#4M8G8HaC& T@VBD5U4Yp2o1!b$DvtdCXnYh9 literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-1600_firefox.png b/test/fixture/web/screenshots/desktop-responsive-document-1600_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..c9284d493f2857f437bab0a8253d3c6a1b2696c6 GIT binary patch literal 11341 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#V0pyB1{8VZuAdF0*pj^6T^Rm@;DWu&Co?eU zFnPK-hE&{odt1LhH=MEk;ntHs)UNJO$`TN`Fz3~-M-PNe7G$m4HK%sRvPGp6W;aNN zvhQRn^*uh_p(*o_yf;%V`&yKpG9Ci^Rh$H35#KZ}70%zDD10Hz)KMg>3tG0@?0?(Qo_hwCx63=a~%86HbL zdGh)3%ZwGt^4|Zn=gZYI?Af?pjv=IyaWwJ9(Xvit<+gZgTl6(6V zE66W4te3^3c5vxCfIZeA!^i?=oDdwk0z0E^8D7ldk6$y7p+MvJ-~3}w|7|z7|NiHo z#P9y_`*IH=zTNLF{Q39odE5Etlkb1OdY#>3O7872e}+YS7#P96FJch@(+cjR0-%5x z4Uf^}z`#ICZU8pMVr-eZw&i{W*W2@&UUKWkw2CW$!*N)&yzZ=(V`w?Mvx@P+#y7tu zrk_6B|MvrXelLIhk87`PGs~Pht-nu7|NoDxXV2Tt^?O`mwRWG~frW2=@2g@Gc*@EF z4u=WK4PctVl4(=`7!sr5F`68JAwWWI*nHOV*(-h%YJ!={5QW}u{um0P7Sxw;XhDT9~N!!p%<0s%%0C!?e1`K+uAr# zEF1_ns9o5)`UBI@A9aBZ7|q#zmAPSEdwV;$!Se54-JSdQ@Bg{;`SbJS`hPWFzcTWr z)_+WjiQBW|=g#Mb$M*gD#K688*q2Hf9pVM0hyfptr(|q#=;g;@>Dv)9#QW>Cyj`R% z>x^Go`{=E4L9BQe5KX+sOf9uuj`GG^f^Z(iD)&Dzw_I&NPdz(ML*_#d)&j0`D z?N#9hjo~!p4J&+y!|?s6UqIEs5SodZlY7oEyuV>lZuDNT%aHcG@_5as?F81#SPEddR@S{BYd4HYJxBj|azkV^aZ>s(MceI2V z%2SA=Wze81gGNdT^Z(~__0{SOGN+Eu-zO(u|LfPY=kw~#j{W-#8tR?)H#|9}uJ(8F zdHbsJH_OYzp=fS?83{1OS~7i@^W@ literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-document-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..4cce4e6b23038ef5910423c015464d33663c5e87 GIT binary patch literal 5379 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9!19QL4JeYNVqgiRSkfJR9T^xl_H+M9WCijW zi-X*q7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk zpaffzx4R3&e-K=-cll%n29bPE7srr_TW_x`o}M2nao}O`vBL(ZR-Ms1G3&3Xt z(+MZ{+5FdAKbz(BD~X&o)%$tUO|_e>dXf{5zf%A3{lLz3`UUr&S03uG?lZi`!0<2J z{1q!hf;$rr10y3_Ljwb|gF^$Og2Dj?0f7Vt4h{nb78VHxra>(2zW0FSnkvR)J|YeYu8W`ZhkAAIznE3eX+BxrEz0#Vw z``-Tb^Y?A7{G4V~ew9D{OjVLKyEEQlSsbm&2S)ZXvc#Eus_O>bAqPh gAGD7C#(Ktt?;%GLBg{Sk2O}9gUHx3vIVCg!0CF9Vi2wiq literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-480_firefox.png b/test/fixture/web/screenshots/desktop-responsive-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..ef71b0da2bae309effde975964db3d3f606bd457 GIT binary patch literal 5431 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9!19QL4JeYNVqgiR*pj^6T^Rm@;DWu&Co?dJ zyzz8#45_&F_WIg$F`*J|56dTi^j%e`kR>2+fk%p+uWtckXmDs6zbQw-1hoXWtBzU$ zrZsX*oNX=g-b`G52?9084Zf@V-lZ13K0Wow+^uKMR5CPlS1pudV2D;Zz#t%yz`(&_ zz`(*H!NA1C!@$VM*3iJf?BLMAsGu--r8lf*k7+KpO?Z55rlp#?e4hXE&3>QWzt6X~ z%C=qboOQ_fV-N>1`A$oiIkVW7iDBC@Zd#_Pvab!<1^a&Po3|nJ^~=+i^Y-ofv9rBA z?OOTk+xfSDeLeGW_UZZ67BXqE*MI$*y-mm4R&g|43~aupTe?_XV0WE+TW)N6-|=qw z>i=J@i~sjpe|>BI_T=~f=O)Yl+xuhZ@4t25e%IFi^^Ly1b>4)}Ohcm7BR@+H_Tv1^ znVoWs4AGBiT5|8MI$&B+ZMRN6=hphqcmJ5(kNx-H@R>EhgpoIQ=HsXRwr3K<>g%#* zE*(t}1D#$r&@Dkkyk?XxFa8~S@87q@#l}bX@4x^5|Ha7bRgULrT6+zx=GH(IJO_-7 zpI5Ok&z>y0U@!y;M_26$%LaF@t zw#w<;Xk9X(qY8AaOXl0#uLU+R)#uyJ_qVIA`&i5`e`byRwe9z}ef>Q1vG{cR?;oD+ zjr{)o)$9CQMKxjmCn^~SwpTXLO+9*-59lLY5oyn2`WYJ5ejL($zyt4M^cfm>KMie9 a)N^Q-AMs&WGY2>l%HZkh=d#Wzp$PzP`pE47 literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-element-footer-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-element-footer-1600_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..7fa5aa65424ca4731b55f672bcd2bd57fff3430c GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0y~yV3`DD8*#7!N%nmo9|0+rbVpxD28NCO+Jr4H}e8=9T`3`ovkWMV+U$t zsN1ug8AR`Bp2z~E9FkNRfz$*EPmrLBn-GZV9F-z2G)}UAW?@RQ*m!;oNWG`4pUXO@ GgeCw+pkWXI literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-element-footer-1600_firefox.png b/test/fixture/web/screenshots/desktop-responsive-element-footer-1600_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..cf9691d46904910f7f11fde0c6144d2b9a263b5f GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0y~yV3`DD8*#7!N%nmo9|0-0ByV>YhW{YAVDIwD3=E7# zo-U3d6}R5r*vNapfaie0_W%Fi%nQhMWcb8%wyG?R9jJ++ZqIUN5WS;$A`6gmNK#=0 pQWGRRL4qo7LLjPhREoIJILZE*g(=Bm&sZGf z?!>U}oXkrgM`tuK(|H(?D01J^ z#WAGf*4wLwj0_4q2R1a;pMTIKr^5BCbnZ-Jh6BO7`4}4HB@Gx@cqAB@*mxKinb{f| s7?~XoG%zY89AFSINMPWQ7`)Ok@dufb*vl4$0KLlK>FVdQ&MBb@08-&Uk^lez literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-document-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-document-1600_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..cfd442cc062ca2dd343ea08599cc916fb807fafe GIT binary patch literal 11276 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#V0pyB1{8VZuAdF0SkfJR9T^xl_H+M9WCijW zi-X*q7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk zpaffzx4R3&e-K=-cll%n2JH$@7srr_TW@bKWzcnl12ri?6L#tA_OFx?I2?;u1i-X{`_L75Zez=^>YM(4KYxY?4PWo=R(}32 ze|bLN0m0XoXBL0IcR8H>LBrN-UsyaoF^$#+z}Oz>!hf_524}gU91W4x^S^!JsJb>Q z4(ydXU2nBb!ym8?qpJG(OU4OXzXO|$~Pu~F?0;3Jf(V`WY5QcJ|9^fw0oUPw8{reZBuYC#XYcd>Idt+ZvG3#*Z1{BYe zV+fU>GtURqPMPo5pT>9ZvN`*M38uww;{G`>~cwg<@W#$F1jBFViob{Za-}}hVRB-v9 z>@V5K9O!973ZG>2GUqT~>Y(nOy}QI4RKHw*E>? zqqqXd8w?J84B+u+h9?|DS76R^c89B*)6XwcXDB$(%+Bw2?yi2kU%YGs^R>I6F_o9y z%mpWA$uR^Dr#9K>s4_SKkB%yXgMr=+wUIG2JMaI8k}4(!_B;PyJUp@U_vi1+*Yh1< zeEoX9`?=bWKaPI6%4qT6-t_Ow)Ey=br}A_NR|TU^2NefHxmG`S>-U!B?iV(rOpG%P zr@=}~fBuG5`F54*prWPb+ueNNxU3&|T=u|~_dou9J`Nh9Jy7-e@Jr4KPe#X7Kna@O z)!XP;#;^mMtO857nH$A zXMG&N!9dX*=dNeY5b_JEiCqZKeH%MImd*!<1z?MuNgYfSfoe8R9p^mcgGx&y-Yc7`1OoI=EIZr{qE=X#^_xRXMe!3|8aqATmvWo7)D!_qeUw)6%6G( zJ<$E5?Dv=F$vK{ny37sAPYux9Yt1xsLmVJNWb+z}{|?F&gF<1n%S*v9)`%ECS@7y>zW#D`hJpi= z&(H6jvwQ!~oL{dPWH!|OseN+CT>qX=ylexroPE8GE#suoZVxz1kua=3+Eo}0F>HOy zk`{k)RxViE={-2EH_o7|k!em+9@$dHQmw_gHULRh5Sy*9o78#sLMkkF&Cyjv# zfs)!~gv=t>|KB%f9>W2~_w^rgfZd?$U(PaGB-Pp!zx(&D`{iopf&;()T_2rE9$i8O zE>=f7g5Y4FXzp|P_k@Pyx;5ZbR>Lw|TX6I@l+PMYi-};P>%(DT6wEK@{wJGOY^Yq> QpbLsIPgg&ebxsLQ05m>!C;$Ke literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-document-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-document-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..9b47d6f613cae24896caf69b0e574a33155cfa16 GIT binary patch literal 9639 zcmeAS@N?(olHy`uVBq!ia0y~yU=?9tV0pyB1{66Rl^+45SkfJR9T^xl_H+M9WCijW zi-X*q7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk zpaffzx4R3&e-K=-cll%n2328C7srr_TW@bEa>u1gG(7y?)1Npc^rGI0S+#1-TuECw z)P8^Z6BB37DYlv;%V1}obW`j`zQsBff4IL}G(Wd4h^>E6d9R4?j?L|;?0BFJ3=9Y7 zz680Eq2aTD2qTF0319*7jT{9*)Cm?>5TzhIDoIHo?Do+w;Qj^-X^Rx;S-)r5a~xRt z*ZM2_PQU#!4bJN>bDt?*$N>uHlqMw*HG#7WL^-HwFoEcq3q~bJ17QfIgl%iLetW43 za&SX&!H`PXH&d$`qc{Bjb^8k!gUp7#-`}0M^LO{l>C6R3zP&tir}qBx`FsZ$Z*TKm zZ*Z=4G^>u5SD-XL91885+pgVOJ{{y6hI0ppR?43Kk~QzpKL31%1A@2BjK19z&-Vq^ zs?6`||2{u)=k-^sza(RR&f<8J7;aBp9W`u#-+lwA*4?if-n_BTd* z59t0#u$>pj*uY#D*Pq7r{<1#%g9*85Z}$CcWSDbv8~H^>KNY2Uq?{|LTiRKgRT->qp;iNZAwD zG}=WS?WYg@!HV4MwY628pnUp3CT2(tzLd?3dmv_0`>Ujim4UC~!-Ipsj_c9xm&=(8 z4wQj&ec!joeD5I(aeTorI$%6HYCfdKBY_i8^W(q`1`GC~m9k@(iSJ;& zU-#)8DBpg#`F(%?nZ4^?f4R(Pk?_iT-~X?d!OZHX)?{3J$!^w~?8-`~OB?d)Wr&ZQH+3-1&QPKV)X-vHY@diRVtEbKj#206@LK z;jjuKCp!D>Wp9vg7@j{EP1!V$RK4F{K#PGG4rC6kf%zd>`)~Tsxbk_(kq7w)PJqJP M)78&qol`;+0LYnkH2?qr literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-document-480_firefox.png b/test/fixture/web/screenshots/desktop-responsive-min-width-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..df2dede09e330d21b0fbe6faf7bf9e224cb64d07 GIT binary patch literal 9554 zcmeAS@N?(olHy`uVBq!ia0y~yU=?9tV0pyB1{66Rl^+45*pj^6T^Rm@;DWu&Co?dp zvU|EXhE&{odrNV>Y^X@XMdK&SW`zhfxd*h@^98aTO!5f$@v3O$y7fv26F8f=?tI>% z^r1yTy5#H!@qKBt-dHEDwcqgF(D>x^y=%9AV+Gp4Ah5@LFNkI+kZV!`(GxhkK$L@; z1`~*$xqt&irHo2a6bRE_vgRGM1BP^aPV(fxjtu8=U+@>rtutq6k6A80NqN?*ZQ%-(T`FSR~zcJGSrFx5Y1~GZ!3KEMDJxW^dg3%l_;S815H}gWEI* zq6J24*3sq#D4h@KHrA%xwOjr5L8TAFoM!GJ)n?SY%zdZn`0JZrxEN$U6xq&|+~dDr zronmJ%#FL{IS#DM4Yr>k{b)$F8AhAuz+^ZY2si^_h_{9xSb;jNG5^~qGggSNGY(Ea z#`K}@N8fHpE8$+#=zAq^-!v2t zt(1K;wW=}t!>jAhFKaUZ`>E&W_nf)A|7Xsxmkcr+{(iW9;?DK+asKwQ4a{sQs2&Z3As-00qq676f!hlf>_aPM$1W4!!D?Uk^CY<_|F;O7gKK|ORJ9iBjSe#n?GcvI{w%Phfd#_0t=H`Kf~O)2_=Z->-tD7b!2R#< z^Pk{6`;XnD~*k~!%&|JR&=Bi5%+%moFxr>mdKI;Vst0QNg33;+NC literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-element-footer_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-element-footer_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..39b5ea200ed638ec3d929e58f323787a786e8727 GIT binary patch literal 541 zcmeAS@N?(olHy`uVBq!ia0y~yU=;zfjX2nVq^@>&3Xoz+cl32+VA$Bt{U?zX$Y(4L za(7}_cTVOdkfV_75#-CjP^HGe(9pub@Czu^@PdJ%)PRBERRRNp)eHs(@q#(K0&Rd2 zY)RhkE)4%caKYZ?lYu66db&7}?f=mYjVt{_^$SOmmxI1|7E;u<*%f~XUtk`x7k-h`!0No*`7mY~4&boFyt=akR{ E0KOq$rT_o{ literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-element-footer_firefox.png b/test/fixture/web/screenshots/desktop-responsive-min-width-element-footer_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..7021a305456537adc488636d24ef4984844b507e GIT binary patch literal 468 zcmeAS@N?(olHy`uVBq!ia0y~yU=;zfjX2nVq^@>&3Xoz;@^*J&_z!{$_AZ~yz`)q) z>EaktaqI03M_vX6fdd^)Lv$xy}fp57_g#f@lR}5fH!O nOaKdrYve2lqE3uTQWOY!6P7Y1v9Xj`f&$ai)z4*}Q$iB}(6hB?N?v)>ASnX`E>I3HDrKGrt%f56HC z=1ov;0MiVXOhZ@T`&-5U)BXQ*{23lJeg2mF^v=(%z+z;b#r^Vgb7#I?&0KKMGQFBf zrIK;93IIm-XblKX@dI814&jE#oSCa>7FVdQ&MBb@ E0Hw$FeEhE&{odwb*BU`G+xK>i}xDGqLaew-l=!Y3ASYAs+XDl+m~FwtA^eRTM}sMU>@ zlYe;Ln`K-)TYAsN;%(wULm3#>C;jn0E4=5n9GJ)O;Tnqon5E#(zzAj(jS7ImVZg)V z-EHOtS=-nd3Qk5^-xOzguvNF#QSSD4wg;1re`Cn_#KZ!QtrLO{V7ftuaZ~^p5~JZU znj9DyNXZSB#@lboIi9z?%?%28AgTS^L@4qtDb$I|CW;>rogT?#jYd3gBRL=wo04GoEk^U4c8>*&VK(`NqVs&LaKkjs5ZW^MM5l zx80u~+l$^k{&-`b6@&N>+4kojMjI)hs2**TfD=3^mGWq-78GQN5E~hd6ubNT^8Fbe yG{tYvw`M>8?JVPtCvRk|?GzaF-{#ahD7>?;`K#|+qU!$;6gZx)elF{r5}E*h!q8a& literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..1268ca34f506db977afab468bc935b6def57c15a GIT binary patch literal 1884 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?OF7tpB1(>`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDUVBp{|U|?a9 zU|<@=((bkoxXNr98iK>Vy#L+Vv}0(weh>#Nc}`n1^X69$h8@!4v`jfNUmLV<+_(SA z!r&JXKmX+Z-#>pv)6~KtkPpamq!ZS?;i_udL~TZR;-bi?{8_7DO1f_YI|J%>{qY7X=(fn zAC}L1#mG?L&cwsO$jH{vz`*R_(7>pmaDYKTAc28{!+?Q>MS_885KH%09T0s}#lWz9 z&70?sSqmA5oCgMR*plwF2;B%D37 z&Yj`F-5s>deh&iqcQjr9xk8FVdQ&MBb@ E0M?x~3;+NC literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-viewport-1600_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..7fabed70e2a6060058ae97e510ce14645251deed GIT binary patch literal 3922 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#U|h<<1{7JOWF-NlSkfJR9T^xl_H+M9WCijW zi-X*q7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk zpaffzx4R3&e-K=-cll%n2EKisE{-7;x8B}1+!*30;(9SNiz!5*k%#ex1EbzCR;~+; z4f7QlMN_8F_~U=qeD^h@3(F^q?}@EV%PVHSch~YZH_%Xq3f9N`x;97K-!g)D3=Hpm z86d1876Gt;g8QfdC?EzpJf82fWq2_Q7)|0O)6V^Uv6|<@{Qc4KPmX^(%c%EaqbrqsakStdfu$ERDC{lw)*#o}&*6xd);>_FF!P#5I6} zk-?IQ1I(D9Jah$$@5?cioL#^DEhoeD;(c|ImgRMM_hlYLo!dUQI6dw6E1>APoAVf4 zDjAu;etp8B0Hz)K7)AwvAu$>rqsf7Rft1`ZXXfpk{)R=x+r&X3_krt}d{hOOz5_TI zNhz8JZQZ^zpP%7S8qj+&=Pk95|NHkZ^Y=4`>7RZcpFg!&zW?~QtBiWbw+mK?4JSVj z+Q=An7${>6i+qJMD(4s%&weWyP;%}YxJr&Y_`{jo{~_y;X`K9LSXH9!c%SY1EKpo| My85}Sb4q9e0BQT~*Z=?k literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-1600_firefox.png b/test/fixture/web/screenshots/desktop-responsive-viewport-1600_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..10bea61c7b5de2dc1130e77b918518a8f8ccbd0e GIT binary patch literal 3982 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#U|hw)1{4V{={O6d*pj^6T^Rm@;DWu&Co?ec zJA1k~hE&{odwXMVh$n;V#a|hJJkvhjJ|4YDp=+HQr%HiZqblpQbmbepO&nRWO9bsM ze|`Q+X64(er&~U*e-)9vhVf6?@r~7tK*JfUJUn=j++jr;ho!9e|&wSsV&tIVTdA(s?{QLTMU#nz`&)vPwZZY+- zMVUXtqCLaF??X7+Mx8!va$w)qW4COXy84p8GlBdR*Zh=QcMr#Ks>3U9*fMZLXMbmE zD4to|bNlVP<8?nC7uHn#-tqez!}3orfA@cUIbXiq{(I5Rp3_e^{r<(U-01loTgHx0 zOrup8Fi8w_qjR+F56YNBIvOmmNo9ZM(6H*e%MJ2M1@AQdEgzJIQzia9@jJtU*LQ#H zsAf8_@{jet-v7t8|CX>N|`UOLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByDD5v)|5xV zAjr-KX3dP{XJlAj$VkH?<-l6G2YPQ}{SQQ)+#J8Y|LZgN-~YeO-BTSKzW3M1KaId7 pAT$VqVu+QhR7-xeNdkYE-X4(loc!#|XJBo};OXk;vd$@?2>_%uBO_Zw0|T>zLj$9N!T|;WfdmE) zj=?KE=N04kg!Sw)cV^AZF8cKJZ;4g*r2X}E|6i=BayZXDB)v3-sWqo*4Jm; z-gZ^EC~oklYSO}a2xV80$F|M9`C5>nz=WppP_T;qPHXLYahcmu#@An;?XUgw!=Qh@ z+^gI2w=TcFZS%Ks_s^ZrKUbc6UR?XvIXZhZSqyj~Pq$>zeE##=c?B8u&r|=MJ^hw{ z-Wzcnl12ri?6L#tA_OFx?I2?;u1i-X{`_L75Zez=^>YM(4KYxY?4PWo=R(}32 ze|bLN0m0XoXBL0IcR8H>LBrN-UsyaoF^$#+z}Oz>!hf_524}gU91W4x^S^!JsJb>Q z4(ydXU2nBb!ym8?qpJG(OU4OXzXO|$~Pu~F?0;3Jf(V`WY5QcJ|9^fw0oUPw8{reZBuYC#XYcd>Idt+ZvG3#*Z1{BYe zV+fU>GtURqPMPo5pT>9ZvN`*M38uww;{G`>~cwg<@W#$F1jBFViob{Za-}}hVRB-v9 z>@V5K9O!973ZG>2GUqT~>Y(nOy}QI4RKHw*E>? zqqqXd8w?J84B+u+h9?|DS76R^c89B*)6XwcXDB$(%+Bw2?yi2kU%YGs^R>I6F_o9y z%mpWA$uR^Dr#9K>s4_SKkB%yXgMr=+wUIG2JMaI8k}4(!_B;PyJUp@U_vi1+*Yh1< zeEoX9`?=bWKaPI6%4qT6-t_Ow)Ey=br}A_NR|TU^2NefHxmG`S>-U!B?iV(rOpG%P zr@=}~fBuG5`F54*prWPb+ueNNxU3&|T=u|~_dou9J`Nh9Jy7-e@Jr4KPe#X7Kna@O z)!XP;#;^mMtO857nH$A zXMG&N!9dX*=dNeY5b_JEiCqZKeH%MImd*!<1z?MuNgYfSfoe8R9p^mcgGx&y-Yc7`1OoI=EIZr{qE=X#^_xRXMe!3|8aqATmvWo7)D!_qeUw)6%6G( zJ<$E5?Dv=F$vK{ny37sAPYux9Yt1xsLmVJNWb+z}{|?F&gF<1n%S*v9)`%ECS@7y>zW#D`hJpi= z&(H6jvwQ!~oL{dPWH!|OseN+CT>qX=ylexroPE8GE#suoZVxz1kua=3+Eo}0F>HOy zk`{k)RxViE={-2EH_o7|k!em+9@$dHQmw_gHULRh5Sy*9o78#sLMkkF&Cyjv# zfs)!~gv=t>|KB%f9>W2~_w^rgfZd?$U(PaGB-Pp!zx(&D`{iopf&;()T_2rE9$i8O zE>=f7g5Y4FXzp|P_k@Pyx;5ZbR>Lw|TX6I@l+PMYi-};P>%(DT6wEK@{wJGOY^Yq> QpbLsIPgg&ebxsLQ05m>!C;$Ke literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-static-document-480_chrome.png b/test/fixture/web/screenshots/desktop-static-document-480_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..9b47d6f613cae24896caf69b0e574a33155cfa16 GIT binary patch literal 9639 zcmeAS@N?(olHy`uVBq!ia0y~yU=?9tV0pyB1{66Rl^+45SkfJR9T^xl_H+M9WCijW zi-X*q7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk zpaffzx4R3&e-K=-cll%n2328C7srr_TW@bEa>u1gG(7y?)1Npc^rGI0S+#1-TuECw z)P8^Z6BB37DYlv;%V1}obW`j`zQsBff4IL}G(Wd4h^>E6d9R4?j?L|;?0BFJ3=9Y7 zz680Eq2aTD2qTF0319*7jT{9*)Cm?>5TzhIDoIHo?Do+w;Qj^-X^Rx;S-)r5a~xRt z*ZM2_PQU#!4bJN>bDt?*$N>uHlqMw*HG#7WL^-HwFoEcq3q~bJ17QfIgl%iLetW43 za&SX&!H`PXH&d$`qc{Bjb^8k!gUp7#-`}0M^LO{l>C6R3zP&tir}qBx`FsZ$Z*TKm zZ*Z=4G^>u5SD-XL91885+pgVOJ{{y6hI0ppR?43Kk~QzpKL31%1A@2BjK19z&-Vq^ zs?6`||2{u)=k-^sza(RR&f<8J7;aBp9W`u#-+lwA*4?if-n_BTd* z59t0#u$>pj*uY#D*Pq7r{<1#%g9*85Z}$CcWSDbv8~H^>KNY2Uq?{|LTiRKgRT->qp;iNZAwD zG}=WS?WYg@!HV4MwY628pnUp3CT2(tzLd?3dmv_0`>Ujim4UC~!-Ipsj_c9xm&=(8 z4wQj&ec!joeD5I(aeTorI$%6HYCfdKBY_i8^W(q`1`GC~m9k@(iSJ;& zU-#)8DBpg#`F(%?nZ4^?f4R(Pk?_iT-~X?d!OZHX)?{3J$!^w~?8-`~OB?d)Wr&ZQH+3-1&QPKV)X-vHY@diRVtEbKj#206@LK z;jjuKCp!D>Wp9vg7@j{EP1!V$RK4F{K#PGG4rC6kf%zd>`)~Tsxbk_(kq7w)PJqJP M)78&qol`;+0LYnkH2?qr literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-static-document-480_firefox.png b/test/fixture/web/screenshots/desktop-static-document-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..df2dede09e330d21b0fbe6faf7bf9e224cb64d07 GIT binary patch literal 9554 zcmeAS@N?(olHy`uVBq!ia0y~yU=?9tV0pyB1{66Rl^+45*pj^6T^Rm@;DWu&Co?dp zvU|EXhE&{odrNV>Y^X@XMdK&SW`zhfxd*h@^98aTO!5f$@v3O$y7fv26F8f=?tI>% z^r1yTy5#H!@qKBt-dHEDwcqgF(D>x^y=%9AV+Gp4Ah5@LFNkI+kZV!`(GxhkK$L@; z1`~*$xqt&irHo2a6bRE_vgRGM1BP^aPV(fxjtu8=U+@>rtutq6k6A80NqN?*ZQ%-(T`FSR~zcJGSrFx5Y1~GZ!3KEMDJxW^dg3%l_;S815H}gWEI* zq6J24*3sq#D4h@KHrA%xwOjr5L8TAFoM!GJ)n?SY%zdZn`0JZrxEN$U6xq&|+~dDr zronmJ%#FL{IS#DM4Yr>k{b)$F8AhAuz+^ZY2si^_h_{9xSb;jNG5^~qGggSNGY(Ea z#`K}@N8fHpE8$+#=zAq^-!v2t zt(1K;wW=}t!>jAhFKaUZ`>E&W_nf)A|7Xsxmkcr+{(iW9;?DK+asKwQ4a{sQs2&Z3As-00qq676f!hlf>_aPM$1W4!!D?Uk^CY<_|F;O7gKK|ORJ9iBjSe#n?GcvI{w%Phfd#_0t=H`Kf~O)2_=Z->-tD7b!2R#< z^Pk{6`;XnD~*k~!%&|JR&=Bi5%+%moFxr>mdKI;Vst0QNg33;+NC literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-static-element-footer_chrome.png b/test/fixture/web/screenshots/desktop-static-element-footer_chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..39b5ea200ed638ec3d929e58f323787a786e8727 GIT binary patch literal 541 zcmeAS@N?(olHy`uVBq!ia0y~yU=;zfjX2nVq^@>&3Xoz+cl32+VA$Bt{U?zX$Y(4L za(7}_cTVOdkfV_75#-CjP^HGe(9pub@Czu^@PdJ%)PRBERRRNp)eHs(@q#(K0&Rd2 zY)RhkE)4%caKYZ?lYu66db&7}?f=mYjVt{_^$SOmmxI1|7E;u<*%f~XUtk`x7k-h`!0No*`7mY~4&boFyt=akR{ E0KOq$rT_o{ literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-static-element-footer_firefox.png b/test/fixture/web/screenshots/desktop-static-element-footer_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..7021a305456537adc488636d24ef4984844b507e GIT binary patch literal 468 zcmeAS@N?(olHy`uVBq!ia0y~yU=;zfjX2nVq^@>&3Xoz;@^*J&_z!{$_AZ~yz`)q) z>EaktaqI03M_vX6fdd^)Lv$xy}fp57_g#f@lR}5fH!O nOaKdrYve2lqE3uTQWOY!6P7Y1v9Xj`f&$ai)z4*}Q$iB}1Of|Mvbh@hAIgiy8EG z=JPkG={tbqt3ig51BkAoA-kAQH9v!_$;{t z+yY>pf;$5vm{G(sbOqwJu{&J-^J}jyV*~fObP0l+XkK4E^fz literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-static-viewport-1600_firefox.png b/test/fixture/web/screenshots/desktop-static-viewport-1600_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..26cfe728ed6ed2434ff6e1c3da0f512c93099b80 GIT binary patch literal 4597 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#VEo0w1{8_^)nEmr*pj^6T^Rm@;DWu&Co?bz zuJUwo45_&F_V&iL!Hy!Xf&4|XQykp<{5V4#gikEu)LOt&RAl6}V4}C+`{?j{QL7s* zC;#xgH_Nzqw)CEj#oNSzhB7d$Px|A1R(Q{CIWUjm!!;HGFiXLmff39o8WjMA!+?j! zyW7kQvbM1^6r7B-zA4V~V5@GequlN9Y!4<#Q z@(auKYH*9{gVwSAS8N)^6~Mvh(8s_8W<22-x&n8$vpZZn^NopNokjZ78~fw$=K~8A zZo5A}wims7{PD&{O?BHKE04S*C&x}&cn1H;CC?mvmFKt5w} zkh>GZx^prwfgFWok04(LhAK4%hK3dfhF?ITh8GMBr9h3Z5*Qe)W-u^_7tGleXakgB zOY(MiVfYV%3-&Ib%)r2Y#M8wwq~g}w>xRCrjv}rXt)GalIKaxZBCv^*YmY*s6k~~m zl+B;%8{$7*f2Cf$Ywqr}G=7E;>*ZcCG8FW)NH8!l@h~tlvNbd?FgrLjFe)eU zVBp{|U|<=<(tTA2MBh{~Ff3p5;{I`A)iI<0Bd*#Pgg&ebxsLQ02$g|>;M1& literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-static-viewport-480_firefox.png b/test/fixture/web/screenshots/desktop-static-viewport-480_firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..b42738952c062336c482b3f929565dfc72d6bfa7 GIT binary patch literal 2081 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?&p6nCBCC62JAf2hlDE4H!+#K5uy^@n1_t(P zo-U3d6}R4A-{`CBD8PDA?#m;E?)Q&{IXx35a4Xix%lEgm$&{&PEww!^fA*`_-n2A+ zh7ZfE19s}6|1sbXMQ zzUIyI$E<~nL(T((IBZFGT7>cD*MbZM=6bYDJQY`%*Co`~UKeJtNZk9!``_L9$M5eN zTB(-wkR9aNam~z|UpW|dNQ=|5#ISkAIDJF;UWNwaYhL^QR#w~nxyCwV3$9_21QO1k zS?A7h;O-7uX1@o4{5zVi|6HNYP;lsfWxn0La}+tT>*l0Yz&fA7)78&q Iol`;+0HbkJng9R* literal 0 HcmV?d00001 diff --git a/test/helper/compareImages.js b/test/helper/compareImages.js index d80fec4..69a72e5 100644 --- a/test/helper/compareImages.js +++ b/test/helper/compareImages.js @@ -7,7 +7,7 @@ export default function compareImages(image1, image2, misMatchPercentage = 0.2) return new Promise((resolve) => { const image = resemble(image1).compareTo(image2); image.onComplete((data) => { - assert.isTrue(data.isSameDimensions, `different dimensions, see "${image1}" and "${image2}"`); + assert.isTrue(data.isSameDimensions, `different dimensions, see "${image1}" and "${image2}".\n Size comparison: ${JSON.stringify(data.dimensionDifference)}`); assert.closeTo(Number(data.misMatchPercentage), 0, misMatchPercentage, `different images, see "${image1}" and "${image2}"`); resolve(); }); diff --git a/test/standalone/standalone.test.js b/test/standalone/standalone.test.js index c0f19e5..437b7e7 100644 --- a/test/standalone/standalone.test.js +++ b/test/standalone/standalone.test.js @@ -10,10 +10,9 @@ const tmpDir = path.join(process.cwd(), '.tmp'); const fixtureDir = path.join(process.cwd(), 'test/fixture'); const screenshotDir = path.join(fixtureDir, '/web/screenshots'); -const screenResponsiveDocument480 = path.join(screenshotDir, 'desktop-responsive-document-480.png'); -const screenResponsiveElemenentFooter480 = path.join(screenshotDir, 'desktop-responsive-element-footer-480.png'); -const screenResponsiveViewport480 = path.join(screenshotDir, 'desktop-responsive-viewport-480.png'); - +const screenResponsiveDocument480 = path.join(screenshotDir, 'desktop-responsive-document-480'); +const screenResponsiveElemenentFooter480 = path.join(screenshotDir, 'desktop-responsive-element-footer-480'); +const screenResponsiveViewport480 = path.join(screenshotDir, 'desktop-responsive-viewport-480'); let selenium; before(async () => { @@ -39,7 +38,12 @@ describe('standalone', () => { let options = { capabilities: { - browserName: 'chrome' + browserName: 'chrome', + 'goog:chromeOptions': { + args: [ + 'disable-infobars', + ], + }, } }; @@ -56,9 +60,7 @@ describe('standalone', () => { // init wdio-screenshot await init(browser); - await browser.setWindowSize(480, 500); - await browser.pause(1000); }); after(async () => { @@ -74,30 +76,38 @@ describe('standalone', () => { assert.isFunction(browser.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); + const refPath = screenResponsiveDocument480 + '_chrome.png'; + await browser.saveDocumentScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveDocument480); + await compareImages(screenPath, refPath); }); it('saveViewportScreenshot should work', async () => { assert.isFunction(browser.saveViewportScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); + const refPath = screenResponsiveViewport480 + '_chrome.png'; + await browser.saveViewportScreenshot(screenPath); - await compareImages(screenPath, screenResponsiveViewport480); + await compareImages(screenPath, refPath); }); it('saveElementScreenshot should work', async () => { assert.isFunction(browser.saveElementScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); + const refPath = screenResponsiveElemenentFooter480 + '_chrome.png'; + await browser.saveElementScreenshot(screenPath, '.footer'); - await compareImages(screenPath, screenResponsiveElemenentFooter480); + + await compareImages(screenPath, refPath); }); }); - context('multi browser', () => { + // SKipped due to: https://github.com/webdriverio/webdriverio/issues/3445 + context.skip('multi browser', () => { let browser; let browserA; let browserB; @@ -120,13 +130,6 @@ describe('standalone', () => { // init wdio-screenshot await init(browser); - console.log("TYPE OF BROWSER", browser.constructor.name); - console.log("ALL BROWSER", browser); - browserA = browser.browserA; - console.log("BROWSER A:", browserA); - browserB = browser.browserB; - console.log("BROWSER B:", browserB); - await browser.setWindowSize(480, 500); await browser.pause(1000); }); @@ -144,7 +147,7 @@ describe('standalone', () => { assert.isFunction(browserA.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); - await browserA.saveDocumentScreenshot(screenPath); + await browser.saveDocumentScreenshot(screenPath); await compareImages(screenPath, screenResponsiveDocument480); }); @@ -153,7 +156,7 @@ describe('standalone', () => { assert.isFunction(browserA.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); - await browserB.saveDocumentScreenshot(screenPath); + await browser.saveDocumentScreenshot(screenPath); await compareImages(screenPath, screenResponsiveDocument480); }); @@ -162,7 +165,7 @@ describe('standalone', () => { assert.isFunction(browserA.saveViewportScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); - await browserA.saveViewportScreenshot(screenPath); + await browser.saveViewportScreenshot(screenPath); await compareImages(screenPath, screenResponsiveViewport480); }); @@ -171,7 +174,7 @@ describe('standalone', () => { assert.isFunction(browserB.saveViewportScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-viewport-480', `${generateUUID()}.png`); - await browserB.saveViewportScreenshot(screenPath); + await browser.saveViewportScreenshot(screenPath); await compareImages(screenPath, screenResponsiveViewport480); }); @@ -180,7 +183,7 @@ describe('standalone', () => { assert.isFunction(browserA.saveElementScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); - await browserA.saveElementScreenshot(screenPath, '.footer'); + await browser.saveElementScreenshot(screenPath, '.footer'); await compareImages(screenPath, screenResponsiveElemenentFooter480); }); @@ -188,9 +191,8 @@ describe('standalone', () => { assert.isFunction(browserB.saveElementScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-element-footer-480', `${generateUUID()}.png`); - await browserB.saveElementScreenshot(screenPath, '.footer'); + await browser.saveElementScreenshot(screenPath, '.footer'); await compareImages(screenPath, screenResponsiveElemenentFooter480); }); }); }); - diff --git a/test/wdio/specs/desktop.test.js b/test/wdio/specs/desktop.test.js index c1c4ebd..0eaef9d 100644 --- a/test/wdio/specs/desktop.test.js +++ b/test/wdio/specs/desktop.test.js @@ -52,6 +52,16 @@ function isIE() { return browserName === 'internet explorer'; } +function isFirefox() { + const {browserName} = browser.capabilities; + return browserName === 'firefox'; +} + +function isChrome() { + const {browserName} = browser.capabilities; + return browserName === 'chrome'; +} + function getBrowserSpecificFile(screenshotPath) { const dir = path.dirname(screenshotPath); const ext = path.extname(screenshotPath); @@ -60,6 +70,15 @@ function getBrowserSpecificFile(screenshotPath) { if (isIE()) { return path.join(dir, `${file}_ie${ext}`); } + + if (isFirefox()) { + return path.join(dir, `${file}_firefox${ext}`); + } + + if (isChrome()) { + return path.join(dir, `${file}_chrome${ext}`); + } + return screenshotPath; } diff --git a/test/wdio/wdio.appveyor-conf.js b/test/wdio/wdio.appveyor-conf.js index c675314..40b88ec 100644 --- a/test/wdio/wdio.appveyor-conf.js +++ b/test/wdio/wdio.appveyor-conf.js @@ -19,6 +19,7 @@ exports.config = { connectionRetryTimeout: 90000, connectionRetryCount: 3, framework: 'mocha', + reporters: ['spec'], mochaOpts: { ui: 'bdd', timeout: 60000, @@ -26,9 +27,6 @@ exports.config = { 'js:babel-register' ], }, - // before: function() { - // require('../../src/WdioScreenshotLauncher').init(browser, {}) - // }, services: ['selenium-standalone', [WdioScreenshot]], seleniumArgs: { javaArgs: [ diff --git a/test/wdio/wdio.local-conf.js b/test/wdio/wdio.local-conf.js index 3700e60..96b1c1b 100644 --- a/test/wdio/wdio.local-conf.js +++ b/test/wdio/wdio.local-conf.js @@ -7,16 +7,19 @@ exports.config = { specs: [ path.join(__dirname, '/specs/desktop.test.js') ], - capabilities: [{ - browserName: 'chrome', - 'goog:chromeOptions': { - args: [ - 'disable-infobars', - ], + capabilities: [ + { + browserName: 'chrome', + 'goog:chromeOptions': { + args: [ + 'disable-infobars', + ], + }, }, - }, { - browserName: 'firefox' - }], + { + browserName: 'firefox' + } + ], sync: false, logLevel: 'silent', coloredLogs: true, @@ -33,9 +36,6 @@ exports.config = { ], }, reporters: ['spec'], - // before: function () { - // require('../../src/WdioScreenshotLauncher').init(browser, {}) - // }, services: ['selenium-standalone', [WdioScreenshot]], seleniumArgs: { version: '3.8.1' From 3315fd42193c126b86183a120b7fc990d5005e87 Mon Sep 17 00:00:00 2001 From: Maciej Jadach Date: Wed, 27 Mar 2019 17:16:52 +0100 Subject: [PATCH 12/12] Changing test approach for headless browsers --- .travis.yml | 14 ++++++------- test/fixture/web/.DS_Store | Bin 0 -> 8196 bytes .../desktop-dynamic-size-document-480.png | Bin 1842 -> 0 bytes ...sktop-dynamic-size-document-480_chrome.png | Bin 1817 -> 2364 bytes .../desktop-dynamic-size-element-480.png | Bin 926 -> 0 bytes ...esktop-dynamic-size-element-480_chrome.png | Bin 1108 -> 1348 bytes .../desktop-dynamic-size-viewport-480.png | Bin 1842 -> 0 bytes ...sktop-dynamic-size-viewport-480_chrome.png | Bin 1817 -> 2364 bytes ...top-element-modifier-hide-document-480.png | Bin 2544 -> 0 bytes ...ment-modifier-hide-document-480_chrome.png | Bin 3944 -> 4190 bytes ...ktop-element-modifier-hide-element-480.png | Bin 2130 -> 0 bytes ...ement-modifier-hide-element-480_chrome.png | Bin 3371 -> 3618 bytes ...top-element-modifier-hide-viewport-480.png | Bin 1015 -> 0 bytes ...ment-modifier-hide-viewport-480_chrome.png | Bin 1830 -> 2380 bytes ...p-element-modifier-remove-document-480.png | Bin 1982 -> 0 bytes ...nt-modifier-remove-document-480_chrome.png | Bin 2394 -> 2632 bytes ...op-element-modifier-remove-element-480.png | Bin 1680 -> 0 bytes ...ent-modifier-remove-element-480_chrome.png | Bin 1963 -> 2207 bytes ...p-element-modifier-remove-viewport-480.png | Bin 1858 -> 0 bytes ...nt-modifier-remove-viewport-480_chrome.png | Bin 1883 -> 2433 bytes .../desktop-fullpage-modal-document-480.png | Bin 2059 -> 0 bytes ...top-fullpage-modal-document-480_chrome.png | Bin 1826 -> 2375 bytes .../desktop-fullpage-modal-viewport-480.png | Bin 2059 -> 0 bytes ...top-fullpage-modal-viewport-480_chrome.png | Bin 1826 -> 2375 bytes .../desktop-overlay-document-480.png | Bin 1902 -> 0 bytes .../desktop-overlay-document-480_chrome.png | Bin 1876 -> 2451 bytes .../desktop-overlay-element-480.png | Bin 1166 -> 0 bytes .../desktop-overlay-element-480_chrome.png | Bin 1421 -> 1677 bytes .../desktop-overlay-viewport-480.png | Bin 1902 -> 0 bytes .../desktop-overlay-viewport-480_chrome.png | Bin 1876 -> 2451 bytes .../desktop-responsive-document-1600.png | Bin 9296 -> 0 bytes ...esktop-responsive-document-1600_chrome.png | Bin 11278 -> 11648 bytes ...sktop-responsive-document-1600_firefox.png | Bin 11341 -> 11194 bytes .../desktop-responsive-document-480.png | Bin 4181 -> 0 bytes ...desktop-responsive-document-480_chrome.png | Bin 5379 -> 5715 bytes ...esktop-responsive-document-480_firefox.png | Bin 5431 -> 5294 bytes ...desktop-responsive-element-footer-1600.png | Bin 366 -> 0 bytes ...-responsive-element-footer-1600_chrome.png | Bin 518 -> 760 bytes .../desktop-responsive-element-footer-480.png | Bin 260 -> 0 bytes ...p-responsive-element-footer-480_chrome.png | Bin 371 -> 614 bytes ...top-responsive-min-width-document-1600.png | Bin 9289 -> 0 bytes ...ponsive-min-width-document-1600_chrome.png | Bin 11276 -> 11644 bytes ...ktop-responsive-min-width-document-480.png | Bin 7044 -> 0 bytes ...sponsive-min-width-document-480_chrome.png | Bin 9639 -> 9977 bytes ...op-responsive-min-width-element-footer.png | Bin 373 -> 0 bytes ...onsive-min-width-element-footer_chrome.png | Bin 541 -> 784 bytes ...top-responsive-min-width-viewport-1600.png | Bin 3775 -> 0 bytes ...ponsive-min-width-viewport-1600_chrome.png | Bin 3921 -> 4932 bytes ...ktop-responsive-min-width-viewport-480.png | Bin 1665 -> 0 bytes ...sponsive-min-width-viewport-480_chrome.png | Bin 1884 -> 2477 bytes .../desktop-responsive-viewport-1600.png | Bin 3777 -> 0 bytes ...esktop-responsive-viewport-1600_chrome.png | Bin 3922 -> 4934 bytes ...sktop-responsive-viewport-1600_firefox.png | Bin 3982 -> 3918 bytes .../desktop-responsive-viewport-480.png | Bin 1723 -> 0 bytes ...desktop-responsive-viewport-480_chrome.png | Bin 1924 -> 2555 bytes ...esktop-responsive-viewport-480_firefox.png | Bin 1957 -> 1895 bytes .../desktop-static-document-1600.png | Bin 9289 -> 0 bytes .../desktop-static-document-1600_chrome.png | Bin 11276 -> 11644 bytes .../desktop-static-document-480.png | Bin 7044 -> 0 bytes .../desktop-static-document-480_chrome.png | Bin 9639 -> 9977 bytes .../desktop-static-element-footer.png | Bin 373 -> 0 bytes .../desktop-static-element-footer_chrome.png | Bin 541 -> 784 bytes .../desktop-static-viewport-1600.png | Bin 3775 -> 0 bytes .../desktop-static-viewport-1600_chrome.png | Bin 4634 -> 5668 bytes .../desktop-static-viewport-480.png | Bin 1665 -> 0 bytes .../desktop-static-viewport-480_chrome.png | Bin 2136 -> 2739 bytes test/standalone/standalone.test.js | 19 +++++++++++++++--- test/wdio/specs/desktop.test.js | 5 +++++ test/wdio/wdio.local-conf.js | 6 +++++- 69 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 test/fixture/web/.DS_Store delete mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-element-480.png delete mode 100644 test/fixture/web/screenshots/desktop-dynamic-size-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-element-480.png delete mode 100644 test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-element-480.png delete mode 100644 test/fixture/web/screenshots/desktop-element-modifier-remove-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-fullpage-modal-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-overlay-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-overlay-element-480.png delete mode 100644 test/fixture/web/screenshots/desktop-overlay-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-document-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-element-footer-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-element-footer-480.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-document-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-element-footer.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-viewport-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-viewport-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-responsive-viewport-480.png delete mode 100644 test/fixture/web/screenshots/desktop-static-document-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-static-document-480.png delete mode 100644 test/fixture/web/screenshots/desktop-static-element-footer.png delete mode 100644 test/fixture/web/screenshots/desktop-static-viewport-1600.png delete mode 100644 test/fixture/web/screenshots/desktop-static-viewport-480.png diff --git a/.travis.yml b/.travis.yml index ca1aa76..30dcf03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ env: matrix: include: - # Node 4 with GraphicsMagick + # Node 8 with GraphicsMagick - node_js: 8 env: GRAPHICSMAGICK=true addons: @@ -33,23 +33,23 @@ matrix: - graphicsmagick - google-chrome-stable - # Node 4 without GraphicsMagick + # Node 8 without GraphicsMagick - node_js: 8 env: GRAPHICSMAGICK=false + addons: + apt: + packages: + - google-chrome-stable - # Node 6 without GraphicsMagick - - node_js: 8 - env: GRAPHICSMAGICK=false before_script: - echo "using chrome $(google-chrome --version)" - echo "using firefox $(firefox --version)" - export FIREFOX_BIN=$(which firefox) - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - npm run server & script: - npm run test + - npm run test:local - npm run test:standalone - if ( [ "${TRAVIS_PULL_REQUEST}" != "false" ] || [ "${TRAVIS_BRANCH}" = "master" ] ) && [ "${TRAVIS_NODE_VERSION}" = "4" ] && [ "$GRAPHICSMAGICK" = "false" ]; then npm run test:sauce; fi diff --git a/test/fixture/web/.DS_Store b/test/fixture/web/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c803885d4429431a0f0172e6390abddbc88150f3 GIT binary patch literal 8196 zcmeHMTWl0n82X_K-th>8z`{l(gvuwy&<)b5_U_=b)DTA+KJPdIy1X1 z)FxHq<-yc=NlZjv2c%qpf{T*X@PfNXrnShAVT1-M1bE93CdiiLOCg9aCJ}-ga9OY z2oNNyQydWZBtn@A<)n~-D~&0l2Mk>?3^7o+lRm-CNv1+MDWq@*6z+iG%os)}7|c$7 ziNG8%C1g}a2t)|XM}U7m6%@1Q!KLW^#`xXKjd~+F%gK?&Z@Cf6^!#M zh`N?LY8sVXN0v*ThwIu61dYfkMuFq+t4IS)C-!u*&7jYS*jENu5@3$kF*| zI(tu&15Mp}RXxEq9j-y89y-)Fs7l78O)xDqY}}$KnTP4fnI{X^rtON_XK6XZV!ABm zX>L)}{-QvV^@N>!TNQO6?+g#qR=g@~47*cps(PBwd{FcJ-Vwv5RbAuL)9$)xRmZrl zP1pIFh(-0PRUt@H{VfRprnjKEoV7N+1iI1d-$61)o^!Y6PIK84TV zI(!2^z)$cC`~iQ$U+_0dxC+-`HP+w;+=|;UiMw$hrmzj$u?G+15lmwSPhlPnJcENc zf@63N$MI2o5~uKad;wp?S8*EO!ng4qd>=o;kMS~I!O!sv{8lV5RwC~q(Jqzv9n}^l zZ}?@$PTz{W@vi+3+#&LQy_7SyYQ;S(SJl=vY}ww@+BSQ#bI$TcQUy#BR0$|lqDXL< zH}P^tP+M77;__UM_Ynh)F^SWNl?&@ce1k;HVUlQWjMqy ziRj7}3++y&StdfWGNIkA?3IYOY{^W`n(Ec}?Nby6{JWEd^~ShN*VMn};suz758x`X z@H%`6-@}jaGyIN-kd-gtYj^>t=WwvQ#6BVM(!v}prd``|>_M_9G5BWZ zsCBy$SR^K>=J9{m!oUCD?qx*dM+ig++(87etTWx&P77G*BIdDng7QO@dE$1HLIy5W oa1-7igySS<|1hL_BGjcqIVmJ*DE;R@1VrzD^!^9TySs~j0L11EjsO4v literal 0 HcmV?d00001 diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-document-480.png b/test/fixture/web/screenshots/desktop-dynamic-size-document-480.png deleted file mode 100644 index 770bb9fa00d8d42372cc2f6f7ac0b6fae819860a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1842 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?UpSb6B3U0Z{TUe8etNn%hE&{odu^lO0RtXp zL(AXq*XTUB7tbKP;n(AtHyIZ^ueN1qux@1Q5XxxK7^OyoU^Eqwkr7sG{$0hyU@m9k qFvWq{g>#e|4T8~BFpwGH3jgiJY)_;nWt;)lg$$mqelF{r5}E)%Liij2 diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-document-480_chrome.png b/test/fixture/web/screenshots/desktop-dynamic-size-document-480_chrome.png index fcd4832ca37234a1cc28a7b0dfbe9d1ab53459c8..ecbc3f4826a2c7082b101ba7baa20c9a3c9f2587 100644 GIT binary patch delta 458 zcmV;*0X6=a4!jbO7k~5!1^@s6<&*vx0003hX+uL$X=7~w04R}tkv%U2Q51$B8;#FM zC=`n6XfPI=l~6FlMs&Nx(#_6}iP#;J*%2Dmmiz;WX#4^yD&6)H8m(Rw+HvkoF_XwR zC-+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q1PiiHUU}oXkrgM~)y<*77pulrr zLu38+b9+zW+C z#0q23_QIfA+0g0-hZ-5P?2b>q^})}Zitsx7PhFl3G@Xtu`F~4B7|7wWWm9;Q|q1z#ss?FqjYg zE97P_=s}{OU*}l+3;^J&uMPl!7a1@B1PmAe0tO5K0kb>;0|K)!0*e6_@BVO1M>k-7srr_ zTW_y!WMmLvIAGxOuYQJp$%L2-Ym57f*%&@tS;frE@W6fZM3qA?qbnV(so S{8tS$j=|H_&t;ucLK6TY<2V!m diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-viewport-480.png b/test/fixture/web/screenshots/desktop-dynamic-size-viewport-480.png deleted file mode 100644 index 770bb9fa00d8d42372cc2f6f7ac0b6fae819860a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1842 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?UpSb6B3U0Z{TUe8etNn%hE&{odu^lO0RtXp zL(AXq*XTUB7tbKP;n(AtHyIZ^ueN1qux@1Q5XxxK7^OyoU^Eqwkr7sG{$0hyU@m9k qFvWq{g>#e|4T8~BFpwGH3jgiJY)_;nWt;)lg$$mqelF{r5}E)%Liij2 diff --git a/test/fixture/web/screenshots/desktop-dynamic-size-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-dynamic-size-viewport-480_chrome.png index fcd4832ca37234a1cc28a7b0dfbe9d1ab53459c8..ecbc3f4826a2c7082b101ba7baa20c9a3c9f2587 100644 GIT binary patch delta 458 zcmV;*0X6=a4!jbO7k~5!1^@s6<&*vx0003hX+uL$X=7~w04R}tkv%U2Q51$B8;#FM zC=`n6XfPI=l~6FlMs&Nx(#_6}iP#;J*%2Dmmiz;WX#4^yD&6)H8m(Rw+HvkoF_XwR zC-+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q1PiiHUU}oXkrgMZI{uY(a6>zG)hrB2v*cq9k})V^mAZg7Ls?F zS*+#)Lm(5cfa)kk^&t5DrD5yuvrie$`LQ!DVv$ntS};mcIS7cTE#`gYp8t(E>)Czn PT_Dw-u6{1-oD!M<$E5rO diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-document-480_chrome.png index 81c7c244635f46d07067c7ab9687a5a5ebb391ce..af0478b9fd3937e0f4666a041ff7304ae4b16b5c 100644 GIT binary patch delta 581 zcmV-L0=oU^9^N33BYy!ZX+uL$X=7~w04R}tkv%U2Q51$B8;#FMC=`n6XfPI=l~6Fl zMs&Nx(#_6}iP#;J*%2Dmmiz;WX#4^yD&6)H8m(Rw+HvkoF_XwRC-+b9+zW+C z#0q23_QIfA+0g0-hZ-5P?2b>q^})}Zitsx7PhFl3G@Xtu`F~4B7|7wWWm9;Q|q1Yb2o1pV+(8p0NB+{JpcfXNVD+)tpl@w z0X6{>to49dem}qK2>|Ti?&+bPFog%RfdYO33Sb#yZ1o5LI2sSL0Rnyj6Tn&znC0#7 zQcnP22j|mmJz)wDvjGBr0TIAj518fU^|77+zz)v!fJr>F0Revj5o;Q_Oe0e%4uSnC0^e7#@l2>@_453>ORegO)=GRD~I5dd&B9+QCqTo(KT0v8r8 TRw@zq00000NkvXXu0mjfR=xyS delta 335 zcmcbo@Ir2aayVO1K$--7srr_ zTW_x$2C_JcxL(Z5vJrUHz{8lG>Kw90Nk<`Jv#I2j882o^kdiL+XS1~ax zueidz?E~ZHMxdFz7Oxn0+sNl}GW_Ge%CuRLsg{w;;JCzUIYx%?$IO!%nWDuS?Pnhn Ve%C54ycg(c22WQ%mvv4FO#lm%dv*W- diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-element-480.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-element-480.png deleted file mode 100644 index ee79176fd990f1f95e48f6ece4c25dce72e8e6a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2130 zcmeAS@N?(olHy`uVBq!ia0y~yV60(aU~b`H0*dI~mOa40z#-}B;uunK>+Q9Tyv+^_ zERGIe9-KL9xtKfriPW6QI~DI7-FM-9NWsNd(^!FeMges~;9c(Cea~O;9&p)qk-1@K z2j2uCSp`)q2d|QbDK8i_FER!#VqW6H?$J3afi*~|6A46{l9w90F8d2xg3|35j0a*y zyBmoqSVJ>gu#V%$*s3n6$L+eiM>f8z*wB@STt0=0LpTLJ9 zcb2vuwlVdyI3}dEaC3v^#e|8z+cdmPT+Lg;kCa~Yz2+L5)>#xY`OK>+m%qQccj#8K zi0k>4+di}Kha3Eumvwo%!7rxzz0&u&)c4 delta 288 zcmZ1^vs!9`ayVO1J86%7srr_ zTW_x!3Nkq|upF#@WjjH!k4IeN5EIi0gOU|L_G<|(i$3TUyt~)%8N-A3v0?lS4`eno zGVNfVe1S2V^LI^sSU$r87P-v}IUE@$C$LL!9WgsLW3@X&fers;MYi9Q71-i9ljMun z-D5bwX|p+z+XJYITadfs?e86DuPQTG%xm9#kuj2yYvcZP->*tDSTsWT92@KB&EgMO g@NM%)psc8UyQWaQ1nbV#KwmI;y85}Sb4q9e0AitJasU7T diff --git a/test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480.png b/test/fixture/web/screenshots/desktop-element-modifier-hide-viewport-480.png deleted file mode 100644 index b1518b97924d1c872e50f067efd209a1f26dbee7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1015 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?UpSb6B3U0Z{TUdT_j$TFhE&{odu5?uOMu7$ zhXv|3OXn}w$atWA=Jc7jVFFWgnSqK&!B7tYyPM0Iug$w}JD1_l#J^U{g~j?_GB8}@ oky1FdfN{|%Mb#jnS6XTC)Hg6+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q1UtbQ6Nn9%so=8JEi-ct00{7?wH^QfZzQuZ0bc}@umOY; zKJ|dR{EuHf0e}a5_pP3A3lFiuegO)=GBamA0s!8|1GB*a9RU{L0&so^=i9y%t^fc4 M07*qoM6N<$f{b0)qW}N^ delta 213 zcmX>jw2W_pc>PiiHUU}oXkrgMksNjv)jQNq*WBnN(Fn_jr#ku~&=0c`?MzI6TmEr8(Q_gED0Ig&2boFyt I=akR{00f&wD*ylh diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-document-480.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-document-480.png deleted file mode 100644 index 7422731c4337530fd935ed0a4027e8903865e4de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1982 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9z@)~(1QcO;f9@Lt1AD8di(^Q|t+&?<16cwE zTrbLI*$6yp=#kNFSrOryp>Utaxw+Bb>C*OB^A|sG-Tu3b8K{*2_|*53G5h-WM>~hCn7>0o758>Ot`Q zOT*Ur=cm8qJm40$oL%SVXi}zCZaxPrKH|^IUlwjydj}ZOKSo2EmLc80`!wSlKlagr inKsFcKwSxv{`Xp3Mvym)F?ZX45ZBYy&t;ucLK6T5jrSq| diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-document-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-document-480_chrome.png index 02ac9a5126869da09ad161c1108370482747711f..48eb58b7c2df954cdf7ccf0c1cd0e2ba440d2a0e 100644 GIT binary patch delta 571 zcmV-B0>u5=637&gBYy!ZX+uL$X=7~w04R}tkv%U2Q51$B8;#FMC=`n6XfPI=l~6Fl zMs&Nx(#_6}iP#;J*%2Dmmiz;WX#4^yD&6)H8m(Rw+HvkoF_XwRC-+b9+zW+C z#0q23_QIfA+0g0-hZ-5P?2b>q^})}Zitsx7PhFl3G@Xtu`F~4B7|7wWWm9;Q|q1XK?@*5FE%Z*oot$3~_}NkN+!j&IGsnxDLB9#&rMyn|i1R0Kh#GlW_xB z5-{rltDH~2^#lMmus=T66PECkVFvS)Kmm*m%zD5oA1_b!1OT|12eSbKH35@Q0!a~I z)&o{~dq30@0NB81JzxPx#AY({UO#lFT zCIA3{ga82g0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy24YJ`L;(K){{a7>y{D4^ z00_oOL_t(|+U?gdQA0r(M$uj7d7#7r9Rgy75*1N|1q7svp&CU(nw@tCa*l#;tGoXk zW2^xHoa&_>007TOlkoyr62MUp*k%3P>IndxU|v4z30t_cVFgeDlfVHl63j8isz+?G z{>L)_cwo+Y!4@vF;RavH)ia zzkb#e064|99Jb3& gY+RG^16&sH3*n^@%#E}AnE(I)07*qoM6N<$f)7f3ng9R* diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-element-480.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-element-480.png deleted file mode 100644 index 0fda30ef41f54f522b38a536654358644a420530..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1680 zcmeAS@N?(olHy`uVBq!ia0y~yV5|Y+FC0ujk&S7L8Vn3<;hrvzAr-gYUNaPAa%5mR zX#dJ~f?^+!xP}w+&vXf^m@}-`*Cs4pDf_uvmSO7cSBwYZT-ZH2`6dX-DyUjHc$G9v zdBLE0kuhiy^O8{s96=&=e9mff2I-HZfkj3#dHlU<%{_*kBbP_h80pz=?)=}yU)d6r v=Z$7q(u=BBd+zOGE)f|m?np1_zp{te@!0>`b}|-N(=d3t`njxgN@xNABc~jW diff --git a/test/fixture/web/screenshots/desktop-element-modifier-remove-element-480_chrome.png b/test/fixture/web/screenshots/desktop-element-modifier-remove-element-480_chrome.png index 279b4923eb661acc656f1fd0b9c8f5b4d195759b..01e499daa887cb1a98c4d08328f73386db4f1165 100644 GIT binary patch literal 2207 zcmeAS@N?(olHy`uVBq!ia0y~yV5|Y+FC1(@5j&P?^+1kRrn7TEW^yhAgT}<#iMIMI zfg)}4(!J+BG(@^yW*CUgo*H0q*sWyukxOUK^>yBmoqSVJ>gu#V%$*s3n6$L+eiM>f z8z*wB@STt0MON%Jo#Az=t7smbM-m-2KC|$L8~m7;b$PnMFQ&cH_qobL&Z{5aEXA2-Yt);hL#S{-97kDp=Djm>Jnz++4D zc6VX;4}uH!E}zW6z%J+M;uunK>+Ll|-a`Qlu7O^w7_?s;;1aeIIO3Mz#4nuL#q~@0 zoh8@3lF!S&|K0kI;YaoFi_8o++8!{waM(Gtj8aq$f+HnAbzZ*^WcV|$onJul2ZLbK zC`IicFtj~?yz~nPL*4nq>>UC%4IBqYDQXA7jQsY?FL)Vp4vYpdt&-Oa`Rl1)*ci+n iJRB{FX;cfILqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A zuqAoByD%_bn@vou913@MrJsH;fE1&L0?+SmYI)Mk%TWK~n57iOuc|1$O+SVN0XrmGt*r zzhN~C!}HIhX_u;L7s;?~-~U=xGc$;P7!6{iP@!sq-u8IuPX^X3egVZF41!Ig6t#ok aBlAyRerq+O373GCCWEJ|pUXO@geCyRC*c~)y=EB55-8w$ zQ8vp);88=5jBd+{2-ggS`#HS4Y<7kBSJn45iQj#9n-{2)061a2jD1b){{EMo2i*G3 z11WC(%ghWB!Wj)3jcgr4qZCzxz-k%$pU1nFi8EMRb{T$gWOm^+ahT#TN>Muq=3ZvL zHt&A^W#NY2J^uU=pGHHPR;dgW(sgnBm#H&E?*xYQhtZIxWk}1FPiMX{mycfE?Kg>RQFz>3sKH+(V#&=G9sC?0W$Tl?pcjF`ehgZv9pYeNt zcEjVhS5>a3`UE}MO@FX-1fPig+JWj$Goh|(+z$x?UlaIwIGW$p()+GF5%;6 zzlYy_3w9r_jhyy$8w11YTUVGF9!PRde#jUhEb+A=^54GtSDXxM9(;YgcAh~i`(#FT zm(3qotr&R|t}v%r?tc%I{9wR8xsmP2aw#lcxRhnm#kiAmf)D<_ zcy)eqPb~vO`>$2(3*tk}1 x!>Ri(m(OE3pjh{s(fh|{K^7s9u2``H+)Li^*3MaEejex}22WQ%mvv4FO#r&dZg>Cy diff --git a/test/fixture/web/screenshots/desktop-fullpage-modal-document-480.png b/test/fixture/web/screenshots/desktop-fullpage-modal-document-480.png deleted file mode 100644 index a07e7e91313fb58556d16c3ae7ea4b080042ecf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2059 zcmeAS@N?(olHy`uVBq!ia0y~yV0-|?UpUx+B2Op(lK@g|N#5=*4F5rJ!QSPQ85r0P zc)B=-RNQ)d-B7T>fPv-U0R@Kt>t1{mkZIsvcVb=B`@Fj9;}z@-A6D;`V_?u0N?_pN z04igVU|?e6VPIrrYiM9#c5rB5R8Tm;ARsU*jT|fwDxR$|XE;z~Ga4+&!7`d!Ml;c9 w;W1ihB9)5AEAM_~V~FTuAFWeJEFJAc7`aMU3C%wZtlb$rUHx3vIVCg!01I*_KmY&$ diff --git a/test/fixture/web/screenshots/desktop-fullpage-modal-document-480_chrome.png b/test/fixture/web/screenshots/desktop-fullpage-modal-document-480_chrome.png index 5b3e29212811ffc3839574b3ac950d2fdb7aeb4d..9ac4a0fb427018a5738b058b771cc9f10e9645c9 100644 GIT binary patch delta 460 zcmV;-0W+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q10000eKiD delta 220 zcmX>uw1{tlc>PiiHUU}oXkrgMl4xFFr~L$TV=TJF%|meO_Jl@d|c^53BdeF)(Ng zZ7yWdW#oKN@obGb!+|0jAh(Tq5_1MufPv-U0R@Kt>t1{mkZIsvcVb=B`@Fj9;}z@-A6D;`V_?u0N?_pN z04igVU|?e6VPIrrYiM9#c5rB5R8Tm;ARsU*jT|fwDxR$|XE;z~Ga4+&!7`d!Ml;c9 w;W1ihB9)5AEAM_~V~FTuAFWeJEFJAc7`aMU3C%wZtlb$rUHx3vIVCg!01I*_KmY&$ diff --git a/test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-fullpage-modal-viewport-480_chrome.png index 5b3e29212811ffc3839574b3ac950d2fdb7aeb4d..9ac4a0fb427018a5738b058b771cc9f10e9645c9 100644 GIT binary patch delta 460 zcmV;-0W+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q10000eKiD delta 220 zcmX>uw1{tlc>PiiHUU}oXkrgMl4xFFr~L$TV=TJF%|meO_Jl@d|c^53BdeF)(Ng zZ7yWdW#oKN@obGb!+|0jAh(Tq5_1Mu~)y?rqEhyf47 zL5qUKS32c$ml`i^RM^qq$DOi_;nW|UA0M}VXJ>Gne_5X4z#6 zClR zT06`d4P#m*esCDSe|eWNZd3ccQb%SNP7{YI4x<#cgCMqg{%qU5G6$q(R<9tCnqS#j u{Jvw~#qhs@fI=FViG#Xq7+HRQ#s0WU;Ps!C{(FG+D1)b~pUXO@geCx2nE+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q1B0O3MNa!~$uk)3O2*dmtn`#M!{6KwMclXMz8@y80S# zr`vJb0095$sU83Tk4Tg80c;S4>f!6lPyOuxu-Sb-C-1tE@gfwE{R!*0J`Qj71OQg( z{d}q?%yI#<0Rv|Nk^vVH80rB_#&N7C0I){qQ@vo83zKmJ_mTpK62MRoSTeqT)e`_% zq07ErFwX^(@dJ00a0B>~0S^ses0S>$>_6)X0PyErlW_tf3)oJ#<5Z6TfJfs3v+)E5 k0khx)7Xg#t1S1yQ0VXvTxN7y9XaE2J07*qoM6N<$g4PHWrvLx| delta 319 zcmbO%e1&gPiiHUU}oXkrgMuczqM*Zf;cK(s{f=ADaDac;+&%Jon+utW z87C*O^6+HuJuor%_A60_2ajVmD{{mzPX558EO@P|QTh7YK#=;XYuqvgjGGlg(i zp2=*U83QuAL+b?-TSL?2hfH$Z2WI*9)yXk77z33tvhXpA>i>%r@~%i|Ujg(OgQu&X J%Q~loCII5^Z|VR5 diff --git a/test/fixture/web/screenshots/desktop-overlay-element-480.png b/test/fixture/web/screenshots/desktop-overlay-element-480.png deleted file mode 100644 index 937d48f7fe1ca1969ffbb2e44aa5e9cac66de3d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1166 zcmeAS@N?(olHy`uVBq!ia0y~yU|a&k4jfECk(%H0zcDbdgnGI-hE&{odu=1{AqN3h z$DWuQrEM>J&iSybv!77^n0Cpx?#q_jKN)`1pTEk?@J^x3q3H%AXA-+ghwKCt&W7{n z-#?DnEAU{_^)2Cc)(Vbq8dx?m3mxI}5E$i<9tPijR`zVHQar%_V>BEoOiMSOKR2{n wEzT5ElSk5qby85}Sb4q9e00$~~WdHyG diff --git a/test/fixture/web/screenshots/desktop-overlay-element-480_chrome.png b/test/fixture/web/screenshots/desktop-overlay-element-480_chrome.png index 5ed73fd5c17f6fe49ed187fe8d82a8178dab0eb6..1521aa3a38a16eef946ae2d0fa0dbb66bbdabfff 100644 GIT binary patch literal 1677 zcmeAS@N?(olHy`uVBq!ia0y~yU|a&k4jgPikp(_C)(<> z1d6oDOZT4l&=Bc*nPDI{duo8eVYiaqM=qT`*VlPNcJfU@sjJieFn4DBVbapN`%Oq{ zZJfxh!goG~lTTQvf1jiN-uCgI)4?CnyLo8R>L@B4c2{Oqm| zR=@pY=kc1%?bH3~?Iv;J;ilB!ibK9XoC=j6W*7`^>^0Zt!DX*5&C2znJz)-{)Er@hW_N z$&&-$ZF}Av{-MrO8p@w#6+8Q%tKa%t^W#jnecUipSnJr{X?2XTJbs2nH#VyQ1CK4q z+ueoXKL{?^yL>VO11pcGi(^Q|t+&?=Hy#QQalQCK-ET!*cheRVivtWz1`W(nGDle= zD(>E%8M)f-=-Y31F4tMsi!;o4lmCs8VS`Q+i$jY7;{*i{1{Dq=22LQi35omq#fQq> z=l6*=Fjwt~cea+tRDq^pl#3jER0xd?eSF(oxPPhRJzIl4ny6q8js!4j@*yj$ zJL~4(+|E?s@caLbbM2@ZWHfxJoZhjd!#Uqh|Fr(i!SF#5XE_Cph7Zj4_xN)2>>5@8 POG*Y$S3j3^P6{RwbiPH{GB6wyP+?GF;cQ@WWKwXPz~BMo3L$ZCr1Rf@zOzc3!TigtH|_j5 z)uCw{~)y?rqEhyf47 zL5qUKS32c$ml`i^RM^qq$DOi_;nW|UA0M}VXJ>Gne_5X4z#6 zClR zT06`d4P#m*esCDSe|eWNZd3ccQb%SNP7{YI4x<#cgCMqg{%qU5G6$q(R<9tCnqS#j u{Jvw~#qhs@fI=FViG#Xq7+HRQ#s0WU;Ps!C{(FG+D1)b~pUXO@geCx2nE+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q1B0O3MNa!~$uk)3O2*dmtn`#M!{6KwMclXMz8@y80S# zr`vJb0095$sU83Tk4Tg80c;S4>f!6lPyOuxu-Sb-C-1tE@gfwE{R!*0J`Qj71OQg( z{d}q?%yI#<0Rv|Nk^vVH80rB_#&N7C0I){qQ@vo83zKmJ_mTpK62MRoSTeqT)e`_% zq07ErFwX^(@dJ00a0B>~0S^ses0S>$>_6)X0PyErlW_tf3)oJ#<5Z6TfJfs3v+)E5 k0khx)7Xg#t1S1yQ0VXvTxN7y9XaE2J07*qoM6N<$g4PHWrvLx| delta 319 zcmbO%e1&gPiiHUU}oXkrgMuczqM*Zf;cK(s{f=ADaDac;+&%Jon+utW z87C*O^6+HuJuor%_A60_2ajVmD{{mzPX558EO@P|QTh7YK#=;XYuqvgjGGlg(i zp2=*U83QuAL+b?-TSL?2hfH$Z2WI*9)yXk77z33tvhXpA>i>%r@~%i|Ujg(OgQu&X J%Q~loCII5^Z|VR5 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-1600.png b/test/fixture/web/screenshots/desktop-responsive-document-1600.png deleted file mode 100644 index 28045110308a9c681b2496c9e9e4461982327e7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9296 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#V0pyB1Qf|t-C@JPpd#++;uunK>+LPY^Ep=~ z+aBgmJb97j=7cI1i$8@O!H!vmz5!n|W-R&`>T9r-CD7&WM+>c2oGWb{lg0KY7`(ar z{a@O;*X(O-yx-`)TeJ1M@R_LWDn_8`+dbKPsp#v3jF(nUVj59*gb?tsnH-9GN~ZC+TZ`d!?mV+ zK}E&wCCtYv8(D!&hgl7SoVt}-#c-$j@2}r4IS)*{cADScs`7vFue<|=*VNPJ?)g4% zpG?7$t=GP=RD9cW095cQ_>NMeK`>-eLGD{y+s5|o*S>(#Zr)@*iRY|hKo&zL(_p8j zzho>B|28j942@cSX-p+O(wqYk8B zuE>7>lGA3-)@91);cuw^@apAhP<^?t`q!T|i@$%l+rYebGvB>B zv4Z$(mH)XbB;pc4-G~Wlqts{+44G80?c2P02M$Lgy1<{AhDOg9(xbfolJUUCb?3k2 zJox{%>e|k9S)MZ=M(f9+(byTSdeN%hAznZJ`uZAFKgR8=sl0UZ_w@K>`s^}kdn*br zovi+qbztK);0O@&XdO9ZYKGBD92QkWypFX0^LjNXW7_?=oUT51kNw|_UquHJui5{r zy>v2vUyX6Cd?%+zq6{CY^q1=PFR6FS~U%skQnN9=l}QMy7S(@!=SqJzjdwo1B=&t zH~Za-udxADoUilm`}sGdpXb&Ab-FIGj8daPFl17}wR@L^D=M;m^?^zEf!WK3!qF;* vCIxHROgRRB;Nk}$2zWMB=Awq!@XUUudEI%t-c0K91O>CFtDnm{r-UW|-kr!% diff --git a/test/fixture/web/screenshots/desktop-responsive-document-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-document-1600_chrome.png index 33fb9f15ca893b0015b1c0540ce746b930156a50..155bc34cfa0b563f848d331d4232e51f17a73048 100644 GIT binary patch delta 1325 zcmb7?dsLEl7{}iiRMt&0JY{BL$If7+r7Je=$lOY7ngX8k*fO${IklEyV420GwQ{y; z>f7{q32mFQol=@Co!bE~l%RO2O!Gn@MN{yeB*IIw7yWO4)$jM$^T+d?&-3{{d4~k? z`M!LRl)85>BQ^0f01ykf1(Y35G49v!n{s=;B)VTWqy(%l`-u@C59j>z;7M0^Ue3T~ zXwc2GugHeZNwJ|wr04VNJZp}+52a5<1wzUog1MY9O)sFq>g}*=CL#eAvI*{2Ky|5?US9j`ROIqJr8BUnK zQ>~o2FqYj)i9G{feu35Xog43@O?TaUIoY@MSyEJt?x4Ersyu{D3u;?Ox-AiW^!Qjo zbUiV07xmNc;vQr?j_#*2zs@;(1nM;2>@`nlT89$dsXf2f&pBb^0v3cPdy50CD86)) zcIDke#<&WOzS&IqaYDX8Se+4zJ-M4%wn(LkhboSe>u2wk;7D!KA|A+GO$$6bAo&mg z0GH$Y_k{s=$FG!%AOP5Aj|ltXVCK-|aL>5d;H5}6E0Xi7-7JrD7@WvKVQQU+!SC0n zcR7StJ1Xy`*LgtVHa`yI8-~p}(t3hibt1j+tCZ3~5;^938ZWH6y+qx>KW>sW(Qhb1 zS<>3B`xnmn!}U{VP#TuX@G%8M5Co@=Y5NT;@;Rm6NQJzaaGYcoTMPyU)3Lzc-f9_{ z0**doRv0^DmeA)3<~`1P=m1RUljF4REB^A2x^xfLC`So_}1g<}Z%58}6XJI)*=k zTa}HljGnN0gjJMOA_T%LlG~^V^hQ5~yw|rfC74-Fa13RwnHb(p0Sj%=9~f2OXb1%u zvv!Qzkq%anmZ$IX9hJ>gDMVsd7Lm>~R~4|uwYAkq6{HCt;XlMmwqU%`2rbDod9Wd) z!W*RiUx^+AT?SPUALYEApjqrRISJ$zOQ>*juz5-@a!ewc(?UYePF=Yn{e+t#kT+UX z`;e7lc#>HkgjXf2flVI}57UYbD;&H>&~QDCF4!6h&0fn0l;8!sY!UWkXbpjG5@5e8uHpxAFA z`()2897ymEHj5K%CQ~2i`iiNA+m($?aDRovco5!Zyoki~PA($TfGZIJH?K^GPo1A<)-YdTV?c&0fCF*W7mxo-N-Fl!m4ij{< z;gVkDJG%I`u_xMbZ<<*X_FWQ0lvRMZ@;MXmTNVrMUzR1X$0Nz(D#7)3=S$R*?Ospw Q#~l(QsI;)!J;%QN5ARBVx&QzG delta 975 zcma)*Z%k5Q6vofJV6f3DR&lfFPS=*El~gmeL?kt9X=uxtSxBYJhAWC336a4U5?)2>=eC8;eMZe(Mr>z`7Yl1oZa7L|5y-}>g>Pv^Yb?>x_W-j~R|yywb_ zQeYpJrb_{ut9ZW;1OWh|-j%uq8l6H9U4$IkwksV#yApsn4-lYR#0WsK2;i#%U{ehM zrZPOvjHfT=9Ndwb3^UBB>$H#nk=pIa(%q-te0yu=)n*CpZr$^OB?Vb6yo1!s{0wP> zz?PqvV(c3#CKb&Ub#utkw$T2?qaw#ydqc_f0i7h_r9@@5bh!VhdOuk7sQgiDJx0#~ z6|YUwqFSt}=P(sOMz&^l8M|qSVN~wr)4j?7v0Gqh}@<><_mYfqhuNCh%`+2piVjCoA9xTXF127M4uR& z*3uOFgM^!L8n0MiOt+QkGPu=2y_!3Uk{N6{Mr#y{(Td)iat7G7rhmHUY1S!(v~e8~ z&JrywX!H9};!}?DbHBx8-KbX+NhK4N16!S)`_{U$IkCclt%G}K#|vk8J(FXeSB$`) zZlCJQpqK`p%h_Nb8#*`ld!BN>zPcS9h6zZbbV&22t*nIExJ7M_|-c!Z!~;qovn}GB%Ie zrpg74PkE$`)g9?{v53YnnK4ZUv4&rMZiV}LOOr6M|q&$XVrETJPX zZojHF>8FbVU!h#>rF5=^MELCeuF_Asm$??gyx~vB&IHH#PdrY`TRxakZ>^+tTkg+O z#g4xA*M~u-oH`zM8Ktea3zS}$5l2##=~0Z(K|xVzp*y03%w%_qhU3LB5}2s6|3eOC zbu`7InX{L6*r;B4q#jUru70<`GO0+$c-Lz6|YRdz`D-Z44HJTC(RWxc!BUil+ zRFTke3~2mqvyQ_?@dR6}aYobIXSUVfcl|qHliX)fp7yr(mimL<=m?}d>q!-`K# zn-kGYhwJvYu%Y<4o~$w|;L~?(T3g>M}RTMLSq;%SY|t z(w{6Sds@rVpP%8-w|Q|41vc5eGQU5)=3kc2SD?|q?|1Q&JExx-)s{9K{+P?M?kM-> zLiXiMlMC1vil+lTd|7!x#@d&xAoK1tz2(=9X%(Mb$b4FD&T@8!*na=>%hVZU&UIhD zJhS=xm$Qs~X=i12*G^#km+o6TrO`%zbD*Lq^W+7x#^Q6fe$VvpZ&@$A!uHIQ7&*n) z?Dem%Vi8$ux))?bL-dBf3tLxzV46Hp_LTOV&tDi8y#DvE4isK@?%wU4vpatOynR*& z7Or9EcRP3YvN*fN0#jRt6GVo;AvpX`$ItWkXRw&#KHpB#vb_H5$uCzK`BH2Dzdo^Z z{k*-ifW|+xsrgk<#U${Qb@M~+c}$ZNxL1j9{$}^~rC`98YhRc^4$V9GtzB&0A@0eA z?5Fk4U1n}rCvW#Z1LV${pO@b&Kaca9{&F?5%&9Boh5x@M{d&dFzWH9gjV)sbkxtbE zJJr74e*Qd$0*m+izNb97^Y=I~Hu_R)EsEd$d$t*5{JCG>o)eW^HXEuhVB`k|=L%3F k27!A?ahnsl7ch$bXKGEZ*l=X~_je#+Pgg&ebxsLQ0BMAV?EnA( delta 994 zcmdlLel}u)X}u1Ur;B4q#jUru_4{+f8QULjJ^4fJ>JFtW0f7s1UhR7HK-gqK*1BDD zYIiJKR61dHgJdZCPNq`d3O7872e}+YSHXr0}Wtw>5h&a&gF}6%y+j75x-8ir5CAV%&tN3I^ z_R|)3*2*!ooZVT)cwpn3-xAYLpY8wqfjz&Mzy8OySGSpEPMy}@C#C=Y$JMjvZRh$u zF0op>&+fp&H^297c9ijB7CUSC?3G}^mfY3iAV+@?@rloPsI_O}#nWcb^S&}Hc>VX| z>8rvFd{5Uu{`_(K$DeQc?fMPBUER)ZF{8GpaOdBR&kN;t*PmjD-`tz~l||tc_hv(G zQRaykj3v@%7oWMRydVQLyek+dFJwOj4cvWI3h9dXfB(;&&!3+s*Z-^e`jwF{wf>x^Go`{=E4L495ERb2rxiw_d%T9~hzY|Jmu)|2uy6eC@Y;n?JtU zn+_Jv|NrRiRpAB={mqU1qChV&8;i`zJ!cr+->@h*dN0Te4a*aLIZfWkdfvQzH9JG> zclny~uPhDDm0zFkKek%`f9>aD|9)UH`}pBUdG_=EI-_s>b-RB3Vrbt~`};4ECfkEe z{{Qp2`f7CsnN!E-?~{|S|MlzH^Lh1V$Nqf=#p1NT;mI*|wZDtc+gFvpSzaCieT~fDu$4=SD8VcV))k&4B3V3^BKkdi1&%i-{2j`TnG~PboFyt=akR{ E0Bi-@u>b%7 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-480.png b/test/fixture/web/screenshots/desktop-responsive-document-480.png deleted file mode 100644 index ad719800ef93a51680d93c4604e5221a0cc4fdb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4181 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9!19QL2`KW`ZFwF8gMf^ui(^Q|t+!Vc*UO|z zv^|_FdUeSp0h=bPKZPAi9AeH*hr*{X-6eOGrCF6jtKj(Kt^>kNITuV1%g=Dww0rV* zyV;NC0~$&>IPi4ZOUCdGe*7jwTUw?V~QQ7bIwRV61N6OXRAB~=YkDfWp z*uTt`dvSaFgDuy0SKHQD=RFXXUCz$1!FK`UA{HqHuThGcK|n;dc@T5@OM~`~{rl(7 z3n(uy-+uY@>)qv-k1y5jmwWr=lT~fhecmghbr0?8T_U0gT=yKD9UtfCzoPon&CPS; z;`aY5`L$!q)2r*P_x|~I^fs`KAZK51WBV}Z_)A8H9N~-xjYhT(p;3yOK|n-ISzI@= zeZW=sO1=e%rl{U%$M6b+lcD)o3))GHntaP5*xWe)^?l z*Y|t%+kl0h{N?Rib>-iF{q*bY^UKGt>fZl5nw@A`h7b`?L@3F-vB^)LA>ndi6$8WV cq0)f(#~M`Xk~BN3y9eY$Pgg&ebxsLQ0K2LwssI20 diff --git a/test/fixture/web/screenshots/desktop-responsive-document-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-document-480_chrome.png index 4cce4e6b23038ef5910423c015464d33663c5e87..a5940198e4bf34ffe403c8a799a8e8714a4ad7b3 100644 GIT binary patch literal 5715 zcmeAS@N?(olHy`uVBq!ia0y~yV0^&9!19QL4JeYNVqggr(8_dn4#-T-Wnj>lSUb^H zpCwSFO^^eo?76= zeX#oNA3KlNWNx4CPj5Gg6Aw3~23H*N{oz!o{4o3I!Mv*i`-JBe8s9nbq4GuhA=}XW z-;Iy>A6_kcea7$o*$t21URAlC>J#`dt0!zSmr1(>jY{CZBmVEJu|CiXLPveUfmJZ_BperDClwrrS^4n)C6a&Yu0H`{Vo{ z>|6J)x%|4(u?TjC5BqNg^D{6Q3negca2PPKut+d4G4U`kGO{%^FfcnfG%zYC9AFR- z7`)Oqt}y2`-#y&^N^n{Ehfh0!l+&`~s!@ZiS___bK$tgZ(8ZurQ z#Gy^T(>C-NUaR6@n9<8k%Oqy@mErb-SK{KYfvMraNB2qP|Np$m*!$~BUhOxhPw#fE z`}*o~^t7d;sbQcqHXT#LRO$a$lzra6-D|G;KCa@W2QW4C?W@+TEKg5g9#>oS?*J)z_D@e~RjDoz4N%!w{;MKOXZia$R;f91GrUG^s8)4ToG*I!@lpL>2^?aAG{+xf4q z_J9B2srFY6OPUr^L$d`=&l0FHwP)isXNChgF|_QJY*@*DgKhe`y}|tkdzFvJ``!Ed z_2}}~SC^MPub!{+zV7?A^T2jw^@FRsUkeuL4c@L1JtJnoYRuCT$!psg8gA~OWmh#J zn12KBz4~Vpt6E;}{qXVVle@y-_k^vt+q&6)@60{bkK50`y1IP(_kHT431Yy95a^d6 z>VAK01}2ERh3`L~++AP)Hw4tttow2K$=&v>l9 zkNrVZ{O4er+ayj!ll&b9CYl>^Uj-nEl$V=N&V*rls*SeAxeMK^y~v-^7W#BnwuG z?_k{>*ARI#rGCHY-=Eok^Zqc48!)JBzR2pyIB|m!SEH%%?l>j}zsF3I6j+@pW5{-~T`J%-*>5UoZDRm*3IAsGzucB6B|DkIane_kZH=k;{?Jk#Xu^7Eswp5L#iw>eSB zlyR~Eix)?BTG?I}hB?P3H!{acO|NQ1X#_BUNEH7l7%qSA0vNZ02*q!_LuWQS^fA>yr=I;CZ*Uzup^7VnEQTcWL z^sv1LcncUeZ)C3mh6@X4gz@IrstgZI^d<|k#Axlf!hNS{`~E$v!Y%GSK0jZ*`1^JL zSIgyd|9;3e`hNFxIna~eKO8+=)jDVLN2b`#A6S(b(QH=(*}muBqsvvTk88hPet+`L z>zLQe<=6iD_j|oLQ2TZ{+qK~*c5Z&iY6-O84K;`~z(HhRzaM0OyS%Ocvv>Bdrq9o< zy>#a8eY@4bi1~W={8uhZ@y(5l>7XDMM~&A#90yXbOEVm3jF~)@<-oQg$h{$0vC9s*!lVvFop()rtzC{ z6iiS{aJ%ZL6<}H;$HdvzBJa(_)t4YpbKKy&%I{rj(d*MwkIdbA=1e6+LwD6eIR=Jk zmB|O$cgk&8%^uTSY@6`-+DuC|b@@F1<(vIJy?>u?Z9q*Q}{{Pjw__VyLIY0 zx7L5Y`^W5l?7s(x&#VC&mN$3i#}Ap#bby($dHKFjMC-Bzhm$H`?k2) z_~`!q_y7OD7<0dDv#n^%)WB&fXTYzTy&$FAa?mr)-bG822U$;(!O#A!syXC(x$B&+`{c-JZ zB@hFHxa|Al-CtYgh;J@rEoPj!ft#x_HSOG24u%_2`jam*#u(hV%DnF2%empNIA?!* zGkyQFoBH)YL;t?*KX>-+`%8TM_hx@R_#0$+<;S;GPUmoV(*o?x`S$i}fkCW3-*&#g zU3J~ZVt)BEYviwOzrXG4=b4Yir`v!3@N947_wTP>=ie%-3G+Wu$+)?ZH5uqEX|9O0 yXEFT@4QoF#O@7F@hx5R@7=4BY-cMkj*nxTu&GI8Y3~S~v0D-5gpUXO@geCwcnTlBe diff --git a/test/fixture/web/screenshots/desktop-responsive-element-footer-1600.png b/test/fixture/web/screenshots/desktop-responsive-element-footer-1600.png deleted file mode 100644 index 824b6cbdacc1c025fae8b1a0486b25b85614cafc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 366 zcmeAS@N?(olHy`uVBq!ia0y~yV3`DD8*wlJ$&Nc|TNxM_O+8&4Ln>~)y>7_Jpuls$ z;K2Up4;!Y-bvEt0yBVnJh1Gs$AXTw37f5Dq<7Hq_IJ=FJfnmu_GX{nRliO?z3=`6B q1LZE|NHZ`v%*q9-_Sih!74N+b9+zW+C z#0q23_QIfA+0g0-hZ-5P?2b>q^})}Zitsx7PhFl3G@Xtu`F~4B7|7wWWm9;Q|q1NV@SoV zw>LKO9x&iJV6grF|2Ojjavd2yF`ca{OJfIW;%2DZvz!^oVA#<-`5=?xWCx~2K-?g9 YlKnFaQzopr0I1J8lK=n! diff --git a/test/fixture/web/screenshots/desktop-responsive-element-footer-480.png b/test/fixture/web/screenshots/desktop-responsive-element-footer-480.png deleted file mode 100644 index 0babece082575773a8066702899a6e10c99bf549..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 260 zcmeAS@N?(olHy`uVBq!ia0y~yV0-{%8*wlJNpAD`Kmmr+o-U3d6}R4AF=S*=;5lG$ zVE^;PhWT=xO>uWOGiX@tXJ)7{&S=nRX6rB-?9{HBuZ+q3-KA1MZ!vhf`njxgN@xNA DR=ZM& diff --git a/test/fixture/web/screenshots/desktop-responsive-element-footer-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-element-footer-480_chrome.png index b01be5a5d7751409a1387bc1df6e655473f93f6f..119a7de1615cd0769dedc4a63712b36d8501c611 100644 GIT binary patch delta 420 zcmV;V0bBm_0_FseBYy!ZX+uL$X=7~w04R}tkv%U2Q51$B8;#FMC=`n6XfPI=l~6Fl zMs&Nx(#_6}iP#;J*%2Dmmiz;WX#4^yD&6)H8m(Rw+HvkoF_XwRC-+b9+zW+C z#0q23_QIfA+0g0-hZ-5P?2b>q^})}Zitsx7PhFl3G@Xtu`F~4B7|7wWWm9;Q|q1z#ss?Fu)29 z@UI9Hn~U{WqM%>rJ^L8|z^7In004hvzyJ_1U;qdhFpX7VrWw3j(5_74_u+ O0000WGZA!u6{1-oD!M+LPY^GlD) zwm&pJ%el+Zj92br>DTqn0T&YtRW$y*di(O#*HB-Bt-h{;JHA>7R5(poQg!wNugB!W zlmFMw`@YNWz!USdBXc9G<0~?L{Ww!Hqr zu;a~3#seqUFrWXH#JGR$;kY%oznpEDywjKe!OhRiqrp9z)Toox=w`~6t>3?}yxV;3 z3#f3)2)37-D<1(WJeF_{b}Du``+?N`f77a%3bbCoJkLIN&wtZe^9M24mb=g0^L^ev znF6iswJ$ks%IgvsfgYNmHcE{K!H`J>+rG`4ccAv#tT<3+%zbry@ldH&QF7I=n*J7&p{~r$*OwQka`^(dY;E$^e&hhJjympCYlo}0!A(INO-McKj z<9yU*P)l!t@861&p;Eb&&6Q)A-mkxYxjMu0PgkE_4RnA1ayO&;=02;6>J1I|uUNf1 z*z~`DsMP&~zHu_@K>9Tx*X~`eUNC>_GI3y@beR3?)&&~CKusr_9B>P-6k`vW_Z_xH{Q zbs=Bx{my4q=^xK)G1JtRVW^ZWgTCk+bs+t!r`)%;wvE5nnC=BuiVU}|^t(T27XvXf znFc#`{Uu|;&u{zlmw_6skM#BVtt#vPT?BO?Bme*TwP136-QUk3UgiI*zb^|{yc^A) z^h;HvIhaaeJ;bx;r^)ud{tSLkH`mvfUpTq_bndUB11n{|uX-cDe-^j`?U(oWf3S0? z3}4Z0;CTE3TaUonJo}oHyV9 zpE>V9@sMc`4EhGkr~~QOsLX!ZkN-hj oHF!zMfrXzopr0Ol;?$N&HU diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-document-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-document-1600_chrome.png index cfd442cc062ca2dd343ea08599cc916fb807fafe..a4fa59764f56ed3b3584d4a000b801f41afa91b8 100644 GIT binary patch delta 1339 zcmb7@ZB$Zs7{Kr4vKZB-q$@Q;cd%&AO`WpTd9@c`rYYztk6HP0thThJk+{r6sja0Q zHT7;b6A{m*?4`na&vey9e3@Dr<`^bMf=Vf_kBre z(eM^TPI8h}8lj@&Mx49*N`M0g2VCp>*L$Z4#|{p|Q%&y}PwCA52_N_dY$0 zZUX>dP3qq85Wr-4{8j-10PkZFA-neHjLbe7m=YR-~Ml*5sh^ z`0=0XEb0?aej~HV0TFh4uwuT5F}@MGe3Vvylv$B*{F>aI7F$Tq4{5ktrDzErC%0mO zFxe!2ar@(kPvyVQJi6UR98Kxd1j3*h0rB7cBj)XJ4~2FEQJjorEvs=&SJ#66}Q zV&~%F|JUfXL74V^-ZvWvJ7vGNYXnp)?WR=akcNm~0+BlBd)^Y64)|&L-n6NT z2Z%vszWP38QZ!%RBM`nV1{wMK`tmHHP-u-tnFi%Ngbr>M;}BOup<}}0$;X252Pjt} zwX?puBX8j8k*n&nc5ZhT#*^ zc!G*k-ImA7#knnkXq|H~grsaDI(lHu&!m*81p1_gXh|);INXw*i`$it)IohOH9r$! zH_UbYRHMnOw5<6b7>wjC97@u;4E6A|upnposkzQdi8AUnG<#V!uV8w!sZ-*bPtJr% z9+QKtlDQcQ2Y-G0?4g&$o^2n&V1*G~urrVE9in3;`;cBk(s>A;>+lv{)$W-`0q}X( z;PQn&+O2D3AkGsu)tGy6o;U1ECj0A!$wr-JUaCYTcDMId8#YvHb?jo)o@=1)tZ+fS zw+L}&7gbJ@rp)Oe_yX?hS}fFU$H-t`s*2kOwmj^2H&{NfgHTdlbCG8fCkQ! zb37k)nHyw4L-fYlrO&wbOui_2TKl<;EyJpB`uqL-86Grzy|-KW`Mdn(`FsZiUtgYC z{QchLaP|icTd#d#@%Y5F`5?1B^W+Q6oZ^wy^S^!JsJb>Q4rCs~ovydqrr{4*CpR*k z)_newal+Q`K&SUbWIws_JbsU9Z7~Dij{jHXm7mAyO@FzXxuD^G;SN6i&5okxAmaqZ z=WP9+>EFK~eeFw7lrS7vdt+ZvF>BmpMyAsm#q;DCLgnYo^8vYUzF&VD-@VJ`><=cG z7Qc!6=fIG6^OkeHg1~du%@;X(nI z)@9`vk=a#@AcG3Dx2?Yt(bHWp%!cQL@e((3s11Fa2_bV)l-uQAkx*|5rE QUNuPE)78&qol`;+0H_YCpa1{> diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-document-480.png b/test/fixture/web/screenshots/desktop-responsive-min-width-document-480.png deleted file mode 100644 index db1ea3ba1ee22b1aaa54b5d05e5a1aa1f83b71ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7044 zcmeAS@N?(olHy`uVBq!ia0y~yU=?9tV0pyB1QcAnonx;uunK>+N;Le%Vxs zwuf_-S9z)`R|X z${tAqsiq1x28ITOd5jDU3LWV{0gh4O(J;Z0AVBGchCt)?mj><|@Bhu1$DotC`|q0t z)4$JOp3i)3Q*G^))4%um%d_jG-j=JWp0|u0=!yedh0g;ifg{F1lI0^0kaV{9BwXSk2$o@U!URHCfTpKHJ|Suzr3B%yYkcH`|Nvb?B*};XP&m{ zK=@M=TaY8x%^fX!M=KuEYF!#8UXanJ%xoVp&AYb;R02Q!diL|;dG~+?uvqbp^>^Mi zv&LNc_Tl#D(ZoC2Y9g=6NRPyO?lN=3(K+%jZXfvlqUOqOcUzu4%f)`InlsvD7;PAl z*I1-&ss%S04&1$a_X|sc=JxH|+4t_*Uu|A1vti2Hi;J7%?k)Fc7TfGlIojkMZP)`7 zA~~HMdZgdk_v8Hh8K!-D(wz=W!1cd>eknWylw z$UWEnMtf?b-Bi+2Gi}o`L+Wg~0!I7VuP;Fb@%=xao;&K#&p&thIHR}ayVaZif3Esv zk)V0o-G90Io$HxZAjia5j}AJFj<}FE+(hF5}>r kL&4k8(NfIO(tqqbY+RD=J}?4K4>2%!y85}Sb4q9e0I98>p#T5? diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-document-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-document-480_chrome.png index 9b47d6f613cae24896caf69b0e574a33155cfa16..f143c34f3323071ac6b212ce30102ac3120853c2 100644 GIT binary patch delta 1219 zcmaiy`#0Nn7{|Z4tTaff(hC)r>BdwmCd$!fI(H=rMx$G(OLeNK7)8vb!*Y}&=eu!w zqAovFPS4!GJH{zRTxus(vK*^hM8;fF#3dvoWBKL}*v{vN&-py(d|uD{dA}cC-~px5 zCLdvc-^(lbeq1sD*l}_>WJh!e{zuCTPsjc3@K4qfh-bM!2NMT<(_an!G4`&!WQqVz z8=Fm5X;38z8l=6wc>lCna}<7txf$dHj=I?@Yi#9Y<>H({aljBJZepKb|Mm2QOpk45 z3ayvZUhfTzbDwOvt7(z7Mx^KEmk;s-eb0|dJL12};!{+fOdIKg;enLNQ?E^Gna*>g zTiL5@J~{lM`te^l>ExpiZ>jRJw#ALfi|^xuLZo4HFNz1RyHMRmPTMy?1)m9{Ih0Pj zn0zFe4n7=pM;E@}aiQ)J3^;Znr%%u^;KJ%0omNQk~MKpicn+I1wA@ z=M5agr@og50>CF(0p4GRWzB5NI0?jmoAyhOOWybgss}y!uGn9k6n9BEvV3>ISuA7zkpg2(@0g2z}e=2SgW(EG0GBs_kz?zo6Pi zByvLbzHN1F&AfTRnWMu)p2()`y9THonSlf=QFLtQ?W%ZJGFk^a&j2~7W@6`ai)hQa z!_`BDKG2jZccxYJsQ1(>jdZ=}Vs(CA@{(Ab;@ayDTuQpiT{9l(h6c>9Bf)wD4tCZ- z(80Ap!Z0_(E1>XXGijEJYr{o#?}}mA*1kCNX;01uoknTJ_G4D&yPbA6g+if11~e^L zW;W=i@1UU#&Si158u?q|_X#PCu8oB?Ato_G2xY+f`!4 zDHzrtliC2bBb%J2AF&E@Q}<+(YsNr?RCBOvBR`VwZ>&usBBVpVgEn%DIa3ep(zm71Wg)<|RP^L*3*YO46&$nTmc-YNRjI5D z;8vHK?ZLH(sWE^CjI@h#13|}iz}vTG4eKiyT<`>$m?l!kh5}G8l;$7B=oGHD-zn=+ zOK7#+C_=%R&4cYa-}!%b#?I*k>)pwH_+JVkYfLNxI|~~`M!{WDtr!po6^l4Kt!$~e Ui*_c35#Vxw57oQHGx~>r0T8)2761SM delta 886 zcmZXRZAepL6vxlKcXP{&>y5U+Ns4KK<;p%V>PLCLoag_X^MC&Q&Xm%SemlAx zc*hk=1we}ypU&k208+enTPidUNS*8@^6>V(N`TT>0L>KuA1i5o0Gvwz_?ZKcbPqs6 z)V+dpb+CexCTL@MJPr`$u#bjS2>c2>~iMfw=*JpitS+jA@&P^-Um)D zBxwFDpcKMPB)W5_jKC*ZQGO&`=htl#(oKQn2|>rM9;s$avjy)j)>9SYJt#@@FNYc1 zCY>=eRdWj$J2k@+I%vw1>6`oioT>$3+sowXS8cGB5zR}UHLMKoeFDW4|{ zR8wojdX#iwaU!ef>!6{QGlGHMYEr>7%4(hb!q?pyML;jKtxKG=N{W)Fbo`x;)JG^`PIgh!g1z?W9{^TsfL(rdR*X+4xX}Xs|Ms z_E^ZcMJ8Zw7aSYyo~nR4t7(2(KG{sO$RQTb;XkT(_!{S}5s7C>O>@!V2<@>e6|f%t*6H zJ!XtMe_zFjQ`Ek*rF;;TxR_oR&bu2<14hv2IZ|rhFi2aKG6Kt@^q3AM8?d!=ZPv`% z_}w2l#ze63YIL#p(@=d`5(rKWO(!OLrw)9Y;q2}1T5oCYSIlJ^~yJM<-o zNIVyF!YpRT_zFuL5cEh+a!+0Ko$NN1YoIsywr`&=(MA8~WnjHJyGDUPBr|;OhE3G*-r}94( CT7TsL diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-element-footer.png b/test/fixture/web/screenshots/desktop-responsive-min-width-element-footer.png deleted file mode 100644 index 105043e10286069c991a9fc3c27b40120fc336f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0y~yU=;zfjX0Qq&3IhY9R;IIaKxT3-1B1rI+KIOM zEP*0z^3uKMJv2nRUS=4G&7K-yaM-P6_mN9y&-HcQkez%}Q0nTmKg^vOf0(qi?tT-J zS{o;FtMHwV;p7t*>fh(6zqkGV_zrig=Mk>t3*Qbch`M><6??ms%Sc(^GwxZ;rS52r%qhuKFD=3N!oCp@pv_|AzBl`q;4*@ou- zZhXZ5@M_uXGk)*SZg~9ms>=0LpTLJ9cb2vuwlVdyI3}dEaC3v^#e|8z+cdmPT+Lg; zkCa~Yz2+L5)>#xY`OK>+m%qQccj#8Ki0k>4+di}Kha3Eumvwo%!7rx0()YR6M7#>0 zU-IO@ciWyfhkvN^l!o$WS;fx&=jylq*8DirZ67zx6xKSncUm1|ERUaI(T&Y&z`$cm z@^*J&_z!{$_AZ|c499*?7srr_TW@bT@*YrNIN)&Ll+1&8K{Ye(zY|r&3Xoz+cl32+VA$Bt{U?zX$Y(4L za(7}_cTVOdkfV_75#-CjP^HGe(9pub@Czu^@PdJ%)PRBERRRNp)eHs(@q#(K0&Rd2 zY)RhkE)4%caKYZ?lYu66db&7}?f=mYjVt{_^$SOmmxI1|7E;u<*%f~XUtk`x7k-h`!0No*`7mY~4&boFyt=akR{ E0KOq$rT_o{ diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-viewport-1600.png b/test/fixture/web/screenshots/desktop-responsive-min-width-viewport-1600.png deleted file mode 100644 index 385338ef45fe1718c7eb709eac9ba718952a0126..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3775 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#VEn?t1QdBSsZ5rEfv?Te#WAGf*4tYf*NPZQ zxLq{7Wu?*BGiQ#_iUzd{U1}>Dgif41snO`>!_JX;|HXdm_j8!mobPPbUcZ-r-mR$1 z+(45S`2MXZ%U{M0WHKDs&k+HlmvD|!)Cq#S%h(TWT+YrQzS+;_b~o#uHJ9Vo{Qh#b zp?jx4|AVWanL#noV8S>`jRwI`Nd;TBe*eNExB1!^P&t$lY(Hi8I zF{gfg__t*8_wO%vGhW|hH@EcDz3N{@2bQkcx=j7Ut)GpoK(9H>Y8a(PgJ7tnf?Kz$ ztC;#Dv#S_^X?M#?`Sa)ab$~2}ODuz(%Dc?`z~bAyIEI+hQR=dPet*6V%$3tWy}Lbs zvfsY@?=Meh);qfTkcIsQkas+UN2$>u7&56Ky4v6Wfnm0lSUb^H zpCwSFO^^eo?76= zeX#oNA3KlNWNx4CPj5Gg6Aw3~23H*N{oz!o{4o3I!Mv*i`-JBe8s9nbq4GuhA=}XW z-;Iy>A6_kcea7$o*$t21URAlC>J#`dt0!zSmr1(>jY{CZBmVbaj=SILIK6Wa?CuElI;~kG z8s@ok!-mu~d$_tab=RtBHocH#;okjLD1xc&%=GRbLjTU3{(R@a&$-V`^wT5#+rJ9` zI56#QVHFe5K86CdYnKzNm>hS%WCU>;802R$fF&57a43KU9QsBDKmjq(;c>36iXr4~ zU2#1y;-q8#eJ*-i3d{g3UD`Th6m-j}nPHyrGqUB6u2VUql4cn&9@58+4~bvih|4dwiIy2@(JW#t!< zWyfD~f;@9zW`uwHOHP)bjKing2De*m>wf2f+AV)R-CVBx-0uI++b>rG8!OH6|K%*d z|N2$+>lH)J1KIZe!~6o^NL6rWfV4-8SVjeaAu<{sqsal73`ocgpq^f76^rfZcNVtb zu(J?;{nEg;QNi8;oWmMq7+JuK6M{om;HE!+!>ac9SYLmJgl7A=yFGJ$Klwi&)G1=~ zxBp-JPiiHUZ(btiIVPik{pF~z5pRqW|-HBn{IhmJ0jzY3W zkS_y6l^O#>Lkk1LFQ8Dv3kHT#0|tgy2@DKYGZ+}e3+C(!v;j)6C3(BMF#HF>1$&oI zW?*?YcQgQ3;ZO64Cjv}rX^)4}oC^SksFzw?Ld9WyU0fQ_@LK{oSpPQ~ne$SnK zFY>g*+*u{+`OD9p$<6z4@Z8Nfps5TDd%8YOou&R`i!GSP@L)0L=0=w3j7oR5vpZbP z;b(X-X>-ZD^#2MB`fqDr%RkvzTg;$WnZw_pra$>3|BT5W_-CSFAMrWH#k1cEewnj* zFWAfq(Z|}R{ts9uPvkhQ`TZ?pfa(7KIsOa}nm&KaeR}8TR-lRNEbf<|n>+LEYUYB2 zmg&_@DwT|zKQjMjnk>NND>i55?VSDv&*!`ag&)I#)e`Y5E16)n8*A>&=Wkdu6DS!| zc<$83`udui`z#s6YySSse|qQm~)y|U5wsDp^B zY5BCBEXvy04r8|wb|%wxE7>d&W|i|1cI?>m0_ zg*C$l-vx||SfmuZMk#6r0TGe%U`6GZ2IDoaU$7q7dnSDA$M0`nzVDxYF`Xe{wga;Z zr-{RqQHq*DKtz-r2>kqlQN3cWotr;H-qY-={jXk^9>1OXMV8@)+69I{CSC#6kxKE; XEarcfuCeq0C>T9m{an^LB{Ts5uFs;* diff --git a/test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-min-width-viewport-480_chrome.png index 1268ca34f506db977afab468bc935b6def57c15a..05f4f5c914ff5aed112cc4e77751d52e724a1060 100644 GIT binary patch delta 625 zcmcb^w^n$9c>Na+HU`53iQJKI8ZP z?1sm0uc};6^$C0!a%XAlVH;CFi(^7s3pY1tUQC$iyG_H(#MQhd{7C6V-)pY1X`Mwe zlh3@Ga{2q4dxvf%i@2U&x$Sd33xBx5k9k>_ryKlY+ADpZYfZ$f@cAWA4t%%md2{%O zI!|dRf0kA3?0>F)>u=4EGu`%a!%ShVV|%C7F~;)v85Z5xtOg7|wj^(N7l!{JxM1({ z$qWn}I-V|$Ar-gYUN_Wh36yBNXx-zr@bbzx4J%Z%mTq045gNt4kz=Zh>P97I=?fEm zoS$rOuNOM6QtVe>eE;3a?Gnj8%nU!mt-mrb+;E#L$h1rBbkza19~PGD)EPFk9p3)^ z+2h4m-z?XgEXej?@&?BF9NmV;Li!mRawjvg#)+reCJ3*Y7yp`*VNK%yM>;>hzy4VB zEn0l?M7D&@8yMvnxf_p4B(HL3IIyjdapJ*fi36MDHgM+E)qylTOw2d``Tgmy5`r4^ u_}{$(X?XeB?&tS!zq6nkfX>+`T0eV=Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF*m;eA5aGbhPJOBUy24YJ` zL;(K){{a7>y{D4^00ziOL_t(|+U?gtO$0#{MbTfR7pTAm0wRzz!bS%I*kP#fFr9Ea z>2vm#db^vyW@Zln@UPzL0RV7ElaT_t5Jx@W3U)mJfKyiV@B4{@xU-Q4YXOrG0~83X znc4LS0Js~IfdpL>9QA-J*xx_(1OQH0U!Tdp`}z8_fCPa72{kjj9svM%;{ubR2V4`Q z9&ibJ*9!nRW3A-d-^a(xZ(XyY0%QS`umT$i*39gB1OVKP3zP8yOcvk|H)at{QMj{N P00000NkvXXu0mjfA1ZWf diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-1600.png b/test/fixture/web/screenshots/desktop-responsive-viewport-1600.png deleted file mode 100644 index 309ad24dca3a5f37e7f0516587739477ffc1f426..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3777 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#VEn?t1QdBSsZ5rEfv>~U#WAGf*4tZ#8$}!? z+%8_f^2&ip($Z2Wpn)@sTUf(^$v9!tfyC^^whg4IX&;{f@q~JfBVG zwVf?PoW1@AP;h$)k5Z#SFl16ebhW?#gO_Vf_X3k{!|^4|$0{3HflP;44TGGzm0QIS zbMW8K>?)>$C0`%@^;CcV{&G2U-)6hHrJwFq|0+5#@mkbn;RjbgGjW6bX2Lj1jRwI` zNd;TBe*eNU?_ShpP@=8yu}YXD9sy)AEa4pN)ZJz52UOqK?q#sJ5~VKt=lAE^FLyJx zSAKtc-c$Yl`|mGLGrE5YJp6w&SB{oQL#|LB+PPA+rsk)WEu+Py{^|PZvU``mXOqd8 yTl(SK=7#LZ=YRDdWL6B3s(;Y8O@_1sZ^dU-X+O1;QQr=#a6Dc8T-G@yGywprTzi24 diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-1600_chrome.png b/test/fixture/web/screenshots/desktop-responsive-viewport-1600_chrome.png index 7fabed70e2a6060058ae97e510ce14645251deed..10e3c7f1948a431ea537911e8e9573b9028380b9 100644 GIT binary patch delta 858 zcmca4cT8=9c>Na+HUfE?Kg>RQFz>3sKH+(V#&=G9sC?0W$Tl?pcjF`ehgZv9pYeNt zcEjVhS5>a3`UE}MO@FX-1fPig+JWj$Goh|(+z$x?UlaIwI5BInl{A&YrfDue5gMWT^pMw~X&XOj z=`7pgBRWZ`<6dLLlG}QXstYXUn+yJ||NP0uyr6Em<=NAb*DfdSWv?kY{m#Oc5olq9 z@rHSPmxUEF&251^Ab5~0yxEa?I-~wge}0BtdHermRWTiS7W41p^D_tI@A$^cCPd$h z>yi2W;nnGvvzc?w&7Qq~nL0yY-DE?y_Q?ip9aylGabfBd^$`T4&8PcMGC%4qgzey{F(B8XS~^VQ{-oDNguHz%@}Fp2$P??3FI UyD#(PcaZBnUHx3vIVCg!0AMASz5oCK delta 466 zcmX@6c1do6c>PiiHUZ(btiIVPik{pF~z5pRqW|-HBn{IhmJ0jzY3W zkS_y6l^O#>Lkk1LFQ8Dv3kHT#0|tgy2@DKYGZ+}e3+C(!v;j)6C3(BMF#HF>1$&oI zW?K$X{y3p7#Uy)HXW%`Ui{&&rH zUo*O}e6skS*xIzbV&;2yEpKxJO=YNHeax?GbF}>}BZ$Yq@ZNXxM2_i<%Fp-NGQ5}t z6csO-cJA+s)jS{O?~jgua{Sv_M!gpsZ5dX4VwyaW>B(jRrc}ns0!;tKERDC{lw)*# zo}&*k=7DIB{gw|Rag!TaPHPq4mt!b7yMFsyPKN2l`|2Vs%j@#)%RGoWw|#DLdfM+- zK+$tI=P|fcGH#wIIG=H|fZ$3-u{kqu=kzx$D&8gzGVcS|G5M$pF8#@ZOs6$>=JPWg zN&`y7oVV0I{_o$v%-_!#rhoc*eE!s8`TpbIt}^N!-!51oroUN`DFtX8#EJFdbBv2; wzZDE9IrohTWM$5;op00i_>zopr05?LhasU7T diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-1600_firefox.png b/test/fixture/web/screenshots/desktop-responsive-viewport-1600_firefox.png index 10bea61c7b5de2dc1130e77b918518a8f8ccbd0e..32552aa0f23158bbef3d6ad832f26eec219ecf5f 100644 GIT binary patch literal 3918 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#U|hw)1{4V{={O6d*pj^6T^Rm@;DWu&Co?ec zGkdx?hE&{odwXNAh@*(>MNN}J0VX*+J4FFT&jo^>0*s0e9zPaj>a59W*}eFFb*UfI z*Hf8`*S|V*=Na3c9mU(kfu=Hikm|AD@)g#aP{2Fws+KY>8 z0Q-xSqG{09?Zx-y7)omQ)ZU%PP+)1F7hlFV@9k{nm@_vm%W5Vt{wv;Qcgo>j{O?eG U-^tUy^MU;B>FVdQ&MBb@0Jy{Sk^lez literal 3982 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#U|hw)1{4V{={O6d*pj^6T^Rm@;DWu&Co?ec zJA1k~hE&{odwXMVh$n;V#a|hJJkvhjJ|4YDp=+HQr%HiZqblpQbmbepO&nRWO9bsM ze|`Q+X64(er&~U*e-)9vhVf6?@r~7tK*JfUJUn=j++jr;ho!9e|&wSsV&tIVTdA(s?{QLTMU#nz`&)vPwZZY+- zMVUXtqCLaF??X7+Mx8!va$w)qW4COXy84p8GlBdR*Zh=QcMr#Ks>3U9*fMZLXMbmE zD4to|bNlVP<8?nC7uHn#-tqez!}3orfA@cUIbXiq{(I5Rp3_e^{r<(U-01loTgHx0 zOrup8Fi8w_qjR+F56YNBIvOmmNo9ZM(6H*e%MJ2M1@AQdEgzJIQzia9@jJtU*LQ#H zsAf8_@{jet-v7t8|CX>N|~)y>c*D#8Jfc z;!4gViW`#8&lBi4;JHA|Q-D!%L;CqXfjJ(Qje;JJGyi6n_%SREzxt|rC(sNkfc)*t z*liBXleR%U{v( z_x1NLExW$HeC(FY@M_b+!Jo%^jl*Z;r%>%ZUMTG=u*+#cb1=ap#BEveVN SlV6?%g{Y^ipUXO@geCyCp|v3Z diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-responsive-viewport-480_chrome.png index 13ea3c92273ecf5eb0bb4a5c363a6b963e934fea..4604c7d97abba1b4553810413c1f84a395adbda1 100644 GIT binary patch delta 709 zcmV;$0y_PK5Bn347k~5!1^@s6<&*vx0003hX+uL$X=7~w04R}tkv%U2Q51$B8;#FM zC=`n6XfPI=l~6FlMs&Nx(#_6}iP#;J*%2Dmmiz;WX#4^yD&6)H8m(Rw+HvkoF_XwR zC-+b9+zW+C#0q23_QIfA+0g0-hZ-5P?2b>q^})}ZihuAr`%hh-4K$sOE%{4E z7|7wWWm9;nS1|aVYSWi6`U1Th-wLc)>Q|q1tS%l0$5sOGFO9$X6th5Y#NG%yFN8tc0t;7@}Is-{zmrfxF ziaclG{&3ftz&VFoZ0<6~SO);`U+vWk0KklsQ3ARrHuVC#;QGOFy~6YkzkX{5-@mC( zpWF9?WbEU!qx$mceLBCYSIGI3AqP#f&;v373RuP%YrO;j%*GFsaROW@HuVC#;O4{U zdWGp7oIXnC{(O5$=vbPj6Y4dWD=Hv(W=Y0h8bXItqbhjIq{B0Kjbg zlVJi}DPU7CunS)P`CG3rz1O#IC37!dJgiTj+R2+Q$=vOBTc18XZ{PReq^%4Lu8$Xk=1zalF)C=r_r}xh46{h$8$9XdM)$eEZ=~KJdf0xX?e)6k6 reR_u<@6;>g{F6Zh)RW)=N*4GBMpP>4ufYct00000NkvXXu0mjfB)?U9 delta 376 zcmew@+`>OWynZPM8v_G_lB22@kYY)9^mSxl*x1kgCy^D%XDkkKcVbv~PUa<$qmb+o ztx}P(#zHnf$R$0&#TX67isO52o zUE1Bzd(+bR89prkca@ppKGD-`(3C z_qQT@ZB@%0?#&-rY#1kBV0Gd;Fl%NkKO@8PLdMAtnWB{std)D9_a@f=K-9_2@$37) zK6C&5|J&R>)v@7we|`MZ$SuJjG&zv<4p3_>rgk5(KTK~ANPA9x_T@7$L>N3>{an^L HB{Ts59TAte diff --git a/test/fixture/web/screenshots/desktop-responsive-viewport-480_firefox.png b/test/fixture/web/screenshots/desktop-responsive-viewport-480_firefox.png index 771637a578907c913bd84996091760742011fba8..e291fac934b4b20b1d3216c19ac6002e24d0457c 100644 GIT binary patch delta 298 zcmV+_0oDGc59bb$HbNXpL_t(|+U?gdZCybSK+)Og;V^`B>C*>-5tu~u6%s*U2m>l-G=7sI0$d|-)eGFh-t`8om5lxW z@>E}bwC{gElDUt^qdxt3-oOtS01}fC0>P7j1G);pnwecM0RX4*1CtR3TQh;HUf>RX w&7XROMez?_)-5x%-s>i>PPur;(^b delta 375 zcmaFPx0HW^nR}F{i(^Q|t+&@V=86PLxLvHj@GOt*)7g^?xWYH)XC4w#$zzBz*twEn zRROE>BdKreOrCoP?|+}!w0is5GjH#_tL1*=6p`nween z>FM7RtL#bp>+Al%SX1S2o_lj5b2j7T0w!Uu17^n6woD9t$G9gqGR7GBeQl`T@V{=Y zy3DPre|FcO%bVMO|CE|myEeZ*=k@b5U$4JCzc)s2^R-p$>oaa|yDD51xA`C|ALHZ= zZ1PB0gmc@>o38~K3QXcAe`Jg?E?C8Wr?qyyxXkS+lp5RepUzcG|k_ m_TP-AN7mJ4&0afi!f*Zyr}RRfb>!7B0D-5gpUXO@geCwC$hGnS diff --git a/test/fixture/web/screenshots/desktop-static-document-1600.png b/test/fixture/web/screenshots/desktop-static-document-1600.png deleted file mode 100644 index baba0fbf491c244f9d2c0e586ad0fe78b09576ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9289 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#V0pyB1Qf|t-C@JPpd#Su;uunK>+LPY^GlD) zwm&pJ%el+Zj92br>DTqn0T&YtRW$y*di(O#*HB-Bt-h{;JHA>7R5(poQg!wNugB!W zlmFMw`@YNWz!USdBXc9G<0~?L{Ww!Hqr zu;a~3#seqUFrWXH#JGR$;kY%oznpEDywjKe!OhRiqrp9z)Toox=w`~6t>3?}yxV;3 z3#f3)2)37-D<1(WJeF_{b}Du``+?N`f77a%3bbCoJkLIN&wtZe^9M24mb=g0^L^ev znF6iswJ$ks%IgvsfgYNmHcE{K!H`J>+rG`4ccAv#tT<3+%zbry@ldH&QF7I=n*J7&p{~r$*OwQka`^(dY;E$^e&hhJjympCYlo}0!A(INO-McKj z<9yU*P)l!t@861&p;Eb&&6Q)A-mkxYxjMu0PgkE_4RnA1ayO&;=02;6>J1I|uUNf1 z*z~`DsMP&~zHu_@K>9Tx*X~`eUNC>_GI3y@beR3?)&&~CKusr_9B>P-6k`vW_Z_xH{Q zbs=Bx{my4q=^xK)G1JtRVW^ZWgTCk+bs+t!r`)%;wvE5nnC=BuiVU}|^t(T27XvXf znFc#`{Uu|;&u{zlmw_6skM#BVtt#vPT?BO?Bme*TwP136-QUk3UgiI*zb^|{yc^A) z^h;HvIhaaeJ;bx;r^)ud{tSLkH`mvfUpTq_bndUB11n{|uX-cDe-^j`?U(oWf3S0? z3}4Z0;CTE3TaUonJo}oHyV9 zpE>V9@sMc`4EhGkr~~QOsLX!ZkN-hj oHF!zMfrXzopr0Ol;?$N&HU diff --git a/test/fixture/web/screenshots/desktop-static-document-1600_chrome.png b/test/fixture/web/screenshots/desktop-static-document-1600_chrome.png index cfd442cc062ca2dd343ea08599cc916fb807fafe..a4fa59764f56ed3b3584d4a000b801f41afa91b8 100644 GIT binary patch delta 1339 zcmb7@ZB$Zs7{Kr4vKZB-q$@Q;cd%&AO`WpTd9@c`rYYztk6HP0thThJk+{r6sja0Q zHT7;b6A{m*?4`na&vey9e3@Dr<`^bMf=Vf_kBre z(eM^TPI8h}8lj@&Mx49*N`M0g2VCp>*L$Z4#|{p|Q%&y}PwCA52_N_dY$0 zZUX>dP3qq85Wr-4{8j-10PkZFA-neHjLbe7m=YR-~Ml*5sh^ z`0=0XEb0?aej~HV0TFh4uwuT5F}@MGe3Vvylv$B*{F>aI7F$Tq4{5ktrDzErC%0mO zFxe!2ar@(kPvyVQJi6UR98Kxd1j3*h0rB7cBj)XJ4~2FEQJjorEvs=&SJ#66}Q zV&~%F|JUfXL74V^-ZvWvJ7vGNYXnp)?WR=akcNm~0+BlBd)^Y64)|&L-n6NT z2Z%vszWP38QZ!%RBM`nV1{wMK`tmHHP-u-tnFi%Ngbr>M;}BOup<}}0$;X252Pjt} zwX?puBX8j8k*n&nc5ZhT#*^ zc!G*k-ImA7#knnkXq|H~grsaDI(lHu&!m*81p1_gXh|);INXw*i`$it)IohOH9r$! zH_UbYRHMnOw5<6b7>wjC97@u;4E6A|upnposkzQdi8AUnG<#V!uV8w!sZ-*bPtJr% z9+QKtlDQcQ2Y-G0?4g&$o^2n&V1*G~urrVE9in3;`;cBk(s>A;>+lv{)$W-`0q}X( z;PQn&+O2D3AkGsu)tGy6o;U1ECj0A!$wr-JUaCYTcDMId8#YvHb?jo)o@=1)tZ+fS zw+L}&7gbJ@rp)Oe_yX?hS}fFU$H-t`s*2kOwmj^2H&{NfgHTdlbCG8fCkQ! zb37k)nHyw4L-fYlrO&wbOui_2TKl<;EyJpB`uqL-86Grzy|-KW`Mdn(`FsZiUtgYC z{QchLaP|icTd#d#@%Y5F`5?1B^W+Q6oZ^wy^S^!JsJb>Q4rCs~ovydqrr{4*CpR*k z)_newal+Q`K&SUbWIws_JbsU9Z7~Dij{jHXm7mAyO@FzXxuD^G;SN6i&5okxAmaqZ z=WP9+>EFK~eeFw7lrS7vdt+ZvF>BmpMyAsm#q;DCLgnYo^8vYUzF&VD-@VJ`><=cG z7Qc!6=fIG6^OkeHg1~du%@;X(nI z)@9`vk=a#@AcG3Dx2?Yt(bHWp%!cQL@e((3s11Fa2_bV)l-uQAkx*|5rE QUNuPE)78&qol`;+0H_YCpa1{> diff --git a/test/fixture/web/screenshots/desktop-static-document-480.png b/test/fixture/web/screenshots/desktop-static-document-480.png deleted file mode 100644 index db1ea3ba1ee22b1aaa54b5d05e5a1aa1f83b71ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7044 zcmeAS@N?(olHy`uVBq!ia0y~yU=?9tV0pyB1QcAnonx;uunK>+N;Le%Vxs zwuf_-S9z)`R|X z${tAqsiq1x28ITOd5jDU3LWV{0gh4O(J;Z0AVBGchCt)?mj><|@Bhu1$DotC`|q0t z)4$JOp3i)3Q*G^))4%um%d_jG-j=JWp0|u0=!yedh0g;ifg{F1lI0^0kaV{9BwXSk2$o@U!URHCfTpKHJ|Suzr3B%yYkcH`|Nvb?B*};XP&m{ zK=@M=TaY8x%^fX!M=KuEYF!#8UXanJ%xoVp&AYb;R02Q!diL|;dG~+?uvqbp^>^Mi zv&LNc_Tl#D(ZoC2Y9g=6NRPyO?lN=3(K+%jZXfvlqUOqOcUzu4%f)`InlsvD7;PAl z*I1-&ss%S04&1$a_X|sc=JxH|+4t_*Uu|A1vti2Hi;J7%?k)Fc7TfGlIojkMZP)`7 zA~~HMdZgdk_v8Hh8K!-D(wz=W!1cd>eknWylw z$UWEnMtf?b-Bi+2Gi}o`L+Wg~0!I7VuP;Fb@%=xao;&K#&p&thIHR}ayVaZif3Esv zk)V0o-G90Io$HxZAjia5j}AJFj<}FE+(hF5}>r kL&4k8(NfIO(tqqbY+RD=J}?4K4>2%!y85}Sb4q9e0I98>p#T5? diff --git a/test/fixture/web/screenshots/desktop-static-document-480_chrome.png b/test/fixture/web/screenshots/desktop-static-document-480_chrome.png index 9b47d6f613cae24896caf69b0e574a33155cfa16..f143c34f3323071ac6b212ce30102ac3120853c2 100644 GIT binary patch delta 1219 zcmaiy`#0Nn7{|Z4tTaff(hC)r>BdwmCd$!fI(H=rMx$G(OLeNK7)8vb!*Y}&=eu!w zqAovFPS4!GJH{zRTxus(vK*^hM8;fF#3dvoWBKL}*v{vN&-py(d|uD{dA}cC-~px5 zCLdvc-^(lbeq1sD*l}_>WJh!e{zuCTPsjc3@K4qfh-bM!2NMT<(_an!G4`&!WQqVz z8=Fm5X;38z8l=6wc>lCna}<7txf$dHj=I?@Yi#9Y<>H({aljBJZepKb|Mm2QOpk45 z3ayvZUhfTzbDwOvt7(z7Mx^KEmk;s-eb0|dJL12};!{+fOdIKg;enLNQ?E^Gna*>g zTiL5@J~{lM`te^l>ExpiZ>jRJw#ALfi|^xuLZo4HFNz1RyHMRmPTMy?1)m9{Ih0Pj zn0zFe4n7=pM;E@}aiQ)J3^;Znr%%u^;KJ%0omNQk~MKpicn+I1wA@ z=M5agr@og50>CF(0p4GRWzB5NI0?jmoAyhOOWybgss}y!uGn9k6n9BEvV3>ISuA7zkpg2(@0g2z}e=2SgW(EG0GBs_kz?zo6Pi zByvLbzHN1F&AfTRnWMu)p2()`y9THonSlf=QFLtQ?W%ZJGFk^a&j2~7W@6`ai)hQa z!_`BDKG2jZccxYJsQ1(>jdZ=}Vs(CA@{(Ab;@ayDTuQpiT{9l(h6c>9Bf)wD4tCZ- z(80Ap!Z0_(E1>XXGijEJYr{o#?}}mA*1kCNX;01uoknTJ_G4D&yPbA6g+if11~e^L zW;W=i@1UU#&Si158u?q|_X#PCu8oB?Ato_G2xY+f`!4 zDHzrtliC2bBb%J2AF&E@Q}<+(YsNr?RCBOvBR`VwZ>&usBBVpVgEn%DIa3ep(zm71Wg)<|RP^L*3*YO46&$nTmc-YNRjI5D z;8vHK?ZLH(sWE^CjI@h#13|}iz}vTG4eKiyT<`>$m?l!kh5}G8l;$7B=oGHD-zn=+ zOK7#+C_=%R&4cYa-}!%b#?I*k>)pwH_+JVkYfLNxI|~~`M!{WDtr!po6^l4Kt!$~e Ui*_c35#Vxw57oQHGx~>r0T8)2761SM delta 886 zcmZXRZAepL6vxlKcXP{&>y5U+Ns4KK<;p%V>PLCLoag_X^MC&Q&Xm%SemlAx zc*hk=1we}ypU&k208+enTPidUNS*8@^6>V(N`TT>0L>KuA1i5o0Gvwz_?ZKcbPqs6 z)V+dpb+CexCTL@MJPr`$u#bjS2>c2>~iMfw=*JpitS+jA@&P^-Um)D zBxwFDpcKMPB)W5_jKC*ZQGO&`=htl#(oKQn2|>rM9;s$avjy)j)>9SYJt#@@FNYc1 zCY>=eRdWj$J2k@+I%vw1>6`oioT>$3+sowXS8cGB5zR}UHLMKoeFDW4|{ zR8wojdX#iwaU!ef>!6{QGlGHMYEr>7%4(hb!q?pyML;jKtxKG=N{W)Fbo`x;)JG^`PIgh!g1z?W9{^TsfL(rdR*X+4xX}Xs|Ms z_E^ZcMJ8Zw7aSYyo~nR4t7(2(KG{sO$RQTb;XkT(_!{S}5s7C>O>@!V2<@>e6|f%t*6H zJ!XtMe_zFjQ`Ek*rF;;TxR_oR&bu2<14hv2IZ|rhFi2aKG6Kt@^q3AM8?d!=ZPv`% z_}w2l#ze63YIL#p(@=d`5(rKWO(!OLrw)9Y;q2}1T5oCYSIlJ^~yJM<-o zNIVyF!YpRT_zFuL5cEh+a!+0Ko$NN1YoIsywr`&=(MA8~WnjHJyGDUPBr|;OhE3G*-r}94( CT7TsL diff --git a/test/fixture/web/screenshots/desktop-static-element-footer.png b/test/fixture/web/screenshots/desktop-static-element-footer.png deleted file mode 100644 index 105043e10286069c991a9fc3c27b40120fc336f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0y~yU=;zfjX0Qq&3IhY9R;IIaKxT3-1B1rI+KIOM zEP*0z^3uKMJv2nRUS=4G&7K-yaM-P6_mN9y&-HcQkez%}Q0nTmKg^vOf0(qi?tT-J zS{o;FtMHwV;p7t*>fh(6zqkGV_zrig=Mk>t3*Qbch`M><6??ms%Sc(^GwxZ;rS52r%qhuKFD=3N!oCp@pv_|AzBl`q;4*@ou- zZhXZ5@M_uXGk)*SZg~9ms>=0LpTLJ9cb2vuwlVdyI3}dEaC3v^#e|8z+cdmPT+Lg; zkCa~Yz2+L5)>#xY`OK>+m%qQccj#8Ki0k>4+di}Kha3Eumvwo%!7rx0()YR6M7#>0 zU-IO@ciWyfhkvN^l!o$WS;fx&=jylq*8DirZ67zx6xKSncUm1|ERUaI(T&Y&z`$cm z@^*J&_z!{$_AZ|c499*?7srr_TW@bT@*YrNIN)&Ll+1&8K{Ye(zY|r&3Xoz+cl32+VA$Bt{U?zX$Y(4L za(7}_cTVOdkfV_75#-CjP^HGe(9pub@Czu^@PdJ%)PRBERRRNp)eHs(@q#(K0&Rd2 zY)RhkE)4%caKYZ?lYu66db&7}?f=mYjVt{_^$SOmmxI1|7E;u<*%f~XUtk`x7k-h`!0No*`7mY~4&boFyt=akR{ E0KOq$rT_o{ diff --git a/test/fixture/web/screenshots/desktop-static-viewport-1600.png b/test/fixture/web/screenshots/desktop-static-viewport-1600.png deleted file mode 100644 index 385338ef45fe1718c7eb709eac9ba718952a0126..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3775 zcmeAS@N?(olHy`uVBq!ia0y~yU~^z#VEn?t1QdBSsZ5rEfv?Te#WAGf*4tYf*NPZQ zxLq{7Wu?*BGiQ#_iUzd{U1}>Dgif41snO`>!_JX;|HXdm_j8!mobPPbUcZ-r-mR$1 z+(45S`2MXZ%U{M0WHKDs&k+HlmvD|!)Cq#S%h(TWT+YrQzS+;_b~o#uHJ9Vo{Qh#b zp?jx4|AVWanL#noV8S>`jRwI`Nd;TBe*eNExB1!^P&t$lY(Hi8I zF{gfg__t*8_wO%vGhW|hH@EcDz3N{@2bQkcx=j7Ut)GpoK(9H>Y8a(PgJ7tnf?Kz$ ztC;#Dv#S_^X?M#?`Sa)ab$~2}ODuz(%Dc?`z~bAyIEI+hQR=dPet*6V%$3tWy}Lbs zvfsY@?=Meh);qfTkcIsQkas+UN2$>u7&56Ky4v6Wfnm01Z$(o0U*7!$x$w#L~^qj)~YEli3j()t3ANiD>)+Dk|Of5*n>u6xwm_Ofi$l zI4AdaU*hHBLCj5-OpyfGN>nkxjNJN;E|`gjd9M(M{GxU1o`LT$9Y|l+*X@ z-on~r6h+Uewtw>k4_7ewo@&#VF!}<$8{Z17Sn5}wbmYMIJ&f$b_$Lf?RS#-9U7P+z zPOsXZUNyGyu$dDo#=Vw)0bLAEF>=_mCIA2c24YJ`L;(K){{a7>y{D4^02HH1L_t(| z+U?sh3S3nfhGFkG3L&D6q_dEK3sA%&Vr6N03s+%fDoY8D1gluN3X3T%t;7@}x&T2e z?1GJA2t=IgB5uOZygbha&Uc#AyqsmbtlJClj4g-r^aKC^007`hY?pO<0zrrA0RR91 z0002bnz7-J0h3?>2r$lZdH_^Cdi(bD1ORrp^~-NF2fy)n`sx7e@yE@PW8b^?=Jd@0 z*x|?fzfVtqBtNr}14#mt5Ci`joMpSL+w=%}mcw~^0ssI20B|L?%Q`)QAU~6l1IsWu zP7i>p$KU@nJpq6nZhr9Y$hm)ib7%VM0POJU#}7x&-L`G|>HzGpEX(u+Nb&=-0R!0r zlMn-M8dx=oLuXE~gwCjbBd0038FyR6d_2=W7y0Rze}oa6KWsQUEZ|E4DZu)|j` zy*P62!%yCszB&Lq-1++Fk#kR{)AZE=*ugsv&xaqgVF3>TvtR)b0kdEM5CM~50T~+3 zvR&3~dIUYo;XFM700000xDwlCot{9DACqAL%Q76N2SC+_uicxT0Kg94{dIrj+`CUd zn!Y*!J3M&#+mUl0z5itT>HzF;>xUcD6ClYCvr!8#1Cy`^85(EVF6%Zuf}Z7Yo}K^z z00017iS4pZPawz-lko-1FOJg#pz7}HuS`z>V21~P{xfs%jnAg94!|Byz8pFB^!Z!U rHwR#c(-*%^Pk8ddXf?xuQAk3$K~gB-;2Wh! zf6w{8Uz57P&-a(=-r)3SX66;C&vW#F1~V|sJNje#EcS}cwqPE^gRPvK7xGMJRN9ln z->~YY9K!+C^p|(G?^9s#e|!I$_>+CL#SD5o^Z6Up^fxzhoMf6@z)~+h$GCX*Tfr}L zHtz)+QX%#@K1=QZ_hdoA)0%PH*d4C^`L)-Uv4Q*CaenRR=lb8yW-d7Tb5HTRGdc0H zKvB!v!U`w3Hwy}WW}3V}FjV~cnLBCKEVigF{J=E%A@eECIn&=VPA~;p)S!JX((>E+ z>E*Z0*&j50zyE*Toa+7ex3A|rz*=|wq2Zp*3k8!w#yt}|cP4k6`-S3j-h$$-ToBNoV>BE_GI<*c8=Ri)Y cVG?_8zc$nG@%4nYCqd?Ty85}Sb4q9e0Ev~#!T~)y|U5wsDp^B zY5BCBEXvy04r8|wb|%wxE7>d&W|i|1cI?>m0_ zg*C$l-vx||SfmuZMk#6r0TGe%U`6GZ2IDoaU$7q7dnSDA$M0`nzVDxYF`Xe{wga;Z zr-{RqQHq*DKtz-r2>kqlQN3cWotr;H-qY-={jXk^9>1OXMV8@)+69I{CSC#6kxKE; XEarcfuCeq0C>T9m{an^LB{Ts5uFs;* diff --git a/test/fixture/web/screenshots/desktop-static-viewport-480_chrome.png b/test/fixture/web/screenshots/desktop-static-viewport-480_chrome.png index 3af7d5288de15b1fb8b1d9d8a93e6bd47a068e96..0f4d6b8cc1f433046b166062aa35cc6d0cc4e5b9 100644 GIT binary patch delta 678 zcmca1uvv71SUr;g2O9$eLmbl%bp{4TtxRX{ta;ILcC?jx7Zp6lzpAv^h|pw!iAf0#Qn{xE52-TfvcwKh)VR^dAz!^tNs z)W6SBe{cK!@g43~&m&yP7rq@@5OwpyEB1CN$<1&2{P%r5cz$+$*9WWL{;~6TP3HFL z{`7W}IPq{(YH-CN-ycqe$`7-T9?ZKcuuphiq4Av)A1Yt8AF>V2|K0eA|KZiL*Ju3R zpWX2I?NycQsXl=ZL+&hXJ#1s@XK_qOYvJYw&5H>WeYa_NnYfy_gdZur=zGmIHm$QL zX7ZU=Q!amhbMMftWD(c%E4S5uX5kMv_%Sc*@^ph=Onas8bFGPZ6+XY@$${^-J#P;G zQ0FNP<ob!_jnI>uNYKf|IMo7I59$Cl*n?!xdN1Q+aG zKAC}m)5z1sF{I+w+v|o|0)Y~47tO82gcN&kEG=Sh3u&6VG<&1b)QF{5S~YfXXdl#? zAe+LRw0Oobg~xJf2doXAf9d~TI=x;hS%;b7$9lOd%nT1YCJVCd5`R{8K(40#>&@m4m@T zN_?^*Q;fu!uMM^pwZ9gE+!J3Hr}{tcU*+asYq=*IvK;}sXBXE2lVcID1Q`lU^d@g) zj1iylnz6dz=NC^~#s*%ye?RWl{Q2?s)pEVbhKx#Lf0(DV%Dt86%j^P%CxfS}pUXO@ GgeCwe4KjrQ delta 373 zcmdlidP87>SUuxI4mJh`hHV|W20)4>-O<;Pfnj4m_n$;oAfK@~$lZxy-8q?;K#oGP zN02WALzNl>LqiJ#!!Mvv!wUw6QlQ3H2@DKYGZ+}e3+C(!v;j)6C3(BMF#HF>1$&oI zW?*1H;_2cTQgQ3;bwgiQM-kVH)=xxN9AH&vS`pa9$+btJQHrrdLdxdP^bPT!uD?<* z-Zgi3S{gsYhxKx=7#RxsCvRj8oh-nVD%e+bK=e%&1HC^8pXo7 zX6DVW91J_m^(G54#fVtEVw}FAd@ny8d&ZKf{BT^_BT{_qN-YLR=%jq$k#BFJvuptZPM-1TZuhJYD@< J);T3K0RTQOi5CC> diff --git a/test/standalone/standalone.test.js b/test/standalone/standalone.test.js index 437b7e7..3ee5c79 100644 --- a/test/standalone/standalone.test.js +++ b/test/standalone/standalone.test.js @@ -42,6 +42,7 @@ describe('standalone', () => { 'goog:chromeOptions': { args: [ 'disable-infobars', + 'headless' ], }, } @@ -76,7 +77,7 @@ describe('standalone', () => { assert.isFunction(browser.saveDocumentScreenshot); const screenPath = path.join(tmpDir, '/desktop-responsive-document-480', `${generateUUID()}.png`); - const refPath = screenResponsiveDocument480 + '_chrome.png'; + const refPath = screenResponsiveDocument480 +"_chrome.png"; await browser.saveDocumentScreenshot(screenPath); @@ -117,12 +118,24 @@ describe('standalone', () => { browser = await multiremote({ browserA: { capabilities: { - browserName: 'chrome' + browserName: 'chrome', + 'goog:chromeOptions': { + args: [ + 'disable-infobars', + 'headless' + ], + } } }, browserB: { capabilities: { - browserName: 'chrome' + browserName: 'chrome', + 'goog:chromeOptions': { + args: [ + 'disable-infobars', + 'headless' + ], + } } } }); diff --git a/test/wdio/specs/desktop.test.js b/test/wdio/specs/desktop.test.js index 0eaef9d..867dc6d 100644 --- a/test/wdio/specs/desktop.test.js +++ b/test/wdio/specs/desktop.test.js @@ -82,6 +82,11 @@ function getBrowserSpecificFile(screenshotPath) { return screenshotPath; } +/** + * Test need to be runned in headless browsers, as this is stable env (virtual buffer) for function setWindowSize(), running test locally on your display + * may lead to comparison errors, different displays/image buffer will render colors differently. + */ + describe('integration tests for desktop browsers', function () { context('static sites - static.html', function () { diff --git a/test/wdio/wdio.local-conf.js b/test/wdio/wdio.local-conf.js index 96b1c1b..3e372d4 100644 --- a/test/wdio/wdio.local-conf.js +++ b/test/wdio/wdio.local-conf.js @@ -13,11 +13,15 @@ exports.config = { 'goog:chromeOptions': { args: [ 'disable-infobars', + 'headless' ], }, }, { - browserName: 'firefox' + browserName: 'firefox', + "moz:firefoxOptions": { + args: ["-headless"] + } } ], sync: false,