Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

protractor-image-comparison

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

protractor-image-comparison - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

9

CHANGELOG.md

@@ -0,1 +1,8 @@

<a name="1.5.0"></a>
# [1.5.0](https://github.com/wswebcreation/protractor-image-comparison/compare/v1.4.0...v1.5.0) (2017-12-17)
### Features
* Remove temporary saving (fullpage)screenshots by saving them to a buffer array. This should prevent an overkill of temp screenshots
<a name="1.4.0"></a>

@@ -19,4 +26,2 @@ # [1.4.0](https://github.com/wswebcreation/protractor-image-comparison/compare/v1.3.0...v1.4.0) (2017-11-17)

<a name="1.2.5"></a>

@@ -23,0 +28,0 @@ ## [1.2.5](https://github.com/wswebcreation/protractor-image-comparison/compare/v1.2.4...v1.2.5) (2017-05-18)

Contributing
============
#Tests
# Tests
There are several test that need to be executed to be able to test the module. When adding a PR all tests must at least pass the local tests.

@@ -10,7 +10,7 @@ Each PR is automatically tested against Sauce Labs, see [Travis-ci with Sauce Labs](#travis-ci-with-sauce-labs).

## Local
**Make sure a local webdriver is installed, see [How to run a local webdriver](#how-to-run-a-local-webdriver) and start your webdriver.**
**Make sure a local webdriver is installed, see [How to run a local webdriver](#how-to-run-a-local-webdriver) and start your webdriver.**
(*DirectConnect from protractor itself is not stable enough to run our tests, that's why we we use a local webdriver*).
First a local baseline needs to be created. This can be done with `npm run test.init`. This command will create a folder called `localBaseline` that will hold all the baseline images.
Then run `npm run test.local`. This will run all tests on a local machine on Chrome (job uses direct connect, first run `npm run wd-update` to update the webdriver.
Then run `npm run test.local`. This will run all tests on a local machine on Chrome (job uses direct connect, first run `npm run wd-update` to update the webdriver.
This needs to be done once after install).

@@ -44,6 +44,6 @@

`npm run test.perfecto`: Run all tests on a real:
- Apple iOS device on Safari in the cloud
- Samsung Android on Chrom in the cloud
**Credentials are needed to be able to test this**

@@ -58,2 +58,2 @@

All PR's are automatically checked against Sauce Labs.
All PR's are automatically checked against Sauce Labs.

@@ -1,5 +0,5 @@

#Conventions
# Conventions
There are directory and naming conventions that must be met.
##Directory structure
## Directory structure
```text

@@ -37,2 +37,2 @@ path

* `mobile` This will add `_app`, of `browserName` after the deviceName to distinguish app screenshots from browser screenshots
* `name` The name from capabilities
* `name` The name from capabilities
Examples
========
##Configuration file setup:
## Configuration file setup:
Load it from the configuration file of *protractor*

@@ -22,3 +22,3 @@

##Jasmine Example:
## Jasmine Example:
Load it in a *spec* file

@@ -59,3 +59,3 @@

##Cucumber Example:
## Cucumber Example:
Load it in a *step* file

@@ -68,3 +68,3 @@

function CucumberSteps() {
browser.protractorImageComparison = new protractorImageComparison({

@@ -74,3 +74,3 @@ baselineFolder: './baseline/',

});
this.Given(/^I load the url$/, function () {

@@ -103,2 +103,2 @@ return browser.get('http://www.example.com/');

For more examples / usage see the [desktop](../test/desktop.spec.js) or [mobile](../test/desktop.spec.js) testcases.
For more examples / usage see the [desktop](../test/desktop.spec.js) or [mobile](../test/desktop.spec.js) testcases.

@@ -1,4 +0,4 @@

#Methods
# Methods
##saveScreen or checkScreen
## saveScreen or checkScreen
The methods `saveScreen` and `checkScreen` create a screenshot of the visible viewport. Be aware that there are different webdriver implementations in creating complete screenshots.

@@ -18,3 +18,3 @@ For example:

##saveElement or checkElement
## saveElement or checkElement
Images are cropped from the complete screenshot by using the `saveElement` or `checkElement` function.

@@ -25,3 +25,3 @@ The method will calculate the correct dimensions based upon the webdriver element selector.

##NEW saveFullPageScreens or checkFullPageScreen
## NEW saveFullPageScreens or checkFullPageScreen
The methods `saveFullPageScreens` and `checkFullPageScreen` create a screenshot of the **complete** page. Basically it will device the complete page into multiple viewports.

@@ -33,3 +33,3 @@ Then it will scroll to each viewport, waits a given timeout (default 1000 milliseconds) and takes a screenshot. When all the viewports have been captured it will compose a new complete fullpage screenshot.

##protractor-image-comparison parameters:
## protractor-image-comparison parameters:

@@ -74,3 +74,3 @@ * `baselineFolder` Defines the path to the reference images that are to be compared.

##Method options:
## Method options:
### blockOut

@@ -94,2 +94,2 @@ Sometimes, it is necessary to block-out some specific areas in an image that should be ignored for comparisons. For example, this can be IDs or even time-labels that change with the time. Adding block-outs to images may decrease false positives and therefore stabilizes these comparisons (see the [examples](./examples.md)).

### More options
For more method options and example usage see [here](./index.md).
For more method options and example usage see [here](./index.md).

@@ -127,3 +127,6 @@ 'use strict';

fs.ensureDirSync(this.diffFolder);
fs.ensureDirSync(this.tempFullScreenFolder);
if(this.debug) {
fs.ensureDirSync(this.tempFullScreenFolder);
}
}

@@ -158,27 +161,23 @@

/**
* Compose a full page screenshot and save it
* Save a full page screenshot
* @param {string} tag The tag that is used
* @param {number} amountOfScreenshots The amount of amountOfScreenshots that need to be processed
* @param {number} currentScreenshotNumber The current currentScreenshotNumber of the screenshot that is being processed
* @param {string} image The current image output that needs to be saved
* @param {Array} screens An array full of buffered screenshots
* @returns {Promise}
* @private
*/
_composeAndSaveFullScreenshot(tag, amountOfScreenshots, currentScreenshotNumber, image) {
const imageHeight = this.fullPageHeight * this.devicePixelRatio;
const imageWidth = this.viewPortWidth * this.devicePixelRatio;
const stitchHeightCoordinate = (this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding) * (currentScreenshotNumber - 1) * this.devicePixelRatio;
_saveFullScreenshot(tag, screens) {
// Calculate total canvas size
const imageHeight = screens.reduce((previous, current) => (previous instanceof Buffer ? previous.readUInt32BE(20) : previous) + current.readUInt32BE(20));
const imageWidth = screens[0].readUInt32BE(16);
const imageOutput = PNGJSImage.createImage(imageWidth, imageHeight);
let offsetY = 0;
let imageOutput = image || null;
if (currentScreenshotNumber === 1) {
imageOutput = PNGJSImage.createImage(imageWidth, imageHeight);
} else if (currentScreenshotNumber > amountOfScreenshots) {
return Promise.resolve(imageOutput.writeImageSync(path.join(this.actualFolder, this._formatFileName(tag))));
// Compose PNG
for (let screen of screens) {
let height = screen.readUInt32BE(20);
PNGJSImage.loadImageSync(screen).getImage().bitblt(imageOutput.getImage(), 0, 0, imageWidth, height, 0, offsetY);
offsetY += height;
}
const stitchImage = PNGJSImage.readImageSync(path.join(this.tempFullScreenFolder, this._formatFileName(`${tag}-${currentScreenshotNumber}`)));
stitchImage.getImage().bitblt(imageOutput.getImage(), 0, 0, stitchImage.getWidth(), stitchImage.getHeight(), 0, stitchHeightCoordinate);
return this._composeAndSaveFullScreenshot(tag, amountOfScreenshots, currentScreenshotNumber + 1, imageOutput)
return Promise.resolve(imageOutput.writeImageSync(path.join(this.actualFolder, this._formatFileName(tag))));
}

@@ -311,3 +310,3 @@

mobileCropData.cropHeight = this.fullPageHeight - ((this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding) * (cropParameters.currentScreenshotNumber - 1));
mobileCropData.cropTopPosition = statusPlusAddressBarHeight + (this.viewPortHeight- this.toolBarShadowPadding) - mobileCropData.cropHeight;
mobileCropData.cropTopPosition = statusPlusAddressBarHeight + (this.viewPortHeight - this.toolBarShadowPadding) - mobileCropData.cropHeight;
} else {

@@ -327,3 +326,3 @@ mobileCropData.cropHeight = this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding;

mobileCropData.cropHeight = this.fullPageHeight - ((this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding) * (cropParameters.currentScreenshotNumber - 1));
mobileCropData.cropTopPosition = safariHeights.addressBarCurrentHeight + (this.viewPortHeight- this.toolBarShadowPadding) - mobileCropData.cropHeight;
mobileCropData.cropTopPosition = safariHeights.addressBarCurrentHeight + (this.viewPortHeight - this.toolBarShadowPadding) - mobileCropData.cropHeight;
} else {

@@ -754,2 +753,30 @@ mobileCropData.cropHeight = this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding;

/**
* Create a new cropped buffered image
* @param {object} bufferedScreenshot a new Buffer screenshot
* @param {object} rectangles x, y, height and width data to determine the crop
* @returns {Buffer} The image buffer
* @private
*/
_getCroppedBufferedScreenshot(bufferedScreenshot, rectangles) {
let imageHeight;
const image = PNGJSImage.loadImageSync(bufferedScreenshot);
// When coordinates have decimals they are `round`ed. This means that the total amount can be bigger
// than the image. That's why we need to resize it.
if ((rectangles.height + rectangles.y) > image.getHeight()) {
imageHeight = rectangles.height - ((rectangles.height + rectangles.y) - image.getHeight());
} else {
imageHeight = rectangles.height;
}
const imageWidth = rectangles.width;
// Create the canvas
const imageOutput = PNGJSImage.createImage(imageWidth, imageHeight);
// Create the image
image.getImage().bitblt(imageOutput.getImage(), rectangles.x, rectangles.y, imageWidth, imageHeight, 0, 0);
return imageOutput.toBlobSync();
}
/**
* Scroll to static horizontal and a given vertical coordinate on the page and wait a given time.

@@ -771,6 +798,7 @@ * @param {number} verticalCoordinate The y-coordinate that needs to be scrolled to

* @param {number} currentScreenshotNumber The currentScreenshotNumber of the screen that is being processed
* @param {Array} screens An array full of buffered screenshots
* @returns {Promise}
* @private
*/
_scrollAndSave(newVerticalCoordinate, tag, currentScreenshotNumber) {
_scrollAndSave(newVerticalCoordinate, tag, currentScreenshotNumber, screens) {
const previousVerticalCoordinate = (currentScreenshotNumber - 1) * this.viewPortHeight;

@@ -821,11 +849,13 @@

console.log('####################################################\n');
this._saveCroppedScreenshot(bufferedScreenshot, this.tempFullScreenFolder, rectangles, `${tag}-${currentScreenshotNumber}`);
}
return this._getCroppedBufferedScreenshot(bufferedScreenshot, rectangles);
})
.then((screen) => {
screens.push(screen);
return this._saveCroppedScreenshot(bufferedScreenshot, this.tempFullScreenFolder, rectangles, `${tag}-${currentScreenshotNumber}`);
})
.then(() => {
if (this.isLastScreenshot) {
return this._composeAndSaveFullScreenshot(tag, currentScreenshotNumber, 1);
return this._saveFullScreenshot(tag, screens);
} else {
return this._scrollAndSave((this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding) * currentScreenshotNumber, tag, currentScreenshotNumber + 1);
return this._scrollAndSave((this.viewPortHeight - this.addressBarShadowPadding - this.toolBarShadowPadding) * currentScreenshotNumber, tag, currentScreenshotNumber + 1, screens);
}

@@ -1057,3 +1087,3 @@ });

return this._getInstanceData()
.then(() => this._scrollAndSave(0, tag, 1));
.then(() => this._scrollAndSave(0, tag, 1, []));
}

@@ -1060,0 +1090,0 @@

{
"name": "protractor-image-comparison",
"version": "1.4.0",
"version": "1.5.0",
"description": "npm-module to compare images with protractor",

@@ -5,0 +5,0 @@ "main": "index.js",

protractor-image-comparison
==========
[![dependencies Status](https://david-dm.org/wswebcreation/protractor-image-comparison/status.svg)](https://david-dm.org/wswebcreation/protractor-image-comparison) [![Build Status](https://travis-ci.org/wswebcreation/protractor-image-comparison.svg?branch=master)](https://travis-ci.org/wswebcreation/protractor-image-comparison) [![Sauce Test Status](https://saucelabs.com/buildstatus/wswebcreation-nl)](https://saucelabs.com/u/wswebcreation-nl)
[![Join the chat at https://gitter.im/wswebcreation/protractor-image-comparison](https://badges.gitter.im/wswebcreation/protractor-image-comparison.svg)](https://gitter.im/wswebcreation/protractor-image-comparison?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![dependencies Status](https://david-dm.org/wswebcreation/protractor-image-comparison/status.svg)](https://david-dm.org/wswebcreation/protractor-image-comparison) [![Build Status](https://travis-ci.org/wswebcreation/protractor-image-comparison.svg?branch=master)](https://travis-ci.org/wswebcreation/protractor-image-comparison) [![Sauce Test Status](https://saucelabs.com/buildstatus/wswebcreation-nl)](https://saucelabs.com/u/wswebcreation-nl)

@@ -23,2 +23,3 @@ [![NPM](https://nodei.co/npm/protractor-image-comparison.png)](https://nodei.co/npm/protractor-image-comparison/)

- **NEW** ignore regions by making them transparent in the base image (all) thanks to [tharders](https://github.com/tharders)
- **NEW** parameter to hide / show scrollbars [pnad](https://github.com/pnad)
- increase the element dimenisions screenshots (all)

@@ -25,0 +26,0 @@ - provide custom iOS and Android offsets for status-/address-/toolbar (mobile only)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc