diff --git a/lib/wraith/gallery.rb b/lib/wraith/gallery.rb index b764dc9a..4017ceca 100755 --- a/lib/wraith/gallery.rb +++ b/lib/wraith/gallery.rb @@ -192,8 +192,10 @@ def check_failed_shots end def prompt_user_to_open_gallery(dest) + gallery_url = "file://#{Dir.pwd}/#{dest}" logger.info "\nView the gallery in your browser:" - logger.info "\t file://" + Dir.pwd + "/" + dest + logger.info "\t #{gallery_url}" + `open #{gallery_url}` end class ErbBinding < OpenStruct diff --git a/lib/wraith/javascript/_helper.js b/lib/wraith/javascript/_helper.js index 12f2bb04..d6a922d2 100644 --- a/lib/wraith/javascript/_helper.js +++ b/lib/wraith/javascript/_helper.js @@ -6,7 +6,7 @@ module.exports = function (commandLineDimensions) { dimensions = /(\d*)x?((\d*))?/i.exec(dimensions); return { 'viewportWidth': parseInt(dimensions[1]), - 'viewportHeight': parseInt(dimensions[2] || 1500) + 'viewportHeight': parseInt(dimensions[2] || false) }; } diff --git a/lib/wraith/javascript/casper.js b/lib/wraith/javascript/casper.js index 5236de0b..f64d5599 100644 --- a/lib/wraith/javascript/casper.js +++ b/lib/wraith/javascript/casper.js @@ -11,7 +11,7 @@ var url = casper.cli.get(0), globalBeforeCaptureJS = casper.cli.get(4), pathBeforeCaptureJS = casper.cli.get(5), dimensionsProcessed = 0, - currentDimensions; + currentDimensions = dimensions; // functions function requireRelative(file) { @@ -23,11 +23,33 @@ function requireRelative(file) { currentFilePath = fs.absolute(currentFilePath.join('/')); return require(currentFilePath + '/' + file); } + +function setViewportHeight() { + if (!currentDimensions.viewportHeight) { + currentDimensions.viewportHeight = 1500; + } +} + function snap() { - console.log('Snapping ' + url + ' at: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); + // dynamic height calculation not possible in non-JavaScript mode + var documentHeight = this.evaluate(function () { + return document.body.offsetHeight; + }) || false; + + if (!documentHeight) { + documentHeight = 1500; + console.log('Could not dynamically determine document height.'); + } + + console.log('Snapping ' + url + ' at: ' + currentDimensions.viewportWidth + 'x' + documentHeight); if (!selector) { - this.capture(image_name); + this.capture(image_name, { + top: 0, + left: 0, + width: currentDimensions.viewportWidth, + height: documentHeight + }); } else { this.captureSelector(image_name, selector); @@ -36,6 +58,7 @@ function snap() { dimensionsProcessed++; if (helper.takingMultipleScreenshots(dimensions) && dimensionsProcessed < dimensions.length) { currentDimensions = dimensions[dimensionsProcessed]; + setViewportHeight(); image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); casper.viewport(currentDimensions.viewportWidth, currentDimensions.viewportHeight); casper.wait(300, function then () { @@ -46,11 +69,11 @@ function snap() { if (helper.takingMultipleScreenshots(dimensions)) { currentDimensions = dimensions[0]; + setViewportHeight(); image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); } -else { - currentDimensions = dimensions; -} + +setViewportHeight(); // Casper can now do its magic casper.start(); diff --git a/lib/wraith/javascript/phantom-helpers/default_settings.js b/lib/wraith/javascript/phantom-helpers/default_settings.js new file mode 100644 index 00000000..3a3c9d2b --- /dev/null +++ b/lib/wraith/javascript/phantom-helpers/default_settings.js @@ -0,0 +1,22 @@ +module.exports = function (page, currentDimensions) { + page.settings = { loadImages: true, javascriptEnabled: true}; + page.settings.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.17'; + + var height = 1500; + + if (currentDimensions.viewportHeight) { + height = currentDimensions.viewportHeight; + console.log('Loading ' + url + ' at dimensions: ' + currentDimensions.viewportWidth + 'x' + height); + } + else { + console.log('Loading ' + url + ' at width: ' + currentDimensions.viewportWidth); + } + + page.viewportSize = { + width: currentDimensions.viewportWidth, + // what matters is the clipRect, not the viewport height. + // And if it DOES matter, users can set it explicitly. + height: height + }; + +} \ No newline at end of file diff --git a/lib/wraith/javascript/phantom-helpers/handle_before_captures.js b/lib/wraith/javascript/phantom-helpers/handle_before_captures.js new file mode 100644 index 00000000..7f39b72c --- /dev/null +++ b/lib/wraith/javascript/phantom-helpers/handle_before_captures.js @@ -0,0 +1,27 @@ +module.exports = function (hooks) { + + var setupJavaScriptRan = false, + globalBeforeCaptureJS = hooks.config_level_js === 'false' ? false : hooks.config_level_js, + pathBeforeCaptureJS = hooks.path_level_js === 'false' ? false : hooks.path_level_js, + callback = hooks.on_completion; + + function runSetupJavaScriptThen(callback) { + setupJavaScriptRan = true; + if (globalBeforeCaptureJS && pathBeforeCaptureJS) { + require(globalBeforeCaptureJS)(page, function thenExecuteOtherBeforeCaptureFile() { + require(pathBeforeCaptureJS)(page, callback); + }); + } + else if (globalBeforeCaptureJS) { + require(globalBeforeCaptureJS)(page, callback); + } + else if (pathBeforeCaptureJS) { + require(pathBeforeCaptureJS)(page, callback); + } + else { + callback(); + } + } + + runSetupJavaScriptThen(callback); +} \ No newline at end of file diff --git a/lib/wraith/javascript/phantom-helpers/wait_for_page_to_load.js b/lib/wraith/javascript/phantom-helpers/wait_for_page_to_load.js new file mode 100644 index 00000000..5db2cece --- /dev/null +++ b/lib/wraith/javascript/phantom-helpers/wait_for_page_to_load.js @@ -0,0 +1,41 @@ +module.exports = function (page, callback) { + + var current_requests = 0; + + var waitTime = 300, + maxWait = 5000, + beenLoadingFor = 0; + + page.onError = function(msg, trace) { + // suppress JS errors from Wraith output + // http://stackoverflow.com/a/19538646 + }; + + page.onResourceRequested = function(req) { + current_requests += 1; + }; + + page.onResourceReceived = function(res) { + if (res.stage === 'end') { + current_requests -= 1; + } + }; + + function checkStatusOfAssets() { + if (current_requests >= 1) { + if (beenLoadingFor > maxWait) { + // sometimes not all assets will download in an acceptable time - continue anyway. + callback(); + } + else { + beenLoadingFor += waitTime; + setTimeout(checkStatusOfAssets, waitTime); + } + } + else { + callback(); + } + } + + setTimeout(checkStatusOfAssets, waitTime); +} \ No newline at end of file diff --git a/lib/wraith/javascript/phantom.js b/lib/wraith/javascript/phantom.js index 78f1a89b..cda242db 100644 --- a/lib/wraith/javascript/phantom.js +++ b/lib/wraith/javascript/phantom.js @@ -4,146 +4,98 @@ var system = require('system'), helper = require('./_helper.js')(system.args[2]); // command line arguments -var url = system.args[1], +var url = system.args[1], dimensions = helper.dimensions, image_name = system.args[3], - selector = system.args[4], + _selector = system.args[4], globalBeforeCaptureJS = system.args[5], - pathBeforeCaptureJS = system.args[6], - dimensionsProcessed = 0, - currentDimensions; - -globalBeforeCaptureJS = globalBeforeCaptureJS === 'false' ? false : globalBeforeCaptureJS; -pathBeforeCaptureJS = pathBeforeCaptureJS === 'false' ? false : pathBeforeCaptureJS; - -var current_requests = 0; -var last_request_timeout; -var final_timeout; - -var setupJavaScriptRan = false; - -var waitTime = 300, - maxWait = 5000, - beenLoadingFor = 0; + pathBeforeCaptureJS = system.args[6], + dimensionsProcessed = 0, + currentDimensions = dimensions; if (helper.takingMultipleScreenshots(dimensions)) { - currentDimensions = dimensions[0]; - image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); -} -else { - currentDimensions = dimensions; + currentDimensions = dimensions[0]; + image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); } -page.settings = { loadImages: true, javascriptEnabled: true}; -page.settings.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.17'; - -page.onError = function(msg, trace) { - // suppress JS errors from Wraith output - // http://stackoverflow.com/a/19538646 -}; - -page.onResourceRequested = function(req) { - current_requests += 1; -}; +// set up default `page` object +require('./phantom-helpers/default_settings.js')(page, currentDimensions); -page.onResourceReceived = function(res) { - if (res.stage === 'end') { - current_requests -= 1; - } -}; - -console.log('Loading ' + url + ' at dimensions: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); -page.viewportSize = { width: currentDimensions.viewportWidth, height: currentDimensions.viewportHeight}; +// functions +var waitForPageToLoad = require('./phantom-helpers/wait_for_page_to_load.js'), + handleBeforeCaptureHooks = require('./phantom-helpers/handle_before_captures.js'); page.open(url, function(status) { - if (status !== 'success') { - console.log('Error with page ' + url); - phantom.exit(); - } - - setTimeout(checkStatusOfAssets, waitTime); -}); - - -function checkStatusOfAssets() { - if (current_requests >= 1) { - - if (beenLoadingFor > maxWait) { - // sometimes not all assets will download in an acceptable time - continue anyway. - markPageAsLoaded(); - } - else { - beenLoadingFor += waitTime; - setTimeout(checkStatusOfAssets, waitTime); + if (status !== 'success') { + exit_phantom('Error with page ' + url); } - } - else { - markPageAsLoaded(); - } -} - -function markPageAsLoaded() { - if (!setupJavaScriptRan) { - runSetupJavaScriptThen(captureImage); - } - else { - captureImage(); - } -} - - -function runSetupJavaScriptThen(callback) { - setupJavaScriptRan = true; - if (globalBeforeCaptureJS && pathBeforeCaptureJS) { - require(globalBeforeCaptureJS)(page, function thenExecuteOtherBeforeCaptureFile() { - require(pathBeforeCaptureJS)(page, callback); + waitForPageToLoad(page, function markPageAsLoaded() { + handleBeforeCaptureHooks({ + config_level_js: globalBeforeCaptureJS, + path_level_js: pathBeforeCaptureJS, + on_completion: captureImage + }); }); - } - else if (globalBeforeCaptureJS) { - require(globalBeforeCaptureJS)(page, callback); - } - else if (pathBeforeCaptureJS) { - require(pathBeforeCaptureJS)(page, callback); - } - else { - callback(); - } -} +}); function captureImage() { - takeScreenshot(); - - dimensionsProcessed++; - if (helper.takingMultipleScreenshots(dimensions) && dimensionsProcessed < dimensions.length) { - currentDimensions = dimensions[dimensionsProcessed]; - image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); - setTimeout(resizeAndCaptureImage, waitTime); - } - else { - exit_phantom(); - } + takeScreenshot(); + + dimensionsProcessed++; + if (helper.takingMultipleScreenshots(dimensions) && dimensionsProcessed < dimensions.length) { + currentDimensions = dimensions[dimensionsProcessed]; + + if (currentDimensions.viewportHeight) { + console.log('Resizing ' + url + ' to: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); + } + else { + currentDimensions.viewportHeight = 1500; + console.log('Resizing ' + url + ' to width: ' + currentDimensions.viewportWidth); + } + + image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); + resizeAndCaptureImage(); + } else { + exit_phantom(); + } } function resizeAndCaptureImage() { - console.log('Resizing ' + url + ' to: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); - page.viewportSize = { width: currentDimensions.viewportWidth, height: currentDimensions.viewportHeight}; - setTimeout(captureImage, 5000); // give page time to re-render properly + console.log('Resizing to: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); + page.viewportSize = { + width: currentDimensions.viewportWidth, + height: currentDimensions.viewportHeight + }; + setTimeout(captureImage, 1500); // give page time to re-render properly } function takeScreenshot() { - console.log('Snapping ' + url + ' at: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); - page.clipRect = { - top: 0, - left: 0, - height: currentDimensions.viewportHeight, - width: currentDimensions.viewportWidth - }; - page.render(image_name); -} + // dynamic height calculation not possible in non-JavaScript mode + var documentHeight = page.evaluate(function () { + return document.body.offsetHeight; + }) || false; + + if (!documentHeight) { + documentHeight = 1500; + console.log('Could not dynamically determine document height.'); + } -function exit_phantom() { - // prevent CI from failing from 'Unsafe JavaScript attempt to access frame with URL about:blank from frame with URL' errors. See https://github.com/n1k0/casperjs/issues/1068 - setTimeout(function(){ - phantom.exit(); - }, 30); + console.log('Snapping ' + url + ' at: ' + currentDimensions.viewportWidth + 'x' + documentHeight); + page.clipRect = { + top: 0, + left: 0, + height: documentHeight, + width: currentDimensions.viewportWidth + }; + page.render(image_name); } + +function exit_phantom(message) { + if (message) { + console.log(message); + } + // prevent CI from failing from 'Unsafe JavaScript attempt to access frame with URL about:blank from frame with URL' errors. See https://github.com/n1k0/casperjs/issues/1068 + setTimeout(function() { + phantom.exit(); + }, 30); +} \ No newline at end of file