gatling 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -9,3 +9,5 @@ test*
9
9
  .DS_Store
10
10
  spec/support/ready_candidate_ref/temp/*
11
11
  reports/*
12
+ vendor/*
13
+
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p125
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@gatling --create
data/Gemfile CHANGED
@@ -4,9 +4,7 @@ source "http://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  group :development, :test, :smoke do
7
- gem 'sinatra' ,'1.3.1'
8
- gem 'rack-test'
9
- gem 'rake'
10
- gem 'rspec-instafail'
11
- gem 'pry'
7
+ gem 'rake'
8
+ gem 'rspec-instafail'
9
+ gem 'pry'
12
10
  end
data/lib/gatling.rb CHANGED
@@ -1,88 +1,74 @@
1
+ #Dir["/gatling/*.rb"].each {|file| require file}
2
+
1
3
  require 'RMagick'
2
- require_relative 'gatling/capture_element'
3
4
  require 'capybara'
4
5
  require 'capybara/dsl'
5
- require 'gatling/config'
6
-
7
-
8
- module Gatling
9
- class Comparison
10
- include Capybara::DSL
11
-
12
- #TODO: Training mode
13
- #TODO: Diff with reports
14
- #TODO: Fuzz matches
15
- #TODO: Helpers for cucumber
16
6
 
17
- def initialize expected, actual
18
- @expected = expected
19
- @actual = actual
20
-
21
- @capture_element = Gatling::CaptureElement.new(@actual)
7
+ require 'gatling/config'
8
+ require 'gatling/file_helper'
9
+ require 'gatling/image'
10
+ require 'gatling/comparison'
11
+ require 'gatling/capture_element'
22
12
 
13
+ # include Gatling::Comparison
23
14
 
24
- @reference_image_path = Gatling::Configuration.reference_image_path
25
- @trainer_toggle = Gatling::Configuration.trainer_toggle
15
+ #TODO: Fuzz matches
16
+ #TODO: Helpers for cucumber
17
+ #TODO: Make directories as needed
26
18
 
27
- @expected_image = "#{@reference_image_path}/#{@expected}"
28
- @expected_filename = "#{@expected}".sub(/\.[a-z]*/,'')
29
- end
19
+ module Gatling
30
20
 
31
- def create_diff
32
- diff_path = "#{@reference_image_path}/diff"
21
+ class << self
33
22
 
34
- FileUtils::mkdir_p(diff_path)
23
+ def matches?(expected_reference_filename, actual_element)
35
24
 
36
- @diff_metric.first.write("#{diff_path}/#{@expected_filename}_diff.png")
25
+ Gatling::FileHelper.make_required_directories
37
26
 
38
- candidate = save_element_as_candidate(@cropped_element)
39
- raise "element did not match #{@expected}. A diff image: #{@expected_filename}_diff.png was created in #{diff_path}. A new reference #{candidate} can be used to fix the test"
40
- end
27
+ expected_reference_file = (File.join(Gatling::Configuration.paths[:reference], expected_reference_filename))
28
+ actual_image = Gatling::Image.new(:from_element, expected_reference_filename, actual_element)
41
29
 
42
- def save_element_as_candidate(element)
43
- candidate_path = "#{@reference_image_path}/candidate"
44
- candidate = @capture_element.save_element(element, @expected_filename, candidate_path)
30
+ if Gatling::Configuration.trainer_toggle
31
+ save_image_as_reference(actual_image)
32
+ return true
45
33
  end
46
34
 
47
- def save_element_as_reference(element)
48
- if File.exists?(@expected_image) == false
49
- @capture_element.save_element(element, @expected_filename, @reference_image_path)
50
- puts "Saved #{@expected_image} as reference"
51
- else
52
- puts "#{@expected_image.upcase} ALREADY EXISTS. REFERENCE IMAGE WAS NOT OVERWRITTEN. PLEASE DELETE THE OLD FILE TO UPDATE USING TRAINER"
53
- end
54
- end
55
-
56
- def matches?
57
- @cropped_element = @capture_element.crop
58
- if !@trainer_toggle
59
- if File.exists?(@expected_image)
60
- self.compare
61
- else
62
- candidate = self.save_element_as_candidate(@cropped_element)
63
- raise "The design reference #{@expected} does not exist, #{candidate} is now available to be used as a reference. Copy candidate to root reference_image_path to use as reference"
64
- end
65
- else
66
- self.save_element_as_reference(@cropped_element)
67
- matches = true
35
+ if !File.exists?(expected_reference_file)
36
+ save_image_as_candidate(actual_image)
37
+ return false
38
+ else
39
+ expected_image = Gatling::Image.new(:from_file, expected_reference_filename)
40
+ comparison = Gatling::Comparison.new(expected_image, actual_image)
41
+ unless comparison.match
42
+ actual_image.save(:as => :candidate)
43
+ save_image_as_diff(comparison.diff_image)
68
44
  end
45
+ comparison.match
69
46
  end
47
+ end
70
48
 
71
- def compare
72
- expected_img = Magick::Image.read(@expected_image).first
73
-
74
- @diff_metric = @cropped_element.compare_channel(expected_img, Magick::MeanAbsoluteErrorMetric)
49
+ private
75
50
 
76
- matches = @diff_metric[1] == 0.0
51
+ def save_image_as_diff(image)
52
+ image.save(:as => :diff)
53
+ raise "element did not match #{image.file_name}. A diff image: #{image.file_name} was created in " +
54
+ "#{File.join(Gatling::Configuration.paths[:diff],image.file_name)}. " +
55
+ "A new reference #{File.join(Gatling::Configuration.paths[:candidate],image.file_name)} can be used to fix the test"
56
+ end
77
57
 
