goggles 0.1.4 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2bd05fb9c67d3e55a5bb2d9a3c26d5c1ddd96636
4
+ data.tar.gz: 594c499843796017d18ca8d75588edc6ea3b7a8e
5
+ SHA512:
6
+ metadata.gz: ead73b5e863e59e3fefcad08225f1b144a6e7a7572902c333ff1ce7774041d24c7eecbb202ba933b3dff7a212e5aaa19b58d84f66712a75ab1fc687c6e6935d1
7
+ data.tar.gz: 616fddeeddf282c24a3ad9eeebfeb1cb8c82f1e79b4656360b8a68bdaa2357c8b996e148c2ca41ecef625bb54a3aa6eb8c93b8ede4d5b8aaf318a9777f291b70
@@ -0,0 +1,29 @@
1
+ # CHANGELOG
2
+
3
+ ## v0.8.0 (Apr 10, 2015)
4
+ * Remove `swim` executable.
5
+ * Remove YAML configuration.
6
+ * Add `Goggles.configure` for configuration through a block (like RSpec).
7
+ * Remove reserved instance variables like `@gg_url`.
8
+ * Scripts are executed via blocks passed to `Goggles.each`.
9
+ * `Goggles.each` yields a browser instance with the `#grab_screenshot` method.
10
+ * README updates.
11
+ * Add this CHANGELOG.
12
+
13
+ ## v0.1.4 (Jan 28, 2014)
14
+ * Small code enhancements with no user impact.
15
+
16
+ ## v0.1.3 (Jan 23, 2014)
17
+ * Do not delete cookies before each script.
18
+ * Make `@gg_url` variable available to scripts.
19
+
20
+ ## v0.1.2 (Jan 21, 2014)
21
+ * Add diff color configuration setting.
22
+ * Default color setting to blue.
23
+ * Prepend all instance variables with `gg_`.
24
+
25
+ ## v0.1.1 (Jan 20, 2014)
26
+ * Add command line option for generating default project
27
+
28
+ ## v0.1.0 (Jan 20, 2014)
29
+ * Initial release
data/README.md CHANGED
@@ -1,98 +1,149 @@
1
1
  # goggles
