simulacrum 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +40 -0
- data/lib/simulacrum/browser.rb +7 -0
- data/lib/simulacrum/comparator.rb +59 -0
- data/lib/simulacrum/component.rb +66 -0
- data/lib/simulacrum/configuration.rb +40 -0
- data/lib/simulacrum/diff/pdiff.rb +47 -0
- data/lib/simulacrum/diff/rmagick.rb +18 -0
- data/lib/simulacrum/diff.rb +20 -0
- data/lib/simulacrum/matchers.rb +42 -0
- data/lib/simulacrum/methods.rb +25 -0
- data/lib/simulacrum/version.rb +5 -0
- data/lib/simulacrum.rb +29 -0
- data/spec/fixtures/a.png +0 -0
- data/spec/fixtures/a2.png +0 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/use_coveralls.rb +2 -0
- data/spec/use_simplecov.rb +14 -0
- metadata +221 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c310ede91a08d7f1f3dc4a8117b2c819cbae6106
|
4
|
+
data.tar.gz: 0baa8198be24a7d440e3c18bc1f2cc3dcf7a155c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73c02e295c5a64c54b5698b9ab635b13949e539f0acbaa246be388b7179c90faf369ea90812e2e7ef0372c66efca1f12a513beba83b7c316efcd72a4d2ffab75
|
7
|
+
data.tar.gz: 43d26d53bbb8562d4bdf036a45206fd09830dc892661244d848f73537e40ba9e1566201d7d01781fdf4a780ca9956755ea4c5d3611e5444aae8e7b284741ad69
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
## Simulacrum
|
2
|
+
|
3
|
+
An opinionated UI component regression testing tool built to be tightly integrated with RSpec, Selenium and tools you already use.
|
4
|
+
|
5
|
+
***
|
6
|
+
|
7
|
+
### Installing
|
8
|
+
`gem 'simulacrum'`
|
9
|
+
|
10
|
+
### Configuring
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include Simulacrum
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
Simulacrum can also be configured once included;
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
Simulacrum.configure do |config|
|
22
|
+
config.images_path = 'somewhere/example/spec/ui_specs'
|
23
|
+
config.acceptable_delta = 2 # allow a maximum of 2% difference
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
### Opinions
|
28
|
+
|
29
|
+
### Usage
|
30
|
+
|
31
|
+
Simulacrum provides a small DSL for configuring and managing UI tests from within Rspec. Basically it boils down to these three methods;
|
32
|
+
|
33
|
+
- `component`
|
34
|
+
- `configure_browser`
|
35
|
+
- `look_the_same`
|
36
|
+
|
37
|
+
#### Inspiration
|
38
|
+
|
39
|
+
- Huxley
|
40
|
+
- Green Onion
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative 'diff/rmagick'
|
2
|
+
|
3
|
+
module Simulacrum
|
4
|
+
# The Comparator class is responsible for comparing and handling
|
5
|
+
# processing of screenshots and candidates
|
6
|
+
class Comparator
|
7
|
+
include RSpec::Core::Pending
|
8
|
+
|
9
|
+
attr_accessor :component, :candidate, :diff
|
10
|
+
|
11
|
+
def initialize(component)
|
12
|
+
@component = component
|
13
|
+
end
|
14
|
+
|
15
|
+
def test
|
16
|
+
@candidate = @component.capture_candidate
|
17
|
+
|
18
|
+
# If the component has a reference then we should diff the candidate
|
19
|
+
# image against the reference
|
20
|
+
if @component.reference?
|
21
|
+
# If there is a diff between the candidate and the reference then we
|
22
|
+
# should save both the candidate and diff images and fail the test
|
23
|
+
perform_diff ? pass : fail
|
24
|
+
|
25
|
+
# Otherwise we should just write the captured candidate to disk, and mark
|
26
|
+
# the spec as being pending until the user works out if the candidate is
|
27
|
+
# OK by renaming candidate.png to reference.png
|
28
|
+
else
|
29
|
+
skip
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def pass
|
36
|
+
@component.remove_candidate
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def fail
|
41
|
+
@diff.save(@component.diff_path)
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
def skip
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def perform_diff()
|
50
|
+
@diff = Simulacrum::RmagicDiff.new(@component.reference_path,
|
51
|
+
@component.candidate_path)
|
52
|
+
diff_delta_percent_is_acceptable
|
53
|
+
end
|
54
|
+
|
55
|
+
def diff_delta_percent_is_acceptable
|
56
|
+
(@diff.delta * 1000) < @component.acceptable_delta
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'capybara'
|
2
|
+
|
3
|
+
module Simulacrum
|
4
|
+
class Component
|
5
|
+
include Capybara::DSL
|
6
|
+
Capybara.default_driver = :selenium
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(name, options)
|
11
|
+
@name = name
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
# Load up the component url and capture an image, returns a File object
|
16
|
+
def capture_candidate
|
17
|
+
ensure_example_path
|
18
|
+
visit(@options.url)
|
19
|
+
within(capture_selector) do
|
20
|
+
page.save_screenshot(candidate_path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove_candidate
|
25
|
+
FileUtils.rm(candidate_path) if candidate?
|
26
|
+
end
|
27
|
+
|
28
|
+
def root_path
|
29
|
+
File.join(Simulacrum.configuration.images_path, name.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def reference_path
|
33
|
+
File.join(root_path, Simulacrum.configuration.reference_filename)
|
34
|
+
end
|
35
|
+
|
36
|
+
def candidate_path
|
37
|
+
File.join(root_path, Simulacrum.configuration.candidate_filename)
|
38
|
+
end
|
39
|
+
|
40
|
+
def diff_path
|
41
|
+
File.join(root_path, Simulacrum.configuration.diff_filename)
|
42
|
+
end
|
43
|
+
|
44
|
+
def reference?
|
45
|
+
File.exists?(reference_path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def candidate?
|
49
|
+
File.exists?(candidate_path)
|
50
|
+
end
|
51
|
+
|
52
|
+
def acceptable_delta
|
53
|
+
@options.acceptable_delta || Simulacrum.configuration.acceptable_delta
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def ensure_example_path
|
59
|
+
FileUtils.mkdir_p(root_path)
|
60
|
+
end
|
61
|
+
|
62
|
+
def capture_selector
|
63
|
+
@options.capture_selector || Simulacrum.configuration.capture_selector
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Simulacrum
|
4
|
+
class Configuration
|
5
|
+
attr_reader :images_path, :reference_filename, :candidate_filename,
|
6
|
+
:diff_filename, :capture_selector, :acceptable_delta
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@config = OpenStruct.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure(config)
|
13
|
+
@config = OpenStruct.new(@config.to_h.merge!(config))
|
14
|
+
end
|
15
|
+
|
16
|
+
def images_path
|
17
|
+
@config.images_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def reference_filename
|
21
|
+
@config.reference_filename || 'reference.png'
|
22
|
+
end
|
23
|
+
|
24
|
+
def candidate_filename
|
25
|
+
@config.candidate_filename || 'candidate.png'
|
26
|
+
end
|
27
|
+
|
28
|
+
def diff_filename
|
29
|
+
@config.diff_filename || 'diff.png'
|
30
|
+
end
|
31
|
+
|
32
|
+
def capture_selector
|
33
|
+
@config.capture_selector || 'html'
|
34
|
+
end
|
35
|
+
|
36
|
+
def acceptable_delta
|
37
|
+
@config.acceptable_delta || 0.0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'chunky_png'
|
2
|
+
require_relative '../diff'
|
3
|
+
|
4
|
+
module Simulacrum
|
5
|
+
class Pdiff < Simulacrum::Diff
|
6
|
+
include ChunkyPNG::Color
|
7
|
+
|
8
|
+
def compare
|
9
|
+
a_image = ChunkyPNG::Image.from_file(@a_path)
|
10
|
+
b_image = ChunkyPNG::Image.from_file(@b_path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# require 'chunky_png'
|
16
|
+
# include ChunkyPNG::Color
|
17
|
+
|
18
|
+
|
19
|
+
# images = [
|
20
|
+
# ChunkyPNG::Image.from_file('1.png'),
|
21
|
+
# ChunkyPNG::Image.from_file('2.png')
|
22
|
+
# ]
|
23
|
+
|
24
|
+
# output = ChunkyPNG::Image.new(images.first.width, images.last.width, WHITE)
|
25
|
+
|
26
|
+
# diff = []
|
27
|
+
|
28
|
+
# images.first.height.times do |y|
|
29
|
+
# images.first.row(y).each_with_index do |pixel, x|
|
30
|
+
# unless pixel == images.last[x,y]
|
31
|
+
# score = Math.sqrt(
|
32
|
+
# (r(images.last[x,y]) - r(pixel)) ** 2 +
|
33
|
+
# (g(images.last[x,y]) - g(pixel)) ** 2 +
|
34
|
+
# (b(images.last[x,y]) - b(pixel)) ** 2
|
35
|
+
# ) / Math.sqrt(MAX ** 2 * 3)
|
36
|
+
|
37
|
+
# output[x,y] = grayscale(MAX - (score * MAX).round)
|
38
|
+
# diff << score
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
|
43
|
+
# puts "pixels (total): #{images.first.pixels.length}"
|
44
|
+
# puts "pixels changed: #{diff.length}"
|
45
|
+
# puts "image changed (%): #{(diff.inject {|sum, value| sum + value} / images.first.pixels.length) * 100}%"
|
46
|
+
|
47
|
+
# output.save('diff.png')
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rmagick'
|
2
|
+
require_relative '../diff'
|
3
|
+
|
4
|
+
module Simulacrum
|
5
|
+
class RmagicDiff < Simulacrum::Diff
|
6
|
+
private
|
7
|
+
|
8
|
+
def compare
|
9
|
+
a_image = Magick::Image.read(@a_path)
|
10
|
+
b_image = Magick::Image.read(@b_path)
|
11
|
+
@image, @delta = compare_images(a_image, b_image)
|
12
|
+
end
|
13
|
+
|
14
|
+
def compare_images(a_image, b_image)
|
15
|
+
a_image[0].compare_channel(b_image[0], Magick::MeanSquaredErrorMetric)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Simulacrum
|
2
|
+
class Diff
|
3
|
+
attr_accessor :a_path, :b_path, :delta, :image
|
4
|
+
|
5
|
+
def initialize(a_path, b_path)
|
6
|
+
@a_path = a_path
|
7
|
+
@b_path = b_path
|
8
|
+
|
9
|
+
compare
|
10
|
+
end
|
11
|
+
|
12
|
+
def save(path)
|
13
|
+
@image.write(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def percent_change
|
17
|
+
(@delta * 1000).round(2)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative 'comparator'
|
2
|
+
|
3
|
+
module Simulacrum
|
4
|
+
module Matchers
|
5
|
+
extend RSpec::Matchers::DSL
|
6
|
+
|
7
|
+
matcher :look_the_same do
|
8
|
+
match do |component|
|
9
|
+
comparator = Simulacrum::Comparator.new(component)
|
10
|
+
case comparator.test
|
11
|
+
when true
|
12
|
+
true
|
13
|
+
when false
|
14
|
+
fail <<-eos
|
15
|
+
The pixel change percentage exceeded the maximum threshold of #{component.acceptable_delta}%.
|
16
|
+
|
17
|
+
There was a #{comparator.diff.percent_change}% pixel difference found between \
|
18
|
+
the reference and the candidate.
|
19
|
+
|
20
|
+
Reference: #{component.reference_path}
|
21
|
+
Candidate: #{component.candidate_path}
|
22
|
+
Diff: #{component.diff_path}
|
23
|
+
|
24
|
+
Please review the diff and resolve manually.
|
25
|
+
eos
|
26
|
+
when nil
|
27
|
+
pending <<-eos
|
28
|
+
No reference image found! New candidate created:
|
29
|
+
|
30
|
+
#{component.candidate_path}
|
31
|
+
|
32
|
+
Please inspect this candidate image and if it looks OK then;
|
33
|
+
|
34
|
+
- mark it as a reference image by renaming it to 'reference.png'
|
35
|
+
- commit 'reference.png' file to your SCM of choice
|
36
|
+
- rerun this spec making sure it passes using the new reference image
|
37
|
+
eos
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require_relative 'browser'
|
3
|
+
require_relative 'component'
|
4
|
+
|
5
|
+
module Simulacrum
|
6
|
+
# Rspec utility methods for defining components, browser environments and
|
7
|
+
module Methods
|
8
|
+
def component(name, &block)
|
9
|
+
options = OpenStruct.new
|
10
|
+
yield options
|
11
|
+
component = Simulacrum::Component.new(name, options)
|
12
|
+
Simulacrum.components[name] = component
|
13
|
+
|
14
|
+
subject do
|
15
|
+
component
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def configure_browser(name, &block)
|
20
|
+
options = OpenStruct.new
|
21
|
+
yield options
|
22
|
+
@browser = Simulacrum::Browser.new(name, options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/simulacrum.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require_relative 'Simulacrum/methods'
|
3
|
+
require_relative 'Simulacrum/matchers'
|
4
|
+
require_relative 'Simulacrum/configuration'
|
5
|
+
|
6
|
+
# Gem module
|
7
|
+
module Simulacrum
|
8
|
+
@components = {}
|
9
|
+
@configuration = Simulacrum::Configuration.new
|
10
|
+
|
11
|
+
def self.components
|
12
|
+
@components
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.configuration
|
16
|
+
@configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configure(&block)
|
20
|
+
options = OpenStruct.new
|
21
|
+
yield options
|
22
|
+
@configuration.configure(options.to_h)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.included(receiver, &block)
|
26
|
+
receiver.extend Simulacrum::Methods
|
27
|
+
receiver.send :include, Simulacrum::Matchers
|
28
|
+
end
|
29
|
+
end
|
data/spec/fixtures/a.png
ADDED
Binary file
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
if ENV['COVERAGE']
|
2
|
+
require_relative 'use_coveralls' if ENV['TRAVIS']
|
3
|
+
require_relative 'use_simplecov' unless ENV['TRAVIS']
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'Simulacrum'
|
8
|
+
require 'rspec/autorun'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.order = "random"
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
puts "[Simplecov] enabled"
|
2
|
+
require 'simplecov'
|
3
|
+
|
4
|
+
class SimpleCov::Formatter::QualityFormatter
|
5
|
+
def format(result)
|
6
|
+
SimpleCov::Formatter::HTMLFormatter.new.format(result)
|
7
|
+
File.open("coverage/covered_percent", "w") do |f|
|
8
|
+
f.puts result.source_files.covered_percent.to_f
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
SimpleCov.formatter = SimpleCov::Formatter::QualityFormatter
|
14
|
+
SimpleCov.start
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simulacrum
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Morris
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capybara
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rmagick
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coveralls
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec-nc
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: shoulda-matchers
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: simplecov
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: An opinionated UI component regression testing tool built to be tightly
|
168
|
+
integrated with RSpec, Selenium and tools you already use.
|
169
|
+
email:
|
170
|
+
- desk@pixelbloom.com
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- lib/simulacrum/browser.rb
|
176
|
+
- lib/simulacrum/comparator.rb
|
177
|
+
- lib/simulacrum/component.rb
|
178
|
+
- lib/simulacrum/configuration.rb
|
179
|
+
- lib/simulacrum/diff/pdiff.rb
|
180
|
+
- lib/simulacrum/diff/rmagick.rb
|
181
|
+
- lib/simulacrum/diff.rb
|
182
|
+
- lib/simulacrum/matchers.rb
|
183
|
+
- lib/simulacrum/methods.rb
|
184
|
+
- lib/simulacrum/version.rb
|
185
|
+
- lib/simulacrum.rb
|
186
|
+
- README.md
|
187
|
+
- spec/fixtures/a.png
|
188
|
+
- spec/fixtures/a2.png
|
189
|
+
- spec/spec_helper.rb
|
190
|
+
- spec/use_coveralls.rb
|
191
|
+
- spec/use_simplecov.rb
|
192
|
+
homepage: https://github.com/plasticine/simulacrum
|
193
|
+
licenses:
|
194
|
+
- MIT
|
195
|
+
metadata: {}
|
196
|
+
post_install_message:
|
197
|
+
rdoc_options: []
|
198
|
+
require_paths:
|
199
|
+
- lib
|
200
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
201
|
+
requirements:
|
202
|
+
- - '>='
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '0'
|
205
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - '>='
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
requirements: []
|
211
|
+
rubyforge_project:
|
212
|
+
rubygems_version: 2.1.11
|
213
|
+
signing_key:
|
214
|
+
specification_version: 4
|
215
|
+
summary: A gem for visually testing and inspecting user interface components.
|
216
|
+
test_files:
|
217
|
+
- spec/fixtures/a.png
|
218
|
+
- spec/fixtures/a2.png
|
219
|
+
- spec/spec_helper.rb
|
220
|
+
- spec/use_coveralls.rb
|
221
|
+
- spec/use_simplecov.rb
|