78
- create_diff unless matches
58
+ def save_image_as_candidate(image)
59
+ image.save :as => :candidate
60
+ raise "The design reference #{image.file_name} does not exist, #{image.path} " +
61
+ "is now available to be used as a reference. Copy candidate to root reference_image_path to use as reference"
62
+ end
79
63
 
80
- matches
64
+ def save_image_as_reference(image)
65
+ if image.exists?
66
+ puts "#{image.path} already exists. reference image was not overwritten. please delete the old file to update using trainer"
67
+ else
68
+ image.save(:as => :reference)
69
+ puts "Saved #{image.path} as reference"
81
70
  end
82
71
  end
83
72
 
73
+ end
84
74
  end
85
-
86
-
87
-
88
-
@@ -1,52 +1,31 @@
1
+ require_relative 'image_wrangler'
2
+
1
3
  module Gatling
2
4
  class CaptureElement
3
5
 
4
- def initialize element_to_capture
6
+ def initialize element_to_capture, *element_to_exclude
5
7
  @reference_image_path = Gatling::Configuration.reference_image_path
6
- @element = element_to_capture
8
+ @element_to_capture = element_to_capture
9
+ @element_to_exclude = element_to_exclude.first
10
+
7
11
  end
8
12
 
9
13
  def capture
10
- temp_dir = "#{@reference_image_path}/temp"
11
14
 
12
- begin
13
- FileUtils::mkdir_p(temp_dir)
14
- rescue
15
- puts "Could not create directory #{temp_dir}. Please make sure you have permission"
16
- end
15
+ screenshot = self.take_screenshot
16
+ screenshot = exclude(screenshot, @element_to_exclude) if @element_to_exclude
17
+ Gatling::ImageWrangler.crop_element(screenshot, @element_to_capture)
18
+ end
17
19
 
20
+ def take_screenshot
21
+ temp_dir = "#{@reference_image_path}/temp"
18
22
  #captures the uncropped full screen
19
23
  begin
20
-
21
24
  Capybara.page.driver.browser.save_screenshot("#{temp_dir}/temp.png")
22
25
  temp_screenshot = Magick::Image.read("#{temp_dir}/temp.png").first
23
26
  rescue
24
27
  raise "Could not save screenshot to #{temp_dir}. Please make sure you have permission"
25
28
  end
26
29
  end
27
-
28
- def crop
29
- element = @element.native
30
- location = element.location
31
- size = element.size
32
- @cropped_element = self.capture.crop(location.x, location.y, size.width, size.height)
33
- end
34
-
35
- def save_element(element, element_name, path)
36
- begin
37
- FileUtils::mkdir_p(path)
38
- rescue
39
- puts "Could not create directory #{path}. Please make sure you have permission"
40
- end
41
-
42
- begin
43
- element.write("#{path}/#{element_name}.png")
44
- element = "#{path}/#{element_name}.png"
45
- rescue
46
- raise "Could not save #{element_name} to #{path}. Please make sure you have permission"
47
- end
48
- end
49
-
50
-
51
30
  end
52
31
  end
@@ -0,0 +1,25 @@
1
+ module Gatling
2
+ class Comparison
3
+
4
+ attr_accessor :match, :diff_image
5
+
6
+ def initialize(actual_image, expected_image)
7
+ compare(actual_image, expected_image)
8
+ end
9
+
10
+ def compare(actual_image, expected_image)
11
+ diff_metric = actual_image.image.compare_channel(expected_image.image, Magick::MeanAbsoluteErrorMetric)
12
+ @match = diff_metric[1] == 0.0
13
+ unless @match
14
+ diff_image = diff_metric.first
15
+ @diff_image = Gatling::Image.new(:from_diff, actual_image.file_name, diff_image)
16
+ end
17
+ @match
18
+ end
19
+
20
+ def diff_image
21
+ @diff_image
22
+ end
23
+
24
+ end
25
+ end
@@ -1,35 +1,59 @@
1
- module Gatling
1
+ module Gatling
2
2
  module Configuration
3
3
 
4
4
  class << self
5
5
 
6
- attr_accessor 'reference_image_path', 'trainer_toggle'
6
+ attr_accessor :reference_image_path, :trainer_toggle
7
+
8
+ attr_reader :paths
7
9
 
8
10
  def reference_image_path
9
- begin
10
- @reference_image_path ||= File.join(Rails.root, 'spec/reference_images')
11
- rescue
12
- raise "Not using Rails? Please set the reference_image_path"
13
- end
11
+ @reference_image_path ||= set_default_path
12
+ end
13
+
14
+ def paths
15
+ Hash[reference:reference_image_path,
16
+ candidate:File.join(reference_image_path, 'candidate'),
17
+ diff:File.join(reference_image_path, 'diff'),
18
+ temp:File.join(reference_image_path, 'temp')]
14
19
  end
15
20
 
16
21
  def trainer_toggle
17
22
  @trainer_value = ENV['GATLING_TRAINER']
18
-
23
+
19
24
  case @trainer_value
20
25
  when nil
21
26
  @trainer_value = nil
22
27
  when 'true'
23
28
  @trainer_value = true
24
29
  when 'false'
25
- @trainer_value = false
30
+ @trainer_value = false
26
31
  else
27
32
  @trainer_value = false
28
- puts 'Unknown GATLING_TRAINER argument. Please supply true, false or nil. DEFAULTING TO FALSE'
33
+ puts 'Unknown GATLING_TRAINER argument. Please supply true, false or nil. DEFAULTING TO FALSE'
29
34
  end
