simulacrum 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|