gnawrnip 0.1.3 → 0.2.0

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/.gitignore CHANGED
@@ -18,3 +18,5 @@ tmp
18
18
  vendor
19
19
  example/vendor
20
20
  example/report.html
21
+ .sass-cache
22
+ example/.sass-cache
data/README.md CHANGED
@@ -21,7 +21,6 @@ So it have potential for massive refactorings (that could be API breaking).
21
21
  * RubyGems
22
22
  * capybara `~> 2.1.0`
23
23
  * turnip_formatter
24
- * rmagick ( **optional** )
25
24
 
26
25
  ## Installation
27
26
 
@@ -50,25 +49,29 @@ You can do to customize a screenshot.
50
49
 
51
50
  ```ruby
52
51
  Gnawrnip.configure do |c|
53
- c.publisher_driver = :js
54
- c.make_animation = true
55
- c.frame_interval = 1000 # milliseconds
56
- c.frame_size = [640, 360] # width, height
52
+ c.frame_interval = 1000 # milliseconds
53
+ c.make_animation = true
54
+ c.max_frame_size = 1024 # pixel
57
55
  end
58
56
  ```
59
57
 
60
- * `publisher_driver` (Symbol) A driver that make screenshot like animation GIF.
61
- * `:js`: use jQuery and image files. **The size of the report file tends to be large this driver**
62
- * `: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:
63
-
64
- ```
65
- gem 'rmagick'
66
- ```
67
58
  * `make_animation` (Boolean) Whether to make animation GIF. (Default: true)
68
59
  * `frame_interval` (Integer) A time (millisecond) between each image in an animation. Default is `1000` (1sec)
69
60
  * This option is enabled only when the `make_animation = true`.
70
- * `frame_size` (Array) A size of screenshot (width, height). Default is `nil` (`nil` means that use `Capybara.current_driver.browser` size) .
71
- * This option is enabled only when the `publisher_driver = :rmagick`.
61
+ * `max_frame_size` (Integer) Maximum size that use to resize of image.
62
+ * If given, it resize the image to fit to this value.
63
+ * Ignored if this value is greater than original width and height.
64
+ * Example:
65
+
66
+ ```
67
+ original: 640x480
68
+ this value: 300
69
+ result : 300x225
70
+
71
+ original: 480x640
72
+ this value: 400
73
+ result : 300x400
74
+ ```
72
75
 
73
76
  As example, see [example/spec/spec_helper.rb](https://github.com/gongo/gnawrnip/tree/master/example/spec/spec_helper.rb) .
74
77
 
@@ -21,10 +21,7 @@ Capybara.default_driver = :poltergeist
21
21
  Capybara.javascript_driver = :selenium
22
22
 
23
23
  Gnawrnip.configure do |c|
24
- # c.publisher_driver = :js
25
- c.publisher_driver = :rmagick
26
24
  c.frame_interval = 1000 # milliseconds
27
- c.frame_size = [640, 360] # width, height
28
- c.make_animation = false
25
+ c.make_animation = true
26
+ c.max_frame_size = 1024 # pixel
29
27
  end
30
-
data/gnawrnip.gemspec CHANGED
@@ -19,10 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'capybara', "~> 2.1"
22
- spec.add_dependency 'turnip_formatter', '~> 0.2.2'
22
+ spec.add_dependency 'turnip_formatter', '~> 0.2.8'
23
+ spec.add_dependency 'oily_png'
23
24
  spec.add_development_dependency "bundler", "~> 1.3"
24
25
  spec.add_development_dependency "rake"
25
26
  spec.add_development_dependency 'rspec'
26
27
  spec.add_development_dependency 'coveralls'
27
- spec.add_development_dependency 'rmagick'
28
28
  end
@@ -1,21 +1,30 @@
1
1
  require 'base64'
2
2
 
3
3
  module Gnawrnip
4
- module Publisher
4
+ class Publisher
5
+
6
+ #
7
+ # @params [Array] paths Array of screenshot image filename
8
+ #
5
9
  def animation(paths)
6
- raise NotImplementedError
10
+ paths.map { |path| image_tag(path) }.join
7
11
  end
8
12
 
13
+ #
14
+ # @params [string] path Screenshot image filename
15
+ #
9
16
  def single(path)
10
- image_tag(image_base64(path))
17
+ image_tag(path)
11
18
  end
12
19
 
13
- def image_base64(path)
14
- Base64.strict_encode64(File.read(path))
15
- end
20
+ private
16
21
 
17
- def image_tag(data, format = :png)
18
- '<img src="data:image/' + format.to_s + ';base64,' + data + '"/>'
19
- end
22
+ def image_tag(path, format = :png)
23
+ %Q|<img src="data:image/#{format.to_s};base64,#{image_base64(path)}"/>|
24
+ end
25
+
26
+ def image_base64(path)
27
+ Base64.strict_encode64(File.read(path))
28
+ end
20
29
  end
21
30
  end
@@ -29,6 +29,7 @@ module Gnawrnip
29
29
  begin
30
30
  tempfile = Tempfile.new(['gnawrnip', '.png'])
31
31
  session.save_screenshot(tempfile.path)
32
+ resize(tempfile.path) if need_resize?
32
33
  tempfile
33
34
  rescue Capybara::NotSupportedByDriverError => e
34
35
  raise e
@@ -41,9 +42,46 @@ module Gnawrnip
41
42
 
42
43
  private
43
44
 
44
- def session
45
- Capybara.current_session
46
- end
45
+ def session
46
+ Capybara.current_session
47
+ end
48
+
49
+ def need_resize?
50
+ !Gnawrnip.max_frame_size.nil?
51
+ end
52
+
53
+ def resize(path)
54
+ require 'oily_png'
55
+
56
+ image = OilyPNG::Canvas.from_file(path)
57
+ new_width, new_height = calculate_new_size(image.width, image.height)
58
+
59
+ image.resample_bilinear!(new_width, new_height)
60
+ image.save(path)
61
+ end
62
+
63
+ #
64
+ # Return new frame size (width and height).
65
+ # This size is keeping original aspect ratio.
66
+ #
67
+ # @return [Array] New width and height size. [width, height]
68
+ #
69
+ def calculate_new_size(width, height)
70
+ ratio = width / height
71
+ target = Gnawrnip.max_frame_size
72
+
73
+ return [width, height] if target > [width, height].max
74
+
75
+ if ratio < 0
76
+ new_width = target * ratio
77
+ new_height = target
78
+ else
79
+ new_width = target
80
+ new_height = target / ratio
81
+ end
82
+
83
+ return [new_width, new_height]
84
+ end
47
85
  end
48
86
  end
49
87
  end
@@ -6,7 +6,7 @@ module Gnawrnip
6
6
  module StepScreenshot
7
7
  class << self
8
8
  #
9
- # @param [Array] png_base64_list array of base64 encoded image
9
+ # @param [Array] png_base64_list array of base64 encoded image
10
10
  #
11
11
  def build(png_base64_list)
12
12
  case png_base64_list.length
@@ -20,9 +20,22 @@ module Gnawrnip
20
20
  end
21
21
 
22
22
  def animation_image(paths)
23
- text = '<div class="screenshot animation">'
23
+ text = <<-EOS
24
+ <div class="screenshot animation">
25
+ <div class="nav">
26
+ <div class="pager"></div>
27
+ <div class="manipulate">
28
+ <span class="play selected">&#9654;</span>
29
+ <span class="stop">&#9632;</span>
30
+ </div>
31
+ </div>
32
+ <div class="slides">
33
+ EOS
24
34
  text += Gnawrnip.publisher.animation(paths)
25
- text + '</div>'
35
+ text + <<-EOS
36
+ </div>
37
+ </div>
38
+ EOS
26
39
  end
27
40
 
28
41
  def single_image(path)
@@ -35,16 +48,93 @@ module Gnawrnip
35
48
  end
36
49
 
37
50
  module TurnipFormatter
51
+ Template.add_js_file('http://cdnjs.cloudflare.com/ajax/libs/jquery.cycle2/20130801/jquery.cycle2.min.js')
52
+
53
+ Template.add_js(<<-EOS)
54
+ $(function() {
55
+ $('.screenshot.animation').each(function() {
56
+ var slide = $(this).find('.slides').cycle({
57
+ timeout: 1000,
58
+ autoHeight: "container",
59
+ pager: $(this).find('div.nav .pager')
60
+ });
61
+
62
+ var nav = $(this).find('div.nav');
63
+ var playButton = nav.find('.play');
64
+ var stopButton = nav.find('.stop');
65
+
66
+ var coloringOfStopped = function() {
67
+ playButton.removeClass("selected");
68
+ stopButton.addClass("selected");
69
+ };
70
+
71
+ var coloringOfPlaying = function() {
72
+ playButton.addClass("selected");
73
+ stopButton.removeClass("selected");
74
+ };
75
+
76
+ playButton.click(function() { slide.cycle('resume'); });
77
+ stopButton.click(function() { slide.cycle('pause'); });
78
+
79
+ slide.on('cycle-pager-activated', function(event, opts) {
80
+ slide.cycle('pause');
81
+ });
82
+
83
+ slide.on('cycle-paused', function(event, opts) {
84
+ coloringOfStopped();
85
+ });
86
+
87
+ slide.on('cycle-resumed', function(event, opts) {
88
+ coloringOfPlaying();
89
+ });
90
+ });
91
+ });
92
+ EOS
93
+
38
94
  Template.add_scss(<<-EOS)
39
95
  div#steps-statistics section.scenario {
40
96
  ul.steps {
41
97
  div.screenshot {
42
- > img {
98
+ img {
43
99
  max-width: 90%;
44
100
  border: 2px solid black;
45
101
  }
46
- }
47
- }
102
+ }
103
+
104
+ div.screenshot.animation {
105
+ > div.nav {
106
+ text-align: center;
107
+
108
+ .pager {
109
+ margin-left: auto;
110
+ margin-right: auto;
111
+
112
+ span {
113
+ font-size: 50px;
114
+ display: inline;
115
+ color: #999999;
116
+ cursor: pointer;
117
+
118
+ &.cycle-pager-active {
119
+ color: red;
120
+ }
121
+ }
122
+ }
123
+
124
+ .manipulate {
125
+ span {
126
+ color: black;
127
+ font-size: 30px;
128
+ cursor: pointer;
129
+
130
+ &.selected {
131
+ color: red;
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
48
138
  }
49
139
  EOS
50
140
 
@@ -1,3 +1,3 @@
1
1
  module Gnawrnip
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/gnawrnip.rb CHANGED
@@ -1,22 +1,43 @@
1
1
  require "gnawrnip/version"
2
2
  require 'gnawrnip/rspec'
3
3
  require 'gnawrnip/photographer'
4
- require 'gnawrnip/step_screenshot'
4
+ require 'gnawrnip/publisher'
5
5
 
6
6
  module Gnawrnip
7
7
  class << self
8
- attr_accessor :publisher_driver
8
+ #
9
+ # [Integer] Time (millisecond) between each image in animation
10
+ #
9
11
  attr_accessor :frame_interval
10
- attr_accessor :frame_size
12
+
13
+ #
14
+ # [Boolean] Whether to make animation GIF
15
+ #
11
16
  attr_accessor :make_animation
12
17
 
18
+ #
19
+ # [Integer] Maximum size that use to resize of image.
20
+ # If given, it resize the image to fit to this value.
21
+ # Ignored if this value is greater than original width and height.
22
+ #
23
+ # Example:
24
+ # original: 640x480
25
+ # this value: 300
26
+ # result : 300x225
27
+ #
28
+ # original: 480x640
29
+ # this value: 400
30
+ # result : 300x400
31
+ #
32
+ attr_accessor :max_frame_size
33
+
13
34
  def configure
14
35
  yield self
15
36
  end
16
37
 
17
38
  def ready!
18
39
  require 'gnawrnip/ext/capybara/session' if animation?
19
- publisher
40
+ require 'gnawrnip/step_screenshot'
20
41
  end
21
42
 
22
43
  def animation?
@@ -24,25 +45,21 @@ module Gnawrnip
24
45
  end
25
46
 
26
47
  def photographer
27
- @photographer ||= Gnawrnip::Photographer.new
48
+ @photographer ||= Photographer.new
28
49
  end
29
50
 
30
51
  def publisher
31
- @publisher ||= case publisher_driver
32
- when :rmagick
33
- require 'gnawrnip/publisher/rmagick'
34
- @publisher = Publisher::RMagick.new
35
- else # :js
36
- require 'gnawrnip/publisher/js'
37
- @publisher = Publisher::JS.new
38
- end
52
+ @publisher ||= Publisher.new
53
+ end
54
+
55
+ def publisher_driver=(driver)
56
+ warn "DEPRECATED: `publisher_driver` option is deprecated (not used)."
39
57
  end
40
58
  end
41
59
  end
42
60
 
43
61
  Gnawrnip.configure do |c|
44
- c.publisher_driver = :js
45
- c.frame_interval = 1000
46
- c.frame_size = nil
47
- c.make_animation = true
62
+ c.frame_interval = 1000
63
+ c.make_animation = true
64
+ c.max_frame_size = nil
48
65
  end
@@ -6,8 +6,24 @@ module Gnawrnip
6
6
  describe '.take' do
7
7
  subject { Screenshot.take.read }
8
8
 
9
- # see GnawrnipTestSession::save_screenshot
10
- it { should == "screenshot" }
9
+ context 'No given max frame size' do
10
+ before do
11
+ Screenshot.stub(:need_resize?) { false }
12
+ Screenshot.should_not_receive(:resize)
13
+ end
14
+
15
+ # see GnawrnipTestSession::save_screenshot
16
+ it { should == "screenshot" }
17
+ end
18
+
19
+ context 'No given max frame size' do
20
+ before do
21
+ Screenshot.stub(:need_resize?) { true }
22
+ Screenshot.should_receive(:resize)
23
+ end
24
+
25
+ it { should == "screenshot" }
26
+ end
11
27
 
12
28
  context 'not support save_screenshot' do
13
29
  before do
@@ -28,7 +28,8 @@ module Gnawrnip
28
28
  should include '<div class="screenshot animation">'
29
29
  should include '<img src="data:image/png;base64,' + data1 + '"/>'
30
30
  should include '<img src="data:image/png;base64,' + data2 + '"/>'
31
- should include '<img src="data:image/png;base64,' + data3 + '"/></div>'
31
+ should include '<img src="data:image/png;base64,' + data3 + '"/>'
32
+ should include '<div class="nav">'
32
33
  end
33
34
  end
34
35
 
@@ -38,6 +39,7 @@ module Gnawrnip
38
39
  data = Base64.strict_encode64('aiueo')
39
40
  should include '<div class="screenshot">'
40
41
  should include '<img src="data:image/png;base64,' + data + '"/></div>'
42
+ should_not include '<div class="nav">'
41
43
  }
42
44
  end
43
45
 
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.3
4
+ version: 0.2.0
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-07-16 00:00:00.000000000 Z
12
+ date: 2013-11-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capybara
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 0.2.2
37
+ version: 0.2.8
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,41 +42,41 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 0.2.2
45
+ version: 0.2.8
46
46
  - !ruby/object:Gem::Dependency
47
- name: bundler
47
+ name: oily_png
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ~>
51
+ - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: '1.3'
54
- type: :development
53
+ version: '0'
54
+ type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ~>
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
- version: '1.3'
61
+ version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: rake
63
+ name: bundler
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
- - - ! '>='
67
+ - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: '0'
69
+ version: '1.3'
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
- - - ! '>='
75
+ - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: '0'
77
+ version: '1.3'
78
78
  - !ruby/object:Gem::Dependency
79
- name: rspec
79
+ name: rake
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
@@ -92,7 +92,7 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: coveralls
95
+ name: rspec
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: rmagick
111
+ name: coveralls
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -149,14 +149,11 @@ files:
149
149
  - lib/gnawrnip/no_screenshot.png
150
150
  - lib/gnawrnip/photographer.rb
151
151
  - lib/gnawrnip/publisher.rb
152
- - lib/gnawrnip/publisher/js.rb
153
- - lib/gnawrnip/publisher/rmagick.rb
154
152
  - lib/gnawrnip/rspec.rb
155
153
  - lib/gnawrnip/screenshot.rb
156
154
  - lib/gnawrnip/step_screenshot.rb
157
155
  - lib/gnawrnip/version.rb
158
156
  - spec/gnawrnip/photographer_spec.rb
159
- - spec/gnawrnip/publisher/rmagick.rb
160
157
  - spec/gnawrnip/rspec_spec.rb
161
158
  - spec/gnawrnip/screenshot_spec.rb
162
159
  - spec/gnawrnip/step_screenshot_spec.rb
@@ -176,7 +173,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
176
173
  version: '0'
177
174
  segments:
178
175
  - 0
179
- hash: 2586147401268872003
176
+ hash: 270195121
180
177
  required_rubygems_version: !ruby/object:Gem::Requirement
181
178
  none: false
182
179
  requirements:
@@ -185,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
182
  version: '0'
186
183
  segments:
187
184
  - 0
188
- hash: 2586147401268872003
185
+ hash: 270195121
189
186
  requirements: []
190
187
  rubyforge_project:
191
188
  rubygems_version: 1.8.23
@@ -194,7 +191,6 @@ specification_version: 3
194
191
  summary: Add-on for TurnipFormatter with Capybara
195
192
  test_files:
196
193
  - spec/gnawrnip/photographer_spec.rb
197
- - spec/gnawrnip/publisher/rmagick.rb
198
194
  - spec/gnawrnip/rspec_spec.rb
199
195
  - spec/gnawrnip/screenshot_spec.rb
200
196
  - spec/gnawrnip/step_screenshot_spec.rb
@@ -1,30 +0,0 @@
1
- require 'gnawrnip/publisher'
2
- require 'turnip_formatter/template'
3
-
4
- module Gnawrnip
5
- module Publisher
6
- class JS
7
- include Gnawrnip::Publisher
8
-
9
- def animation(images)
10
- images.map { |img| single(img) }.join
11
- end
12
- end
13
- end
14
- end
15
-
16
- TurnipFormatter::Template.add_js(<<-EOS)
17
- $(function() {
18
- $('.screenshot.animation').each(function() {
19
- var imgs = $(this).children('img');
20
- var frame = 0;
21
-
22
- imgs.hide();
23
- setInterval(function() {
24
- imgs.hide();
25
- imgs.eq(frame).show();
26
- frame = (++frame % imgs.length);
27
- }, #{Gnawrnip.frame_interval.to_s});
28
- });
29
- });
30
- EOS
@@ -1,47 +0,0 @@
1
- require 'gnawrnip/publisher'
2
-
3
- module Gnawrnip
4
- module Publisher
5
- class RMagick
6
- include Gnawrnip::Publisher
7
-
8
- def initialize
9
- Kernel.require 'RMagick'
10
- rescue LoadError => e
11
- if e.message =~ /cannot load.*RMagick/
12
- raise LoadError, "Please install the gem and add `gem 'rmagick'` to your Gemfile if you are using bundler."
13
- else
14
- raise e
15
- end
16
- end
17
-
18
- def animation(images)
19
- creator = photo_creator(images)
20
- tempfile = Tempfile.new(['gnawrnip', '.gif'])
21
- creator.write(tempfile.path)
22
-
23
- image_tag(image_base64(tempfile.path), :gif)
24
- end
25
-
26
- def single(image)
27
- animation([image])
28
- end
29
-
30
- private
31
-
32
- def photo_creator(images)
33
- paths = images.map(&:path)
34
- photos = ::Magick::ImageList.new(*paths)
35
-
36
- photos.delay = Gnawrnip.frame_interval / 10.0
37
- unless Gnawrnip.frame_size.nil?
38
- photos.each do |p|
39
- p.scale!(*Gnawrnip.frame_size)
40
- end
41
- end
42
-
43
- photos
44
- end
45
- end
46
- end
47
- end
@@ -1,56 +0,0 @@
1
- require 'spec_helper'
2
- require 'gnawrnip/publisher/rmagick'
3
- require 'RMagick'
4
-
5
- module Gnawrnip
6
- module Publisher
7
- describe RMagick do
8
- let(:photographer) { RMagick.new }
9
-
10
- describe '.new' do
11
- subject { lambda { photographer } }
12
-
13
- context 'cannot load rmagick' do
14
- before do
15
- error = LoadError.new("LoadError: cannot load such file -- RMagick")
16
- Kernel.stub(:require).and_raise(error)
17
- end
18
-
19
- it { should raise_error LoadError, /gem 'rmagick'/ }
20
- end
21
-
22
- context 'cannot load other library' do
23
- before do
24
- error = LoadError.new("LoadError: cannot load such file -- samurai")
25
- Kernel.stub(:require).and_raise(error)
26
- end
27
-
28
- it { should raise_error LoadError, /such file -- samurai/ }
29
- end
30
- end
31
-
32
- describe '#animation' do
33
- let(:screenshot_list) {
34
- [GnawrnipTest.image('hoge'), GnawrnipTest.image('fuga')]
35
- }
36
-
37
- let(:creator) {
38
- d = double
39
- d.stub(:write) { |path| File.write(path, d.data) }
40
- d
41
- }
42
-
43
- context 'exists image files' do
44
- before do
45
- photographer.stub(:photo_creator) do |args|
46
- creator.stub(:data).and_return(args.map(&:read).join)
47
- end.and_return(creator)
48
- end
49
-
50
- subject { photographer.animation(screenshot_list) }
51
- it { should eq '<img src="data:image/gif;base64,aG9nZWZ1Z2E="/>' }
52
- end
53
- end
54
- end
55
- end
56
- end