From bcf0adf8c86cd904ceaf4f32a56943f0715bcc69 Mon Sep 17 00:00:00 2001 From: Dave Spurr Date: Thu, 8 Oct 2015 19:06:46 +0100 Subject: [PATCH 1/8] Capture failures for none 200 responses --- lib/screencap/raster.js | 9 +++++++-- spec/screencap_spec.rb | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/screencap/raster.js b/lib/screencap/raster.js index 884abe3..f3205f4 100644 --- a/lib/screencap/raster.js +++ b/lib/screencap/raster.js @@ -194,6 +194,11 @@ page.onResourceReceived = function(res) { renderTimeout = setTimeout(doRender, resourceWait); } } + + if(res.url === args.url && res.status !== 200) { + console.log('Unable to load: ' + args.url); + phantom.exit(); + } }; // @@ -205,8 +210,8 @@ setupMask(); console.log(JSON.stringify(args)); if( !args.url || !args.output ) { - console.log('Usage: raster.js url=URL output=filename width=width[optional] height=height[optional] debug=true/false[optional] (div=div[optional] OR top=top left=left width=width height=height)'); - phantom.exit(); + console.log('Usage: raster.js url=URL output=filename width=width[optional] height=height[optional] debug=true/false[optional] (div=div[optional] OR top=top left=left width=width height=height)'); + phantom.exit(); } page.viewportSize = { width: args.width, height: args.height || 1024 }; diff --git a/spec/screencap_spec.rb b/spec/screencap_spec.rb index 96d9fab..11bac1e 100644 --- a/spec/screencap_spec.rb +++ b/spec/screencap_spec.rb @@ -8,7 +8,7 @@ it 'throws error when phantom could not load page' do expect { - Screencap::Fetcher.new('http://doesnotexistatallipromise.com/').fetch(output: TMP_DIRECTORY + 'foo.png') - }.to raise_error Screencap::Error, "Could not load URL http://doesnotexistatallipromise.com/" + Screencap::Fetcher.new('http://www.google.com/404').fetch(output: TMP_DIRECTORY + 'foo.png') + }.to raise_error Screencap::Error, "Could not load URL http://www.google.com/404" end -end \ No newline at end of file +end From d20c1f526ea35a4e5c4ea498f1e04def43f1a42c Mon Sep 17 00:00:00 2001 From: Dave Spurr Date: Thu, 8 Oct 2015 19:11:40 +0100 Subject: [PATCH 2/8] Remove injection of jQuery For some reason it wasn't loading for me and thus the callback was never called. We don't need jQuery to do those calculations anyway so clean it up by removing it. --- lib/screencap/raster.js | 114 +++++++++++++++++++--------------------- spec/fetcher_spec.rb | 9 ++-- 2 files changed, 58 insertions(+), 65 deletions(-) diff --git a/lib/screencap/raster.js b/lib/screencap/raster.js index f3205f4..18bc6c3 100644 --- a/lib/screencap/raster.js +++ b/lib/screencap/raster.js @@ -71,10 +71,10 @@ function doRender() { // if the page is taking too long (set via cutoffWait) to load, just exit cleanly function cutoff() { - clearTimeout(renderTimeout); - clearTimeout(forcedRenderTimeout); - console.log('Unable to load: ' + args.url + '. Process exceeded cutoff timeout.'); - phantom.exit(); + clearTimeout(renderTimeout); + clearTimeout(forcedRenderTimeout); + console.log('Unable to load: ' + args.url + '. Process exceeded cutoff timeout.'); + phantom.exit(); } function delayScreenshotForResources() { @@ -94,58 +94,54 @@ function evaluateWithArgs(func) { } function takeScreenshot() { - cutoffExecution(); - page.open(args.url, function(status) { + cutoffExecution(); + page.open(args.url, function(status) { if(status !== 'success') { console.log('Unable to load: ' + args.url); phantom.exit(); } else { - delayScreenshotForResources(); - page.includeJs( - "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js", - function() { - - var foundDiv = true; - page.evaluate(function(){ jQuery.noConflict(); }); - - if(args.div) { - var clip = evaluateWithArgs(withinPage_GetDivDimensions, args.div); - foundDiv = clip; - page.clipRect = clip; - } else if(mask) { - page.clipRect = mask; - } else if(args.height) { - // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619 - evaluateWithArgs( - function(w,h) { - jQuery('body, html').css({ - width: w + 'px', - height: h + 'px', - overflow: 'hidden' - }); - }, - page.viewportSize.width, - page.viewportSize.height / args.dpi - ); - } - - if (args.dpi !== 1) { - evaluateWithArgs( - function(dpi) { - document.body.style.webkitTransform = "scale(" + dpi + ")"; - document.body.style.webkitTransformOrigin = "0% 0%"; - document.body.style.width = (100 / dpi) + "%"; - }, - args.dpi - ); - } - - if(!foundDiv) { - phantom.exit(); - } - } - ); + var foundDiv = true; + + if(args.div) { + var clip = evaluateWithArgs(withinPage_GetDivDimensions, args.div); + foundDiv = clip; + page.clipRect = clip; + } else if(mask) { + page.clipRect = mask; + } else if(args.height) { + // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619 + evaluateWithArgs( + function(w,h) { + var els = document.querySelectorAll('html, body'); + for(var i = 0; i < els.length; i++) { + var el = els[i]; + el.style.width = w + 'px'; + el.style.height = h + 'px'; + el.style.overflow = 'hidden'; + }; + }, + page.viewportSize.width, + page.viewportSize.height / args.dpi + ); + } + + if (args.dpi !== 1) { + evaluateWithArgs( + function(dpi) { + document.body.style.webkitTransform = "scale(" + dpi + ")"; + document.body.style.webkitTransformOrigin = "0% 0%"; + document.body.style.width = (100 / dpi) + "%"; + }, + args.dpi + ); + } + + if(!foundDiv) { + phantom.exit(); + } + + delayScreenshotForResources(); } }); } @@ -154,18 +150,14 @@ function takeScreenshot() { // Functions evaluated within the page context // function withinPage_GetDivDimensions(div){ - var $el = jQuery(div); - - if($el.length === 0){ + var el = document.querySelector(div); + if(el === null) { console.log(div + ' was not found. exiting'); return false; } - var dims = $el.offset(); - dims.height = $el.height(); - dims.width = $el.width(); - return dims; -} + return el.getBoundingClientRect(); +}; // // Event handlers @@ -210,8 +202,8 @@ setupMask(); console.log(JSON.stringify(args)); if( !args.url || !args.output ) { - console.log('Usage: raster.js url=URL output=filename width=width[optional] height=height[optional] debug=true/false[optional] (div=div[optional] OR top=top left=left width=width height=height)'); - phantom.exit(); + console.log('Usage: raster.js url=URL output=filename width=width[optional] height=height[optional] debug=true/false[optional] (div=div[optional] OR top=top left=left width=width height=height)'); + phantom.exit(); } page.viewportSize = { width: args.width, height: args.height || 1024 }; diff --git a/spec/fetcher_spec.rb b/spec/fetcher_spec.rb index 05f8c2c..ddeb3e7 100644 --- a/spec/fetcher_spec.rb +++ b/spec/fetcher_spec.rb @@ -6,7 +6,7 @@ end it 'supports a custom filename' do - screenshot = Screencap::Fetcher.new('http://yahoo.com').fetch(:output => TMP_DIRECTORY + 'custom_filename.png') + screenshot = Screencap::Fetcher.new('http://stackoverflow.com').fetch(:output => TMP_DIRECTORY + 'custom_filename.png') File.exists?(screenshot).should == true end @@ -22,12 +22,13 @@ end it 'captures a given element' do - screenshot = Screencap::Fetcher.new('http://placehold.it').fetch(:output => TMP_DIRECTORY + 'given_element.jpg', :div => 'img.image') - FastImage.size(screenshot)[0].should == 140 + screenshot = Screencap::Fetcher.new('http://placekitten.com').fetch(:output => TMP_DIRECTORY + 'given_element.jpg', :div => '#image-1') + FastImage.size(screenshot)[0].should == 200 + FastImage.size(screenshot)[1].should == 287 end it 'should work when given a query string with ampersand in it' do screenshot = Screencap::Fetcher.new('http://google.com?1=2&3=4').fetch(:output => TMP_DIRECTORY + 'ampersand.jpg', :width => 800) FastImage.size(screenshot)[0].should == 800 end -end \ No newline at end of file +end From 166358bc152daca207343797ff492af96e87f9c2 Mon Sep 17 00:00:00 2001 From: Dave Spurr Date: Thu, 8 Oct 2015 19:12:15 +0100 Subject: [PATCH 3/8] Bump version --- lib/screencap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screencap/version.rb b/lib/screencap/version.rb index 25ee083..bb189be 100644 --- a/lib/screencap/version.rb +++ b/lib/screencap/version.rb @@ -1,3 +1,3 @@ module Screencap - VERSION = "0.1.4" + VERSION = "0.1.5" end From 6b0b8816e74043252cbdb812d20b9a68a06c1df2 Mon Sep 17 00:00:00 2001 From: Dave Spurr Date: Wed, 14 Oct 2015 11:04:48 +0100 Subject: [PATCH 4/8] Add support for phantomjs 2.0 system args --- lib/screencap/raster.js | 19 +++++++++++++++---- lib/screencap/version.rb | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/screencap/raster.js b/lib/screencap/raster.js index 18bc6c3..d02c58d 100644 --- a/lib/screencap/raster.js +++ b/lib/screencap/raster.js @@ -34,12 +34,23 @@ var page = new WebPage(), // Functions // function pickupNamedArguments() { - var i, pair; - for(i = 0; i < phantom.args.length; i++) { - pair = phantom.args[i].split(/=(.*)/); - args[pair[0]] = pair[1]; + var pair, scriptArgs; + if(typeof phantom.args != 'undefined') { + // phantomjs < 2.0 + scriptArgs = phantom.args; + } else { + // phantomjs 2.0 + var system = require('system'); + scriptArgs = system.args; + // remove first arg as always script name + scriptArgs.shift(); } + scriptArgs.forEach(function(arg, i) { + pair = arg.split(/=(.*)/); + args[pair[0]] = pair[1]; + }); + if(!args.width) { args.width = 1024; } if(!args.dpi) { args.dpi = 1; } if(args.url) { args.url = decodeURIComponent(args.url); } diff --git a/lib/screencap/version.rb b/lib/screencap/version.rb index bb189be..74cc37c 100644 --- a/lib/screencap/version.rb +++ b/lib/screencap/version.rb @@ -1,3 +1,3 @@ module Screencap - VERSION = "0.1.5" + VERSION = "0.2.0" end From cf5bf509f92f332d35f16ae15ea81167545125bf Mon Sep 17 00:00:00 2001 From: Jeremy Kallman Date: Mon, 22 Feb 2016 16:13:06 -0800 Subject: [PATCH 5/8] Ignore .idea. --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5826969..b396901 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .bundle .config .yardoc +.idea Gemfile.lock InstalledFiles _yardoc @@ -15,4 +16,4 @@ spec/reports test/tmp test/version_tmp tmp -.DS_Store \ No newline at end of file +.DS_Store From 64214bc93e433a5ae84b4e1880e998f891134368 Mon Sep 17 00:00:00 2001 From: Jeremy Kallman Date: Mon, 22 Feb 2016 16:14:44 -0800 Subject: [PATCH 6/8] =?UTF-8?q?Fix=20for=20div=20not=20found=20when=20it?= =?UTF-8?q?=20hasn=E2=80=99t=20rendered=20yet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Happens when div loading is dependent on resources loading. --- lib/screencap/raster.js | 87 +++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/lib/screencap/raster.js b/lib/screencap/raster.js index d02c58d..cdd3648 100644 --- a/lib/screencap/raster.js +++ b/lib/screencap/raster.js @@ -76,7 +76,11 @@ function doRender() { clearTimeout(renderTimeout); clearTimeout(forcedRenderTimeout); clearTimeout(cutoffTimeout); - page.render(args.output); + if (updateClipping()) { + page.render(args.output); + } else { + console.log('Not rendering as clipping failed, likely due to not finding the div'); + } phantom.exit(); } @@ -111,52 +115,51 @@ function takeScreenshot() { console.log('Unable to load: ' + args.url); phantom.exit(); } else { - - var foundDiv = true; - - if(args.div) { - var clip = evaluateWithArgs(withinPage_GetDivDimensions, args.div); - foundDiv = clip; - page.clipRect = clip; - } else if(mask) { - page.clipRect = mask; - } else if(args.height) { - // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619 - evaluateWithArgs( - function(w,h) { - var els = document.querySelectorAll('html, body'); - for(var i = 0; i < els.length; i++) { - var el = els[i]; - el.style.width = w + 'px'; - el.style.height = h + 'px'; - el.style.overflow = 'hidden'; - }; - }, - page.viewportSize.width, - page.viewportSize.height / args.dpi - ); - } - - if (args.dpi !== 1) { - evaluateWithArgs( - function(dpi) { - document.body.style.webkitTransform = "scale(" + dpi + ")"; - document.body.style.webkitTransformOrigin = "0% 0%"; - document.body.style.width = (100 / dpi) + "%"; - }, - args.dpi - ); - } - - if(!foundDiv) { - phantom.exit(); - } - delayScreenshotForResources(); } }); } +function updateClipping() { + var foundDiv = true; + + if(args.div) { + var clip = evaluateWithArgs(withinPage_GetDivDimensions, args.div); + foundDiv = !!clip; + page.clipRect = clip; + } else if(mask) { + page.clipRect = mask; + } else if(args.height) { + // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619 + evaluateWithArgs( + function(w,h) { + var els = document.querySelectorAll('html, body'); + for(var i = 0; i < els.length; i++) { + var el = els[i]; + el.style.width = w + 'px'; + el.style.height = h + 'px'; + el.style.overflow = 'hidden'; + } + }, + page.viewportSize.width, + page.viewportSize.height / args.dpi + ); + } + + if (args.dpi !== 1) { + evaluateWithArgs( + function(dpi) { + document.body.style.webkitTransform = "scale(" + dpi + ")"; + document.body.style.webkitTransformOrigin = "0% 0%"; + document.body.style.width = (100 / dpi) + "%"; + }, + args.dpi + ); + } + + return foundDiv +} + // // Functions evaluated within the page context // From 376bb70a295a063e4da1c5ff2bf74f86d35b1a11 Mon Sep 17 00:00:00 2001 From: Jeremy Kallman Date: Mon, 22 Feb 2016 16:16:39 -0800 Subject: [PATCH 7/8] Bump version. --- lib/screencap/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screencap/version.rb b/lib/screencap/version.rb index 74cc37c..d9a9e33 100644 --- a/lib/screencap/version.rb +++ b/lib/screencap/version.rb @@ -1,3 +1,3 @@ module Screencap - VERSION = "0.2.0" + VERSION = "0.2.1" end From 0478476c539d753644599f4f679ba0ab546f2f99 Mon Sep 17 00:00:00 2001 From: Jeremy Kallman Date: Thu, 31 Mar 2016 17:18:20 -0700 Subject: [PATCH 8/8] Fix for not capturing with a height arg correctly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Instead of modifying the height of the body (and html) after render we just set the mask to take care of it. The image we were getting was of the full size page cropped down to the height and the rest filled with white. I think this is because the larger initial page size caused the viewport to expand but then it didn’t contract. - Since args.div will supersede the mask eventually, don’t set the mask up front if args.div is present. Set the mask solely on the height arg as we can default top and left to 0. This fixes the failing unit tests when running locally. --- lib/screencap/raster.js | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/lib/screencap/raster.js b/lib/screencap/raster.js index cdd3648..b5beac6 100644 --- a/lib/screencap/raster.js +++ b/lib/screencap/raster.js @@ -62,10 +62,10 @@ function pickupNamedArguments() { function setupMask() { // if given settings for an area to take create a mask for that - if( args.top && args.left && args.width && args.height) { + if(!args.div && args.width && args.height) { mask = { - top: args.top, - left: args.left, + top: args.top || 0, + left: args.left || 0, width: args.width, height: args.height }; @@ -129,21 +129,6 @@ function updateClipping() { page.clipRect = clip; } else if(mask) { page.clipRect = mask; - } else if(args.height) { - // have a height resize the html & body to workaround https://github.com/ariya/phantomjs/issues/10619 - evaluateWithArgs( - function(w,h) { - var els = document.querySelectorAll('html, body'); - for(var i = 0; i < els.length; i++) { - var el = els[i]; - el.style.width = w + 'px'; - el.style.height = h + 'px'; - el.style.overflow = 'hidden'; - } - }, - page.viewportSize.width, - page.viewportSize.height / args.dpi - ); } if (args.dpi !== 1) { @@ -157,7 +142,7 @@ function updateClipping() { ); } - return foundDiv + return foundDiv } //