UNPKG

muxley

Version:
247 lines (206 loc) 7.24 kB
'use strict'; var colors = require('colors'); var fs = require('fs'); var mkdirp = require('mkdirp'); var path = require('path'); var browser = require('./source/browser/driver'); var consts = require('./source/constants'); var defaultDoneCallback = require('./source/defaultDoneCallback'); var playback = require('./source/playback'); var record = require('./source/record'); var getPlaybackInfos = require('./source/playback/getPlaybackInfos'); // TODO: integration with remote environment // whenever 'path' is mentioned and it concerns a file, the file's name itself // isn't included // flow: // recordTasks: // _recordTasks -> getPlaybackInfos -> _openRunAndClose -> _runEachPlayback -> // _runActionOrDisplaySkipMsg -> _recordAndSave -> record -> // _saveTaskAsJsonToFolder -> _runActionOrDisplaySkipMsg // playbackTasksAndCompareScreenshots: // _playbackTasksAndXScreenshots -> getPlaybackInfos -> _openRunAndClose -> // _runEachPlayback -> _runActionOrDisplaySkipMsg -> playback -> // _runActionOrDisplaySkipMsg function _saveTaskAsJsonToFolder(recordPath, taskEvents, next) { mkdirp(recordPath, function(err) { if (err) return next(err); // prettify, 2-space indent json + line feed fs.writeFile( path.join(recordPath, consts.RECORD_FILE_NAME), JSON.stringify(taskEvents, null, 2) + '\n', next ); }); } function _recordAndSave(playbackInfo, next) { record(playbackInfo.driver, function(err, allEvents) { _saveTaskAsJsonToFolder(playbackInfo.recordPath, allEvents, next); }); } function _runEachPlayback(playbackInfos, action, next) { var currentIndex = 0; _runActionOrDisplaySkipMsg( playbackInfos[currentIndex], action, function _next(err) { if (err) return next(err); if (currentIndex === playbackInfos.length - 1) return next(); _runActionOrDisplaySkipMsg(playbackInfos[++currentIndex], action, _next); } ); } // does nothing but open and close the browser and handle its errors // needs to know nothing but a command to run in-between, and the callback function _openRunAndClose(playbackInfos, openDummy, action, next) { // playbackInfos all have the same browserName. Arbitrarily choose the first var browserName = playbackInfos[0].browserName; var serverUrl = playbackInfos[0].serverUrl; browser.open(browserName, serverUrl, function(err, driver) { if (err) { if (driver == null) return next(err); return browser.quit(driver, function(err2) { next(err || err2 || null); }); } playbackInfos.forEach(function(info) { info.driver = driver; }); if (openDummy) { return browser.openDummy(browserName, serverUrl, function(err, dummyDriver) { process.on('SIGINT', function() { browser.quit(driver, function() { browser.quit(dummyDriver, process.exit); }); }); if (err) { return browser.quit(dummyDriver, function(err2) { next(err || err2 || null); }); } action(function(err) { browser.quit(driver, function(err2) { browser.quit(dummyDriver, function(err3) { next(err || err2 || err3 || null); }); }); }); }); } else { process.on('SIGINT', function() { browser.quit(driver, process.exit); }); action(function(err) { browser.quit(driver, function(err2) { next(err || err2 || null); }); }); } }); } function _runActionOrDisplaySkipMsg(playbackInfo, action, next) { console.log( '\nAt %s'.underline, path.relative(process.cwd(), playbackInfo.recordPath) ); if (playbackInfo.isSkipped) { console.log('Marked as skipped.'); return next(); } var browserChromeWidth; var browserChromeHeight; if (playbackInfo.browserName === 'firefox') { // for FF, one place where quirks show up is when (page scrolls to the // bottom && browser exceeds max monitor screen size): say, for height, // viewport ~600, screenSize 700, scrollY 1000, page height 1600. If we // naively cut at scrollY til bottom, we don't get the 700 we want. This is // fixed in playback @ _simulateScreenshot, for config top/left browserChromeWidth = consts.FIREFOX_CHROME_SIZE[0]; browserChromeHeight = consts.FIREFOX_CHROME_SIZE[1]; } else { // assume Chrome browserChromeWidth = consts.CHROME_CHROME_SIZE[0]; browserChromeHeight = consts.CHROME_CHROME_SIZE[1]; } browser.goToUrl( playbackInfo.driver, playbackInfo.url, playbackInfo.screenSize[0] + browserChromeWidth, playbackInfo.screenSize[1] + browserChromeHeight, function(err) { action(playbackInfo, next); } ); } function _recordTasks(browserName, serverUrl, globs, next) { _getRunnableRecords(globs, false, function(err, playbackInfos) { if (err) return next(err); playbackInfos.forEach(function(info) { info.browserName = browserName; info.serverUrl = serverUrl; }); _openRunAndClose( playbackInfos, false, _runEachPlayback.bind(null, playbackInfos, _recordAndSave), next ); }); } // where `x` is either compare or update screenshot function _playbackTasksAndXScreenshots( browserName, serverUrl, globs, saveInsteadOfCompare, next ) { _getRunnableRecords(globs, true, function(err, playbackInfos) { if (err) return next(err); playbackInfos.forEach(function(info) { info.browserName = browserName; info.overrideScreenshots = saveInsteadOfCompare; info.serverUrl = serverUrl; }); _openRunAndClose( playbackInfos, true, _runEachPlayback.bind(null, playbackInfos, playback), next ); }); } function _getRunnableRecords(globs, loadRecords, next) { if (!globs.length) globs = ['**/']; getPlaybackInfos(globs, loadRecords, function(err, playbackInfos) { if (err) return next(err); var hasRunnableRecords = playbackInfos.some(function(info) { return !info.isSkipped; }); if (!hasRunnableRecords) { return next('Every task is marked as skipped.'); } next(null, playbackInfos); }); } function recordTasks(browserName, serverUrl, globs, next) { browserName = browserName || 'firefox'; _recordTasks(browserName, serverUrl, globs, function(err) { if (err) return next(err); console.log('\nDon\'t move! Simulating the recording now...'.yellow); playbackTasksAndSaveScreenshots(browserName, serverUrl, globs, next); }); } function playbackTasksAndCompareScreenshots(browserName, serverUrl, globs, next) { browserName = browserName || 'firefox'; _playbackTasksAndXScreenshots(browserName, serverUrl, globs, false, next); } function playbackTasksAndSaveScreenshots(browserName, serverUrl, globs, next) { browserName = browserName || 'firefox'; _playbackTasksAndXScreenshots(browserName, serverUrl, globs, true, next); } module.exports = { injectDriver: browser.injectDriver, recordTasks: recordTasks, playbackTasksAndSaveScreenshots: playbackTasksAndSaveScreenshots, playbackTasksAndCompareScreenshots: playbackTasksAndCompareScreenshots, defaultDoneCallback: defaultDoneCallback };