30
35
  @trainer_toggle ||= @trainer_value ||= false
31
36
  end
32
37
 
38
+ def path_from_type(type)
39
+ if paths.keys.include? type
40
+ return paths[type]
41
+ else
42
+ raise "Unkown image type '#{type}'"
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def set_default_path
49
+ begin
50
+ @reference_image_path ||= File.join(Rails.root, 'spec/reference_images')
51
+ rescue
52
+ @reference_image_path = 'spec/reference_images'
53
+ puts "Currently defaulting to #{@reference_image_path}. Overide this by setting Gatling::Configuration.reference_image_path=[refpath]"
54
+ end
55
+ @reference_image_path
56
+ end
33
57
  end
34
58
 
35
59
  end
@@ -0,0 +1,17 @@
1
+ module Gatling
2
+ class FileHelper
3
+ class << self
4
+
5
+ def make_required_directories
6
+ Gatling::Configuration.paths.each { | key, directory | make_dir directory }
7
+ end
8
+
9
+ private
10
+
11
+ def make_dir(path)
12
+ FileUtils::mkdir_p(File.join(path))
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,50 @@
1
+ module Gatling
2
+ class Image
3
+
4
+ attr_accessor :file_name, :path, :image
5
+
6
+ attr_reader :type
7
+
8
+ def initialize(type, file_name, element_or_image = nil)
9
+
10
+ @file_name = file_name
11
+
12
+ case type
13
+ when :from_file
14
+ @image = image_from_file(file_name)
15
+ when :from_element
16
+ @image = image_from_element(element_or_image)
17
+ when :from_diff
18
+ @image = element_or_image
19
+ else
20
+ raise 'WRONG IMAGE TYPE'
21
+ end
22
+
23
+ end
24
+
25
+ def save type
26
+ @path = File.join(Gatling::Configuration.path_from_type(type[:as]), @file_name)
27
+ @image.write @path
28
+ @path
29
+ end
30
+
31
+ def exists?
32
+ File.exists?(File.join(Gatling::Configuration.path_from_type(:reference), @file_name))
33
+ end
34
+
35
+ private
36
+
37
+ def image_from_element element
38
+ Gatling::CaptureElement.new(element).capture
39
+ end
40
+
41
+ def image_from_file file_name
42
+ Magick::Image.read(File.join(Gatling::Configuration.path_from_type(:reference), file_name)).first
43
+ end
44
+
45
+
46
+ end
47
+
48
+ end
49
+
50
+
@@ -0,0 +1,25 @@
1
+ module Gatling
2
+ class ImageWrangler
3
+
4
+ def self.get_element_position element
5
+
6
+ element = element.native
7
+ position = Hash.new{}
8
+ position[:x] = element.location.x
9
+ position[:y] = element.location.y
10
+ position[:width] = element.size.width
11
+ position[:height] = element.size.height
12
+ position
13
+ end
14
+
15
+ def self.crop_element image, element_to_crop
16
+ position = get_element_position(element_to_crop)
17
+ @cropped_element = image.crop(position[:x], position[:y], position[:width], position[:height])
18
+ end
19
+
20
+ def self.exclude image, element_to_exclude
21
+ end
22
+
23
+
24
+ end
25
+ end
@@ -2,7 +2,6 @@ require 'gatling'
2
2
 
3
3
  RSpec::Matchers.define :look_like do |expected|
4
4
  match do |actual|
5
- compare = Gatling::Comparison.new(expected, actual)
6
- compare.matches?
5
+ compare = Gatling.matches?(expected, actual)
7
6
  end
8
7
  end
@@ -1,3 +1,3 @@
1
1
  module Gatling
2
- VERSION = "1.0.6"
2
+ VERSION = "1.0.7"
3
3
  end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gatling::CaptureElement do
4
+
5
+ before do
6
+
7
+ capybara_node = mock (Capybara::Node::Element)
8
+ Gatling::Configuration.reference_image_path="./"
9
+ Gatling::CaptureElement.new capybara_node, capybara_node
10
+ end
11
+
12
+
13
+
14
+ # it 'should exclude a specified element from capture' do
15
+ # element_to_capture =
16
+
17
+ # element_to_exclude = 'womething.child'
18
+ # # @cropped_and_censored_element = (element_to_capture, element_to_exclude).exclude
19
+ # @cropped_and_censored_element.should_not equal(@element_to_capture)
20
+ # @cropped_and_censored_element.should_not equal(@element_to_exclude)
21
+ # end
22
+
23
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gatling::Comparison do
4
+
5
+ before do
6
+ apple = Magick::Image.new(100,100) { self.background_color = "green" }
7
+ orange = Magick::Image.new(100,100) { self.background_color = "orange" }
8
+ @apple = Gatling::Image.new(:from_diff, 'apple.png', apple)
9
+ @orange = Gatling::Image.new(:from_diff, 'orange.png', orange)
10
+ end
11
+
12
+ describe 'will compare two images' do
13
+
14
+ it 'will return true if the images are identical' do
15
+ subject = Gatling::Comparison.new(@apple, @apple)
16
+ subject.match.should == true
17
+ end
18
+
19
+ it 'will return false if the images are different' do
20
+ subject = Gatling::Comparison.new(@apple, @orange)
21
+ subject.match.should == false
22
+ end
23
+ end
24
+
25
+ describe 'Diff images' do
26
+ it 'will give us a diff' do
27
+ subject = Gatling::Comparison.new(@apple, @orange)
28
+ subject.diff_image.class.should == Gatling::Image
29
+ end
30
+ end
31
+ end
@@ -1,67 +1,86 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Gatling::Configuration" do
3
+ describe Gatling::Configuration do
4
4
 
