zinserjan / wdio-screenshot Goto Github PK
View Code? Open in Web Editor NEWA WebdriverIO plugin. Additional commands for taking screenshots with WebdriverIO.
License: MIT License
A WebdriverIO plugin. Additional commands for taking screenshots with WebdriverIO.
License: MIT License
I'm trying to make it work with the mocha framework, but I can't get it to work.
I keep on having this error
Timeout of 10000ms exceeded. Try to reduce the run time or increase your timeout for test specs (http://webdriver.io/guide/testrunner/timeouts.html); if returning a Promise, ensure it resolves.
I've been trying to change "sync" property to true, add "asyncOnly" of "mochaOpts" to true too, and my test looks like that
it("captures Account view", function() {
browser.url("/account");
return browser.saveElementScreenshot(`${outputPath}/AccountView.png`, ".Account-View");
});
Would love some help, thx :)
I'm facing issues when I am trying to take screenshots and applying visual regression (with multiple different viewports to check desktop and mobile view) at the bottom of a page.
This is the error I am faced with: TypeError: "value" argument is out of bounds
test.js
describe('bottom scroll', () => {
beforeEach(() => {
browser.url('http://webdriver.io/')
browser.scroll('footer')
})
it('should take visual regression test at footer', () => {
const fileName = './myscreenshots/test.png'
browser.saveViewportScreenshot(fileName);
})
})
wdio.js
var path = require('path');
var VisualRegressionCompare = require('wdio-visual-regression-service/compare');
function getScreenshotName(basePath) {
return function(context) {
var type = context.type;
var testName = context.test.title;
var browserVersion = parseInt(context.browser.version, 10);
var browserName = context.browser.name;
var browserViewport = context.meta.viewport;
var browserWidth = browserViewport.width;
var browserHeight = browserViewport.height;
return path.join(basePath, `${testName}_${type}_${browserName}_v${browserVersion}_${browserWidth}x${browserHeight}.png`);
};
}
exports.config = {
specs: [
'./test/specs/**/*.js'
],
exclude: [
],
maxInstances: 10,
capabilities: [{
maxInstances: 5,
browserName: 'chrome',
}],
sync: true,
logLevel: 'silent',
coloredLogs: true,
bail: 0,
screenshotPath: './errorShots/',
baseUrl: '/',
waitforTimeout: 10000,
connectionRetryTimeout: 90000,
connectionRetryCount: 3,
services: ['visual-regression'],
visualRegression: {
compare: new VisualRegressionCompare.LocalCompare({
referenceName: getScreenshotName(path.join(process.cwd(), 'screenshots/reference')),
screenshotName: getScreenshotName(path.join(process.cwd(), 'screenshots/screen')),
diffName: getScreenshotName(path.join(process.cwd(), 'screenshots/diff')),
misMatchTolerance: 0.01,
}),
viewportChangePause: 300,
viewports: [{ width: 320, height: 480 }, { width: 480, height: 320 }, { width: 1024, height: 768 }],
},
framework: 'jasmine',
reporters: ['dot','spec'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
//
// Jasmine default timeout
defaultTimeoutInterval: 1000000,
//
// The Jasmine framework allows interception of each assertion in order to log the state of the application
// or website depending on the result. For example, it is pretty handy to take a screenshot every time
// an assertion fails.
expectationResultHandler: function(passed, assertion) {
// do something
}
},
port: '9515',
path: '/',
}
It seems to work fine when I use visual regression at the top of the page, but when I scroll to the bottom it breaks.
I've managed to take screenshot with saveScreenShot()
API, and that worked fine, but not much luck on the checkViewPort()
1) mobile view bottom scrollsuite1 should take visual regression test at footer:
TypeError: "value" argument is out of bounds
running chrome
TypeError: "value" argument is out of bounds
at checkInt (buffer.js:1011:11)
at Buffer.writeUInt32BE (buffer.js:1104:5)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
Please remember that, with sample code; it's easier to reproduce bug and much faster to fix it.
So I've found some strange visual artifacts occur in one of my tests. I tracked the problem down to this virtual scroll execution here. I've found that specific line of code is not even necessary for my test case because it's trying to scroll from 0, 0 to 0, 0 (not doing anything). So I was wondering if it would be possible to only execute that virtual scroll when the scroll indexes are actually different? I'll add a pull request to show what I mean.
It captures the bar along with the other browser ui components. Here is a list of what the screenshots look like in ios devices: https://www.dropbox.com/sh/pono8nrymhrqgay/AABxQWDqNUqjlrgwkcRRNLTba?dl=0
Test files to reproduce: (requires a browser stack account)
configuration: ios_test_config.js
exports.config = {
user: process.env.USER,
key: process.env.KEY,
commonCapabilities: {
name: '',
build: ''
},
specs: [
'./screenshot-ios.js'
],
capabilities: require('./ios.js'),
framework: 'mocha',
mochaOpts: {
ui: 'bdd',
timeout: 999999
},
plugins: {
'wdio-screenshot': {}
},
reporters: ['spec'],
logLevel: 'command',
coloredLogs: true,
screenshotPath: './errorShots/',
baseUrl: '',
waitforTimeout: 100000,
connectionRetryTimeout: 90000,
connectionRetryCount: 3,
maxInstances: 20
}
// Code to support common capabilities
exports.config.capabilities.forEach(function (caps) {
for (var i in exports.config.commonCapabilities) caps[i] = caps[i] || exports.config.commonCapabilities[i];
});
capabilities: ios.js
module.exports = [
{
os_version: '11.0',
device: 'iPhone 8',
real_mobile: 'true'
},
{
os_version: '11.0',
device: 'iPhone 8 Plus',
real_mobile: 'true'
},
{
os_version: '10.3',
device: 'iPhone 7 Plus',
real_mobile: 'true'
},
{
os_version: '10.3',
device: 'iPhone 7',
real_mobile: 'true'
},
{
os_version: '11.0',
device: 'iPhone X',
real_mobile: 'true'
},
{
os_version: '11.2',
device: 'iPhone SE',
real_mobile: 'true'
},
{
os_version: '11.0',
device: 'iPad 5th',
real_mobile: 'true'
},
{
os_version: '11.2',
device: 'iPad Pro',
real_mobile: 'true'
}
];
Test: screenshot-ios.js
describe('Testing webpage with visible scrollbar', function () {
it('Opens URL', function () {
browser.url('https://developer.mozilla.org/en-US/docs/tag/Types');
});
it('ios screenshot test', function () {
browser.saveDocumentScreenshot('test.png');
});
});
Currently wdio-screenshot does not work for browser.select(Browser) (WebDriverIO multiremote)
browser.select(browser).saveViewportScreenshot('great-shot.jpg')
For example, above call errors with:
Invalid attempt to destructure non-iterable instance running TypeError: Invalid attempt to destructure non-iterable instance
I would like to be able to pass a cropElement
option (maybe a better name ๐) to the makeElementScreenshot()
, such that when an element is larger than the viewport, a screenshot is taken of the visible portion of the element.
Currently, when using the wdio-visual-regression service, when using checkElement()
and an element is larger than the viewport, the screenshot fails because the BaseStrategy attempts to scroll the element in view. The error outputs are a bit unclear as to why until digging through code.
Outputs typically received:
endX is out of range
or
endY is out of range
There are instances "chopping" the visible element is desired. For example, when creating a slide-panel React component, we close the panel, it is placed off-screen using css using transform: translate3d(100%, 0, 0);
and then is set to visibility: hidden;
. Using checkElement()
, we cannot take a screenshot.
Add a screenshot option to return the the documentX
and documentY
values if the start/end x/y values are too large.
When using the exposed checkDocument
function only the viewport is taken a screenshot of. I would expect this to take a screenshot of the entire page so that I can check if visual regressions are present past the end of the current viewport. Instead this function seems to behave the same as checkViewport
. Checking the source seems to confirm this.
Here's some sample code from my step definition (Cucumber) for ensuring the document hasn't visually regressed:
/**
* Check the screenshot of the page against the existing baseline
* @param {Function} done Function to execute when finished
*/
module.exports = (done) => {
const results = browser.checkDocument();
results.forEach((result) => {
expect(result.isWithinMisMatchTolerance).to.be.true;
});
done();
};
This works for the viewport but doesn't check changes beyond its boundary.
Error when trying to use wdio-screenshot. I believe that it results in the driver crashing because I get no more data back from the driver after the error occurs.
OS: Mac 10.12 (or any mac os)
CHROME DRIVER: chromedriverVersion=2.28.455517
Chrome Browser version: any version
ERROR: "message: 'unknown error: unhandled inspector error: {"code":-32000,"message":"Unable to capture screenshot"
On my local machine it works fine and I also have the same setup:
OS: Mac 10.12 (or any mac os)
CHROME DRIVER: chromedriverVersion=2.28.455517
I'm not sure how the "cloud" part comes in to play here.
NOTE: I have not yet tried other versions of chromedriver because I myself don't have the ability to update these driver on the cloud service.
NOTE: webdriverio "saveScreenshot" command works fine in this scenario. The problem is specific to wdio-screenshot.
Logs:
https://gist.github.com/maggiesavovska/95a5e44fe065cfc1c3fcfa33293e580b
Hi,
saveViewportScreenshot takes scroll offset as starting point and screen dimensions as ending point. This creates images which have height of screenHeight-scrollOffset, which in turn creates problems when we scroll past the height of one screen and try to take a shot.
Is this indended?
I'm encountering a problem where tests fail on screenshot differences due to the generated image sometimes having a partial scrollbar in view and sometimes not.
The problem is intermittent and I cannot seem to nail down any circumstances in which it will or will not happen, despite playing around with pauses and the viewportChangePause parameter.
I'm running my suite remotely though browserstack when encountering this problem and it is so far occurring only in the ie9 browser that browserstack has.
Has anyone experienced a similar issue?
Thanks!
At this stage I'm not sure what the necessary changes to make this compatible with with wdio v5 (http://beta.webdriver.io/).
@zinserjan Would you be happy to have a look?
I can reproduce this issue and provide code samples if you need. I've been able to fix this issue by modding my runtime copy of wdio-screenshot.
The short version is that part of my page isn't being captured by the screenshot system and the problem can be fixed by skipping the cropping code that occurs here: https://github.com/zinserjan/wdio-screenshot/blob/master/src/modules/makeAreaScreenshot.js#L46
browser.checkViewport
commandviewportChangeDelay
has no effectEditing my node_modules/wdio-screenshot/lib/modules/makeAreaScreenshot.js
to skip the cropping step works as expected
I haven't had the time yet to actually read your code so I don't know what's going on. I will take a look later this week-end and find the details. I wondered if you might have any ideas off the top of your head.
Hello there!
I get an error message when trying to save a screenshot. This is the error message:
write EPIPE
running firefox
Error: write EPIPE
at Object.Future.wait (D:\QA\testscreenshot\node_modules\wdio-mocha-framework\node_modules\wdio-sync\node_modules\fibers\future.js:449:15)
at Object.saveDocumentScreenshot (D:\QA\testscreenshot\node_modules\wdio-mocha-framework\node_modules\wdio-sync\build\index.js:345:27)
at Context.<anonymous> (D:\QA\testscreenshot\test\specs\test.js:6:17)
at D:\QA\testscreenshot\node_modules\wdio-mocha-framework\node_modules\wdio-sync\build\index.js:649:20
- - - - -
at exports._errnoException (util.js:870:11)
at Socket._writeGeneric (net.js:681:26)
at Socket._write (net.js:700:8)
at doWrite (_stream_writable.js:300:12)
at writeOrBuffer (_stream_writable.js:286:5)
at Socket.Writable.write (_stream_writable.js:214:11)
at Socket.write (net.js:626:40)
at gm._spawn (D:\QA\testscreenshot\node_modules\wdio-screenshot\node_modules\gm\lib\command.js:249:18)
at D:\QA\testscreenshot\node_modules\wdio-screenshot\node_modules\gm\lib\command.js:140:19
at series (D:\QA\testscreenshot\node_modules\wdio-screenshot\node_modules\gm\node_modules\array-series\index.js:11:36)
I am running on Windows 10 and all of the required software is installed and wdio is properly configured.
Thanks for the help in advance!
Screnshots of elements with position: fixed
are currently not supported. But it would be nice to support that.
I think this can be done in the following way:
We coud use a simple script to detect if the element is fixed, like the following:
function isFixed(elem){
do {
if (window.getComputedStyle(elem).position == 'fixed') {
return true;
}
} while (elem = elem.offsetParent);
return false;
}
re: BaseStrategy.js
I updated the following code in order to debug your library as I was getting an exception when saving full document screenshots.
} else if (endY > documentHeight) { throw new Error(
${endY} is out of range ${documentHeight}); }
The output is as follows:
Error: 2030 is out of range 2029
at MergeScreenshotStrategy.setScrollArea (node_modules/wdio-screenshot/lib/utils/strategies/BaseStrategy.js:48:15)
at makeAreaScreenshot$ (node_modules/wdio-screenshot/lib/modules/makeAreaScreenshot.js:85:30)
at tryCatch (node_modules/regenerator-runtime/runtime.js:64:40)
at GeneratorFunctionPrototype.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:355:22)
at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:116:21)
at tryCatch (node_modules/regenerator-runtime/runtime.js:64:40)
at invoke (node_modules/regenerator-runtime/runtime.js:154:20)
at node_modules/regenerator-runtime/runtime.js:164:13
at process._tickDomainCallback (internal/process/next_tick.js:129:7)
I have a menu bar that is locked to the bottom for tablet and moves with scroll, when I take a screenshot with saveScreenshot it is displayed. but when I use the saveViewport or saveElement versions of wdio-screenshot the element is missing. The HTML I have I cant post here I'm going to try and find an example online that I can send you.
My findings so far point me to the issue possibly being around virtual scroll that is used during the service.
my element uses background-attachment: scroll
Firefox introduced a new selenium driver (Marionette) which is required to run selenium tests since version 47.
Unfortunately they changed the way how Firefox takes screenshots. Until this change we always got whole page screenshots, but with Marionette we just get viewport screenshots.
We need to investigate
Related:
Currently, I see two solutions to fix this:
These lines seem to cause Firefox on OSX to display scroll bars for a short time, which can cause image diffs (via wdio-visual-regression-service) to fail.
There are some things that we can improve to get more screens in time. The goal is to reduce browser idle times as much as possible as the browser is the bottleneck and should theoretically never idle.
There are some optimizations that are safe to do (without breaking browser screenshots):
And some others need further researches or additional/manual tests to avoid errors:
Curious why the argument order is different from current webdriverio commands? Changing the selector order around could allow for element chaining. E.g.:
browser.element('#myDiv').saveElementScreenshot('myFile.png')
At the moment all screenshots commands emitting a screenshot that respects the display size.
This means for devices with a pixel ratio of 2, the resulting screenshot is twice as big like on other devices with a pixel ratio of 1.
Currently I see some reasons to start scaling retina images down:
Any opinions about this change?
Hi
When taking a screenshot om Android I can't figure out how to omit the statusbar. Is anyone able to help with this? I assume this isn't possible but would be if the exclude functionality was implemented
It's needed for autocompletion.
/**
* @alias browser.saveDocumentScreenshot
* @param {string} fileName
* @param {Object} options
*/
/**
* @alias browser.saveElementScreenshot
* @param {string} fileName
* @param {Object} options
*/
/**
* @alias browser.saveViewportScreenshot
* @param {string} fileName
* @param {Object} options
*/
Could you please add these annotations?
I have not found a place where it can be added without refactoring. I mean:
export default async function async(browser, fileName, options = {}) {}
...
Looks like the commands only save the image, but I don't want to save the image on the FS, since I'm
using it to build a PDF. Maybe expose the make* functions?
Thanks for this plugin!
We want to test hover states, so we use moveToObject to position the cursor, but this tool always scroll first, hence loosing the hover.
Can we add an option to disable all scrolling?
When taking a screenshot of a hookshot/pop-up element with dir='rtl', using a specific selector results in the following screenshot:
However, fullscreen is correct:
I think this is an issue with the wdio-screenshot's virtual scroll / element reposition for cropped screenshots. I've seen this behavior on IE popups recently as well.
hookshot-spec.js
test. Specifically this testTerra.should.matchScreenshot('fullscreen', { selector: '#root' });
Terra.should.matchScreenshot('use_element', { selector: '#ContentOffset-bounds' });
Linked Issue: https://github.com/cerner/terra-toolkit/issues/278
Hi,
I stumbled upon this great project and wondering if you would like to join forces and merge this into the webdrivercss project?
What do you think about that?
Cheers
Think it would be possible? https://github.com/oliver-moran/jimp
I think more people would use this plugin if they didn't have to install GraphicsMagick.
browser.saveElementScreenshot([fileName], elementSelector)
does not seem to work for me. elementSelector was 'body'. It fails silently - I'll try provide more debug info... can someone confirm that this works/doesn't work on the latest version?
Now that Firefox does no longer support full document screenshot, and considering that the project can not point to a git hash in package.json (because of build), will you please consider releasing a new version of this package so the support for FF is maintained?
This library doesn't seem to emit the runner:screenshot
event when it takes a screenshot.
Create a custom reporter that listens for runner:screenshot
this.on('runner:screenshot', function (payload) {
console.log('screenshot taken');
});
Then have a test call browser.saveDocumentScreenshot(fileName);
'screenshot taken' is never logged.
var options = {
desiredCapabilities: {
browserName: 'chrome'
},
plugins: {
'wdio-screenshot': {}
}
};
webdriverio
.remote(options)
.init()
.setViewportSize(size, false)
.url(url)
.pause(10000)
//.screenshot()
.saveViewportScreenshot('out.png')
.then(function(res) {
if (res.state === 'success') {
fs.writeFile('out.png', res.value, 'base64', function(err) {
if (err) console.error(err);
});
} else {
console.log(res);
}
})
.end();
Tried the following and got:
TypeError: webdriverio.remote(...).init(...).setViewportSize(...).url(...).pause(...).saveViewportScreenshot is not a function
at Object.<anonymous> (/Users/iradchenko/workspace/mapgeo2/tools/selenium-screenshot.js:38:4)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:968:3
My script require()
s WebdriverIO rather than using the testrunner, apparently called "Standalone Mode": http://webdriver.io/guide/getstarted/modes.html
The instructions in the README for wdio-screenshot
mention wdio.config.js
, but that appears to be only for the testrunner. Doing require('webdriverio').remote({desiredCapabilities: {...}, plugins: {'wdio-screenshot': {}}})
results in an object without the .saveDocumentScreenshot()
method. Does this only work with the testrunner?
If anybody had issue with screenshot higher/wider then view port which are caused by
javascript srollHeight (which takes scrollHeight even if it's not visible ) use this npm run role
"fix-wdio-screenshot": "sed -i -e 's/scrollHeight: body.scrollHeight/scrollHeight: body.clientHeight/g' node_modules/wdio-screenshot/lib/scripts/getScreenDimensions.js",
I will try to make PR however I see that this repo is death. Anybody have 'up to date' repo here ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.