2
2
  [![Gem Version](https://badge.fury.io/rb/goggles.png)](http://badge.fury.io/rb/goggles)
3
3
 
4
- Goggles is a visual testing tool inspired by [wraith](http://github.com/bbc-news/wraith) and powered by [watir-webdriver](http://github.com/watir/watir-webdriver). It allows you to compare screenshots of your web application in different browsers, and you can execute Ruby scripts to setup as many screenshots as you need.
4
+ Goggles is a visual testing tool inspired by [wraith](http://github.com/bbc-news/wraith) and powered by [watir-webdriver](http://github.com/watir/watir-webdriver). It compares screenshots of your web applications in different browsers at differents sizes.
5
5
 
6
- ## Installation
6
+ ## Usage
7
7
 
8
- Install ImageMagick:
8
+ ### Configuration
9
9
 
10
- * OSX: `$ brew install imagemagick`
11
- * Linux: `$ sudo apt-get install imagemagick`
12
- * Windows: [Download](http://www.imagemagick.org/script/binary-releases.php#windows) installer and add to your PATH.
10
+ Configure Goggles with a block passed to the `Goggles.configure` method, which will yield a config object to your block for manipulation. The `directory` setting must be configured for Goggles to work. You'll also need to provide `browsers` and `sizes` that you'd like to compare, but those can be configured with the script.
13
11
 
14
- Add this line to your application's Gemfile:
12
+ The `fuzzing` and `color` attributes default to "blue" and "20%" respectively.
15
13
 
16
- gem 'goggles'
14
+ ```ruby
15
+ Goggles.configure do |config|
16
+ config.directory = "/path/to/my/results"
17
+ config.browsers = [:chrome, :firefox, :phantomjs]
18
+ config.sizes = [1080, 600]
19
+ config.color = "red"
20
+ end
21
+ ```
17
22
 
18
- And then execute:
23
+ ### Scripting
19
24
 
20
- $ bundle
25
+ Your Scripts are passed to `Goggles.each` as blocks. Goggles will iterate over the block with each combination of browser/browser size configured, and the method will yield a browser object to your script block.
21
26
 
22
- Or install it yourself with:
27
+ ```ruby
28
+ Goggles.each do |browser|
29
+ browser.goto "http://www.google.com"
30
+ browser.text_field(id: "lst-ib").value = "Google"
31
+ end
32
+ ```
23
33
 
24
- $ gem install goggles
34
+ #### Browsers and sizes
25
35
 
26
- ## Usage
36
+ You can pass additional browsers or browser sizes to `Goggles.each` as arrays. With version 0.8.0, these arguments will overwrite what you've configured through `Goggles.configure`.
37
+
38
+ ```ruby
39
+ Goggles.each([:chrome, :firefox], [1080]) do |browser|
40
+ # ...
41
+ end
42
+ ```
27
43
 
28
- Generate a config file with `swim --init` to point goggles in the right direction.
44
+ **TODO**
29
45
 
30
- $ swim -i /home/configs/config.yaml
46
+ Before the 1.0.0 release, these arguments will act as additonal browsers/sizes to script against. That way, the base configuration can be extended for particular script instances.
31
47
 
32
- ``` yaml
33
- # config.yaml
34
- # Directory where you want to store your results. Required.
35
- results_directory: "/home/example/results"
48
+ #### Screenshots
36
49
 
37
- # Directory where you're storing your scripts. Optional.
38
- scripts_directory: "/home/example/scripts"
50
+ Your script blocks should include the `Watir::Browser#grab_screenshot` method, which has been patched onto the browser objects yielded to your blocks. Simply give the method a description argument and the screenshot will be saved to your configured directory.
39
51
 
40
- # Scripts to execute in the scripts directory. Optional.
41
- scripts_to_execute:
42
- - "first_script.rb"
43
- - "second_script.rb"
52
+ ```ruby
53
+ Goggles.each do |browser|
54
+ browser.goto "http://www.google.com"
55
+ browser.grab_screenshot "homepage"
56
+ end
57
+ ```
44
58
 
45
- # Domain to test. Required.
46
- domain_under_test: "http://www.google.com"
59
+ #### Closing the browser
47
60
 
48
- # Paths to pages you want to test. Label them with a page name. Required.
49
- paths_to_capture:
50
- home: "/"
51
- gmail: "/gmail"
61
+ There's no need to explicitly close the browser objects in your script blocks. Goggles will handle that.
52
62
 
53
- # Browsers you want to compare. Cannot specify more than two (yet). Required.
54
- browsers:
55
- - "chrome"
56
- - "firefox"
63
+ #### Results
57
64
 
58
- # Widths at which you would like screenshots compared. All screenshots will be taken at a height of 768. Required.
59
- browser_widths:
60
- - 1024
65
+ Screenshots are saved to your configured directory. Screenshot comparison results are saved to a sub-folder based on the screenshot description and browser size. Results include a diff image and data file.
61
66
 
62
- # Fuzzing percentage. Play around with this to find the right fit. Required.
63
- image_fuzzing: "20%"
67
+ ```ruby
68
+ Goggles.configure do |c|
69
+ c.directory = "/goggles/results"
70
+ c.browsers = [:chrome, :firefox, :phantomjs]
71
+ c.sizes = [1080, 600]
72
+ end
64
73
 
65
- # Color for diffing images. Defaults to blue. Optional.
66
- diff_color: "blue"
74
+ Goggles.each do |browser|
75
+ browser.goto "http://www.google.com"
76
+ browser.grab_screenshot "google"
77
+ end
67
78
  ```
68
79
 
69
- If you pass scripts to goggles as part of your testing, you **must** specify when screenshots should be taken with the `#grab_screenshot` method. If you do not specify scripts in configuration, goggles will open each of your paths and take a screenshot.
70
80
 
71
- NOTE: I've tried to keep variable names as unlikely to interrupt your code as possible, but `@watir` is reserved for the browser instance currently executing scripts.
81
+ ```
82
+ /goggles/results
83
+ |- google_1080_chrome.png
84
+ |- google_1080_firefox.png
85
+ |- google_1080_phantomjs.png
86
+ |- google_600_chrome.png
87
+ |- google_600_firefox.png
88
+ |- google_600_phantomjs.png
89
+ |- /google_1080
90
+ |- chrome_firefox_data.txt
91
+ |- chrome_firefox_diff.png
92
+ |- chrome_phantomjs_data.txt
93
+ |- chrome_phantomjs_diff.png
94
+ |- firefox_phantomjs_data.txt
95
+ |- firefox_phantomjs_diff.png
96
+ |- /google_600
97
+ |- chrome_firefox_data.txt
98
+ |- chrome_firefox_diff.png
99
+ |- chrome_phantomjs_data.txt
100
+ |- chrome_phantomjs_diff.png
101
+ |- firefox_phantomjs_data.txt
102
+ |- firefox_phantomjs_diff.png
103
+ ```
72
104
 
73
- ``` ruby
74
- # script_to_execute.rb
75
- require 'goggles'
76
- @watir.cookies.add("cookie_name", "cookie_value")
105
+ ## Road to 1.0.0
77
106
 
78
- # Pass a short description to the method for naming the resultant screenshot
79
- Goggles.grab_screenshot("with_cookie_set")
80
- ```
107
+ I've made a lot of changes recently and bumped the version up to 0.8.0. Check the [/CHANGELOG.md](changelog) for more information about those changes.
108
+
109
+ ### v0.9.0
81
110
 
82
- Execute a goggles test through the command line with `swim --config CONFIG_FILE` or use `swim --help` to see command options.
111
+ * Browser/size arguments against `Goggles.each` extend configuration instead of overwriting it.
112
+ * End-to-end Cucumber tests
83
113
 
84
- $ swim -c config.yml
114
+ ### v1.0.0
115
+
116
+ * Documentation
117
+ * Examples
118
+ * TravisCI integration for specs (but not features)
119
+
120
+ ## Installation
121
+
122
+ Install ImageMagick:
123
+
124
+ * OSX: `$ brew install imagemagick`
125
+ * Ubuntu: `$ sudo apt-get install imagemagick`
126
+ * Windows: [Download](http://www.imagemagick.org/script/binary-releases.php#windows) installer and add to your PATH.
127
+
128
+ Add this line to your application's Gemfile:
129
+
130
+ gem 'goggles'
131
+
132
+ And then execute:
133
+
134
+ $ bundle
135
+
136
+ Or install it yourself with:
137
+
138
+ $ gem install goggles
85
139
 
86
140
  ## Contributing
87
141
 
88
142
  1. Fork it ( http://github.com/jdenen/goggles/fork )
89
143
  2. Create your feature branch (`git checkout -b my-new-feature`)
90
- 3. Code until specs pass (`rspec`)*
91
- 4. Commit your changes (`git commit -am 'Add some feature'`)
92
- 5. Push to the branch (`git push origin my-new-feature`)
93
- 6. Create new Pull Request
94
-
95
- \*Chrome and [ChromeDriver](http://code.google.com/p/selenium/wiki/ChromeDriver) are required to pass specs. Download the latest version and add it to your PATH before running `rspec`.
144
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
145
+ 4. Push to the branch (`git push origin my-new-feature`)
146
+ 5. Create new Pull Request
96
147
 
97
148
  ## Questions, Comments, Concerns
98
- Easiest place to reach me is Twitter, [@jpdenen](http://twitter.com/jpdenen)
149
+ Find me on Twitter ([@jpdenen](http://twitter.com/jpdenen)) or write up an issue.
@@ -7,9 +7,9 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "goggles"
8
8
  spec.version = Goggles::VERSION
9
9
  spec.authors = ["Johnson Denen"]
10
- spec.email = ["jdenen@manta.com"]
11
- spec.summary = %q{comparing responsive screenshots under watir-webdriver}
12
- spec.description = %q{comparing responsive screenshots under watir-webdriver}
10
+ spec.email = ["johnson.denen@gmail.com"]
11
+ spec.summary = %q{Compare screenshots in different browers at differnt sizes}
12
+ spec.description = %q{Compare screenshots in different browers at differnt sizes}
13
13
  spec.homepage = "http://github.com/jdenen/goggles"
14
14
  spec.license = "MIT"
15
15
 
@@ -23,6 +23,4 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_runtime_dependency "watir-webdriver"
25
25
  spec.add_runtime_dependency "image_size"
26
-
27
- spec.executables << "swim"
28
26
  end
@@ -1,81 +1,28 @@
1
- require "goggles/version"
1
+ require "goggles/configuration"
2
2
  require "goggles/comparison"
3
- require "goggles/error"
4
-
5
- require "watir-webdriver"
6
- require "yaml"
7
- require "fileutils"
3
+ require "goggles/iteration"
8
4
 
9
5
  module Goggles
10
6
  extend self
11
-
12
- def swim(config_path)
13
- conf = YAML::load(File.open(config_path))
14
-
15
- @gg_result_dir = conf['results_directory']
16
- @gg_script_dir = conf['scripts_directory']
17
- @gg_domain = conf['domain_under_test']
18
- @gg_paths = conf['paths_to_capture']
19
- @gg_scripts = conf['scripts_to_execute']
20
- @gg_platforms = conf['browsers']
21
- @gg_widths = conf['browser_widths']
22
- @gg_fuzz = conf['image_fuzzing']
23
- @gg_color = conf['diff_color'] || 'blue'
24
-
25
- embark!
26
- diff_images
7
+
8
+ def configure &block
9
+ configuration.tap { |conf| yield conf }
27
10
  end
28
11
 
29
- def grab_screenshot(detail)
30
- make_result_dir
31
-
32
- image_dir = "#{@gg_result_dir}/#{@gg_label}"
33
- image_name = "#{detail}_#{@gg_size}_#{@gg_browser}"
34
-
35
- @watir.screenshot.save "#{image_dir}/#{image_name}.png"
36
- end
37
-
38
- private
39
-
40
- def embark!
41
- ensure_fresh_start
12
+ def each browsers = nil, sizes = nil, &block
13
+ browsers ||= configuration.browsers
14
+ sizes ||= configuration.sizes
42
15
 
43
- @gg_widths.each do |size|
44
- @gg_size = size.to_i
45
-
46
- @gg_platforms.each do |pf|
47
- @gg_browser = pf
48
-
49
- @watir = Watir::Browser.new pf.to_sym
50
- @watir.driver.manage.window.resize_to(@gg_size, 768)
51
-
52
- @gg_paths.each do |label, path|
53
- @gg_label = label
54
- @gg_url = "#{@gg_domain}#{path}"
55
-
56
- if @gg_scripts.nil?
57
- @watir.goto @gg_url
58
- grab_screenshot("screenshot")
59
- else
60
- @gg_scripts.each do |script|
61
- script = "#{@gg_script_dir}/#{script}"
62
- @watir.goto @gg_url
63
- eval(File.read(script))
64
- end
65
- end
66
- end
67
-
68
- @watir.close
69
- end
16
+ browsers.product(sizes).each do |browser, size|
17
+ Iteration.new browser, size, configuration, &block
70
18
  end
19
+
20
+ Comparison.new(configuration).tap { |comparison| comparison.make! }
71
21
  end
72
22
 
73
- def ensure_fresh_start
74
- FileUtils.rm_rf("#{@gg_result_dir}")
75
- end
23
+ private
76
24
 
77
- def make_result_dir
78
- FileUtils.mkdir_p("#{@gg_result_dir}/#{@gg_label}")
25
+ def configuration
26
+ @configuration ||= Configuration.new
79
27
  end
80
-
81
28
  end
@@ -1,50 +1,84 @@
1
1
  require "image_size"
2
2
 
3
3
  module Goggles
4
+ class Comparison
5
+ attr_reader :directory, :fuzzing, :color, :groups, :results_dir
6
+
7
+ def initialize config
8
+ @directory = config.directory
9
+ @fuzzing = config.fuzzing
10
+ @color = config.color
11
+ @groups = config.groups
12
+ end
13
+
14
+ def make!
15
+ cut_to_common_size
16
+ highlight_differences
17
+ end
18
+
19
+ def cut_to_common_size
20
+ groups.each_with_object([]) do |group, sizes|
21
+ collection = find_comparable group
22
+
23
+ collection.each do |img|
24
+ File.open(img, 'rb'){ |file| sizes << read_size(file) }
25
+ end
4
26
 
5
- def diff_images
6
- images = Dir.glob("#{@gg_result_dir}/*/*.png").sort
7
- raise Goggles::EmptyResultError, "No screenshots found in results directory: #{@gg_result_dir}" if images.empty?
8
-
9
- size_to_smallest!
27
+ cut! collection, sizes
28
+ end
29
+ end
10
30
 
11
- until images.empty?
12
- one = images.slice!(0)
13
- two = images.slice!(0)
31
+ def highlight_differences
32
+ groups.each do |desc|
33
+ ensure_result_directory desc
34
+ find_comparable(desc).combination(2).to_a.each { |imgs| diff imgs[0], imgs[1] }
35
+ end
36
+ end
14
37
 
15
- out_path = one.gsub(/[^_]*$/, '')
38
+ def find_comparable description
39
+ Dir.glob("#{directory}/*.png").grep(/#{description}_/).sort
40
+ end
16
41
 
17
- diff_out = "#{out_path}diff.png"
18
- data_out = "#{out_path}data.txt"
42
+ def find_common_width array
43
+ array.collect(&:first).sort.first
44
+ end
19
45
 
20
- `compare -fuzz #{@gg_fuzz} -metric AE -highlight-color #{@gg_color} #{one} #{two} #{diff_out} 2>#{data_out}`
46
+ def find_common_height array
47
+ array.collect(&:last).sort.first
21
48
  end
22
- end
23
49
 
24
- def size_to_smallest!
25
- images = Dir.glob("#{@gg_result_dir}/*/*.png").sort
50
+ private
26
51
 
27
- until images.empty?
28
- pair = images.slice!(0..1)
29
- widths = []
30
- heights = []
52
+ attr_writer :results_dir
31
53
 
32
- File.open(pair[0], 'rb') do |one|
33
- size = ImageSize.new(one.read).size
34
- widths << size[0]
35
- heights << size[1]
54
+ def cut! images, sizes
55
+ w = find_common_width sizes
56
+ h = find_common_height sizes
57
+ images.each { |img| `convert #{img} -background none -extent #{w}x#{h} #{img}` }
58
+ end
36
59
 
37
- File.open(pair[1], 'rb') do |two|
38
- size = ImageSize.new(two.read).size
39
- widths << size[0]
40
- heights << size[1]
60
+ def diff img_one, img_two
61
+ b1 = diffed img_one
62
+ b2 = diffed img_two
63
+
64
+ fuzz = "#{results_dir}/#{b1}_#{b2}_diff.png"
65
+ data = "#{results_dir}/#{b1}_#{b2}_data.txt"
66
+
67
+ `compare -fuzz #{fuzzing} -metric AE -highlight-color #{color} #{img_one} #{img_two} #{fuzz} 2>#{data}`
68
+ end
41
69
 
42
- pair.each do |file|
43
- `convert #{file} -background none -extent #{widths.sort[0]}x#{heights.sort[0]} #{file}`
44
- end
45
- end
46
- end
70
+ def diffed img
71
+ File.basename(img).match(/\d+_(.*)\.png/)[1]
72
+ end
73
+
74
+ def read_size file
75
+ ImageSize.new(file.read).size
47
76
  end
48
- end
49
77
 
78
+ def ensure_result_directory description
79
+ self.results_dir = "#{directory}/#{description}"
80
+ FileUtils.rm_rf results_dir
81
+ FileUtils.mkdir_p results_dir
82
+ end
83
+ end
50
84
  end
@@ -0,0 +1,20 @@
1
+ module Goggles
2
+ class Configuration
3
+ attr_accessor :browsers, :sizes, :fuzzing, :color, :groups
4
+ attr_reader :directory
5
+
6
+ def initialize
7
+ @browsers = []
8
+ @sizes = []
9
+ @groups = []
10
+ @directory = ""
11
+ @color = "blue"
12
+ @fuzzing = "20%"
13
+ end
14
+
15
+ def directory=(path)
16
+ @directory = path
17
+ FileUtils.mkdir_p path unless path.empty?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ require "watir-webdriver"
2
+
3
+ module Watir
4
+ class Browser
5
+ attr_accessor :goggles, :iteration
6
+
7
+ def grab_screenshot name
8
+ description = "#{name}_#{iteration.size}"
9
+ goggles.groups << description unless goggles.groups.include? description
10
+ screenshot.save "#{goggles.directory}/#{description}_#{iteration.browser_name}.png"
11
+ end
12
+ end
13
+ end
14
+
15
+ module Goggles
16
+ class Iteration
17
+ attr_reader :browser, :browser_name, :size, :config
18
+
19
+ def initialize driver, width, config, &block
20
+ @browser_name = driver
21
+ @config = config
22
+ @size = width
23
+ build_browser
24
+ yield browser
25
+ browser.close
26
+ end
27
+
28
+ private
29
+
30
+ def build_browser
31
+ @browser = Watir::Browser.new(browser_name).tap do |engine|
32
+ engine.goggles = config
33
+ engine.iteration = self
34
+ engine.driver.manage.window.resize_to size, 768
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Goggles
2
- VERSION = "0.1.4"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -0,0 +1,99 @@
1
+ require "spec_helper"
2
+
3
+ describe Goggles::Comparison do
4
+ let(:config){ instance_double "configuration" }
5
+ let(:comparison){ Goggles::Comparison.new config }
6
+
7
+ before do
8
+ allow(config).to receive_messages(
9
+ directory: "dir",
10
+ fuzzing: "20%",
11
+ color: "blue",
12
+ groups: [1])
13
+ end
14
+
15
+ it "reads attributes from a given configuration object" do
16
+ expect(config).to receive(:directory)
17
+ expect(config).to receive(:fuzzing)
18
+ expect(config).to receive(:color)
19
+ Goggles::Comparison.new config
20
+ end
21
+
22
+ describe "#make!" do
23
+ it "cuts images and highlights their differences" do
24
+ expect(comparison).to receive(:cut_to_common_size)
25
+ expect(comparison).to receive(:highlight_differences)
26
+ comparison.make!
27
+ end
28
+ end
29
+
30
+ describe "#cut_to_common_size" do
31
+ it "iterates over screenshot descriptions" do
32
+ groups = instance_double "[groups]"
33
+ expect(comparison).to receive(:groups).and_return groups
34
+ expect(groups).to receive(:each_with_object).with([])
35
+ comparison.cut_to_common_size
36
+ end
37
+
38
+ it "collects comparable screenshots" do
39
+ expect(comparison).to receive(:groups).and_return [1, 2]
40
+ expect(comparison).to receive(:find_comparable).with(1).and_return([])
41
+ expect(comparison).to receive(:find_comparable).with(2).and_return([])
42
+ comparison.cut_to_common_size
43
+ end
44
+
45
+ context "with collection of comparable screenshots" do
46
+ it "iterates over the collection" do
47
+ screens = instance_double "[screenshots]"
48
+ expect(comparison).to receive(:groups).and_return ["foo"]
49
+ expect(comparison).to receive(:find_comparable).and_return screens
50
+ expect(screens).to receive(:each)
51
+ expect(comparison).to receive(:cut!).with(screens, [])
52
+ comparison.cut_to_common_size
53
+ end
54
+ end
55
+
56
+ context "while iterating over collected comparable images" do
57
+ it "opens each image in binary mode" do
58
+ expect(comparison).to receive(:find_comparable).and_return [:foo]
59
+ expect(File).to receive(:open).with(:foo, 'rb')
60
+ expect(comparison).to receive(:cut!)
61
+ comparison.cut_to_common_size
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "#highlight_differences" do
67
+ it "diffs every combination of comparable screenshots" do
68
+ images = ["foo_1.png", "foo_2.png", "foo_3.png"]
69
+ expect(comparison).to receive(:groups).and_return ["foo"]
70
+ expect(comparison).to receive(:find_comparable).with("foo").and_return images
71
+ images.combination(2).to_a.each do |i|
72
+ expect(comparison).to receive(:diff).with i[0], i[1]
73
+ end
74
+ comparison.highlight_differences
75
+ end
76
+ end
77
+
78
+ describe "#find_comparable" do
79
+ it "returns an array of file paths" do
80
+ array = ["/foo_chrome.png", "/bar_chrome.png", "/foo_ff.png", "/bar_ff.png"]
81
+ expect(Dir).to receive(:glob).and_return array
82
+ expect(comparison.find_comparable "foo").to eq ["/foo_chrome.png", "/foo_ff.png"]
83
+ end
84
+ end
85
+
86
+ describe "#find_common_width" do
87
+ it "returns the smallest number from first items in an array of arrays" do
88
+ arrays = [[100,40], [68,300], [104,98]]
89
+ expect(comparison.find_common_width arrays).to eq 68
90
+ end
91
+ end
92
+
93
+ describe "#find_common_height" do
94
+ it "returns the smallest number from second items in an array of arrays" do
95
+ arrays = [[100,40], [68,300], [104,98]]
96
+ expect(comparison.find_common_height arrays).to eq 40
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Goggles::Configuration do
4
+ let(:config) { Goggles::Configuration.new }
5
+
6
+ it "has attributes by default" do
7
+ expect(config).to have_attributes(
8
+ :browsers => [],
9
+ :sizes => [],
10
+ :groups => [],
11
+ :directory => "",
12
+ :color => "blue",
13
+ :fuzzing => "20%"
14
+ )
15
+ end
16
+
17
+ it "has attributes that can be set" do
18
+ config.browsers << "chrome"
19
+ config.sizes << 100
20
+ config.groups << "foo"
21
+ config.color = "red"
22
+ config.fuzzing = "10%"
23
+
24
+ expect(config).to have_attributes(
25
+ :browsers => ["chrome"],
26
+ :sizes => [100],
27
+ :groups => ["foo"],
28
+ :color => "red",
29
+ :fuzzing => "10%"
30
+ )
31
+ end
32
+
33
+ describe "#directory=" do
34
+ it "ensures the directory exists" do
35
+ expect(FileUtils).to receive(:mkdir_p).with "/foo/bar"
36
+ config.directory = "/foo/bar"
37
+ expect(config.directory).to eq "/foo/bar"
38
+ end
39
+
40
+ context "when attribute is empty" do
41
+ it "does not create the directory" do
42
+ expect(FileUtils).to_not receive(:mkdir_p)
43
+ config.directory = ""
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe Goggles::Iteration do
4
+ let(:watir) { instance_double("browser") }
5
+
6
+ before do
7
+ allow(watir).to receive_messages(
8
+ :driver => watir,
9
+ :manage => watir,
10
+ :window => watir,
11
+ :goggles= => nil,
12
+ :iteration= => nil,
13
+ :resize_to => nil,
14
+ :close => nil)
15
+ end
16
+
17
+ it "yields an instantiated browser" do
18
+ expect(Watir::Browser).to receive(:new).and_return watir
19
+ expect { |b| Goggles::Iteration.new "", "", "", &b }.to yield_with_args watir
20
+ end
21
+
22
+ it "yields the browser based on the browser_name attribute" do
23
+ expect(Watir::Browser).to receive(:new).with(:foo).and_return watir
24
+ Goggles::Iteration.new(:foo, "", ""){ "bar" }
25
+ end
26
+
27
+ it "resizes the browser based on the size attribute" do
28
+ expect(Watir::Browser).to receive(:new).with(:foo).and_return watir
29
+ expect(watir).to receive(:resize_to).with(500, 768)
30
+ Goggles::Iteration.new(:foo, 500, ""){ "bar" }
31
+ end
32
+ end
@@ -1,41 +1,68 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Goggles do
4
- Given(:config_path) { "./spec/support/configs" }
5
- Given(:images) { Dir.glob("./spec/support/results/*/*.png") }
6
- Given(:diffs) { Dir.glob("./spec/support/results/*/*diff.png") }
7
- Given(:datas) { Dir.glob("./spec/support/results/*/*data.txt") }
4
+ before { allow(FileUtils).to receive(:mkdir_p) }
5
+
6
+ describe ".configure" do
7
+ it "yields a configuration object" do
8
+ expect { |b| Goggles.configure &b }.to yield_with_args Goggles::Configuration
9
+ end
8
10
 
9
- context "swimming with one script at multiple sizes" do
10
- describe "taking screenshots" do
11
- Given(:sizes_config) { "#{config_path}/test_config_1024_600.yml" }
12
- When { Goggles.swim(sizes_config) }
13
- Then { images.size.should == 6 }
14
- And { diffs.size.should == 2 }
15
- And { datas.size.should == 2 }
11
+ it "returns a configuration object" do
12
+ expect(Goggles.configure { "foo" }).to be_a Goggles::Configuration
16
13
  end
17
14
 
18
- describe "generating error" do
19
- Given(:no_shot_config) { "#{config_path}/test_config_no_screenshot.yml" }
20
- Then { expect{ Goggles.swim(no_shot_config) }.to raise_error(Goggles::EmptyResultError) }
15
+ it "memoizes the configuration object" do
16
+ expect(Goggles.configure { "foo" }).to equal Goggles.configure { "bar" }
21
17
  end
22
18
  end
23
19
 
24
- context "swimming against multiple paths with no scripts" do
25
- describe "taking screenshots when commanded" do
26
- Given(:scriptless_config) { "#{config_path}/test_config_scriptless.yml" }
27
- When { Goggles.swim(scriptless_config) }
28
- Then { images.size.should == 6 }
29
- And { diffs.size.should == 2 }
30
- And { datas.size.should == 2 }
20
+ describe ".each" do
21
+ let(:config) do
22
+ Goggles.configure do |conf|
23
+ conf.browsers = [:foo]
24
+ conf.sizes = [500]
25
+ end
31
26
  end
32
- end
33
27
 
34
- describe "creating empty configuration with --init" do
35
- Given(:conf) { "spec/support/configs/empty_config.yml" }
36
- Given { FileUtils.rm_f conf }
37
- When { `swim -i #{conf}` }
38
- Then { File.exists?(conf).should be_true }
39
- end
28
+ before do
29
+ allow(config).to receive_messages(directory: "/dir", fuzzing: "20%", color: "blue", groups: [])
30
+ end
31
+
32
+ it "passes browser, width, and configuration to an iteration object" do
33
+ expect(Goggles::Iteration).to receive(:new).with(:foo, 500, config)
34
+ Goggles.each { "foo" }
35
+ end
36
+
37
+ it "accepts non-configured browser and size arguments" do
38
+ expect(Goggles::Iteration).to receive(:new).with(:bar, 300, config)
39
+ Goggles.each([:bar], [300]) { "foo" }
40
+ end
41
+
42
+ it "returns a comparison object" do
43
+ expect(Goggles::Iteration).to receive(:new).with(:foo, 500, config)
44
+ expect(Goggles.each { "foo" }).to be_a Goggles::Comparison
45
+ end
46
+
47
+ context "when configured for browsers at one size" do
48
+ it "creates an iteration for each browser with the width" do
49
+ config.browsers << :bar
50
+ [:foo, :bar].each { |browser| expect(Goggles::Iteration).to receive(:new).with browser, 500, config }
51
+ Goggles.each { "foo" }
52
+ end
53
+ end
54
+
55
+ context "when configured for browsers at different sizes" do
56
+ it "creates an iteration for every browser and width combination" do
57
+ config.browsers << :bar
58
+ config.sizes << 1000
40
59
 
60
+ [:foo, :bar].product([500, 1000]).each do |browser, width|
61
+ expect(Goggles::Iteration).to receive(:new).with browser, width, Object
62
+ end
63
+
64
+ Goggles.each { "foo" }
65
+ end
66
+ end
67
+ end
41
68
  end
@@ -1,10 +1,2 @@
1
- require 'rspec'
2
- require 'rspec-given'
1
+ require "goggles"
3
2
 
4
- require 'goggles'
5
-
6
- RSpec.configure do |config|
7
- config.order = 'default'
8
- config.treat_symbols_as_metadata_keys_with_true_values = true
9
- config.filter_run_excluding :skip => true
10
- end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goggles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
5
- prerelease:
4
+ version: 0.8.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Johnson Denen
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-01-28 00:00:00.000000000 Z
11
+ date: 2015-04-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,124 +27,111 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: watir-webdriver
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: image_size
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - '>='
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
- description: comparing responsive screenshots under watir-webdriver
83
+ description: Compare screenshots in different browers at differnt sizes
95
84
  email:
96
- - jdenen@manta.com
97
- executables:
98
- - swim
85
+ - johnson.denen@gmail.com
86
+ executables: []
99
87
  extensions: []
100
88
  extra_rdoc_files: []
101
89
  files:
102
90
  - .gitignore
91
+ - CHANGELOG.md
103
92
  - Gemfile
104
93
  - LICENSE.txt
105
94
  - README.md
106
95
  - Rakefile
107
- - bin/swim
108
96
  - goggles.gemspec
109
97
  - lib/goggles.rb
110
- - lib/goggles/cli.rb
111
98
  - lib/goggles/comparison.rb
112
- - lib/goggles/error.rb
99
+ - lib/goggles/configuration.rb
100
+ - lib/goggles/iteration.rb
113
101
  - lib/goggles/version.rb
102
+ - spec/goggles/comparison_spec.rb
103
+ - spec/goggles/configuration_spec.rb
104
+ - spec/goggles/iteration_spec.rb
114
105
  - spec/goggles_spec.rb
115
106
  - spec/spec_helper.rb
116
- - spec/support/configs/test_config_1024_600.yml
117
- - spec/support/configs/test_config_no_screenshot.yml
118
- - spec/support/configs/test_config_scriptless.yml
119
- - spec/support/scripts/google_search.rb
120
- - spec/support/scripts/no_screenshot.rb
121
107
  homepage: http://github.com/jdenen/goggles
122
108
  licenses:
123
109
  - MIT
110
+ metadata: {}
124
111
  post_install_message:
125
112
  rdoc_options: []
126
113
  require_paths:
127
114
  - lib
128
115
  required_ruby_version: !ruby/object:Gem::Requirement
129
- none: false
130
116
  requirements:
131
- - - ! '>='
117
+ - - '>='
132
118
  - !ruby/object:Gem::Version
133
119
  version: '0'
134
120
  required_rubygems_version: !ruby/object:Gem::Requirement
135
- none: false
136
121
  requirements:
137
- - - ! '>='
122
+ - - '>='
138
123
  - !ruby/object:Gem::Version
139
124
  version: '0'
140
125
  requirements: []
141
126
  rubyforge_project:
142
- rubygems_version: 1.8.23
127
+ rubygems_version: 2.0.14
143
128
  signing_key:
144
- specification_version: 3
145
- summary: comparing responsive screenshots under watir-webdriver
129
+ specification_version: 4
130
+ summary: Compare screenshots in different browers at differnt sizes
146
131
  test_files:
132
+ - spec/goggles/comparison_spec.rb
133
+ - spec/goggles/configuration_spec.rb
134
+ - spec/goggles/iteration_spec.rb
147
135
  - spec/goggles_spec.rb
148
136
  - spec/spec_helper.rb
149
- - spec/support/configs/test_config_1024_600.yml
150
- - spec/support/configs/test_config_no_screenshot.yml
151
- - spec/support/configs/test_config_scriptless.yml
152
- - spec/support/scripts/google_search.rb
153
- - spec/support/scripts/no_screenshot.rb
137
+ has_rdoc:
data/bin/swim DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'goggles/cli'
4
-
5
- Goggles::CLI.new ARGV
@@ -1,60 +0,0 @@
1
- require 'goggles'
2
- require 'optparse'
3
- require 'pathname'
4
-
5
- module Goggles
6
- class CLI
7
-
8
- def initialize(argv)
9
- opt_parser = OptionParser.new do |opts|
10
- opts.banner = "Goggles: Compare responsive screenshots in multiple browsers"
11
- opts.separator ""
12
- opts.separator "Options"
13
-
14
- opts.on("-c", "--config CONFIG_FILE", "configuration to execute") do |config|
15
- run_conf(config)
16
- end
17
-
18
- opts.on("-i", "--init CONFIG_FILE", "create empty config file") do |config|
19
- file = Pathname.new(config)
20
-
21
- if file.exist?
22
- puts "Configuration file already exists: #{Pathname.new(config).realpath}"
23
- else
24
- File.open(file, 'w+') { |f| f.write(YAML::dump(EMPTY_CONFIG)) }
25
- end
26
- end
27
-
28
- opts.on("-v", "--version", "Goggles::VERSION") do
29
- puts Goggles::VERSION
30
- end
31
-
32
- opts.on("-h", "--help", "help text") do
33
- puts opt_parser
34
- end
35
- end
36
-
37
- opt_parser.parse!
38
- end
39
-
40
- def run_conf(config)
41
- if File.exists? config
42
- Goggles.swim config
43
- else
44
- puts "Not a valid configuration file: #{config}"
45
- end
46
- end
47
-
48
- EMPTY_CONFIG = {
49
- 'results_directory' => "/home/example/results",
50
- 'scripts_directory' => "/home/example/scripts",
51
- 'scripts_to_execute' => ["first_example.rb", "second_example.rb"],
52
- 'domain_under_test' => "http://www.google.com",
53
- 'paths_to_capture' => { 'home' => "/", 'gmail' => "/gmail" },
54
- 'browsers' => ["chrome", "firefox"],
55
- 'browser_widths' => [1024, 600],
56
- 'image_fuzzing' => "20%",
57
- 'diff_color' => "blue"
58
- }
59
- end
60
- end
@@ -1,3 +0,0 @@
1
- module Goggles
2
- class EmptyResultError < StandardError; end
3
- end
@@ -1,20 +0,0 @@
1
- results_directory: "spec/support/results"
2
- scripts_directory: "spec/support/scripts"
3
-
4
- domain_under_test: "http://www.google.com"
5
-
6
- paths_to_capture:
7
- home: "/"
8
-
9
- scripts_to_execute:
10
- - "google_search.rb"
11
-
12
- browsers:
13
- - "firefox"
14
- - "chrome"
15
-
16
- browser_widths:
17
- - 1024
18
- - 600
19
-
20
- image_fuzzing: "20%"
@@ -1,19 +0,0 @@
1
- results_directory: "spec/support/results"
2
- scripts_directory: "spec/support/scripts"
3
-
4
- domain_under_test: "http://www.google.com"
5
-
6
- paths_to_capture:
7
- home: "/"
8
-
9
- scripts_to_execute:
10
- - "no_screenshot.rb"
11
-
12
- browsers:
13
- - "firefox"
14
- - "chrome"
15
-
16
- browser_widths:
17
- - 320
18
-
19
- image_fuzzing: "20%"
@@ -1,19 +0,0 @@
1
- results_directory: "spec/support/results"
2
- scripts_directory: "spec/support/scripts"
3
-
4
- domain_under_test: "http://www.google.com"
5
-
6
- paths_to_capture:
7
- home: "/"
8
- email: "/gmail"
9
-
10
- scripts_to_execute:
11
-
12
- browsers:
13
- - "firefox"
14
- - "chrome"
15
-
16
- browser_widths:
17
- - 1024
18
-
19
- image_fuzzing: "20%"
@@ -1,14 +0,0 @@
1
- require 'goggles'
2
- require 'page-object'
3
-
4
- class Search
5
- include PageObject
6
-
7
- text_field(:search_box, :id => "gbqfq")
8
- end
9
-
10
- Goggles.grab_screenshot("homepage")
11
-
12
- page = Search.new(@watir)
13
- page.search_box = "manta"
14
- sleep 1
@@ -1,12 +0,0 @@
1
- require 'goggles'
2
- require 'page-object'
3
-
4
- class Search
5
- include PageObject
6
-
7
- text_field(:search_box, :id => "gbqfq")
8
- end
9
-
10
- page = Search.new(@watir)
11
- page.search_box = "manta"
12
- sleep 1