5
5
  describe "#reference_image_path" do
6
+ before :each do
7
+ Gatling::Configuration.reference_image_path = nil
8
+ end
6
9
 
7
- before do
8
- begin
9
- # Check that rails exists, otherwise fake it for the test
10
- Module.const_get("Rails")
11
- rescue NameError
12
- module Rails
13
- def self.root
14
- "fake_rails_root"
10
+ describe "Without Rails" do
11
+ it "should default to './spec/reference_images' when not in a rails environment" do
12
+ Gatling::Configuration.reference_image_path.should eql("spec/reference_images")
13
+ end
14
+ end
15
+
16
+ describe "with rails" do
17
+
18
+ before do
19
+ begin
20
+ # Check that rails exists, otherwise fake it for the test
21
+ Module.const_get("Rails")
22
+ rescue NameError
23
+ module Rails
24
+ def self.root
25
+ "fake_rails_root"
26
+ end
15
27
  end
16
28
  end
17
29
  end
18
- end
19
-
20
30
 
31
+ it "should default to <Rails.root>/spec/reference_images in a rails environment" do
32
+ Gatling::Configuration.reference_image_path.should eql("fake_rails_root/spec/reference_images")
33
+ end
21
34
 
22
- it "should default to <Rails.root>/spec/reference_images" do
23
- Gatling::Configuration.reference_image_path.should eql("fake_rails_root/spec/reference_images")
24
- end
35
+ it "should be overrideable in a rails environment" do
36
+ Gatling::Configuration.reference_image_path = "my custom path"
37
+ Gatling::Configuration.reference_image_path.should eql("my custom path")
38
+ end
25
39
 
26
- it "should be overrideable" do
27
- Gatling::Configuration.reference_image_path = "my custom path"
28
- Gatling::Configuration.reference_image_path.should eql("my custom path")
29
40
  end
30
-
31
-
32
- end
41
+ end
33
42
 
34
43
  describe '#trainer_toggle' do
35
44
 
36
45
  it 'should default to false' do
37
46
  Gatling::Configuration.trainer_toggle.should eql(false)
38
47
  end
39
-
48
+
40
49
  it 'can be toggled to true' do
41
50
  Gatling::Configuration.trainer_toggle = true
42
51
  Gatling::Configuration.trainer_toggle.should eql(true)
43
52
  end
44
-
53
+
45
54
  it 'toggeled using GATLING_TRAINER = false' do
46
55
  ENV['GATLING_TRAINER'] = 'false'
47
56
  Gatling::Configuration.trainer_toggle.should eql(false)
48
57
  end
49
-
58
+
50
59
  it 'toggeled using GATLING_TRAINER = true' do
51
60
  ENV['GATLING_TRAINER'] = 'true'
52
61
  Gatling::Configuration.trainer_toggle.should eql(true)
53
62
  end
54
-
63
+
55
64
  it 'toggeled using GATLING_TRAINER = nil' do
56
65
  ENV['GATLING_TRAINER'] = nil
57
66
  Gatling::Configuration.trainer_toggle.should eql(false)
58
67
  end
59
-
68
+
60
69
  after(:each) do
61
70
  Gatling::Configuration.trainer_toggle = false
62
71
  ENV['GATLING_TRAINER'] = nil
63
72
  end
64
-
65
73
  end
66
74
 
75
+ describe 'paths' do
76
+ it 'should return the directory for a type of image' do
77
+ Gatling::Configuration.reference_image_path = "a_path"
78
+ Gatling::Configuration.path_from_type(:temp).should == 'a_path/temp'
79
+ end
80
+
81
+ it 'should thrown an error when you ask for the path of an unknown image type' do
82
+ expect { Gatling::Configuration.path_from_type(:unknown)}.should raise_error "Unkown image type 'unknown'"
83
+ end
84
+ end
85
+
67
86
  end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gatling::FileHelper do
4
+
5
+ describe ':make_dir' do
6
+ before :all do
7
+ Gatling::Configuration.reference_image_path = './gatling'
8
+ end
9
+
10
+ it 'should make required directories' do
11
+ FileUtils.should_receive(:mkdir_p).with './gatling/candidate'
12
+ FileUtils.should_receive(:mkdir_p).with './gatling/diff'
13
+ FileUtils.should_receive(:mkdir_p).with './gatling'
14
+ FileUtils.should_receive(:mkdir_p).with './gatling/temp'
15
+ Gatling::FileHelper.make_required_directories
16
+ end
17
+ end
18
+ end
data/spec/gatling_spec.rb CHANGED
@@ -1,107 +1,89 @@
1
1
  require 'spec_helper'
2
2
  include Capybara::DSL
3
3
 
4
-
5
4
  describe 'Gatling' do
6
5
 
7
-
8
6
  before(:all) do
9
-
10
- include Rack::Test::Methods
11
-
12
- def app
13
- Sinatra::Application
14
- end
15
-
16
- #expected image to compare with
17
- @example_good_image = 'smiley-faceicon.png'
18
-
19
7
  @spec_support_root = spec_support_root
8
+ @black_box = 'black.png'
9
+ @red_box = 'red.png'
10
+ create_images_for_web_page
20
11
  end
21
12
 
13
+ before(:each) do
14
+ @ref_path = Gatling::Configuration.reference_image_path = File.join(spec_support_root, 'ref_path')
15
+ end
22
16
 
