Created
October 4, 2017 16:32
-
-
Save maggiesavovska/3002573f6bec1085a1dee888e0563348 to your computer and use it in GitHub Desktop.
screenshot and image diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @description | |
* Takes a screenshot of page. | |
* Stores screenshot url to be embedded in reporter | |
* Runs image diff | |
* @param {Object} options | |
* @param {Object} options.test - test object | |
* @param {String} [options.filename = 'screenshot'] - keyword for screenshot filename | |
* @param {String} options.filepath - path to folder where screenshots are stored | |
* @param {Bool} options.element - provide element selector if only element should be captured | |
*/ | |
const sanitize = require('sanitize-filename'); | |
const wdioScreenshot = require('wdio-screenshot'); | |
const addContext = require('./addContext.es6').addContext; | |
const runGenerator = require('./run-generator.es6').runGenerator; | |
const resemble = require('node-resemble-js'); | |
function scale(shrink, element){ | |
// adjust scale to length of page | |
let pageHeight = 1500; | |
process.driver.execute(function(){ | |
var body = document.body, | |
html = document.documentElement; | |
var pageHeight = Math.max( body.scrollHeight, body.offsetHeight, | |
html.clientHeight, html.scrollHeight, html.offsetHeight ); | |
return pageHeight; | |
}).then(function(res){ | |
pageHeight = res; | |
}).catch(function(e){ | |
console.log(e); | |
}); | |
let scalePercent = '.40'; | |
if(pageHeight > 1000){ | |
scalePercent = '.30'; | |
} | |
if(pageHeight > 1500){ | |
scalePercent = '.20'; | |
} | |
var s = ''; | |
// if wdio screenshot not compatible | |
// scale page to get full screenshot | |
// scale more for mobile | |
if(!shrink){ | |
s = 'scale(1)'; | |
}else{ | |
if(element){ | |
s = 'scale(10)'; | |
}else{ | |
s = 'scale(' + scalePercent + ')'; | |
} | |
} | |
if(element){ | |
process.driver.execute(function(s, el, shrink){ | |
$(el).css({ | |
transform: s | |
}); | |
if(shrink){ | |
$(el).css({ | |
'z-index': 1000, | |
position: 'fixed', | |
top:'40%', | |
left:'40%' | |
}); | |
}else{ | |
$(el).css({ | |
transform:'scale(1)', | |
'z-index': 'inherit', | |
position: 'static', | |
top:'inherit', | |
left:'inherit' | |
}); | |
} | |
//$(el)[0].scrollIntoView(); | |
return 'done scaling'; | |
}, s, element, shrink); | |
}else{ | |
process.driver.execute(function(scale){ | |
$('body').css({ | |
transform: scale, | |
transformOrigin: 'left top' | |
}); | |
return 'done scaling'; | |
}, s); | |
} | |
}; | |
exports.screenshot = function (options) { | |
console.log('in screenshot'); | |
const addData = options.data == undefined ? {} : options.data; | |
let data; | |
return new Promise(function (resolve, reject) { | |
runGenerator(function *main(){ | |
try{ | |
let filename = options.filename + `_${process.cbProcessData.country}_`; | |
// file name cannot be too long or won't display on windows | |
filename = sanitize(filename).replace(/\s/g, '_') + utils.getDateStamp(); | |
let p = `${options.filepath + filename}.png`; | |
let rp = path.normalize(`./screenshots/${filename}.png`); | |
if(addData){ | |
data = Object.assign(addData, {spath:rp}); | |
}else{ | |
data = {spath:rp}; | |
} | |
const driver = process.driver; | |
if(options.imageDiff == true){ | |
// click on a non actionable element | |
// to make sure there is no hover state that will affect the diff | |
try{ | |
const headlineVisible = yield process.driver.isVisible('div.blockHeadline'); | |
if(headlineVisible){ | |
yield process.driver.click('div.blockHeadline'); | |
} | |
}catch(e){ | |
console.log(e); | |
} | |
yield process.driver.pause(300); | |
const suiteDiffDir = path.join('./results/', options.suiteName); | |
const suiteDiffScreenshotDir = path.join(suiteDiffDir + '/screenshots'); | |
const screenshotDiffName = path.join(suiteDiffScreenshotDir, `${options.filename}.png`); | |
var hideElement = function(selectors, hide){ | |
var style; | |
for(var i = 0; i < selectors.length; i++){ | |
var s = selectors[i]; | |
var pid = document.querySelector(s); | |
if(pid){ | |
if(hide){ | |
pid.style['opacity'] = 0; | |
}else{ | |
pid.style['opacity'] = 1; | |
} | |
style = pid.style; | |
} | |
} | |
return style; | |
}; | |
var selectors = ['#cleverPurchaseId .accentuate', | |
'.cbProductActions a.CBHyperLink']; | |
// hide elements that create false positives | |
var d = yield driver.execute(hideElement, selectors, true); | |
var screenshotString = yield wdioScreenshot.makeDocumentScreenshot(driver, {}); | |
var screenshot = new Buffer(screenshotString, 'base64'); | |
// check if file already exists from last run | |
// if file doesn't exist create it | |
if(!fs.existsSync(screenshotDiffName)) { | |
if(!fs.existsSync(suiteDiffDir)){ | |
fs.mkdirSync(suiteDiffDir); | |
fs.mkdirSync(suiteDiffScreenshotDir); | |
} | |
fs.writeFileSync(screenshotDiffName, screenshot); | |
return resolve(); | |
} else{ | |
// if previous file exists then do a diff | |
// if previous file exists then do a diff | |
resemble(screenshotDiffName) | |
.compareTo(screenshot) | |
.onComplete(function(data){ | |
if (Number(data.misMatchPercentage) <= 0.01) { | |
return resolve(); | |
} else { | |
const diffShotPath = path.join(options.filepath, `diff_${options.filename}.png`); | |
//save to report | |
data.getDiffImage().pack().pipe(fs.createWriteStream(diffShotPath)); | |
const embedLink = path.normalize(`./screenshots/diff_${options.filename}.png`); | |
const edata = Object.assign({spath:embedLink}, data); | |
addContext(options.test, edata); | |
return resolve(); | |
} | |
}); | |
} | |
yield driver.execute(hideElement, selectors, false); | |
} else if(options.screenshot !== false){ | |
if (options.element && !process.cbProcessData.ie8 && !options.forceScale) { | |
console.log('element screenshot'); | |
yield wdioScreenshot.saveElementScreenshot(p, options.element, driver, {}); | |
addContext(options.test, data); | |
return resolve(); | |
} else if(options.element && !process.cbProcessData.ie8 && options.forceScale){ | |
console.log('element screenshot scale'); | |
scale(true, options.element); | |
yield process.driver.pause(300); | |
yield process.driver.saveScreenshot(p); | |
scale(false); | |
addContext(options.test, data); | |
return resolve(); | |
}else if((process.cbProcessData.macos && process.cbProcessData.cloud && !process.cbProcessData.isMobile) || options.forceScale){ | |
console.log('scale..'); | |
// scale page for browsers that don't take full page screenshots | |
// also scale for mac os in cloud | |
scale(true); | |
yield process.driver.saveScreenshot(p); | |
scale(false); | |
addContext(options.test, data); | |
return resolve(); | |
}else if(process.cbProcessData.ie8){ | |
console.log('save screenshot'); | |
yield process.driver.saveScreenshot(p); | |
addContext(options.test, data); | |
return resolve(); | |
}else{ | |
console.log('save document screenshot'); | |
yield wdioScreenshot.saveDocumentScreenshot(p, driver, {}); | |
console.log('screenshot done'); | |
addContext(options.test, data); | |
console.log('add context done'); | |
return resolve(); | |
} | |
} | |
}catch(err){ | |
console.log(err); | |
reject(); | |
} | |
});//end | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment