| // This script assumes the following: |
| // 1. You've installed wd with `npm install wd'. |
| // 2. You've set the environment variables $SAUCE_USERNAME and $SAUCE_ACCESS_KEY. |
| // 3. If the environment variable $CIRCLE_ARTIFACTS is not set images will be saved in /tmp |
| // |
| // This scripts creates following files for each browser in browserVersions: |
| // $CIRCLE_ARTIFACTS/imgs/{browser_version_platform}/#.png |
| // |
| // The intention of this script is that it will be ran from CircleCI |
| // |
| // Example usage: |
| // node screenshots.js http://localhost:9292/test/visual.html |
| // node screenshots.js http://google.com |
| |
| var wd = require('wd'); |
| var fs = require('fs'); |
| var username = process.env['SAUCE_USERNAME']; |
| var accessKey = process.env['SAUCE_ACCESS_KEY']; |
| var baseDir = process.env['CIRCLE_ARTIFACTS'] || '/tmp'; |
| var url = process.argv[2]; |
| var allImgsDir = baseDir+'/imgs'; |
| var build_name = 'CircleCI build #' + process.env.CIRCLE_BUILD_NUM; |
| if (process.env.CIRCLE_PR_NUMBER) { |
| build_name += ': PR #' + process.env.CIRCLE_PR_NUMBER; |
| if (process.env.CIRCLE_BRANCH) build_name += ' (' + process.env.CIRCLE_BRANCH + ')'; |
| } else { |
| build_name += ': ' + process.env.CIRCLE_BRANCH; |
| } |
| build_name += ' @ ' + process.env.CIRCLE_SHA1.slice(0, 7); |
| |
| fs.mkdirSync(allImgsDir); |
| |
| var browserVersions = [ |
| { |
| 'version': { |
| // Expecting IE 8 |
| 'browserName': 'Internet Explorer', |
| 'platform': 'Windows XP' |
| }, |
| 'pinned': 'PINNED' |
| }, |
| { |
| 'version': { |
| // Expecting IE 11 |
| 'browserName': 'Internet Explorer', |
| 'platform': 'Windows 7' |
| }, |
| 'pinned': 'PINNED' |
| }, |
| { |
| 'version': { |
| 'browserName': 'MicrosoftEdge', |
| 'platform': 'Windows 10' |
| }, |
| 'pinned': 'EVERGREEN' |
| }, |
| { |
| 'version': { |
| 'browserName': 'Firefox', |
| 'platform': 'OS X 10.11' |
| }, |
| 'pinned': 'EVERGREEN' |
| }, |
| { |
| 'version': { |
| 'browserName': 'Safari', |
| 'platform': 'OS X 10.11' |
| }, |
| 'pinned': 'EVERGREEN' |
| }, |
| { |
| 'version': { |
| 'browserName': 'Chrome', |
| 'platform': 'OS X 10.11' |
| }, |
| 'pinned': 'EVERGREEN' |
| }, |
| { |
| 'version': { |
| 'browserName': 'Firefox', |
| 'platform': 'Linux' |
| }, |
| 'pinned': 'EVERGREEN' |
| }, |
| ]; |
| |
| |
| browserVersions.forEach(function(obj) { |
| var cfg = obj.version; |
| cfg.build = build_name; |
| var browserDriver = wd.promiseChainRemote('ondemand.saucelabs.com', 80, username, accessKey); |
| return browserDriver.init(cfg) |
| .then(function(_, capabilities) { |
| console.log(cfg.browserName,cfg.platform,'init'); |
| |
| var browser = cfg.browserName.replace(/\s/g, '_'); |
| var platform = cfg.platform.replace(/\s/g, '_'); |
| var piecesDir = allImgsDir+'/'+obj.pinned+'_'+platform+'_'+browser; |
| fs.mkdirSync(piecesDir); |
| |
| return browserDriver; |
| }) |
| .get(url) |
| .then(function() { |
| console.log(cfg.browserName,cfg.platform,'get'); |
| return [browserDriver.safeExecute('document.documentElement.scrollHeight'), |
| browserDriver.safeExecute('document.documentElement.clientHeight')]; |
| }) |
| .spread(function(scrollHeight, viewportHeight) { |
| console.log(cfg.browserName, cfg.platform, 'get scrollHeight, clientHeight', scrollHeight, viewportHeight); |
| |
| // Firefox and Internet Explorer will take a screenshot of the entire webpage, |
| if (cfg.browserName != 'Safari' && cfg.browserName != 'Chrome' && cfg.browserName != 'MicrosoftEdge') { |
| // saves file in the file `piecesDir/browser_version_platform/*.png` |
| var filename = piecesDir+'/'+browser+'_'+platform+'.png'; |
| console.log(cfg.browserName, cfg.platform, 'about to saveScreenshot'); |
| return browserDriver.saveScreenshot(filename) |
| .then(willLog(cfg.browserName,cfg.platform,'saveScreenshot')) |
| .log('browser') |
| .then(function(logs) { |
| console.log(cfg.browserName,cfg.platform,'log'); |
| |
| var logfile = baseDir+'/'+browser+'_'+platform+'.log' |
| logs = logs || []; |
| return new Promise(function(resolve, reject) { |
| fs.writeFile(logfile,logs.join('\n'), function(err) { |
| if (err) return reject(err); |
| |
| return resolve(browserDriver.quit()); |
| }); |
| }); |
| }); |
| } else { |
| var scrollTop = 0; |
| |
| // loop generates the images. Firefox and Internet Explorer will take |
| // a screenshot of the entire webpage, but Opera, Safari, and Chrome |
| // do not. For those browsers we scroll through the page and take |
| // incremental screenshots. |
| return (function loop() { |
| var index = (scrollTop/viewportHeight) + 1; |
| // saves file in the file `piecesDir/browser_version_platform/#.png` |
| var filename = piecesDir+'/'+index+'.png'; |
| |
| // Use `window.scrollTo` because thats what jQuery does |
| // https://github.com/jquery/jquery/blob/1.12.3/src/offset.js#L186 |
| // `window.scrollTo` was used instead of jQuery because jQuery was |
| // causing a stackoverflow in Safari. |
| return browserDriver.safeEval('window.scrollTo(0,'+scrollTop+');') |
| .then(willLog(cfg.browserName,cfg.platform,'safeEval 1')) |
| .saveScreenshot(filename) |
| .then(function() { |
| console.log(cfg.browserName,cfg.platform,'saveScreenshot'); |
| |
| scrollTop += viewportHeight; |
| if (scrollTop + viewportHeight > scrollHeight) { |
| return browserDriver.getWindowSize() |
| .then(function(size) { |
| console.log(cfg.browserName,cfg.platform,'getWindowSize'); |
| // account for the viewport offset |
| var extra = size.height - viewportHeight; |
| return browserDriver.setWindowSize(size.width, (scrollHeight-scrollTop)+extra) |
| .then(willLog(cfg.browserName,cfg.platform,'setWindowSize')) |
| .safeEval('window.scrollTo(0,'+scrollHeight+');') |
| .then(function() { |
| console.log(cfg.browserName,cfg.platform,'safeEval 2'); |
| |
| index++; |
| var filename = piecesDir+'/'+index+'.png'; |
| return browserDriver.saveScreenshot(filename) |
| .then(willLog(cfg.browserName,cfg.platform,'saveScreenshot Final')) |
| .log('browser') |
| .then(function(logs) { |
| console.log(cfg.browserName,cfg.platform,'log'); |
| |
| var logfile = baseDir+'/'+browser+'_'+platform+'.log' |
| logs = logs || []; |
| return new Promise(function(resolve, reject) { |
| fs.writeFile(logfile,logs.join('\n'), function(err) { |
| if (err) return reject(err); |
| console.log(cfg.browserName,cfg.platform,'writeFile'); |
| |
| return resolve(browserDriver.quit()); |
| }); |
| }); |
| }); |
| }); |
| }); |
| } else { |
| return loop(); |
| } |
| }); |
| })(); |
| } |
| }) |
| .fail(function(err) { |
| console.log(JSON.stringify(obj, null, 2)); |
| }); |
| |
| function willLog() { |
| var msg = [].join.call(arguments); |
| return function() { |
| console.log(msg); |
| return browserDriver; |
| }; |
| } |
| }); |