23
17
  after(:each) do
24
18
  remove_refs(@ref_path)
19
+ Gatling::Configuration.trainer_toggle = false
25
20
  end
26
-
27
-
28
-
29
- describe 'creating an initial reference (expected) image' do
30
21
 
31
- before(:each) do
32
- @ref_path = Gatling::Configuration.reference_image_path = File.join(@spec_support_root, 'ref_path')
33
- end
22
+ describe 'Gatling, when no reference image exists' do
34
23
 
35
- it "should notify that no reference exists for image and create a candidate" do
36
- gatling = gatling_for_spec('smiley-faceicon.png')
37
- expect {gatling.matches?}.should raise_error(RuntimeError, "The design reference #{@example_good_image} does not exist, #{@ref_path}/candidate/#{@example_good_image} is now available to be used as a reference. Copy candidate to root reference_image_path to use as reference")
38
- File.exists?(File.join(@ref_path,'candidate','smiley-faceicon.png')).should be_true
39
- end
40
- end
24
+ it "will notify that no reference image exists and create a candidate image" do
25
+ black_element = element_for_spec
26
+ expected_error = "The design reference #{@black_box} does not exist, #{@ref_path}/candidate/#{@black_box} " +
27
+ "is now available to be used as a reference. " +
28
+ "Copy candidate to root reference_image_path to use as reference"
41
29
 
30
+ expect {Gatling.matches?(@black_box, black_element)}.should raise_error(RuntimeError, expected_error)
42
31
 
32
+ File.exists?(File.join(@ref_path, 'candidate', @black_box)).should be_true
33
+ end
34
+ end
43
35
 
44
- describe 'image comparison' do
36
+ describe 'Gatling image comparison' do
45
37
 
46
38
  before(:each) do
47
- # @ready_ref = Gatling::Configuration.reference_image_path = File.join(@spec_support_root, 'ready_candidate_ref')
48
- @ref_path = Gatling::Configuration.reference_image_path = File.join(@spec_support_root, 'ref_path')
49
- save_element_for_test
39
+ create_square_image(@ref_path, 'black')
50
40
  end
51
41
 
52
- it 'images match' do
53
- @gatling = gatling_for_spec('smiley-faceicon.png')
54
- @gatling.matches?.should be_true
42
+ it 'will return true if the images are identical' do
43
+ black_element = element_for_spec('#black')
44
+
45
+ Gatling.matches?(@black_box, black_element).should be_true
55
46
  end
56
47
 
57
- it 'images do not match and diff created' do
58
- #convert -fill none -stroke black -strokewidth 5 smiley-faceicon.png -draw 'arc 155,25 185,45 180' sad-faceicon.png
59
- convert_element_to_bad_element(File.join(@ref_path,"#{@example_good_image}"))
60
- gatling = gatling_for_spec('smiley-faceicon.png')
61
- expect {gatling.matches?}.should raise_error(RuntimeError, "element did not match #{@example_good_image}. A diff image: smiley-faceicon_diff.png was created in #{@ref_path}/diff. A new reference #{@ref_path}/candidate/#{@example_good_image} can be used to fix the test")
62
- File.exists?(File.join(@ref_path,'diff','smiley-faceicon_diff.png')).should be_true
63
- end
48
+ it 'will return false, creates new diff and candidate images if the images are different' do
49
+ red_element = element_for_spec('#red')
50
+ expected_error = "element did not match #{@black_box}. " +
51
+ "A diff image: #{@black_box} was created in #{@ref_path}/diff/#{@black_box}. " +
52
+ "A new reference #{@ref_path}/candidate/#{@black_box} can be used to fix the test"
53
+
54
+ expect {Gatling.matches?(@black_box, red_element)}.should raise_error(RuntimeError, expected_error)
55
+
56
+ File.exists?(File.join(@ref_path,'diff', @black_box)).should be_true
57
+ File.exists?(File.join(@ref_path,'candidate', @black_box)).should be_true
58
+ end
64
59
  end
65
60
 
61
+ describe 'Gatling trainer toggle' do
66
62
 
63
+ it 'will save a reference file if no reference file already exists' do
64
+ Gatling::Configuration.trainer_toggle = true
65
+ File.exists?(File.join(@ref_path, @black_box)).should be_false
66
+ $stdout.should_receive(:puts).with "Saved #{@ref_path}/#{@black_box} as reference"
67
+ black_element = element_for_spec
67
68
 
68
- describe 'trainer toggle' do
69
+ expect {Gatling.matches?(@black_box, black_element)}.should_not raise_error
69
70
 
70
- before(:each) do
71
- @ref_path = Gatling::Configuration.reference_image_path = File.join(@spec_support_root, 'ref_path')
71
+ File.exists?(File.join(@ref_path, @black_box)).should be_true
72
72
  end
73
73
 
74
- it 'should save a reference file to the nominated folder without raising an exception' do
74
+ it 'will warn if a reference already exists and not overwrite it' do
75
+ create_square_image(@ref_path, 'black')
75
76
  Gatling::Configuration.trainer_toggle = true
76
- gatling = gatling_for_spec('smiley-faceicon.png')
77
+ expected_message = " already exists. reference image was not overwritten. " +
78
+ "please delete the old file to update using trainer"
79
+ black_element = element_for_spec
80
+ reference_file_ctime = File.ctime(File.join(@ref_path,@black_box))
81
+
82
+ $stdout.should_receive(:puts).with expected_message
83
+ expect {Gatling.matches?(@black_box, black_element)}.should_not raise_error
77
84
 
