diff --git a/README.md b/README.md index a3efe0e15..7e4e0540d 100644 --- a/README.md +++ b/README.md @@ -6,67 +6,69 @@ Hermione is a utility for integration testing of web pages using [WebdriverIO](h -- [Why you should choose hermione](#why-you-should-choose-hermione) - - [Easy to use](#easy-to-use) - - [Runs tests in parallel](#runs-tests-in-parallel) - - [Runs tests in subprocesses](#runs-tests-in-subprocesses) - - [Extensible](#extensible) - - [Retries failed tests](#retries-failed-tests) - - [Executes separate tests](#executes-separate-tests) - - [Skips tests in specific browsers](#skips-tests-in-specific-browsers) - - [Offers flexible test configuration](#offers-flexible-test-configuration) - - [Automatically initializes and closes grid sessions](#automatically-initializes-and-closes-grid-sessions) -- [Prerequisites](#prerequisites) -- [Hooks](#hooks) -- [Skip](#skip) -- [Only](#only) -- [WebdriverIO extensions](#webdriverio-extensions) - - [Sharable meta info](#sharable-meta-info) - - [Execution context](#execution-context) -- [Quick start](#quick-start) -- [.hermione.conf.js](#hermioneconfjs) - - [sets](#sets) - - [browsers](#browsers) - - [gridUrl](#gridurl) - - [baseUrl](#baseurl) - - [httpTimeout](#httptimeout) - - [sessionRequestTimeout](#sessionrequesttimeout) - - [sessionQuitTimeout](#sessionquittimeout) - - [waitTimeout](#waittimeout) - - [sessionsPerBrowser](#sessionsperbrowser) - - [screenshotOnReject](#screenshotonreject) - - [screenshotOnRejectTimeout](#screenshotonrejecttimeout) - - [testsPerSession](#testspersession) - - [retry](#retry) - - [shouldRetry](#shouldretry) - - [calibrate](#calibrate) - - [meta](#meta) - - [windowSize](#windowsize) - - [system](#system) - - [debug](#debug) - - [mochaOpts](#mochaopts) - - [ctx](#ctx) - - [patternsOnReject](#patternsonreject) - - [workers](#workers) - - [testsPerWorker](#testsperworker) - - [plugins](#plugins) - - [prepareBrowser](#preparebrowser) - - [prepareEnvironment](#prepareenvironment) -- [CLI](#cli) -- [Reporters](#reporters) -- [Overriding settings](#overriding-settings) -- [Tests API](#tests-api) - - [AssertView](#assertview) -- [Programmatic API](#programmatic-api) - - [init](#init) - - [run](#run) - - [readTests](#readtests) - - [isFailed](#isfailed) - - [isWorker](#isworker) - - [halt](#halt) -- [Environment variables](#environment-variables) - - [HERMIONE_SKIP_BROWSERS](#hermione_skip_browsers) -- [Test Collection](#test-collection) +- [Hermione](#hermione) + - [Why you should choose hermione](#why-you-should-choose-hermione) + - [Easy to use](#easy-to-use) + - [Runs tests in parallel](#runs-tests-in-parallel) + - [Runs tests in subprocesses](#runs-tests-in-subprocesses) + - [Extensible](#extensible) + - [Retries failed tests](#retries-failed-tests) + - [Executes separate tests](#executes-separate-tests) + - [Skips tests in specific browsers](#skips-tests-in-specific-browsers) + - [Offers flexible test configuration](#offers-flexible-test-configuration) + - [Automatically initializes and closes grid sessions](#automatically-initializes-and-closes-grid-sessions) + - [Prerequisites](#prerequisites) + - [Hooks](#hooks) + - [Skip](#skip) + - [Only](#only) + - [WebdriverIO extensions](#webdriverio-extensions) + - [Sharable meta info](#sharable-meta-info) + - [Execution context](#execution-context) + - [Quick start](#quick-start) + - [.hermione.conf.js](#hermioneconfjs) + - [sets](#sets) + - [browsers](#browsers) + - [gridUrl](#gridurl) + - [baseUrl](#baseurl) + - [httpTimeout](#httptimeout) + - [sessionRequestTimeout](#sessionrequesttimeout) + - [sessionQuitTimeout](#sessionquittimeout) + - [waitTimeout](#waittimeout) + - [sessionsPerBrowser](#sessionsperbrowser) + - [screenshotOnReject](#screenshotonreject) + - [screenshotOnRejectTimeout](#screenshotonrejecttimeout) + - [testsPerSession](#testspersession) + - [retry](#retry) + - [shouldRetry](#shouldretry) + - [calibrate](#calibrate) + - [meta](#meta) + - [windowSize](#windowsize) + - [screenshotDelay](#screenshotdelay) + - [system](#system) + - [debug](#debug) + - [mochaOpts](#mochaopts) + - [ctx](#ctx) + - [patternsOnReject](#patternsonreject) + - [workers](#workers) + - [testsPerWorker](#testsperworker) + - [plugins](#plugins) + - [prepareBrowser](#preparebrowser) + - [prepareEnvironment](#prepareenvironment) + - [CLI](#cli) + - [Reporters](#reporters) + - [Overriding settings](#overriding-settings) + - [Tests API](#tests-api) + - [AssertView](#assertview) + - [Programmatic API](#programmatic-api) + - [init](#init) + - [run](#run) + - [readTests](#readtests) + - [isFailed](#isfailed) + - [isWorker](#isworker) + - [halt](#halt) + - [Environment variables](#environment-variables) + - [HERMIONE_SKIP_BROWSERS](#hermione-skip-browsers) + - [Test Collection](#test-collection) @@ -477,6 +479,7 @@ Option name | Description `screenshotPath` | Directory to save screenshots by Webdriverio. Default value is `null`. `meta` | Additional data that can be obtained via .getMeta() method `windowSize` | Browser window dimensions. Default value is `null`. +`screenshotDelay` | Allows to specify a delay (in milliseconds) before making any screenshot. ### gridUrl Selenium grid URL. Default value is `http://localhost:4444/wd/hub`. @@ -543,6 +546,9 @@ are the same. :warning: You can't set specific resolutions for browser Opera or mobile platforms. They use only full-screen resolution. +### screenshotDelay +Allows to specify a delay (in milliseconds) before making any screenshot. This is useful when the page has elements which are animated or if you do not want to screen a scrollbar. Default value is `0`. + ### system #### debug diff --git a/lib/browser/existing-browser.js b/lib/browser/existing-browser.js index dad70f61c..e14737ceb 100644 --- a/lib/browser/existing-browser.js +++ b/lib/browser/existing-browser.js @@ -117,7 +117,8 @@ module.exports = class ExistingBrowser extends Browser { } captureViewportImage(page) { - return this._camera.captureViewportImage(page); + return Promise.delay(this.config.screenshotDelay) + .then(() => this._camera.captureViewportImage(page)); } scrollBy(x, y) { diff --git a/lib/config/browser-options.js b/lib/config/browser-options.js index f9df7ac79..9ec52628f 100644 --- a/lib/config/browser-options.js +++ b/lib/config/browser-options.js @@ -101,6 +101,8 @@ function buildBrowserOptions(defaultFactory, extra) { } }), + screenshotDelay: options.nonNegativeInteger('screenshotDelay'), + tolerance: option({ defaultValue: defaultFactory('tolerance'), parseEnv: Number, diff --git a/lib/config/defaults.js b/lib/config/defaults.js index 7f88811b4..e754d5394 100644 --- a/lib/config/defaults.js +++ b/lib/config/defaults.js @@ -11,6 +11,7 @@ module.exports = { tolerance: 2.3, calibrate: false, screenshotMode: 'auto', + screenshotDelay: 0, compositeImage: false, prepareBrowser: null, prepareEnvironment: null, diff --git a/test/lib/browser/existing-browser.js b/test/lib/browser/existing-browser.js index 1426123ca..21fc86958 100644 --- a/test/lib/browser/existing-browser.js +++ b/test/lib/browser/existing-browser.js @@ -1,5 +1,6 @@ 'use strict'; +const Promise = require('bluebird'); const {Calibrator, clientBridge, browser: {Camera}} = require('gemini-core'); const webdriverio = require('webdriverio'); const Browser = require('lib/browser/existing-browser'); @@ -327,6 +328,17 @@ describe('NewBrowser', () => { describe('captureViewportImage', () => { beforeEach(() => { sandbox.stub(Camera.prototype, 'captureViewportImage'); + sandbox.stub(Promise, 'delay').returns(Promise.resolve()); + }); + + it('should delay capturing by the configured amount of time', () => { + Camera.prototype.captureViewportImage.withArgs({foo: 'bar'}).resolves({some: 'image'}); + + return mkBrowser_({screenshotDelay: 100500}).captureViewportImage({foo: 'bar'}) + .then(() => { + assert.calledOnceWith(Promise.delay, 100500); + assert.callOrder(Promise.delay, Camera.prototype.captureViewportImage); + }); }); it('should delegate actual capturing to camera object', () => { diff --git a/test/lib/browser/utils.js b/test/lib/browser/utils.js index eeaa6ba06..53dad5716 100644 --- a/test/lib/browser/utils.js +++ b/test/lib/browser/utils.js @@ -17,6 +17,7 @@ function createBrowserConfig_(opts = {}) { sessionQuitTimeout: null, screenshotOnReject: true, screenshotOnRejectTimeout: 3000, + screenshotDelay: 0, windowSize: null, getScreenshotPath: () => '/some/path', system: opts.system || {} diff --git a/test/lib/config/browser-options.js b/test/lib/config/browser-options.js index a63520eea..db91e66d1 100644 --- a/test/lib/config/browser-options.js +++ b/test/lib/config/browser-options.js @@ -529,7 +529,10 @@ describe('config browser-options', () => { }); }); - ['retry', 'httpTimeout', 'sessionRequestTimeout', 'sessionQuitTimeout', 'screenshotOnRejectTimeout'].forEach((option) => { + [ + 'retry', 'httpTimeout', 'sessionRequestTimeout', 'sessionQuitTimeout', + 'screenshotOnRejectTimeout', 'screenshotDelay' + ].forEach((option) => { describe(`${option}`, () => { it(`should throw error if ${option} is not a number`, () => { const readConfig = {