UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

241 lines (188 loc) 8.33 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ !function () { var fs = require('fs') var fse = require('fs-extra') var path = require('path'); var child_process = require('child_process'); Role('Siesta.Launcher.Page.CanWorkWithImagesNodeJS', { has : { similarityThreshold : 0.85, commandInstalledCache : Joose.I.Object }, methods : { fileExistsInPath : function (fileName) { if (this.commandInstalledCache.hasOwnProperty(fileName)) return this.commandInstalledCache[ fileName ] var envPath = process.env.PATH || '' var envPaths = envPath.split(/:|;/) var exists = false Joose.A.each(envPaths, function (envPath) { if (fs.existsSync(path.resolve(envPath, fileName))) { exists = true return false } }) return this.commandInstalledCache[ fileName ] = exists }, // promised method runImageMagickCommand : function (command, argv, acceptNonZeroExitCode) { var me = this var launcher = this.launcher return new Promise(function (callback, errback) { var fileName = command + (launcher.isWindows ? '.exe' : '') if (!me.fileExistsInPath(fileName)) { fileName = launcher.binDir + '/binary/imagemagick/' + launcher.getPlatformId() + '/' + fileName } child_process.execFile( fileName, argv, {}, function (error, stdout, stderr) { var output = "STDOUT:\n" + (stdout || '') + "\nSTDERR:\n" + (stderr || '') var exitCode = error == null ? 0 : error.code me.debug("IMGCK command: " + command + ', exitCode: ' + exitCode + ', args: ' + argv.join(' ') + ', output: ' + output) if (error == null || acceptNonZeroExitCode) callback({ exitCode : exitCode, stdout : stdout, stderr : stderr }) else errback({ exitCode : exitCode, stdout : stdout, stderr : stderr }) } ) }) }, // promised method extentImage : function (fileName, width, height) { // ssi - siesta screenshot image var tempFileName = require('tmp').fileSync({ prefix : 'ssi' }).name return this.runImageMagickCommand('convert', [ '-background', 'none', '-gravity', 'NorthWest', '-extent', width + 'x' + height, fileName, tempFileName ]).then(function () { return tempFileName }) }, // promised method cropImage : function (fileName, x, y, width, height) { // ssi - siesta screenshot image var tempFileName = require('tmp').fileSync({ prefix : 'ssi' }).name return this.runImageMagickCommand('convert', [ '-extract', width + 'x' + height + '+' + x + '+' + y, fileName, tempFileName ]).then(function () { return tempFileName }) }, // promised method getPNGImageSize : function (fileName) { var PNG = require('pngjs').PNG; return new Promise(function (resolve, reject) { var png = new PNG({}) png.on('metadata', function (metadata) { resolve({ width : metadata.width, height : metadata.height }) }) png.on('error', function (error) { reject(error) }) fs.createReadStream(fileName).pipe(png) }) // return this.runImageMagickCommand('identify', [ // fileName, // '-format', '%w %h' // ]).then(function (res) { // var match = /(\d+) (\d+)/.exec(res.stdout) // // return { // width : Number(match[ 1 ]), // height : Number(match[ 2 ]) // } // }) }, // promised method equalizeImageSizes : function (fileName1, fileName2) { var me = this return Promise.all([ this.getPNGImageSize(fileName1), this.getPNGImageSize(fileName2) ]).then(function (results) { var image1 = results[ 0 ] var image2 = results[ 1 ] if (image1 instanceof Error || image2 instanceof Error) throw new Error("Something went wrong") var maxWidth = Math.max(image1.width, image2.width) var maxHeight = Math.max(image1.height, image2.height) if ( image1.width != maxWidth || image2.width != maxWidth || image1.height != maxHeight || image2.height != maxHeight ) { return Promise.all([ me.extentImage(fileName1, maxWidth, maxHeight), me.extentImage(fileName2, maxWidth, maxHeight) ]).then(function (results) { return { image1 : results[ 0 ], image2 : results[ 1 ] } }) } else { return { image1 : fileName1, image2 : fileName2 } } }) }, // promised method compareImages : function (image1, image2, diffImage, options) { var me = this return this.equalizeImageSizes(image1, image2).then(function (files) { options = Joose.O.extend(me.dispatcher.screenshotCompareConfig || { fuzz : '5%', metric : 'NCC', compose : 'src-over', 'highlight-color' : '#e500f4' }, options || {}) var argv = [] Joose.O.each(options, function (value, name) { if (!/^\$/.test(name)) { argv.push('-' + name) argv.push(value) } }) argv.push(files.image1, files.image2, diffImage) return me.runImageMagickCommand('compare', argv, true).then(function (res) { res.similar = res.exitCode != 2 && Number(res.stderr) > (options.$similarityThreshold || me.similarityThreshold) res.similarity = Number(res.stderr) return res }) }) }, // promised method scaleImage : function (buffImage, scale) { throw "Not implemented" // var scaleTransform = java.awt.geom.AffineTransform.getScaleInstance(scale, scale) // // var scaleTransformOp = new java.awt.image.AffineTransformOp(scaleTransform, java.awt.image.AffineTransformOp.TYPE_BICUBIC) // // var newWidth = Math.ceil(buffImage.getWidth() * scale) // var newHeight = Math.ceil(buffImage.getHeight() * scale) // // return scaleTransformOp.filter(buffImage, new java.awt.image.BufferedImage(newWidth, newHeight, buffImage.getType())) } } // eof methods }) }();