78
- expect {gatling.matches?}.should_not raise_error
79
- File.exists?(File.join(@ref_path,'smiley-faceicon.png')).should be_true
80
- end
81
-
82
- it 'should alert that the file should be deleted if a reference already exists and not overwrite file' do
83
- save_element_for_test
84
- Gatling::Configuration.trainer_toggle = true
85
- gatling = gatling_for_spec('smiley-faceicon.png')
86
-
87
- reference_file_ctime = File.ctime(File.join(@ref_path,'smiley-faceicon.png'))
88
85
  sleep(1)
89
- expect {gatling.matches?}.should_not raise_error
90
-
91
- #checks if file was overwritten by comparing the time stamps
92
- reference_file_ctime.eql?(File.ctime(File.join(@ref_path,'smiley-faceicon.png'))).should be_true
86
+ reference_file_ctime.eql?(File.ctime(File.join(@ref_path, @black_box))).should be_true
93
87
  end
94
-
95
88
  end
96
-
97
-
98
-
99
-
100
- # MOCK SELENIUM ELEMENT
101
- # correct size (340px*42px)
102
- # image magick saves screenshot
103
- #create diff creates the correct candidate
104
-
105
-
106
89
  end
107
-
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gatling::Image do
4
+
5
+ before :all do
6
+ Gatling::Configuration.reference_image_path = './image_tests'
7
+ end
8
+
9
+ describe 'should initialize from' do
10
+
11
+ it 'image file type' do
12
+ File.stub(:exists?).and_return true
13
+ image_mock = mock(Magick::Image)
14
+ Magick::Image.should_receive(:read).with('./image_tests/image.png').and_return([image_mock])
15
+
16
+ subject = Gatling::Image.new(:from_file, 'image.png')
17
+ subject.image.should == image_mock
18
+ subject.file_name.should == 'image.png'
19
+ end
20
+
21
+ it 'web element type' do
22
+ mock_element = mock(Capybara::Node::Element)
23
+ mock_capture_element = mock(Gatling::CaptureElement)
24
+ mock_image = mock(Magick::Image)
25
+
26
+ Gatling::CaptureElement.should_receive(:new).and_return mock_capture_element
27
+ mock_capture_element.should_receive(:capture).and_return mock_image
28
+ subject = Gatling::Image.new(:from_element, 'image.png', mock_element)
29
+ subject.image.should == mock_image
30
+ subject.file_name.should == 'image.png'
31
+ end
32
+
33
+ it 'diff image' do
34
+ mock_image = mock(Magick::Image)
35
+ subject = Gatling::Image.new(:from_diff, 'image.png', mock_image)
36
+ subject.image.should == mock_image
37
+ subject.file_name.should == 'image.png'
38
+ end
39
+ end
40
+
41
+ it 'should be ok with nil' do
42
+ pending
43
+ end
44
+
45
+ it 'should save an image to the path for the type' do
46
+ mock_image = mock(Magick::Image)
47
+ mock_image.should_receive(:write).with('./image_tests/temp/image.png').and_return()
48
+ subject = Gatling::Image.new(:from_diff, 'image.png', mock_image)
49
+ subject.image = mock_image
50
+ subject.file_name = 'image.png'
51
+ subject.save(:as => :temp)
52
+ subject.path.should == './image_tests/temp/image.png'
53
+ end
54
+
55
+ it 'should check if a file exists, with the file name and type' do
56
+ mock_image = mock(Magick::Image)
57
+ File.should_receive(:exists?).with './image_tests/image.png'
58
+ subject = Gatling::Image.new(:from_diff, 'image.png', mock_image)
59
+ subject.file_name = 'image.png'
60
+ subject.exists?
61
+ end
62
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gatling::ImageWrangler do
4
+
5
+ class Point
6
+ attr_accessor :x, :y
7
+ end
8
+
9
+ class Size
10
+ attr_accessor :width, :height
11
+ end
12
+
13
+ it 'should get the position of the css element' do
14
+
15
+ #Overiding the stupid public method :y of YAML module
16
+
17
+ location = Point.new
18
+ location.x = 1
19
+ location.y = 2
20
+
21
+ size = Size.new
22
+ size.width = 100
23
+ size.height = 200
24
+
25
+ mock_element = mock
26
+ mock_element.stub(:native).and_return(mock_element)
27
+ mock_element.stub(:location).and_return(location)
28
+ mock_element.stub(:size).and_return(size)
29
+
30
+ position = Gatling::ImageWrangler.get_element_position(mock_element)
31
+
32
+ position[:x].should eql(1)
33
+ position[:y].should eql(2)
34
+ position[:width].should eql(100)
35
+ position[:height].should eql(200)
36
+ end
37
+
38
+
39
+
40
+
41
+ end
@@ -1,46 +1,39 @@
1
1
  require 'spec_helper'
2
2
  include Capybara::DSL
3
3
 
4
-
5
4
  describe 'rspec matcher' do
6
-
5
+
7
6
  before(:all) do
7
+ @black_box = 'black.png'
8
+ @ref_path = Gatling::Configuration.reference_image_path = File.join(spec_support_root, 'ref_path')
9
+ create_images_for_web_page
10
+ end
11
+
12
+ after(:each) do
13
+ Gatling::Configuration.trainer_toggle = false
14
+ remove_refs(@ref_path)
15
+ end
8
16
 
9
- include Rack::Test::Methods
17
+ describe 'initializing and runnin gatling' do
10
18
 
11
- def app
12
- Sinatra::Application
19
+ it 'will pass if images matches refernce' do
20
+ create_square_image(@ref_path, 'black')
21
+ black_element = element_for_spec("#black")
22
+ black_element.should look_like(@black_box)
13
23
  end
