gnawrnip 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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