Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authordiosmosis <benaka@piwik.pro>2015-03-16 19:57:39 +0300
committerdiosmosis <benaka@piwik.pro>2015-03-16 19:57:39 +0300
commit8976cfd575ce5673b0c52889ae43315006d01f9f (patch)
tree91e1110b99ed0c063ed99b658d9f4ecf7eca1b8b /tests
parent8d1065144b6c309adb8067e8202a5ad41371abd7 (diff)
parent47a61c1ad87c9208db5a673346bb762cec7bf32f (diff)
Merge branch 'master' into 7276_update_command_progress
Conflicts: plugins/CoreUpdater/Controller.php
Diffstat (limited to 'tests')
-rw-r--r--tests/PHPUnit/Framework/Fixture.php10
-rw-r--r--tests/PHPUnit/TestingEnvironment.php15
-rw-r--r--tests/UI/Fixtures/UpdaterTestFixture.php21
m---------tests/UI/expected-ui-screenshots0
-rw-r--r--tests/UI/screenshot-diffs/comparator.js86
-rw-r--r--tests/UI/screenshot-diffs/diffgenerator.js13
-rw-r--r--tests/UI/screenshot-diffs/singlediff.html29
-rw-r--r--tests/UI/screenshot-diffs/style.css156
-rw-r--r--tests/UI/specs/CoreUpdaterCode_spec.js34
-rw-r--r--tests/UI/specs/CoreUpdaterDb_spec.js (renamed from tests/UI/specs/Updater_spec.js)6
-rwxr-xr-x[-rw-r--r--]tests/lib/resemblejs/resemble.js1247
-rw-r--r--tests/lib/screenshot-testing/support/test-environment.js3
-rwxr-xr-xtests/travis/travis.sh16
13 files changed, 1008 insertions, 628 deletions
diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php
index 71cce331a8..9d2fb8a2d7 100644
--- a/tests/PHPUnit/Framework/Fixture.php
+++ b/tests/PHPUnit/Framework/Fixture.php
@@ -882,4 +882,14 @@ class Fixture extends \PHPUnit_Framework_Assert
return $result;
}
+
+ /**
+ * Use this method to return custom container configuration that you want to apply for the tests.
+ *
+ * @return array
+ */
+ public function provideContainerConfig()
+ {
+ return array();
+ }
}
diff --git a/tests/PHPUnit/TestingEnvironment.php b/tests/PHPUnit/TestingEnvironment.php
index 97d98dbff8..3acc202a91 100644
--- a/tests/PHPUnit/TestingEnvironment.php
+++ b/tests/PHPUnit/TestingEnvironment.php
@@ -2,10 +2,12 @@
use Piwik\Common;
use Piwik\Config;
+use Piwik\Container\StaticContainer;
use Piwik\Piwik;
use Piwik\Option;
use Piwik\Plugin\Manager as PluginManager;
use Piwik\DbHelper;
+use Piwik\Tests\Framework\Fixture;
require_once PIWIK_INCLUDE_PATH . "/core/Config.php";
@@ -148,6 +150,19 @@ class Piwik_TestingEnvironment
$testingEnvironment->configFileGlobal, $testingEnvironment->configFileLocal, $testingEnvironment->configFileCommon
));
+ // Apply DI config from the fixture
+ if ($testingEnvironment->fixtureClass) {
+ $fixtureClass = $testingEnvironment->fixtureClass;
+ if (class_exists($fixtureClass)) {
+ /** @var Fixture $fixture */
+ $fixture = new $fixtureClass;
+ $diConfig = $fixture->provideContainerConfig();
+ if (!empty($diConfig)) {
+ StaticContainer::addDefinitions($diConfig);
+ }
+ }
+ }
+
\Piwik\Cache\Backend\File::$invalidateOpCacheBeforeRead = true;
Piwik::addAction('Access.createAccessSingleton', function($access) use ($testingEnvironment) {
diff --git a/tests/UI/Fixtures/UpdaterTestFixture.php b/tests/UI/Fixtures/UpdaterTestFixture.php
deleted file mode 100644
index e2b3a0024e..0000000000
--- a/tests/UI/Fixtures/UpdaterTestFixture.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/**
- * Piwik - free/libre analytics platform
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-namespace Piwik\Tests\Fixtures;
-
-class UpdaterTestFixture extends SqlDump
-{
- public function performSetUp($setupEnvironmentOnly = false)
- {
- $this->dumpUrl = PIWIK_INCLUDE_PATH . "/tests/UI/resources/piwik1.0.sql.gz";
- $this->dropDatabaseInSetUp = true;
- $this->resetPersistedFixture = true;
-
- parent::performSetUp($setupEnvironmentOnly);
- }
-} \ No newline at end of file
diff --git a/tests/UI/expected-ui-screenshots b/tests/UI/expected-ui-screenshots
-Subproject 560c44710748f4f27ceaee0955f59aa1336ee4a
+Subproject 8426ae2a418fc251f0408977622b560e33f31f2
diff --git a/tests/UI/screenshot-diffs/comparator.js b/tests/UI/screenshot-diffs/comparator.js
new file mode 100644
index 0000000000..75b2e025c1
--- /dev/null
+++ b/tests/UI/screenshot-diffs/comparator.js
@@ -0,0 +1,86 @@
+jQuery(document).ready(function($){
+ //check if the .cd-image-container is in the viewport
+ //if yes, animate it
+ checkPosition($('.cd-image-container'));
+ $(window).on('scroll', function(){
+ checkPosition($('.cd-image-container'));
+ });
+
+ //make the .cd-handle element draggable and modify .cd-resize-img width according to its position
+ $('.cd-image-container').each(function(){
+ var actual = $(this);
+ drags(actual.find('.cd-handle'), actual.find('.cd-resize-img'), actual, actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-image-label[data-type="modified"]'));
+ });
+
+ //upadate images label visibility
+ $(window).on('resize', function(){
+ $('.cd-image-container').each(function(){
+ var actual = $(this);
+ updateLabel(actual.find('.cd-image-label[data-type="modified"]'), actual.find('.cd-resize-img'), 'left');
+ updateLabel(actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-resize-img'), 'right');
+ });
+ });
+});
+
+function checkPosition(container) {
+ container.each(function(){
+ var actualContainer = $(this);
+ if( $(window).scrollTop() + $(window).height()*0.5 > actualContainer.offset().top) {
+ actualContainer.addClass('is-visible');
+ }
+ });
+}
+
+//draggable funtionality - credits to http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
+function drags(dragElement, resizeElement, container, labelContainer, labelResizeElement) {
+ dragElement.on("mousedown vmousedown", function(e) {
+ dragElement.addClass('draggable');
+ resizeElement.addClass('resizable');
+
+ var dragWidth = dragElement.outerWidth(),
+ xPosition = dragElement.offset().left + dragWidth - e.pageX,
+ containerOffset = container.offset().left,
+ containerWidth = container.outerWidth(),
+ minLeft = containerOffset + 10,
+ maxLeft = containerOffset + containerWidth - dragWidth - 10;
+
+ dragElement.parents().on("mousemove vmousemove", function(e) {
+ leftValue = e.pageX + xPosition - dragWidth;
+
+ //constrain the draggable element to move inside his container
+ if(leftValue < minLeft ) {
+ leftValue = minLeft;
+ } else if ( leftValue > maxLeft) {
+ leftValue = maxLeft;
+ }
+
+ widthValue = (leftValue + dragWidth/2 - containerOffset)*100/containerWidth+'%';
+
+ $('.draggable').css('left', widthValue).on("mouseup vmouseup", function() {
+ $(this).removeClass('draggable');
+ resizeElement.removeClass('resizable');
+ });
+
+ $('.resizable').css('width', widthValue);
+
+ updateLabel(labelResizeElement, resizeElement, 'left');
+ updateLabel(labelContainer, resizeElement, 'right');
+
+ }).on("mouseup vmouseup", function(e){
+ dragElement.removeClass('draggable');
+ resizeElement.removeClass('resizable');
+ });
+ e.preventDefault();
+ }).on("mouseup vmouseup", function(e) {
+ dragElement.removeClass('draggable');
+ resizeElement.removeClass('resizable');
+ });
+}
+
+function updateLabel(label, resizeElement, position) {
+ if(position == 'left') {
+ ( label.offset().left + label.outerWidth() < resizeElement.offset().left + resizeElement.outerWidth() ) ? label.removeClass('is-hidden') : label.addClass('is-hidden') ;
+ } else {
+ ( label.offset().left > resizeElement.offset().left + resizeElement.outerWidth() ) ? label.removeClass('is-hidden') : label.addClass('is-hidden') ;
+ }
+}
diff --git a/tests/UI/screenshot-diffs/diffgenerator.js b/tests/UI/screenshot-diffs/diffgenerator.js
index 78063a6674..c2de59f9eb 100644
--- a/tests/UI/screenshot-diffs/diffgenerator.js
+++ b/tests/UI/screenshot-diffs/diffgenerator.js
@@ -20,7 +20,7 @@ resemble.outputSettings({
function compareImages(expected, expectedGithub, processed)
{
- resemble(processed).compareTo(expected).onComplete(function(data){
+ var resembleControl = resemble(processed).compareTo(expected).onComplete(function(data){
var info = 'Mismatch percentage: ' + data.misMatchPercentage + '%';
@@ -35,6 +35,8 @@ function compareImages(expected, expectedGithub, processed)
$('.processed').attr('src', encodeURI(processed));
$('.expected').attr('src', encodeURI(expected));
$('.expectedGithub').attr('src', 'https://raw.githubusercontent.com/piwik/piwik-ui-tests/master/' + encodeURI(expectedGithub));
+
+ return resembleControl;
}
function getUrlQueryParam(sParam) {
@@ -54,5 +56,12 @@ $(function () {
var processed = getUrlQueryParam('processed');
var expected = getUrlQueryParam('expected');
var github = getUrlQueryParam('github');
- compareImages(expected, github, processed);
+ var resembleControl = compareImages(expected, github, processed);
+
+ $('#toggleAliasing').click(function () {
+ resembleControl.ignoreAntialiasing();
+ });
+
+ $('#original').attr('src', expected);
+ $('#modified').attr('src', processed);
}); \ No newline at end of file
diff --git a/tests/UI/screenshot-diffs/singlediff.html b/tests/UI/screenshot-diffs/singlediff.html
index a91ffa7a40..b80c764957 100644
--- a/tests/UI/screenshot-diffs/singlediff.html
+++ b/tests/UI/screenshot-diffs/singlediff.html
@@ -1,12 +1,14 @@
<html>
<head>
+ <link rel="stylesheet" href="style.css"/>
<!-- loaded when on build-artifacts -->
<script src='jquery.js'></script>
<script src='resemble.js'></script>
<!-- loaded when viewing within piwik -->
- <script src='../../../../libs/bower_components/jquery/dist/jquery.min.js'></script>
- <script src='../../../../tests/lib/resemblejs/resemble.js'></script>
+ <script src='../../../libs/bower_components/jquery/dist/jquery.min.js'></script>
+ <script src='../../../tests/lib/resemblejs/resemble.js'></script>
<script src='diffgenerator.js'></script>
+ <script src='comparator.js'></script>
</head>
<body>
@@ -15,6 +17,26 @@
<br />
<img class="diff">
+<br/><br/>
+
+<div id="controls">
+ <button id="toggleAliasing">Ignore aliasing</button>
+</div>
+
+<br/><br/>
+
+<figure class="cd-image-container">
+ <img id="original">
+ <span class="cd-image-label" data-type="original">Original</span>
+
+ <div class="cd-resize-img"> <!-- the resizable image on top -->
+ <img id="modified">
+ <span class="cd-image-label" data-type="modified">Modified</span>
+ </div>
+
+ <span class="cd-handle"></span>
+</figure>
+
<h2>Processed</h2>
<img class="processed">
@@ -24,4 +46,5 @@
<h2>Expected GitHub</h2>
<img class="expectedGithub">
-</body></html> \ No newline at end of file
+</body>
+</html> \ No newline at end of file
diff --git a/tests/UI/screenshot-diffs/style.css b/tests/UI/screenshot-diffs/style.css
new file mode 100644
index 0000000000..367b01f0f8
--- /dev/null
+++ b/tests/UI/screenshot-diffs/style.css
@@ -0,0 +1,156 @@
+img {
+ max-width: 100%;
+ display: block;
+ margin: 0 auto;
+}
+
+#controls {
+ margin: 0 auto;
+ width: 100px;
+}
+
+.cd-image-container {
+ position: relative;
+ width: 90%;
+ max-width: 768px;
+ margin: 0em auto;
+}
+.cd-image-container img {
+ display: block;
+}
+
+.cd-image-label {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ color: #ffffff;
+ padding: 1em;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ opacity: 0;
+ -webkit-transform: translateY(20px);
+ -moz-transform: translateY(20px);
+ -ms-transform: translateY(20px);
+ -o-transform: translateY(20px);
+ transform: translateY(20px);
+ -webkit-transition: -webkit-transform 0.3s 0.7s, opacity 0.3s 0.7s;
+ -moz-transition: -moz-transform 0.3s 0.7s, opacity 0.3s 0.7s;
+ transition: transform 0.3s 0.7s, opacity 0.3s 0.7s;
+}
+.cd-image-label.is-hidden {
+ visibility: hidden;
+}
+.is-visible .cd-image-label {
+ opacity: 1;
+ -webkit-transform: translateY(0);
+ -moz-transform: translateY(0);
+ -ms-transform: translateY(0);
+ -o-transform: translateY(0);
+ transform: translateY(0);
+}
+
+.cd-resize-img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 0;
+ height: 100%;
+ overflow: hidden;
+ /* Force Hardware Acceleration in WebKit */
+ -webkit-transform: translateZ(0);
+ -moz-transform: translateZ(0);
+ -ms-transform: translateZ(0);
+ -o-transform: translateZ(0);
+ transform: translateZ(0);
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+}
+.cd-resize-img img {
+ position: absolute;
+ left: 0;
+ top: 0;
+ display: block;
+ height: 100%;
+ width: auto;
+ max-width: none;
+}
+.cd-resize-img .cd-image-label {
+ right: auto;
+ left: 0;
+}
+.is-visible .cd-resize-img {
+ width: 50%;
+ /* bounce in animation of the modified image */
+ -webkit-animation: cd-bounce-in 0.7s;
+ -moz-animation: cd-bounce-in 0.7s;
+ animation: cd-bounce-in 0.7s;
+}
+
+@-webkit-keyframes cd-bounce-in {
+ 0% {
+ width: 0;
+ }
+ 60% {
+ width: 55%;
+ }
+ 100% {
+ width: 50%;
+ }
+}
+@-moz-keyframes cd-bounce-in {
+ 0% {
+ width: 0;
+ }
+ 60% {
+ width: 55%;
+ }
+ 100% {
+ width: 50%;
+ }
+}
+@keyframes cd-bounce-in {
+ 0% {
+ width: 0;
+ }
+ 60% {
+ width: 55%;
+ }
+ 100% {
+ width: 50%;
+ }
+}
+.cd-handle {
+ position: absolute;
+ height: 44px;
+ width: 44px;
+ /* center the element */
+ left: 50%;
+ top: 50%;
+ margin-left: -22px;
+ margin-top: -22px;
+ border-radius: 50%;
+ background: #dc717d no-repeat center center;
+ cursor: move;
+ box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.2), 0 0 10px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.3);
+ opacity: 0;
+ -webkit-transform: translate3d(0, 0, 0) scale(0);
+ -moz-transform: translate3d(0, 0, 0) scale(0);
+ -ms-transform: translate3d(0, 0, 0) scale(0);
+ -o-transform: translate3d(0, 0, 0) scale(0);
+ transform: translate3d(0, 0, 0) scale(0);
+}
+.cd-handle.draggable {
+ /* change background color when element is active */
+ background-color: #445b7c;
+}
+.is-visible .cd-handle {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 0, 0) scale(1);
+ -moz-transform: translate3d(0, 0, 0) scale(1);
+ -ms-transform: translate3d(0, 0, 0) scale(1);
+ -o-transform: translate3d(0, 0, 0) scale(1);
+ transform: translate3d(0, 0, 0) scale(1);
+ -webkit-transition: -webkit-transform 0.3s 0.7s, opacity 0s 0.7s;
+ -moz-transition: -moz-transform 0.3s 0.7s, opacity 0s 0.7s;
+ transition: transform 0.3s 0.7s, opacity 0s 0.7s;
+}
diff --git a/tests/UI/specs/CoreUpdaterCode_spec.js b/tests/UI/specs/CoreUpdaterCode_spec.js
new file mode 100644
index 0000000000..807810869b
--- /dev/null
+++ b/tests/UI/specs/CoreUpdaterCode_spec.js
@@ -0,0 +1,34 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * Installation screenshot tests.
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+describe("CoreUpdaterCode", function () {
+ this.timeout(0);
+
+ this.fixture = "Piwik\\Plugins\\CoreUpdater\\Test\\Fixtures\\FailUpdateHttpsFixture";
+
+ var url = "?module=CoreUpdater&action=newVersionAvailable";
+
+ it("should show a new version is available", function (done) {
+ expect.screenshot("newVersion").to.be.capture(function (page) {
+ page.load(url);
+ }, done);
+ });
+
+ it("should offer to update over http when updating over https fails", function (done) {
+ expect.screenshot("httpsUpdateFail").to.be.capture(function (page) {
+ page.click('#updateAutomatically');
+ }, done);
+ });
+
+ it("should show the update steps when updating over http succeeds", function (done) {
+ expect.screenshot("httpUpdateSuccess").to.be.capture(function (page) {
+ page.click('#updateUsingHttp');
+ }, done);
+ });
+});
diff --git a/tests/UI/specs/Updater_spec.js b/tests/UI/specs/CoreUpdaterDb_spec.js
index 0ddc8b67cb..f77776a4ca 100644
--- a/tests/UI/specs/Updater_spec.js
+++ b/tests/UI/specs/CoreUpdaterDb_spec.js
@@ -7,10 +7,10 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
-describe("Updater", function () {
+describe("CoreUpdaterDb", function () {
this.timeout(0);
- this.fixture = "Piwik\\Tests\\Fixtures\\UpdaterTestFixture";
+ this.fixture = "Piwik\\Plugins\\CoreUpdater\\Test\\Fixtures\\DbUpdaterTestFixture";
before(function () {
testEnvironment.tablesPrefix = 'piwik_';
@@ -34,4 +34,4 @@ describe("Updater", function () {
page.click('.submit');
}, done);
});
-}); \ No newline at end of file
+});
diff --git a/tests/lib/resemblejs/resemble.js b/tests/lib/resemblejs/resemble.js
index dbb927a7cd..bdd375634a 100644..100755
--- a/tests/lib/resemblejs/resemble.js
+++ b/tests/lib/resemblejs/resemble.js
@@ -1,600 +1,659 @@
/*
- James Cryer / Huddle 2014
- URL: https://github.com/Huddle/Resemble.js
- */
+James Cryer / Huddle 2014
+URL: https://github.com/Huddle/Resemble.js
+*/
(function(_this){
- 'use strict';
-
- var pixelTransparency = 1;
-
- var errorPixelColor = { // Color for Error Pixels. Between 0 and 255.
- red: 255,
- green: 0,
- blue: 255,
- alpha: 255
- };
-
- var errorPixelTransform = {
- flat : function (d1, d2){
- return {
- r: errorPixelColor.red,
- g: errorPixelColor.green,
- b: errorPixelColor.blue,
- a: errorPixelColor.alpha
- }
- },
- movement: function (d1, d2){
- return {
- r: ((d2.r*(errorPixelColor.red/255)) + errorPixelColor.red)/2,
- g: ((d2.g*(errorPixelColor.green/255)) + errorPixelColor.green)/2,
- b: ((d2.b*(errorPixelColor.blue/255)) + errorPixelColor.blue)/2,
- a: d2.a
- }
- }
- };
-
- var errorPixelTransformer = errorPixelTransform.flat;
-
- _this['resemble'] = function( fileData ){
-
- var data = {};
- var images = [];
- var updateCallbackArray = [];
-
- var tolerance = { // between 0 and 255
- red: 16,
- green: 16,
- blue: 16,
- alpha: 16,
- minBrightness: 16,
- maxBrightness: 240
- };
-
- var ignoreAntialiasing = false;
- var ignoreColors = false;
-
- function triggerDataUpdate(){
- var len = updateCallbackArray.length;
- var i;
- for(i=0;i<len;i++){
- if (typeof updateCallbackArray[i] === 'function'){
- updateCallbackArray[i](data);
- }
- }
- }
-
- function loop(x, y, callback){
- var i,j;
-
- for (i=0;i<x;i++){
- for (j=0;j<y;j++){
- callback(i, j);
- }
- }
- }
-
- function parseImage(sourceImageData, width, height){
-
- var pixleCount = 0;
- var redTotal = 0;
- var greenTotal = 0;
- var blueTotal = 0;
- var brightnessTotal = 0;
-
- loop(height, width, function(verticalPos, horizontalPos){
- var offset = (verticalPos*width + horizontalPos) * 4;
- var red = sourceImageData[offset];
- var green = sourceImageData[offset + 1];
- var blue = sourceImageData[offset + 2];
- var brightness = getBrightness(red,green,blue);
-
- pixleCount++;
-
- redTotal += red / 255 * 100;
- greenTotal += green / 255 * 100;
- blueTotal += blue / 255 * 100;
- brightnessTotal += brightness / 255 * 100;
- });
-
- data.red = Math.floor(redTotal / pixleCount);
- data.green = Math.floor(greenTotal / pixleCount);
- data.blue = Math.floor(blueTotal / pixleCount);
- data.brightness = Math.floor(brightnessTotal / pixleCount);
-
- triggerDataUpdate();
- }
-
- function loadImageData( fileData, callback ){
- var fileReader;
- var hiddenImage = new Image();
-
- hiddenImage.onload = function() {
-
- var hiddenCanvas = document.createElement('canvas');
- var imageData;
- var width = hiddenImage.width;
- var height = hiddenImage.height;
-
- hiddenCanvas.width = width;
- hiddenCanvas.height = height;
- hiddenCanvas.getContext('2d').drawImage(hiddenImage, 0, 0, width, height);
- imageData = hiddenCanvas.getContext('2d').getImageData(0, 0, width, height);
-
- images.push(imageData);
-
- callback(imageData, width, height);
- };
-
- if (typeof fileData === 'string') {
- hiddenImage.src = fileData;
- } else {
- fileReader = new FileReader();
- fileReader.onload = function (event) {
- hiddenImage.src = event.target.result;
- };
- fileReader.readAsDataURL(fileData);
- }
- }
-
- function isColorSimilar(a, b, color){
-
- var absDiff = Math.abs(a - b);
-
- if(typeof a === 'undefined'){
- return false;
- }
- if(typeof b === 'undefined'){
- return false;
- }
-
- if(a === b){
- return true;
- } else if ( absDiff < tolerance[color] ) {
- return true;
- } else {
- return false;
- }
- }
-
- function isNumber(n) {
- return !isNaN(parseFloat(n));
- }
-
- function isPixelBrightnessSimilar(d1, d2){
- var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
- var brightness = isColorSimilar(d1.brightness, d2.brightness, 'minBrightness');
- return brightness && alpha;
- }
-
- function getBrightness(r,g,b){
- return 0.3*r + 0.59*g + 0.11*b;
- }
-
- function isRGBSame(d1,d2){
- var red = d1.r === d2.r;
- var green = d1.g === d2.g;
- var blue = d1.b === d2.b;
- return red && green && blue;
- }
-
- function isRGBSimilar(d1, d2){
- var red = isColorSimilar(d1.r,d2.r,'red');
- var green = isColorSimilar(d1.g,d2.g,'green');
- var blue = isColorSimilar(d1.b,d2.b,'blue');
- var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
-
- return red && green && blue && alpha;
- }
-
- function isContrasting(d1, d2){
- return Math.abs(d1.brightness - d2.brightness) > tolerance.maxBrightness;
- }
-
- function getHue(r,g,b){
-
- r = r / 255;
- g = g / 255;
- b = b / 255;
- var max = Math.max(r, g, b), min = Math.min(r, g, b);
- var h;
- var d;
-
- if (max == min){
- h = 0; // achromatic
- } else{
- d = max - min;
- switch(max){
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
- case g: h = (b - r) / d + 2; break;
- case b: h = (r - g) / d + 4; break;
- }
- h /= 6;
- }
-
- return h;
- }
-
- function isAntialiased(sourcePix, data, cacheSet, verticalPos, horizontalPos, width){
- var offset;
- var targetPix;
- var distance = 1;
- var i;
- var j;
- var hasHighContrastSibling = 0;
- var hasSiblingWithDifferentHue = 0;
- var hasEquivilantSibling = 0;
-
- addHueInfo(sourcePix);
-
- for (i = distance*-1; i <= distance; i++){
- for (j = distance*-1; j <= distance; j++){
-
- if(i===0 && j===0){
- // ignore source pixel
- } else {
-
- offset = ((verticalPos+j)*width + (horizontalPos+i)) * 4;
- targetPix = getPixelInfo(data, offset, cacheSet);
-
- if(targetPix === null){
- continue;
- }
-
- addBrightnessInfo(targetPix);
- addHueInfo(targetPix);
-
- if( isContrasting(sourcePix, targetPix) ){
- hasHighContrastSibling++;
- }
-
- if( isRGBSame(sourcePix,targetPix) ){
- hasEquivilantSibling++;
- }
-
- if( Math.abs(targetPix.h - sourcePix.h) > 0.3 ){
- hasSiblingWithDifferentHue++;
- }
-
- if( hasSiblingWithDifferentHue > 1 || hasHighContrastSibling > 1){
- return true;
- }
- }
- }
- }
-
- if(hasEquivilantSibling < 2){
- return true;
- }
-
- return false;
- }
-
- function errorPixel(px, offset, data1, data2){
- var data = errorPixelTransformer(data1, data2);
- px[offset] = data.r;
- px[offset + 1] = data.g;
- px[offset + 2] = data.b;
- px[offset + 3] = data.a;
- }
-
- function copyPixel(px, offset, data){
- px[offset] = data.r; //r
- px[offset + 1] = data.g; //g
- px[offset + 2] = data.b; //b
- px[offset + 3] = data.a * pixelTransparency; //a
- }
-
- function copyGrayScalePixel(px, offset, data){
- px[offset] = data.brightness; //r
- px[offset + 1] = data.brightness; //g
- px[offset + 2] = data.brightness; //b
- px[offset + 3] = data.a * pixelTransparency; //a
- }
-
- function getPixelInfo(data, offset, cacheSet){
- var r;
- var g;
- var b;
- var d;
- var a;
-
- r = data[offset];
-
- if(typeof r !== 'undefined'){
- g = data[offset+1];
- b = data[offset+2];
- a = data[offset+3];
- d = {
- r: r,
- g: g,
- b: b,
- a: a
- };
-
- return d;
- } else {
- return null;
- }
- }
-
- function addBrightnessInfo(data){
- data.brightness = getBrightness(data.r,data.g,data.b); // 'corrected' lightness
- }
-
- function addHueInfo(data){
- data.h = getHue(data.r,data.g,data.b);
- }
-
- function analyseImages(img1, img2, width, height){
-
- var hiddenCanvas = document.createElement('canvas');
-
- var data1 = img1.data;
- var data2 = img2.data;
-
- hiddenCanvas.width = width;
- hiddenCanvas.height = height;
-
- var context = hiddenCanvas.getContext('2d');
- var imgd = context.createImageData(width,height);
- var targetPix = imgd.data;
-
- var mismatchCount = 0;
-
- var time = Date.now();
-
- var skip;
-
- if( (width > 1200 || height > 1200) && ignoreAntialiasing){
- skip = 6;
- }
-
- loop(height, width, function(verticalPos, horizontalPos){
-
- if(skip){ // only skip if the image isn't small
- if(verticalPos % skip === 0 || horizontalPos % skip === 0){
- return;
- }
- }
-
- var offset = (verticalPos*width + horizontalPos) * 4;
- var pixel1 = getPixelInfo(data1, offset, 1);
- var pixel2 = getPixelInfo(data2, offset, 2);
-
- if(pixel1 === null || pixel2 === null){
- return;
- }
-
- if (ignoreColors){
-
- addBrightnessInfo(pixel1);
- addBrightnessInfo(pixel2);
-
- if( isPixelBrightnessSimilar(pixel1, pixel2) ){
- copyGrayScalePixel(targetPix, offset, pixel2);
- } else {
- errorPixel(targetPix, offset, pixel1, pixel2);
- mismatchCount++;
- }
- return;
- }
-
- if( isRGBSimilar(pixel1, pixel2) ){
- copyPixel(targetPix, offset, pixel1, pixel2);
-
- } else if( ignoreAntialiasing && (
- addBrightnessInfo(pixel1), // jit pixel info augmentation looks a little weird, sorry.
- addBrightnessInfo(pixel2),
- isAntialiased(pixel1, data1, 1, verticalPos, horizontalPos, width) ||
- isAntialiased(pixel2, data2, 2, verticalPos, horizontalPos, width)
- )){
+ 'use strict';
+
+ var pixelTransparency = 1;
+
+ var errorPixelColor = { // Color for Error Pixels. Between 0 and 255.
+ red: 255,
+ green: 0,
+ blue: 255,
+ alpha: 255
+ };
+
+ function colorsDistance(c1, c2){
+ return (Math.abs(c1.r - c2.r) + Math.abs(c1.g - c2.g) + Math.abs(c1.b - c2.b))/3;
+ }
+
+ var errorPixelTransform = {
+ flat : function (d1, d2){
+ return {
+ r: errorPixelColor.red,
+ g: errorPixelColor.green,
+ b: errorPixelColor.blue,
+ a: errorPixelColor.alpha
+ }
+ },
+ movement: function (d1, d2){
+ return {
+ r: ((d2.r*(errorPixelColor.red/255)) + errorPixelColor.red)/2,
+ g: ((d2.g*(errorPixelColor.green/255)) + errorPixelColor.green)/2,
+ b: ((d2.b*(errorPixelColor.blue/255)) + errorPixelColor.blue)/2,
+ a: d2.a
+ }
+ },
+ flatDifferenceIntensity: function (d1, d2){
+ return {
+ r: errorPixelColor.red,
+ g: errorPixelColor.green,
+ b: errorPixelColor.blue,
+ a: colorsDistance(d1, d2)
+ }
+ },
+ movementDifferenceIntensity: function (d1, d2){
+ var ratio = colorsDistance(d1, d2)/255 * 0.8;
+ return {
+ r: ((1-ratio)*(d2.r*(errorPixelColor.red/255)) + ratio*errorPixelColor.red),
+ g: ((1-ratio)*(d2.g*(errorPixelColor.green/255)) + ratio*errorPixelColor.green),
+ b: ((1-ratio)*(d2.b*(errorPixelColor.blue/255)) + ratio*errorPixelColor.blue),
+ a: d2.a
+ }
+ }
+ };
+
+ var errorPixelTransformer = errorPixelTransform.flat;
+
+ var largeImageThreshold = 1200;
+
+ var httpRegex = /^https?:\/\//;
+ var document = typeof window != "undefined" ? window.document : {};
+ var documentDomainRegex = new RegExp('^https?://' + document.domain);
+
+ _this['resemble'] = function( fileData ){
+
+ var data = {};
+ var images = [];
+ var updateCallbackArray = [];
+
+ var tolerance = { // between 0 and 255
+ red: 16,
+ green: 16,
+ blue: 16,
+ alpha: 16,
+ minBrightness: 16,
+ maxBrightness: 240
+ };
+
+ var ignoreAntialiasing = false;
+ var ignoreColors = false;
+
+ function triggerDataUpdate(){
+ var len = updateCallbackArray.length;
+ var i;
+ for(i=0;i<len;i++){
+ if (typeof updateCallbackArray[i] === 'function'){
+ updateCallbackArray[i](data);
+ }
+ }
+ }
+
+ function loop(x, y, callback){
+ var i,j;
+
+ for (i=0;i<x;i++){
+ for (j=0;j<y;j++){
+ callback(i, j);
+ }
+ }
+ }
+
+ function parseImage(sourceImageData, width, height){
+
+ var pixelCount = 0;
+ var redTotal = 0;
+ var greenTotal = 0;
+ var blueTotal = 0;
+ var brightnessTotal = 0;
+
+ loop(height, width, function(verticalPos, horizontalPos){
+ var offset = (verticalPos*width + horizontalPos) * 4;
+ var red = sourceImageData[offset];
+ var green = sourceImageData[offset + 1];
+ var blue = sourceImageData[offset + 2];
+ var brightness = getBrightness(red,green,blue);
+
+ pixelCount++;
+
+ redTotal += red / 255 * 100;
+ greenTotal += green / 255 * 100;
+ blueTotal += blue / 255 * 100;
+ brightnessTotal += brightness / 255 * 100;
+ });
+
+ data.red = Math.floor(redTotal / pixelCount);
+ data.green = Math.floor(greenTotal / pixelCount);
+ data.blue = Math.floor(blueTotal / pixelCount);
+ data.brightness = Math.floor(brightnessTotal / pixelCount);
+
+ triggerDataUpdate();
+ }
+
+ function loadImageData( fileData, callback ){
+ var fileReader;
+ var hiddenImage = new Image();
+
+ if (httpRegex.test(fileData) && !documentDomainRegex.test(fileData)) {
+ hiddenImage.setAttribute('crossorigin', 'anonymous');
+ }
+
+ hiddenImage.onload = function() {
+
+ var hiddenCanvas = document.createElement('canvas');
+ var imageData;
+ var width = hiddenImage.width;
+ var height = hiddenImage.height;
+
+ hiddenCanvas.width = width;
+ hiddenCanvas.height = height;
+ hiddenCanvas.getContext('2d').drawImage(hiddenImage, 0, 0, width, height);
+ imageData = hiddenCanvas.getContext('2d').getImageData(0, 0, width, height);
+
+ images.push(imageData);
+
+ callback(imageData, width, height);
+ };
+
+ if (typeof fileData === 'string') {
+ hiddenImage.src = fileData;
+ if (hiddenImage.complete) {
+ hiddenImage.onload();
+ }
+ } else if (typeof fileData.data !== 'undefined'
+ && typeof fileData.width === 'number'
+ && typeof fileData.height === 'number') {
+ images.push(fileData);
+ callback(fileData, fileData.width, fileData.height);
+ } else {
+ fileReader = new FileReader();
+ fileReader.onload = function (event) {
+ hiddenImage.src = event.target.result;
+ };
+ fileReader.readAsDataURL(fileData);
+ }
+ }
+
+ function isColorSimilar(a, b, color){
+
+ var absDiff = Math.abs(a - b);
+
+ if(typeof a === 'undefined'){
+ return false;
+ }
+ if(typeof b === 'undefined'){
+ return false;
+ }
+
+ if(a === b){
+ return true;
+ } else if ( absDiff < tolerance[color] ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function isNumber(n) {
+ return !isNaN(parseFloat(n));
+ }
+
+ function isPixelBrightnessSimilar(d1, d2){
+ var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
+ var brightness = isColorSimilar(d1.brightness, d2.brightness, 'minBrightness');
+ return brightness && alpha;
+ }
+
+ function getBrightness(r,g,b){
+ return 0.3*r + 0.59*g + 0.11*b;
+ }
+
+ function isRGBSame(d1,d2){
+ var red = d1.r === d2.r;
+ var green = d1.g === d2.g;
+ var blue = d1.b === d2.b;
+ return red && green && blue;
+ }
+
+ function isRGBSimilar(d1, d2){
+ var red = isColorSimilar(d1.r,d2.r,'red');
+ var green = isColorSimilar(d1.g,d2.g,'green');
+ var blue = isColorSimilar(d1.b,d2.b,'blue');
+ var alpha = isColorSimilar(d1.a, d2.a, 'alpha');
+
+ return red && green && blue && alpha;
+ }
+
+ function isContrasting(d1, d2){
+ return Math.abs(d1.brightness - d2.brightness) > tolerance.maxBrightness;
+ }
+
+ function getHue(r,g,b){
+
+ r = r / 255;
+ g = g / 255;
+ b = b / 255;
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
+ var h;
+ var d;
+
+ if (max == min){
+ h = 0; // achromatic
+ } else{
+ d = max - min;
+ switch(max){
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+
+ return h;
+ }
+
+ function isAntialiased(sourcePix, data, cacheSet, verticalPos, horizontalPos, width){
+ var offset;
+ var targetPix;
+ var distance = 1;
+ var i;
+ var j;
+ var hasHighContrastSibling = 0;
+ var hasSiblingWithDifferentHue = 0;
+ var hasEquivilantSibling = 0;
+
+ addHueInfo(sourcePix);
+
+ for (i = distance*-1; i <= distance; i++){
+ for (j = distance*-1; j <= distance; j++){
+
+ if(i===0 && j===0){
+ // ignore source pixel
+ } else {
+
+ offset = ((verticalPos+j)*width + (horizontalPos+i)) * 4;
+ targetPix = getPixelInfo(data, offset, cacheSet);
+
+ if(targetPix === null){
+ continue;
+ }
+
+ addBrightnessInfo(targetPix);
+ addHueInfo(targetPix);
+
+ if( isContrasting(sourcePix, targetPix) ){
+ hasHighContrastSibling++;
+ }
+
+ if( isRGBSame(sourcePix,targetPix) ){
+ hasEquivilantSibling++;
+ }
+
+ if( Math.abs(targetPix.h - sourcePix.h) > 0.3 ){
+ hasSiblingWithDifferentHue++;
+ }
+
+ if( hasSiblingWithDifferentHue > 1 || hasHighContrastSibling > 1){
+ return true;
+ }
+ }
+ }
+ }
+
+ if(hasEquivilantSibling < 2){
+ return true;
+ }
+
+ return false;
+ }
+
+ function errorPixel(px, offset, data1, data2){
+ var data = errorPixelTransformer(data1, data2);
+ px[offset] = data.r;
+ px[offset + 1] = data.g;
+ px[offset + 2] = data.b;
+ px[offset + 3] = data.a;
+ }
+
+ function copyPixel(px, offset, data){
+ px[offset] = data.r; //r
+ px[offset + 1] = data.g; //g
+ px[offset + 2] = data.b; //b
+ px[offset + 3] = data.a * pixelTransparency; //a
+ }
+
+ function copyGrayScalePixel(px, offset, data){
+ px[offset] = data.brightness; //r
+ px[offset + 1] = data.brightness; //g
+ px[offset + 2] = data.brightness; //b
+ px[offset + 3] = data.a * pixelTransparency; //a
+ }
+
+ function getPixelInfo(data, offset, cacheSet){
+ var r;
+ var g;
+ var b;
+ var d;
+ var a;
+
+ r = data[offset];
+
+ if(typeof r !== 'undefined'){
+ g = data[offset+1];
+ b = data[offset+2];
+ a = data[offset+3];
+ d = {
+ r: r,
+ g: g,
+ b: b,
+ a: a
+ };
+
+ return d;
+ } else {
+ return null;
+ }
+ }
+
+ function addBrightnessInfo(data){
+ data.brightness = getBrightness(data.r,data.g,data.b); // 'corrected' lightness
+ }
+
+ function addHueInfo(data){
+ data.h = getHue(data.r,data.g,data.b);
+ }
+
+ function analyseImages(img1, img2, width, height){
+
+ var hiddenCanvas = document.createElement('canvas');
+
+ var data1 = img1.data;
+ var data2 = img2.data;
+
+ hiddenCanvas.width = width;
+ hiddenCanvas.height = height;
+
+ var context = hiddenCanvas.getContext('2d');
+ var imgd = context.createImageData(width,height);
+ var targetPix = imgd.data;
+
+ var mismatchCount = 0;
+ var diffBounds = {
+ top: height,
+ left: width,
+ bottom: 0,
+ right: 0
+ };
+ var updateBounds = function(x, y) {
+ diffBounds.left = Math.min(x, diffBounds.left);
+ diffBounds.right = Math.max(x, diffBounds.right);
+ diffBounds.top = Math.min(y, diffBounds.top);
+ diffBounds.bottom = Math.max(y, diffBounds.bottom);
+ }
+
+ var time = Date.now();
+
+ var skip;
+
+ if(!!largeImageThreshold && ignoreAntialiasing && (width > largeImageThreshold || height > largeImageThreshold)){
+ skip = 6;
+ }
+
+ loop(height, width, function(verticalPos, horizontalPos){
+
+ if(skip){ // only skip if the image isn't small
+ if(verticalPos % skip === 0 || horizontalPos % skip === 0){
+ return;
+ }
+ }
+
+ var offset = (verticalPos*width + horizontalPos) * 4;
+ var pixel1 = getPixelInfo(data1, offset, 1);
+ var pixel2 = getPixelInfo(data2, offset, 2);
+
+ if(pixel1 === null || pixel2 === null){
+ return;
+ }
+
+ if (ignoreColors){
+
+ addBrightnessInfo(pixel1);
+ addBrightnessInfo(pixel2);
+
+ if( isPixelBrightnessSimilar(pixel1, pixel2) ){
+ copyGrayScalePixel(targetPix, offset, pixel2);
+ } else {
+ errorPixel(targetPix, offset, pixel1, pixel2);
+ mismatchCount++;
+ updateBounds(horizontalPos, verticalPos);
+ }
+ return;
+ }
+
+ if( isRGBSimilar(pixel1, pixel2) ){
+ copyPixel(targetPix, offset, pixel1, pixel2);
+
+ } else if( ignoreAntialiasing && (
+ addBrightnessInfo(pixel1), // jit pixel info augmentation looks a little weird, sorry.
+ addBrightnessInfo(pixel2),
+ isAntialiased(pixel1, data1, 1, verticalPos, horizontalPos, width) ||
+ isAntialiased(pixel2, data2, 2, verticalPos, horizontalPos, width)
+ )){
+
+ if( isPixelBrightnessSimilar(pixel1, pixel2) ){
+ copyGrayScalePixel(targetPix, offset, pixel2);
+ } else {
+ errorPixel(targetPix, offset, pixel1, pixel2);
+ mismatchCount++;
+ updateBounds(horizontalPos, verticalPos);
+ }
+ } else {
+ errorPixel(targetPix, offset, pixel1, pixel2);
+ mismatchCount++;
+ updateBounds(horizontalPos, verticalPos);
+ }
+
+ });
+
+ data.misMatchPercentage = (mismatchCount / (height*width) * 100).toFixed(2);
+ data.diffBounds = diffBounds;
+ data.analysisTime = Date.now() - time;
+
+ data.getImageDataUrl = function(text){
+ var barHeight = 0;
+
+ if(text){
+ barHeight = addLabel(text,context,hiddenCanvas);
+ }
+
+ context.putImageData(imgd, 0, barHeight);
+
+ return hiddenCanvas.toDataURL("image/png");
+ };
+ }
+
+ function addLabel(text, context, hiddenCanvas){
+ var textPadding = 2;
+
+ context.font = '12px sans-serif';
+
+ var textWidth = context.measureText(text).width + textPadding*2;
+ var barHeight = 22;
+
+ if(textWidth > hiddenCanvas.width){
+ hiddenCanvas.width = textWidth;
+ }
+
+ hiddenCanvas.height += barHeight;
+
+ context.fillStyle = "#666";
+ context.fillRect(0,0,hiddenCanvas.width,barHeight -4);
+ context.fillStyle = "#fff";
+ context.fillRect(0,barHeight -4,hiddenCanvas.width, 4);
+
+ context.fillStyle = "#fff";
+ context.textBaseline = "top";
+ context.font = '12px sans-serif';
+ context.fillText(text, textPadding, 1);
+
+ return barHeight;
+ }
+
+ function normalise(img, w, h){
+ var c;
+ var context;
+
+ if(img.height < h || img.width < w){
+ c = document.createElement('canvas');
+ c.width = w;
+ c.height = h;
+ context = c.getContext('2d');
+ context.putImageData(img, 0, 0);
+ return context.getImageData(0, 0, w, h);
+ }
+
+ return img;
+ }
+
+ function compare(one, two){
+
+ function onceWeHaveBoth(){
+ var width;
+ var height;
+ if(images.length === 2){
+ width = images[0].width > images[1].width ? images[0].width : images[1].width;
+ height = images[0].height > images[1].height ? images[0].height : images[1].height;
+
+ if( (images[0].width === images[1].width) && (images[0].height === images[1].height) ){
+ data.isSameDimensions = true;
+ } else {
+ data.isSameDimensions = false;
+ }
+
+ data.dimensionDifference = { width: images[0].width - images[1].width, height: images[0].height - images[1].height };
+
+ analyseImages( normalise(images[0],width, height), normalise(images[1],width, height), width, height);
+
+ triggerDataUpdate();
+ }
+ }
+
+ images = [];
+ loadImageData(one, onceWeHaveBoth);
+ loadImageData(two, onceWeHaveBoth);
+ }
+
+ function getCompareApi(param){
+
+ var secondFileData,
+ hasMethod = typeof param === 'function';
+
+ if( !hasMethod ){
+ // assume it's file data
+ secondFileData = param;
+ }
- if( isPixelBrightnessSimilar(pixel1, pixel2) ){
- copyGrayScalePixel(targetPix, offset, pixel2);
- } else {
- errorPixel(targetPix, offset, pixel1, pixel2);
- mismatchCount++;
- }
- } else {
- errorPixel(targetPix, offset, pixel1, pixel2);
- mismatchCount++;
- }
+ var self = {
+ ignoreNothing: function(){
+
+ tolerance.red = 16;
+ tolerance.green = 16;
+ tolerance.blue = 16;
+ tolerance.alpha = 16;
+ tolerance.minBrightness = 16;
+ tolerance.maxBrightness = 240;
+
+ ignoreAntialiasing = false;
+ ignoreColors = false;
- });
+ if(hasMethod) { param(); }
+ return self;
+ },
+ ignoreAntialiasing: function(){
+
+ tolerance.red = 32;
+ tolerance.green = 32;
+ tolerance.blue = 32;
+ tolerance.alpha = 32;
+ tolerance.minBrightness = 64;
+ tolerance.maxBrightness = 96;
+
+ ignoreAntialiasing = true;
+ ignoreColors = false;
+
+ if(hasMethod) { param(); }
+ return self;
+ },
+ ignoreColors: function(){
+
+ tolerance.alpha = 16;
+ tolerance.minBrightness = 16;
+ tolerance.maxBrightness = 240;
+
+ ignoreAntialiasing = false;
+ ignoreColors = true;
+
+ if(hasMethod) { param(); }
+ return self;
+ },
+ repaint: function(){
+ if(hasMethod) { param(); }
+ return self;
+ },
+ onComplete: function( callback ){
+
+ updateCallbackArray.push(callback);
+
+ var wrapper = function(){
+ compare(fileData, secondFileData);
+ };
+
+ wrapper();
+
+ return getCompareApi(wrapper);
+ }
+ };
+
+ return self;
+ }
+
+ return {
+ onComplete: function( callback ){
+ updateCallbackArray.push(callback);
+ loadImageData(fileData, function(imageData, width, height){
+ parseImage(imageData.data, width, height);
+ });
+ },
+ compareTo: function(secondFileData){
+ return getCompareApi(secondFileData);
+ }
+ };
- data.misMatchPercentage = (mismatchCount / (height*width) * 100).toFixed(2);
- data.analysisTime = Date.now() - time;
-
- data.getImageDataUrl = function(text){
- var barHeight = 0;
-
- if(text){
- barHeight = addLabel(text,context,hiddenCanvas);
- }
-
- context.putImageData(imgd, 0, barHeight);
-
- return hiddenCanvas.toDataURL("image/png");
- };
- }
-
- function addLabel(text, context, hiddenCanvas){
- var textPadding = 2;
-
- context.font = '12px sans-serif';
-
- var textWidth = context.measureText(text).width + textPadding*2;
- var barHeight = 22;
-
- if(textWidth > hiddenCanvas.width){
- hiddenCanvas.width = textWidth;
- }
-
- hiddenCanvas.height += barHeight;
-
- context.fillStyle = "#666";
- context.fillRect(0,0,hiddenCanvas.width,barHeight -4);
- context.fillStyle = "#fff";
- context.fillRect(0,barHeight -4,hiddenCanvas.width, 4);
-
- context.fillStyle = "#fff";
- context.textBaseline = "top";
- context.font = '12px sans-serif';
- context.fillText(text, textPadding, 1);
-
- return barHeight;
- }
-
- function normalise(img, w, h){
- var c;
- var context;
-
- if(img.height < h || img.width < w){
- c = document.createElement('canvas');
- c.width = w;
- c.height = h;
- context = c.getContext('2d');
- context.putImageData(img, 0, 0);
- return context.getImageData(0, 0, w, h);
- }
-
- return img;
- }
-
- function compare(one, two){
-
- function onceWeHaveBoth(){
- var width;
- var height;
- if(images.length === 2){
- width = images[0].width > images[1].width ? images[0].width : images[1].width;
- height = images[0].height > images[1].height ? images[0].height : images[1].height;
-
- if( (images[0].width === images[1].width) && (images[0].height === images[1].height) ){
- data.isSameDimensions = true;
- } else {
- data.isSameDimensions = false;
- }
-
- data.dimensionDifference = { width: images[0].width - images[1].width, height: images[0].height - images[1].height };
-
- analyseImages( normalise(images[0],width, height), normalise(images[1],width, height), width, height);
-
- triggerDataUpdate();
- }
- }
-
- images = [];
- loadImageData(one, onceWeHaveBoth);
- loadImageData(two, onceWeHaveBoth);
- }
-
- function getCompareApi(param){
-
- var secondFileData,
- hasMethod = typeof param === 'function';
-
- if( !hasMethod ){
- // assume it's file data
- secondFileData = param;
- }
-
- var self = {
- ignoreNothing: function(){
-
- tolerance.red = 16;
- tolerance.green = 16;
- tolerance.blue = 16;
- tolerance.alpha = 16;
- tolerance.minBrightness = 16;
- tolerance.maxBrightness = 240;
-
- ignoreAntialiasing = false;
- ignoreColors = false;
-
- if(hasMethod) { param(); }
- return self;
- },
- ignoreAntialiasing: function(){
-
- tolerance.red = 32;
- tolerance.green = 32;
- tolerance.blue = 32;
- tolerance.alpha = 32;
- tolerance.minBrightness = 64;
- tolerance.maxBrightness = 96;
-
- ignoreAntialiasing = true;
- ignoreColors = false;
-
- if(hasMethod) { param(); }
- return self;
- },
- ignoreColors: function(){
-
- tolerance.alpha = 16;
- tolerance.minBrightness = 16;
- tolerance.maxBrightness = 240;
-
- ignoreAntialiasing = false;
- ignoreColors = true;
-
- if(hasMethod) { param(); }
- return self;
- },
- repaint: function(){
- if(hasMethod) { param(); }
- return self;
- },
- onComplete: function( callback ){
-
- updateCallbackArray.push(callback);
-
- var wrapper = function(){
- compare(fileData, secondFileData);
- };
-
- wrapper();
-
- return getCompareApi(wrapper);
- }
- };
-
- return self;
- }
-
- return {
- onComplete: function( callback ){
- updateCallbackArray.push(callback);
- loadImageData(fileData, function(imageData, width, height){
- parseImage(imageData.data, width, height);
- });
- },
- compareTo: function(secondFileData){
- return getCompareApi(secondFileData);
- }
- };
-
- };
-
- _this['resemble'].outputSettings = function(options){
- var key;
- var undefined;
-
- if(options.errorColor){
- for (key in options.errorColor) {
- errorPixelColor[key] = options.errorColor[key] === undefined ? errorPixelColor[key] : options.errorColor[key];
- }
- }
-
- if(options.errorType && errorPixelTransform[options.errorType] ){
- errorPixelTransformer = errorPixelTransform[options.errorType];
- }
-
- pixelTransparency = options.transparency || pixelTransparency;
-
- return this;
- };
-
-}(this)); \ No newline at end of file
+ };
+
+ _this['resemble'].outputSettings = function(options){
+ var key;
+ var undefined;
+
+ if(options.errorColor){
+ for (key in options.errorColor) {
+ errorPixelColor[key] = options.errorColor[key] === undefined ? errorPixelColor[key] : options.errorColor[key];
+ }
+ }
+
+ if(options.errorType && errorPixelTransform[options.errorType] ){
+ errorPixelTransformer = errorPixelTransform[options.errorType];
+ }
+
+ pixelTransparency = isNaN(Number(options.transparency)) ? pixelTransparency : options.transparency;
+
+ if (options.largeImageThreshold !== undefined) {
+ largeImageThreshold = options.largeImageThreshold;
+ }
+
+ return this;
+ };
+
+}(this));
diff --git a/tests/lib/screenshot-testing/support/test-environment.js b/tests/lib/screenshot-testing/support/test-environment.js
index 9379ab88da..8a8dc183bf 100644
--- a/tests/lib/screenshot-testing/support/test-environment.js
+++ b/tests/lib/screenshot-testing/support/test-environment.js
@@ -153,6 +153,9 @@ TestingEnvironment.prototype.setupFixture = function (fixtureClass, done) {
self.reload();
self.addPluginOnCmdLineToTestEnv();
+ self.fixtureClass = fixtureClass;
+ self.save();
+
console.log();
if (code) {
diff --git a/tests/travis/travis.sh b/tests/travis/travis.sh
index fcdcbfff1c..2696abe897 100755
--- a/tests/travis/travis.sh
+++ b/tests/travis/travis.sh
@@ -43,15 +43,21 @@ then
echo ""
echo "http://builds-artifacts.piwik.org/$artifacts_folder/$TRAVIS_JOB_NUMBER/screenshot-diffs/diffviewer.html"
echo ""
- echo "If the new screenshots are valid, then you can copy them over to tests/UI/expected-ui-screenshots/"
+ echo "If the new screenshots are valid, then you can copy them over to the right directory with the command:"
+ echo ""
+ echo "./console development:sync-ui-test-screenshots $TRAVIS_JOB_NUMBER"
if [ -n "$PLUGIN_NAME" ]
then
- echo " with command:"
- echo ""
- echo "./console development:sync-ui-test-screenshots $TRAVIS_JOB_NUMBER"
- echo ""
+ echo " --plugin=$PLUGIN_NAME"
+
+ if [ "$UNPROTECTED_ARTIFACTS" = "" ];
+ then
+ echo " --http-user=... --http-password=..."
+ fi
fi
+
+ echo ""
if [ -n "$PLUGIN_NAME" ]
then