14
-
15
- #expected image to compare with
16
- @example_good_image = 'smiley-faceicon.png'
17
24
 
18
- @spec_support_root = spec_support_root
19
-
20
- @ref_path = Gatling::Configuration.reference_image_path = File.join(@spec_support_root, 'ref_path')
21
- end
25
+ it 'will fail if images dosent matches refernce' do
26
+ create_square_image(@ref_path, 'black')
27
+ red_element = element_for_spec("#red")
28
+ expect{red_element.should look_like(@black_box)}.should raise_error
29
+ end
22
30
 
31
+ it 'will return true if it makes a new reference image in trainer mode' do
32
+ Gatling::Configuration.trainer_toggle = true
33
+ black_element = element_for_spec("#black")
34
+ black_element.should look_like(@black_box)
35
+ File.exists?(File.join(@ref_path, @black_box)).should be_true
36
+ end
23
37
 
24
- after(:each) do
25
- remove_refs(@ref_path)
26
- end
27
-
28
- it 'should initialize and run gatling' do
29
-
30
- save_element_for_test
31
-
32
- visit('/')
33
- @element = page.find(:css, "#smiley")
34
- @element.should look_like('smiley-faceicon.png')
35
- end
36
-
37
- it 'should initialize and run training mode when GATLING_TRAINER is toggled' do
38
- ENV['GATLING_TRAINER'] = 'true'
39
-
40
- visit('/')
41
- @element = page.find(:css, "#smiley")
42
- @element.should look_like('smiley-faceicon.png')
43
- File.exists?(File.join(@ref_path,'smiley-faceicon.png')).should be_true
44
38
  end
45
-
46
- end
39
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,68 +1,54 @@
1
- require File.join(File.dirname(__FILE__), '/support/assets/smiley_app')
2
-
3
1
  require 'rubygems'
4
- require 'sinatra'
5
- Sinatra::Application.environment = :test
6
- require 'rack/test'
7
- # require 'spec'
8
- # require 'spec/autorun'
9
- # require 'spec/interop/test'
10
2
  require 'capybara'
11
3
  require 'capybara/dsl'
12
4
  require 'capybara/rspec'
13
5
  require 'gatling'
14
6
  require 'gatling/matchers/look_like_matcher'
15
7
  require 'fileutils'
8
+ require 'pry'
9
+
10
+ #todo: spec folders clean up method
16
11
 
17
12
  RSpec.configure do |config|
18
13
  config.color_enabled = true
19
14
  config.formatter = 'documentation'
20
15
  end
21
16
 
22
- Capybara.app = Sinatra::Application
17
+ Capybara.app_host = "file://#{File.expand_path(File.dirname(__FILE__))}/support/assets"
23
18
  Capybara.default_driver = :selenium
24
-
25
- def app
26
- @app ||= Sinatra::Application
27
- end
28
-
29
- set :run, false
30
- set :environment, :test
19
+ Capybara.run_server = false
31
20
 
32
21
  def remove_refs(dir)
33
- FileUtils.rm_rf dir.to_s
22
+ Dir.glob("#{dir}/**/*.png").each {|image| FileUtils.rm image}
34
23
  end
35
24
 
36
- def gatling_for_spec(expected)
37
- visit('/')
38
- @element = page.find(:css, "#smiley")
39
-
40
- @gatling = Gatling::Comparison.new(expected, @element)
25
+ def element_for_spec(css = '#black')
26
+ visit('/fruit_app.html')
27
+ @element = page.find(:css, css)
41
28
  end
42
29
 
43
30
  def spec_support_root
44
- File.join(File.dirname(__FILE__), 'support')
31
+ File.join(File.dirname(__FILE__), 'support')
45
32
  end
46
33
 
47
- def save_element_for_test
48
- Gatling::Configuration.trainer_toggle = true
49
- gatling_for_spec('smiley-faceicon.png').matches?
50
- Gatling::Configuration.trainer_toggle = false
34
+ def create_images_for_web_page
35
+ asset_path = File.join(spec_support_root, 'assets')
36
+ create_square_image(asset_path, 'black')
37
+ create_square_image(asset_path, 'red')
51
38
  end
52
39
 
53
- def convert_element_to_bad_element(image_file)
54
- #convert -fill none -stroke black -strokewidth 5 smiley-faceicon.png -draw 'arc 155,25 185,45 180' sad-faceicon.png
55
- image = Magick::Image.read(image_file).first
56
- frown = Magick::Draw.new
57
- frown.stroke('black')
58
- frown.stroke_width(5)
59
- frown.fill_opacity(0)
60
- frown.stroke_opacity(10)
61
- frown.arc(155,25,185,45,180,0)
62
- frown.draw(image)
63
- bad_element = image.write(image_file)
64
- end
65
-
66
- #todo: spec folders clean up method
40
+ def create_square_image(path, color)
41
+ # We make the images, rather then check them in because otherwise the comparison tests
42
+ # become very flakey depending on the graphics set up on the computer running them
43
+ FileUtils::mkdir_p(path)
67
44
 
45
+ reference_file = Magick::Image.new(100,100) { self.background_color = 'white' }
46
+ square = Magick::Draw.new
47
+ square.fill_opacity(100)
48
+ square.fill_color(color)
49
+ square.rectangle(10,10, 90,90)
50
+ square.draw(reference_file)
68
51
 
