smartshot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a05d7100ca627ef66d421eccc73d2f141e3258d6
4
+ data.tar.gz: 75e0b0dad27d08463325808b873134f83754eb2b
5
+ SHA512:
6
+ metadata.gz: 80a8ac8dbc6d6a1f09a94de3b1bfd2a7227abd4e51762e97afa5ea2e4ae6f7bb765ba3e2d80ca1e07ad43ce3dffb86f88faa2f3c5208db9c815661a59da779a9
7
+ data.tar.gz: 734000531cd2aa9822541eac895fd9f5660a13f0b768191fd4452cbe7f4cf139a82c4a31067f941007d2ca5350ca417ee12fbff0ad7604a26956260a2791abe2
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.sw*
2
+ test/data
data/CONTRIBUTORS ADDED
@@ -0,0 +1 @@
1
+ Caio Almeida
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Caio Almeida
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Smartshot
2
+
3
+ Captures a web page as a screenshot using Poltergeist, Capybara and PhantomJS.
4
+ It can wait for elements and also dive into iframes, while the existing gems
5
+ just wait for time or expect elements on the main window.
6
+
7
+ ## Installation
8
+
9
+ Download and install [PhantomJS](http://phantomjs.org/),
10
+ add the directory containing the binary to your PATH.
11
+
12
+ Add the `smartshot` gem to your Gemfile:
13
+
14
+ gem "smartshot"
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install smartshot
23
+
24
+ ## Usage
25
+
26
+ ```rb
27
+ # Instantiate - additional "options" can be passed to Capybara
28
+ fetcher = Smartshot::Screenshot.new(window_size: [800, 600])
29
+
30
+ # Simpler usage - you can now grab a screenshot of a page
31
+ fetcher.take_screenshot! url: 'http://www.google.com', output: '/tmp/google.png'
32
+
33
+ # More complex example
34
+ # Let's take the screenshot only when some element (here a "div"
35
+ # with class "embed") is present on an iframe which is inside two
36
+ # other iframes - the iframes path to be followed by the bot
37
+ # is defined by an array, where iframes can be defined by
38
+ # index (0-based), name or id
39
+ fetcher.take_screenshot! url: 'http://some.page.with/deep/iframes',
40
+ output: '/tmp/screenshot.png',
41
+ wait_for_element: 'div.embed',
42
+ frames_path: [0, 'name-of-an-iframe-inside-the-first-iframe', 'id-of-an-iframe-inside-the-previous-one']
43
+ ```
44
+
45
+ Besides the four options presented so far, it's possible to pass the same options accepted by
46
+ [Poltergeist's save screenshot method](https://github.com/teampoltergeist/poltergeist#taking-screenshots-with-some-extensions),
47
+ for example:
48
+
49
+ ```rb
50
+ fetcher.take_screenshot! url: 'http://google.com', output: '/tmp/google.png', full: false, selector: '#myDiv .my-class p'
51
+ ```
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+ require "rdoc/task"
5
+
6
+ desc "Default: run tests."
7
+ task :default => :test
8
+
9
+
10
+ desc "Run smartshot tests."
11
+ Rake::TestTask.new do |t|
12
+ t.libs << "test"
13
+ t.libs << "lib"
14
+ t.test_files = Dir[ "test/*_test.rb" ]
15
+ t.verbose = true
16
+ end
data/lib/smartshot.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'capybara/dsl'
2
+ require 'capybara/poltergeist'
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+ require 'smartshot/version'
6
+ require 'smartshot/errors'
7
+ require 'smartshot/screenshot'
8
+
9
+ module Smartshot
10
+
11
+ end
@@ -0,0 +1,3 @@
1
+ module Smartshot
2
+ class SmartshotError < RuntimeError; end
3
+ end
@@ -0,0 +1,42 @@
1
+ module Smartshot
2
+ class Screenshot
3
+ include Capybara::DSL
4
+
5
+ def self.setup_capybara(options = {})
6
+ defaults = { js_errors: false, phantomjs_options: ['--ignore-ssl-errors=yes', '--ssl-protocol=any'] }
7
+ Capybara.register_driver :poltergeist do |app|
8
+ Capybara::Poltergeist::Driver.new(app, defaults.merge(options))
9
+ end
10
+ Capybara.run_server = false
11
+ Capybara.current_driver = :poltergeist
12
+ Capybara.default_wait_time = 30
13
+ end
14
+
15
+ def initialize(options = {})
16
+ Smartshot::Screenshot.setup_capybara(options)
17
+ end
18
+
19
+ def take_screenshot!(params = {})
20
+ options = { full: true, output: 'screenshot.png', url: 'http://ca.ios.ba', wait_for_element: 'body', frames_path: [] }.merge(params)
21
+ begin
22
+ visit options.delete(:url)
23
+ inside_frames options.delete(:frames_path) do
24
+ page.find options.delete(:wait_for_element)
25
+ end
26
+ page.driver.save_screenshot(options.delete(:output), options)
27
+ rescue => e
28
+ raise SmartshotError.new("Error: #{e.message.inspect}")
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ def inside_frames(frames = [], &block)
35
+ block.call and return if frames.empty?
36
+ frame = frames.shift
37
+ within_frame frame do
38
+ inside_frames(frames, &block)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module Smartshot
2
+ VERSION = '0.0.1'
3
+ end
data/smartshot.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'smartshot/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'smartshot'
8
+ spec.version = Smartshot::VERSION
9
+ spec.authors = ['Caio Almeida']
10
+ spec.email = ['caiosba@gmail.com']
11
+ spec.description = %q{Captures a web page as a screenshot using Poltergeist, Capybara and PhantomJS,
12
+ optionally waiting for elements (defined by CSS selectors) that can be inside iframes}
13
+ spec.summary = %q{Captures a web page as a screenshot using Poltergeist, Capybara and PhantomJS,
14
+ optionally waiting for elements (defined by CSS selectors) that can be inside iframes}
15
+ spec.homepage = 'https://github.com/caiosba/smartshot'
16
+ spec.license = 'MIT'
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'minitest'
26
+ spec.add_development_dependency 'gem-release'
27
+
28
+ spec.add_dependency 'activesupport'
29
+ spec.add_dependency 'poltergeist', '~> 1.5.0'
30
+ spec.add_dependency 'faye-websocket', '~> 0.7.3'
31
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+
3
+ class SmartshotTest < MiniTest::Unit::TestCase
4
+
5
+ DATA_DIR = File.expand_path(File.dirname(__FILE__) + '/data')
6
+
7
+ def setup
8
+ FileUtils.mkdir_p(DATA_DIR) unless File.directory?(DATA_DIR)
9
+ @smartshot = Smartshot::Screenshot.new
10
+ end
11
+
12
+ def test_http
13
+ %w(www.yahoo.com).each do |name|
14
+ output = thumb(name)
15
+ File.delete output if File.exists? output
16
+ @smartshot.take_screenshot! url: "http://#{name}/", output: output
17
+ assert File.exists? output
18
+ end
19
+ end
20
+
21
+ def test_https
22
+ %w(github.com).each do |name|
23
+ output = thumb(name)
24
+ File.delete output if File.exists? output
25
+ @smartshot.take_screenshot! url: "https://#{name}/", output: output
26
+ assert File.exists? output
27
+ end
28
+ end
29
+
30
+ def test_invalid_url
31
+ %w(nxdomain).each do |name|
32
+ assert_raises Smartshot::SmartshotError do
33
+ @smartshot.take_screenshot! url: "http://#{name}/", output: thumb(name)
34
+ end
35
+ end
36
+ end
37
+
38
+ def test_iframe
39
+ waited = notwaited = nil
40
+
41
+ %w(waited).each do |name|
42
+ waited = thumb(name)
43
+ File.delete waited if File.exists? waited
44
+ @smartshot.take_screenshot! url: 'http://ca.ios.ba/files/others/smartshot.html', output: waited, wait_for_element: 'p.Tweet-text',
45
+ frames_path: [0, 'child', 'twitter-widget-0']
46
+ assert File.exists? waited
47
+ end
48
+
49
+ %w(notwaited).each do |name|
50
+ notwaited = thumb(name)
51
+ File.delete notwaited if File.exists? notwaited
52
+ @smartshot.take_screenshot! url: 'http://ca.ios.ba/files/others/smartshot.html', output: notwaited
53
+ assert File.exists? notwaited
54
+ end
55
+
56
+ assert File.size(waited) > File.size(notwaited)
57
+ end
58
+
59
+ def thumb(name)
60
+ File.join(DATA_DIR, "#{name}.png")
61
+ end
62
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'smartshot'
3
+ require 'minitest/autorun'
4
+ require 'minitest/unit'
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smartshot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Caio Almeida
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gem-release
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: poltergeist
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 1.5.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 1.5.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: faye-websocket
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 0.7.3
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 0.7.3
111
+ description: |-
112
+ Captures a web page as a screenshot using Poltergeist, Capybara and PhantomJS,
113
+ optionally waiting for elements (defined by CSS selectors) that can be inside iframes
114
+ email:
115
+ - caiosba@gmail.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - CONTRIBUTORS
122
+ - Gemfile
123
+ - LICENSE.txt
124
+ - README.md
125
+ - Rakefile
126
+ - lib/smartshot.rb
127
+ - lib/smartshot/errors.rb
128
+ - lib/smartshot/screenshot.rb
129
+ - lib/smartshot/version.rb
130
+ - smartshot.gemspec
131
+ - test/smartshot_test.rb
132
+ - test/test_helper.rb
133
+ homepage: https://github.com/caiosba/smartshot
134
+ licenses:
135
+ - MIT
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubyforge_project:
153
+ rubygems_version: 2.0.14
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: Captures a web page as a screenshot using Poltergeist, Capybara and PhantomJS,
157
+ optionally waiting for elements (defined by CSS selectors) that can be inside iframes
158
+ test_files:
159
+ - test/smartshot_test.rb
160
+ - test/test_helper.rb