gnawrnip 0.1.0 → 0.1.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.
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in gnawrnip.gemspec
4
4
  gemspec
5
5
 
6
- group :test do
6
+ group :example do
7
7
  gem 'poltergeist'
8
8
  gem 'selenium-webdriver'
9
9
  gem 'sinatra'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Gnawrnip
2
2
 
3
- Gnawrnip is a [TurnipFormatter](https://github.com/gongo/turnip_formatter) Add-on that provides put a screen shot to report use [Capybara](https://github.com/jnicklas/capybara)
3
+ Gnawrnip is a [TurnipFormatter](https://github.com/gongo/turnip_formatter) Add-on that provides put a screenshot (like animation gif) to report use [Capybara](https://github.com/jnicklas/capybara)
4
4
 
5
5
  [![Build Status](https://travis-ci.org/gongo/gnawrnip.png?branch=master)](https://travis-ci.org/gongo/gnawrnip)
6
6
  [![Coverage Status](https://coveralls.io/repos/gongo/gnawrnip/badge.png?branch=master)](https://coveralls.io/r/gongo/gnawrnip)
@@ -16,6 +16,7 @@ Gnawrnip is a [TurnipFormatter](https://github.com/gongo/turnip_formatter) Add-o
16
16
  * RubyGems
17
17
  * capybara `~> 2.1.0`
18
18
  * turnip_formatter
19
+ * rmagick ( **optional** )
19
20
 
20
21
  ## Installation
21
22
 
@@ -31,18 +32,41 @@ Or install it yourself as:
31
32
 
32
33
  $ gem install gnawrnip
33
34
 
34
- ## Usage
35
+ ## Setup
35
36
 
36
- Edit the `.rspec` file in your project directory (create it if doesn't exist), and add the following line:
37
+ In your test setup file add:
37
38
 
38
- -r turnip
39
- -r turnip/capybara
40
- -r gnawrnip
39
+ require 'gnawrnip'
40
+ Gnawrnip.ready!
41
41
 
42
- And run this command.
42
+ ## Customization
43
43
 
44
- $ rspec --format RSpecTurnipFormatter --out report.html
44
+ You can do to customize a screenshot.
45
45
 
46
+ ```ruby
47
+ Gnawrnip.configure do |c|
48
+ c.photographer_driver = :js
49
+ c.frame_interval = 1000 # milliseconds
50
+ c.frame_size = [640, 360] # width, height
51
+ end
52
+
53
+ Gnawrnip.ready!
54
+ ```
55
+
56
+ `Gnawrnip.readty!` must be issued after `Gnawrnip.configure` in setup file.
57
+
58
+ * `photographer_driver` (Symbol) A driver that make screenshot like animation GIF.
59
+ * `:js`: use jQuery and image files. **The size of the report file tends to be large this driver**
60
+ * `:rmagick`: Make pure animation GIF using [RMagick](http://rmagick.rubyforge.org/). This driver is requires Gem `rmagick`. Add this line to your application's Gemfile:
61
+
62
+ ```
63
+ gem 'rmagick'
64
+ ```
65
+ * `frame_interval` (Integer) A time (millisecond) between each image in an animation. Default is `1000` (1sec)
66
+ * `frame_size` (Array) A size of screenshot (width, height). Default is `nil` (`nil` means that use `Capybara.current_driver.browser` size) .
67
+ * This option is enabled only when the `photographer_driver = :rmagick`.
68
+
69
+ As example, see [example/spec/spec_helper.rb](https://github.com/gongo/gnawrnip/tree/master/example/spec/spec_helper.rb) .
46
70
 
47
71
  ## Example
48
72
 
data/example/.rspec CHANGED
@@ -1,4 +1,4 @@
1
1
  --colour
2
2
  -r turnip
3
3
  -r turnip/capybara
4
- -r gnawrnip
4
+
@@ -3,8 +3,9 @@ require 'turnip_formatter'
3
3
  require 'rspec/expectations'
4
4
  require 'capybara'
5
5
  require 'turnip/capybara'
6
- require 'gnawrnip'
7
6
  require 'capybara/poltergeist'
7
+ require 'selenium-webdriver'
8
+ require 'gnawrnip'
8
9
 
9
10
  # Load turnip steps
10
11
  Dir.glob(File.dirname(__FILE__) + "/steps/**/*steps.rb") { |f| load f, true }
@@ -19,3 +20,11 @@ Capybara.app = Sinatra::Application.new
19
20
  Capybara.default_driver = :poltergeist
20
21
  Capybara.javascript_driver = :selenium
21
22
 
23
+ Gnawrnip.configure do |c|
24
+ c.photographer_driver = :js
25
+ #c.photographer_driver = :rmagick
26
+ c.frame_interval = 1000 # milliseconds
27
+ c.frame_size = [640, 360] # width, height
28
+ end
29
+
30
+ Gnawrnip.ready!
data/gnawrnip.gemspec CHANGED
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency 'rspec'
26
26
  spec.add_development_dependency 'coveralls'
27
+ spec.add_development_dependency 'rmagick'
27
28
  end
@@ -0,0 +1,26 @@
1
+ require 'gnawrnip/photographer'
2
+ require 'turnip_formatter/template'
3
+
4
+ module Gnawrnip::JS
5
+ class Photographer
6
+ include Gnawrnip::Photographer
7
+
8
+ def animation(images)
9
+ images.map { |img| single(img) }.join
10
+ end
11
+ end
12
+ end
13
+
14
+ TurnipFormatter::Template.add_js(<<-EOS)
15
+ $('.screenshot.animation').each(function() {
16
+ var imgs = $(this).children('img');
17
+ var frame = 0;
18
+
19
+ imgs.hide();
20
+ setInterval(function() {
21
+ imgs.hide();
22
+ imgs.eq(frame).show();
23
+ frame = (++frame % imgs.length);
24
+ }, #{Gnawrnip.frame_interval.to_s});
25
+ });
26
+ EOS
@@ -0,0 +1,22 @@
1
+ require 'tempfile'
2
+ require 'base64'
3
+
4
+ module Gnawrnip
5
+ module Photographer
6
+ def animation(paths)
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def single(path)
11
+ image_tag(image_base64(path))
12
+ end
13
+
14
+ def image_base64(path)
15
+ Base64.strict_encode64(File.read(path))
16
+ end
17
+
18
+ def image_tag(data, format = :png)
19
+ '<img src="data:image/' + format.to_s + ';base64,' + data + '"/>'
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,43 @@
1
+ require 'gnawrnip/photographer'
2
+
3
+ module Gnawrnip::RMagick
4
+ class Photographer
5
+ include Gnawrnip::Photographer
6
+
7
+ def initialize
8
+ Kernel.require 'RMagick'
9
+ rescue LoadError => e
10
+ if e.message =~ /cannot load.*RMagick/
11
+ raise LoadError, "Please install the gem and add `gem 'rmagick'` to your Gemfile if you are using bundler."
12
+ else
13
+ raise e
14
+ end
15
+ end
16
+
17
+ def animation(images)
18
+ creator = photo_creator(images)
19
+ tempfile = Tempfile.new(['gnawrnip', '.gif'])
20
+ creator.write(tempfile.path)
21
+
22
+ image_tag(image_base64(tempfile.path), :gif)
23
+ end
24
+
25
+ def single(image)
26
+ animation([image])
27
+ end
28
+
29
+ def photo_creator(images)
30
+ paths = images.map(&:path)
31
+ photos = ::Magick::ImageList.new(*paths)
32
+
33
+ photos.delay = Gnawrnip.frame_interval / 10.0
34
+ unless Gnawrnip.frame_size.nil?
35
+ photos.each do |p|
36
+ p.scale!(*Gnawrnip.frame_size)
37
+ end
38
+ end
39
+
40
+ photos
41
+ end
42
+ end
43
+ end
@@ -1,4 +1,5 @@
1
1
  require 'tempfile'
2
+ require 'time'
2
3
  require 'capybara'
3
4
 
4
5
  module Gnawrnip
@@ -8,17 +9,34 @@ module Gnawrnip
8
9
  #
9
10
  # Screenshot of current capybara session
10
11
  #
12
+ # When browser is still loading page, raise follow exception (maybe...)
13
+ #
14
+ # Selenium::WebDriver::Error::UnknownError:
15
+ # Could not take screenshot of current page - TypeError: c is null
16
+ #
17
+ # So, to retry during +wait_second+ seconds.
18
+ #
11
19
  # @example
12
20
  # image = Gnawrnip::Screenshot.take
13
21
  #
14
- # @return [String] Base64-encoded image of screenshot
15
22
  #
16
- def take
17
- tempfile = Tempfile.new(['gnawrnip', '.png'])
18
- session.save_screenshot(tempfile.path)
19
- image = Base64.strict_encode64(tempfile.read)
20
- tempfile.close
21
- image
23
+ # @param [Fixnum] wait_second Second to repeat the retry
24
+ # @return [Tempfile] Image file of screenshot
25
+ #
26
+ def take(wait_second = Capybara.default_wait_time)
27
+ start_time = Time.now
28
+
29
+ begin
30
+ tempfile = Tempfile.new(['gnawrnip', '.png'])
31
+ session.save_screenshot(tempfile.path)
32
+ tempfile
33
+ rescue Capybara::NotSupportedByDriverError => e
34
+ raise e
35
+ rescue => e
36
+ raise e if (Time.now - start_time) >= wait_second
37
+ sleep(0.3)
38
+ retry
39
+ end
22
40
  end
23
41
 
24
42
  private
@@ -11,36 +11,24 @@ module Gnawrnip
11
11
  def build(png_base64_list)
12
12
  case png_base64_list.length
13
13
  when 0
14
- description_no_screenshot
14
+ ''
15
15
  when 1
16
- still_image(png_base64_list.first)
16
+ single_image(png_base64_list.first)
17
17
  else
18
18
  animation_image(png_base64_list)
19
19
  end
20
20
  end
21
21
 
22
- def description_no_screenshot
23
- @no_screenshot ||= description_frame(:no_screenshot)
24
- still_image(@no_screenshot)
25
- end
26
-
27
- def animation_image(images)
22
+ def animation_image(paths)
28
23
  text = '<div class="screenshot animation">'
29
- text += images.map { |data| img_tag(data) }.join
24
+ text += Gnawrnip.photographer.animation(paths)
30
25
  text + '</div>'
31
26
  end
32
27
 
33
- def still_image(data)
34
- '<div class="screenshot">' + img_tag(data) + '</div>'
35
- end
36
-
37
- def img_tag(data)
38
- '<img src="data:image/png;base64,' + data + '"/>'
39
- end
40
-
41
- def description_frame(scene)
42
- path = File.dirname(__FILE__) + "/#{scene.to_s}.png"
43
- Base64.strict_encode64(File.read(path))
28
+ def single_image(path)
29
+ text = '<div class="screenshot">'
30
+ text += Gnawrnip.photographer.single(path)
31
+ text + '</div>'
44
32
  end
45
33
  end
46
34
  end
@@ -52,7 +40,7 @@ module TurnipFormatter
52
40
  ul.steps {
53
41
  div.screenshot {
54
42
  > img {
55
- width: 90%;
43
+ max-width: 90%;
56
44
  border: 2px solid black;
57
45
  }
58
46
  }
@@ -60,22 +48,6 @@ module TurnipFormatter
60
48
  }
61
49
  EOS
62
50
 
63
- Template.add_js(<<-EOS)
64
- $(function() {
65
- $('.screenshot.animation').each(function() {
66
- var imgs = $(this).children('img');
67
- var frame = 0;
68
-
69
- imgs.hide();
70
- setInterval(function() {
71
- imgs.hide();
72
- imgs.eq(frame).show();
73
- frame = (++frame % imgs.length);
74
- }, 1000);
75
- });
76
- });
77
- EOS
78
-
79
51
  Step::Failure.add_template Gnawrnip::StepScreenshot do
80
52
  example.metadata[:gnawrnip][:screenshot] || []
81
53
  end
@@ -1,3 +1,3 @@
1
1
  module Gnawrnip
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/gnawrnip.rb CHANGED
@@ -1,9 +1,40 @@
1
1
  require "gnawrnip/version"
2
+ require 'gnawrnip/rmagick/photographer'
3
+ require 'gnawrnip/ext/capybara/session'
4
+ require 'gnawrnip/animation'
5
+ require 'gnawrnip/screenshot'
6
+ require 'gnawrnip/step_screenshot'
7
+ require 'gnawrnip/rspec'
2
8
 
3
9
  module Gnawrnip
4
- require 'gnawrnip/ext/capybara/session'
5
- require 'gnawrnip/animation'
6
- require 'gnawrnip/screenshot'
7
- require 'gnawrnip/step_screenshot'
8
- require 'gnawrnip/rspec'
10
+ class << self
11
+ attr_accessor :photographer_driver
12
+ attr_accessor :frame_interval
13
+ attr_accessor :frame_size
14
+
15
+ def configure
16
+ yield self
17
+ end
18
+
19
+ def ready!
20
+ photographer # Try to load driver library.
21
+ end
22
+
23
+ def photographer
24
+ @photographer ||= case photographer_driver
25
+ when :rmagick
26
+ require 'gnawrnip/rmagick/photographer'
27
+ @photographer = RMagick::Photographer.new
28
+ else # :js
29
+ require 'gnawrnip/js/photographer'
30
+ @photographer = JS::Photographer.new
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ Gnawrnip.configure do |c|
37
+ c.photographer_driver = :js
38
+ c.frame_interval = 1000
39
+ c.frame_size = nil
9
40
  end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'gnawrnip/rmagick/photographer'
3
+ require 'RMagick'
4
+
5
+ module Gnawrnip::RMagick
6
+ describe Photographer do
7
+ let(:photographer) { Photographer.new }
8
+
9
+ describe '.new' do
10
+ subject { lambda { photographer } }
11
+
12
+ context 'cannot load rmagick' do
13
+ before do
14
+ error = LoadError.new("LoadError: cannot load such file -- RMagick")
15
+ Kernel.stub(:require).and_raise(error)
16
+ end
17
+
18
+ it { should raise_error LoadError, /gem 'rmagick'/ }
19
+ end
20
+
21
+ context 'cannot load other library' do
22
+ before do
23
+ error = LoadError.new("LoadError: cannot load such file -- samurai")
24
+ Kernel.stub(:require).and_raise(error)
25
+ end
26
+
27
+ it { should raise_error LoadError, /such file -- samurai/ }
28
+ end
29
+ end
30
+
31
+ describe '#animation' do
32
+ let(:screenshot_list) {
33
+ [GnawrnipTest.image('hoge'), GnawrnipTest.image('fuga')]
34
+ }
35
+
36
+ let(:creator) {
37
+ d = double
38
+ d.stub(:write) { |path| File.write(path, d.data) }
39
+ d
40
+ }
41
+
42
+ context 'exists image files' do
43
+ before do
44
+ photographer.stub(:photo_creator) do |args|
45
+ creator.stub(:data).and_return(args.map(&:read).join)
46
+ end.and_return(creator)
47
+ end
48
+
49
+ subject { photographer.animation(screenshot_list) }
50
+ it { should eq '<img src="data:image/gif;base64,aG9nZWZ1Z2E="/>' }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -4,10 +4,46 @@ require 'gnawrnip/screenshot'
4
4
  module Gnawrnip
5
5
  describe Screenshot do
6
6
  describe '.take' do
7
- subject { Screenshot.take }
7
+ subject { Screenshot.take.read }
8
8
 
9
9
  # see GnawrnipTestSession::save_screenshot
10
- it { should == "c2NyZWVuc2hvdA==" }
10
+ it { should == "screenshot" }
11
+
12
+ context 'not support save_screenshot' do
13
+ before do
14
+ GnawrnipTest::Session.any_instance.stub(:save_screenshot) do
15
+ raise Capybara::NotSupportedByDriverError
16
+ end
17
+ end
18
+
19
+ subject { lambda { Screenshot.take } }
20
+ it { should raise_error Capybara::NotSupportedByDriverError }
21
+ end
22
+
23
+ context 'raise unknown error' do
24
+ before do
25
+ GnawrnipTest::Session.any_instance.stub(:save_screenshot) do
26
+ raise Timeout::Error
27
+ end
28
+ end
29
+
30
+ context 'timeout' do
31
+ before do
32
+ now = Time.now
33
+ Time.stub(:now).and_return(now, now + 3)
34
+ end
35
+
36
+ subject do
37
+ lambda {
38
+ Capybara.using_wait_time 2 do
39
+ Screenshot.take
40
+ end
41
+ }
42
+ end
43
+
44
+ it { should raise_error Timeout::Error }
45
+ end
46
+ end
11
47
  end
12
48
  end
13
49
  end
@@ -3,9 +3,7 @@ require 'gnawrnip/step_screenshot'
3
3
 
4
4
  module Gnawrnip
5
5
  describe StepScreenshot do
6
- let :template do
7
- StepScreenshot
8
- end
6
+ let(:template) { StepScreenshot }
9
7
 
10
8
  it 'exists failure step template' do
11
9
  expect(TurnipFormatter::Step::Failure.templates).to have_key template
@@ -15,29 +13,37 @@ module Gnawrnip
15
13
  subject { template.build(data_list) }
16
14
 
17
15
  context 'has multiple data' do
18
- let(:data_list) { ['aiueo', '12345', 'abcde'] }
19
- it {
16
+ let(:data_list) do
17
+ [
18
+ GnawrnipTest.image('aiueo'),
19
+ GnawrnipTest.image('12345'),
20
+ GnawrnipTest.image('abcde')
21
+ ]
22
+ end
23
+
24
+ it 'should get image tag and source that base64 encoded' do
25
+ data1 = Base64.strict_encode64('aiueo')
26
+ data2 = Base64.strict_encode64('12345')
27
+ data3 = Base64.strict_encode64('abcde')
20
28
  should include '<div class="screenshot animation">'
21
- should include '<img src="data:image/png;base64,aiueo"/>'
22
- should include '<img src="data:image/png;base64,12345"/>'
23
- should include '<img src="data:image/png;base64,abcde"/></div>'
24
- }
29
+ should include '<img src="data:image/png;base64,' + data1 + '"/>'
30
+ should include '<img src="data:image/png;base64,' + data2 + '"/>'
31
+ should include '<img src="data:image/png;base64,' + data3 + '"/></div>'
32
+ end
25
33
  end
26
34
 
27
35
  context 'has single data' do
28
- let(:data_list) { ['aiueo'] }
36
+ let(:data_list) { [GnawrnipTest.image('aiueo')] }
29
37
  it {
38
+ data = Base64.strict_encode64('aiueo')
30
39
  should include '<div class="screenshot">'
31
- should include '<img src="data:image/png;base64,aiueo"/></div>'
40
+ should include '<img src="data:image/png;base64,' + data + '"/></div>'
32
41
  }
33
42
  end
34
43
 
35
44
  context 'has no data' do
36
45
  let(:data_list) { [] }
37
- it {
38
- should include '<div class="screenshot">'
39
- should include '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhQ'
40
- }
46
+ it { should eq '' }
41
47
  end
42
48
  end
43
49
  end
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,34 @@
1
+ require 'tempfile'
2
+ require 'capybara'
3
+
1
4
  require 'coveralls'
2
5
  Coveralls.wear!
3
6
 
4
7
  require 'gnawrnip'
5
- require 'capybara'
6
8
 
7
- class GnawrnipTestSession
8
- def save_screenshot(file_path)
9
- File.open(file_path, 'w') do |fp|
10
- fp.print 'screenshot'
11
- end
9
+ module GnawrnipTest
10
+ def self.image(data)
11
+ tempfile = Tempfile.new('gnarwnip_test')
12
+ tempfile.write(data)
13
+ tempfile.rewind
14
+ tempfile
12
15
  end
13
16
 
14
- def method_missing(name, *args, &block)
15
- # nooooooop
17
+ class Session
18
+ def save_screenshot(file_path)
19
+ File.open(file_path, 'w') do |fp|
20
+ fp.print 'screenshot'
21
+ end
22
+ end
23
+
24
+ def method_missing(name, *args, &block)
25
+ # nooooooop
26
+ end
16
27
  end
17
28
  end
18
29
 
19
30
  module Capybara
20
31
  def self.current_session
21
- GnawrnipTestSession.new
32
+ GnawrnipTest::Session.new
22
33
  end
23
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gnawrnip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-26 00:00:00.000000000 Z
12
+ date: 2013-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capybara
@@ -107,6 +107,22 @@ dependencies:
107
107
  - - ! '>='
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rmagick
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
110
126
  description: Gnawrnip is a TurnipFormatter Add-on that provides put a screen shot
111
127
  to report use Capybara
112
128
  email:
@@ -131,12 +147,16 @@ files:
131
147
  - lib/gnawrnip.rb
132
148
  - lib/gnawrnip/animation.rb
133
149
  - lib/gnawrnip/ext/capybara/session.rb
150
+ - lib/gnawrnip/js/photographer.rb
134
151
  - lib/gnawrnip/no_screenshot.png
152
+ - lib/gnawrnip/photographer.rb
153
+ - lib/gnawrnip/rmagick/photographer.rb
135
154
  - lib/gnawrnip/rspec.rb
136
155
  - lib/gnawrnip/screenshot.rb
137
156
  - lib/gnawrnip/step_screenshot.rb
138
157
  - lib/gnawrnip/version.rb
139
158
  - spec/gnawrnip/animation_spec.rb
159
+ - spec/gnawrnip/rmagick/photographer_spec.rb
140
160
  - spec/gnawrnip/rspec_spec.rb
141
161
  - spec/gnawrnip/screenshot_spec.rb
142
162
  - spec/gnawrnip/step_screenshot_spec.rb
@@ -168,6 +188,7 @@ specification_version: 3
168
188
  summary: Add-on for TurnipFormatter with Capybara
169
189
  test_files:
170
190
  - spec/gnawrnip/animation_spec.rb
191
+ - spec/gnawrnip/rmagick/photographer_spec.rb
171
192
  - spec/gnawrnip/rspec_spec.rb
172
193
  - spec/gnawrnip/screenshot_spec.rb
173
194
  - spec/gnawrnip/step_screenshot_spec.rb