52
+ reference_file.write(File.join(path, "#{color}.png"))
53
+ reference_file
54
+ end
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
+ "http://www.w3.org/TR/html4/loose.dtd">
3
+ <html>
4
+ <head>
5
+ <title>The Smiley Site</title>
6
+ </head>
7
+ <body>
8
+ <img src='./black.png' id="black"/>
9
+ <img src='./red.png' id="red"/>
10
+ </body>
11
+ </html>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gatling
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-28 00:00:00.000000000Z
12
+ date: 2012-03-19 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rmagick
16
- requirement: &70095506844640 !ruby/object:Gem::Requirement
16
+ requirement: &70287958354680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70095506844640
24
+ version_requirements: *70287958354680
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-core
27
- requirement: &70095506844220 !ruby/object:Gem::Requirement
27
+ requirement: &70287958354160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70095506844220
35
+ version_requirements: *70287958354160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70095506843800 !ruby/object:Gem::Requirement
38
+ requirement: &70287958353700 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70095506843800
46
+ version_requirements: *70287958353700
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: capybara
49
- requirement: &70095506843380 !ruby/object:Gem::Requirement
49
+ requirement: &70287958353180 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70095506843380
57
+ version_requirements: *70287958353180
58
58
  description: Add visual comparison matchers for rspec
59
59
  email:
60
60
  - grotbart@gmail.com
@@ -64,29 +64,36 @@ extra_rdoc_files: []
64
64
  files:
65
65
  - .DS_Store
66
66
  - .gitignore
67
+ - .rbenv-version
68
+ - .rvmrc
67
69
  - Gemfile
68
70
  - Gemfile.lock
69
71
  - LICENSE.txt
70
72
  - README.rdoc
71
73
  - Rakefile
72
- - foo.rb
73
74
  - gatling.gemspec
74
75
  - lib/gatling.rb
75
76
  - lib/gatling/capture_element.rb
77
+ - lib/gatling/comparison.rb
76
78
  - lib/gatling/config.rb
79
+ - lib/gatling/file_helper.rb
80
+ - lib/gatling/image.rb
81
+ - lib/gatling/image_wrangler.rb
77
82
  - lib/gatling/matchers/look_like_matcher.rb
78
83
  - lib/gatling/version.rb
79
84
  - pkg/gatling-0.0.1.gem
80
85
  - reports/rspec_unit_test_output.html
86
+ - spec/capture_spec.rb
87
+ - spec/comparison_spec.rb
81
88
  - spec/configuration_spec.rb
89
+ - spec/file_helper_spec.rb
82
90
  - spec/gatling_spec.rb
91
+ - spec/image_spec.rb
92
+ - spec/image_wrangler_spec.rb
83
93
  - spec/rspec_matcher_spec.rb
84
94
  - spec/spec.opts
85
95
  - spec/spec_helper.rb
86
- - spec/support/assets/public/smiley-faceicon.jpg
87
- - spec/support/assets/smiley-bad.jpg
88
- - spec/support/assets/smiley_app.rb
89
- - spec/support/assets/views/smiley_site.erb
96
+ - spec/support/assets/fruit_app.html
90
97
  homepage: http://github.com/GabrielRotbart/gatling
91
98
  licenses: []
92
99
  post_install_message:
@@ -107,17 +114,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
114
  version: '0'
108
115
  requirements: []
109
116
  rubyforge_project: gatling
110
- rubygems_version: 1.8.12
117
+ rubygems_version: 1.8.10
111
118
  signing_key:
112
119
  specification_version: 3
113
120
  summary: Automated visual testing
114
121
  test_files:
122
+ - spec/capture_spec.rb
123
+ - spec/comparison_spec.rb
115
124
  - spec/configuration_spec.rb
125
+ - spec/file_helper_spec.rb
116
126
  - spec/gatling_spec.rb
127
+ - spec/image_spec.rb
128
+ - spec/image_wrangler_spec.rb
117
129
  - spec/rspec_matcher_spec.rb
118
130
  - spec/spec.opts
119
131
  - spec/spec_helper.rb
120
- - spec/support/assets/public/smiley-faceicon.jpg
121
- - spec/support/assets/smiley-bad.jpg
122
- - spec/support/assets/smiley_app.rb
123
- - spec/support/assets/views/smiley_site.erb
132
+ - spec/support/assets/fruit_app.html
data/foo.rb DELETED
@@ -1,9 +0,0 @@
1
- puts ENV['GEM_PATH']
2
- def foo
3
- puts ">"
4
- bar = false unless ENV['BARRR']='true'
5
- puts ">>>"
6
- puts bar.inspect
7
- end
8
-
9
- foo
Binary file
@@ -1,18 +0,0 @@
1
- require 'sinatra'
2
-
3
- set :app_file, __FILE__
4
-
5
- set :root, File.expand_path(File.dirname(__FILE__))
6
- set :static, true
7
-
8
- get '/' do
9
- erb :smiley_site
10
- end
11
-
12
- get '/root' do
13
- 'root is ' + settings.root
14
- end
15
-
16
- get '/public' do
17
- 'root is ' + settings.public_directory
18
- end
@@ -1,19 +0,0 @@
1
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
- "http://www.w3.org/TR/html4/loose.dtd">
3
- <html>
4
- <head>
5
- <title>The Smiley Site</title>
6
- <style type="text/css">
7
- div {width:100%;}
8
- img
9
- {
10
- border:1
11
- }
12
- </style>
13
- </head>
14
- <body>
15
- <div style="width:340px;text-align:center;float:left;" id="smiley">
16
- <img src="smiley-faceicon.jpg" alt="Smiley" height="42" width="42" />
17
- </div>
18
- </body>
19
- </html>