diff --git a/Gemfile b/Gemfile index ea32a130..6c546840 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ source "https://rubygems.org" -# Specify your gem's dependencies in ..gemspec +# Specify your gem's dependencies in wraith.gemspec gemspec diff --git a/lib/wraith/gallery.rb b/lib/wraith/gallery.rb index 01bca02b..7431de23 100755 --- a/lib/wraith/gallery.rb +++ b/lib/wraith/gallery.rb @@ -123,6 +123,19 @@ def sorting_dirs(dirs) Hash[@sorted] end + def generate_gallery(with_path = "") + dest = "#{@location}/gallery.html" + directories = parse_directories(@location) + + template = File.expand_path("gallery_template/#{wraith.gallery_template}.erb", File.dirname(__FILE__)) + generate_html(@location, directories, template, dest, with_path) + + puts "Gallery generated" + failed = check_failed_shots + prompt_user_to_open_gallery dest + exit 1 if failed + end + def generate_html(location, directories, template, destination, path) template = File.read(template) locals = { @@ -130,7 +143,6 @@ def generate_html(location, directories, template, destination, path) :directories => directories, :path => path, :threshold => wraith.threshold - } html = ERB.new(template).result(ErbBinding.new(locals).get_binding) File.open(destination, "w") do |outf| @@ -138,20 +150,6 @@ def generate_html(location, directories, template, destination, path) end end - def generate_gallery(with_path = "") - dest = "#{@location}/gallery.html" - directories = parse_directories(@location) - - slideshow_template = File.expand_path("gallery_template/#{wraith.gallery_template}.erb", File.dirname(__FILE__)) - - generate_html(@location, directories, slideshow_template, dest, with_path) - - puts "Gallery generated" - failed = check_failed_shots - prompt_user_to_open_gallery dest - exit 1 if failed - end - def check_failed_shots if @multi return false diff --git a/lib/wraith/javascript/_helper.js b/lib/wraith/javascript/_helper.js index 12f2bb04..d2415486 100644 --- a/lib/wraith/javascript/_helper.js +++ b/lib/wraith/javascript/_helper.js @@ -17,9 +17,11 @@ module.exports = function (commandLineDimensions) { dimensionsToPass = multipleDimensions.map(function (cliDimensions) { return getWidthAndHeight(cliDimensions); }); + console.log('Capturing in resize mode (more efficient)'); } else { dimensionsToPass = getWidthAndHeight(commandLineDimensions); + console.log('Capturing in reload mode'); } return { diff --git a/lib/wraith/javascript/_phantom__common.js b/lib/wraith/javascript/_phantom__common.js index 282f78e3..9505f593 100644 --- a/lib/wraith/javascript/_phantom__common.js +++ b/lib/wraith/javascript/_phantom__common.js @@ -25,6 +25,12 @@ module.exports = function (config) { var last_request_timeout; var final_timeout; + var setupJavaScriptRan = false; + + var waitTime = 300, + maxWait = 5000, + beenLoadingFor = 0; + if (helper.takingMultipleScreenshots(dimensions)) { currentDimensions = dimensions[0]; image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); @@ -33,11 +39,14 @@ module.exports = function (config) { currentDimensions = dimensions; } - page.settings = { loadImages: true, javascriptEnabled: javascriptEnabled }; - - // If you want to use additional phantomjs commands, place them here + page.settings = { loadImages: true, javascriptEnabled: javascriptEnabled}; 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; }; @@ -45,76 +54,106 @@ module.exports = function (config) { page.onResourceReceived = function(res) { if (res.stage === 'end') { current_requests -= 1; - debounced_render(); } }; + console.log('Loading ' + url + ' at dimensions: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); + page.viewportSize = { width: currentDimensions.viewportWidth, height: currentDimensions.viewportHeight}; + page.open(url, function(status) { if (status !== 'success') { console.log('Error with page ' + url); phantom.exit(); } + + setTimeout(checkStatusOfAssets, waitTime); }); - function runSetupJavaScriptThenCaptureImage() { - resize(); - if (globalBeforeCaptureJS) { - require(globalBeforeCaptureJS)(page); + + function checkStatusOfAssets() { + if (current_requests >= 1) { + + if (beenLoadingFor > maxWait) { + console.log('Timed out waiting for assets. Continuing...'); + markPageAsLoaded(); + } + else { + console.log('Still loading page...'); + beenLoadingFor += waitTime; + setTimeout(checkStatusOfAssets, waitTime); + } } - if (pathBeforeCaptureJS) { - require(pathBeforeCaptureJS)(page); + else { + console.log('Page has finished loading'); + markPageAsLoaded(); } - resizeAndCaptureImage(); } - function resize() { - page.viewportSize = { width: currentDimensions.viewportWidth, height: currentDimensions.viewportHeight}; + function markPageAsLoaded() { + if (!setupJavaScriptRan) { + runSetupJavaScriptThen(captureImage); + } + else { + captureImage(); + } } - function resizeAndCaptureImage() { - console.log('Snapping ' + url + ' at: ' + currentDimensions.viewportWidth + 'x' + currentDimensions.viewportHeight); - resize(); - setTimeout(captureImage, 1000); // give page time to re-render properly + + 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(); + } } function captureImage() { - page.clipRect = { - top: 0, - left: 0, - height: currentDimensions.viewportHeight, - width: currentDimensions.viewportWidth - }; - page.render(image_name); + takeScreenshot(); dimensionsProcessed++; + console.log('dimensions processed: ' + dimensionsProcessed + ' out of ' + dimensions.length); if (helper.takingMultipleScreenshots(dimensions) && dimensionsProcessed < dimensions.length) { currentDimensions = dimensions[dimensionsProcessed]; image_name = helper.replaceImageNameWithDimensions(image_name, currentDimensions); - setTimeout(resizeAndCaptureImage, 1000); + setTimeout(resizeAndCaptureImage, waitTime); } else { - // 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); + exit_phantom(); } } - function debounced_render() { - clearTimeout(last_request_timeout); - clearTimeout(final_timeout); + 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 + } - // If there's no more ongoing resource requests, wait for 1 second before - // rendering, just in case the page kicks off another request - if (current_requests < 1) { - clearTimeout(final_timeout); - last_request_timeout = setTimeout(runSetupJavaScriptThenCaptureImage, 1000); - } + 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); + } - // Sometimes, straggling requests never make it back, in which - // case, timeout after 5 seconds and render the page anyway - final_timeout = setTimeout(runSetupJavaScriptThenCaptureImage, 5000); + 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); } } \ No newline at end of file diff --git a/lib/wraith/wraith.rb b/lib/wraith/wraith.rb index 4b202b42..0051526e 100644 --- a/lib/wraith/wraith.rb +++ b/lib/wraith/wraith.rb @@ -17,6 +17,7 @@ def validate(mode = false) list_debug_information if verbose validate_basic_properties validate_mode_properties(mode) if mode + # if we get this far, we've only had warnings at worst, not errors. puts "Config validated. No serious issues found." end @@ -239,7 +240,7 @@ def thumb_width end def phantomjs_options - @config["phantomjs_options"] + @config["phantomjs_options"] || '--ignore-ssl-errors=true --ssl-protocol=tlsv1' end def verbose diff --git a/templates/javascript/beforeCapture--casper_example.js b/templates/javascript/beforeCapture--casper_example.js index 9f795541..4e681962 100644 --- a/templates/javascript/beforeCapture--casper_example.js +++ b/templates/javascript/beforeCapture--casper_example.js @@ -1,10 +1,13 @@ -module.exports = function (casper) { +module.exports = function (casper, ready) { /* you may want to test some interaction on the page */ casper.wait(2000, function() { casper.click('.ns-panel__hotspot--2'); }); + /* or you may need to make Wraith wait a bit longer before taking the screenshot */ + casper.wait(2000, ready); // you MUST call the ready() callback for Wraith to continue + /* or you may want to see how your page looks without JavaScript */ // casper.options.pageSettings.javascriptEnabled = false; // casper.thenOpen(casper.page.url); diff --git a/templates/javascript/beforeCapture--phantom_example.js b/templates/javascript/beforeCapture--phantom_example.js index cc1dfa4e..4a9b88c7 100644 --- a/templates/javascript/beforeCapture--phantom_example.js +++ b/templates/javascript/beforeCapture--phantom_example.js @@ -1,4 +1,4 @@ -module.exports = function (phantom) { +module.exports = function (phantom, ready) { /* you may want to test some interaction on the page */ phantom.evaluate(function(){ @@ -9,6 +9,9 @@ module.exports = function (phantom) { waitforload = true; }); + /* or you may need to make Wraith wait a bit longer before taking the screenshot */ + setTimeout(ready, 1000); // you MUST call the ready() callback for Wraith to continue + /* or you may want to see how your page looks without JavaScript */ // phantom.settings.javascriptEnabled = false; // phantom.open(phantom.page.url);