janus-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/Guardfile +6 -0
- data/LICENSE +20 -0
- data/README.md +106 -0
- data/Rakefile +6 -0
- data/bin/janus +57 -0
- data/janus.gemspec +29 -0
- data/lib/janus/command/initialize.rb +15 -0
- data/lib/janus/command/record.rb +22 -0
- data/lib/janus/command/validate.rb +22 -0
- data/lib/janus/configuration.rb +43 -0
- data/lib/janus/screenshot.rb +37 -0
- data/lib/janus/template/Janusfile +6 -0
- data/lib/janus/test.rb +10 -0
- data/lib/janus/version.rb +3 -0
- data/lib/janus.rb +3 -0
- data/spec/janus/command/initialize_spec.rb +24 -0
- data/spec/janus/command/record_spec.rb +36 -0
- data/spec/janus/command/validate_spec.rb +44 -0
- data/spec/janus/configuration_spec.rb +57 -0
- data/spec/janus/screenshot_spec.rb +79 -0
- data/spec/janus/test_spec.rb +13 -0
- data/spec/spec_helper.rb +3 -0
- metadata +203 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 48d541d4807829c7904dd94f3c490782ac384a8e
|
4
|
+
data.tar.gz: e6a8dee5095f4f7bfb37534e9e51c21015db496e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dad2010d9f66f0e98abeeb55cf025b36151c187367b26498a556b834271e3c2d509b63fa06658033f3f506f797348f28224b52b7bd54d4bd3bcdfe04a70d9fc1
|
7
|
+
data.tar.gz: 1393f2a3b1bd0349d6c300ad5b7dd31f3ecda5f3a2a3c4ed3c18af21528a6f30a7756dec9e711f503fa9fef9dca2c39b2a32caf5fa8e05be59eb87560f6c661a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Brad Gignac
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
janus
|
2
|
+
=====
|
3
|
+
|
4
|
+
[](https://travis-ci.org/bradgignac/janus)
|
5
|
+
[](https://codeclimate.com/github/bradgignac/janus)
|
6
|
+
[](https://gemnasium.com/bradgignac/janus)
|
7
|
+
|
8
|
+
Janus is a tool for performing automated visual regression testing against web
|
9
|
+
applications. It works by comparing screenshots of your application in a known
|
10
|
+
good state to fresh screenshots of your application. A number of [similar tools exist](#inspiration),
|
11
|
+
but Janus excels for projects with the following needs:
|
12
|
+
|
13
|
+
- *Automated testing across a large number of browsers and operating systems.*
|
14
|
+
Janus was built with multi-browser support as a primary concern. By building on top
|
15
|
+
of Sauce Labs' testing platform, you have access to the full array of [Sauce Labs platforms](https://saucelabs.com/docs/platforms).
|
16
|
+
|
17
|
+
- *Testing of applications where subtle visual differences are allowed.*
|
18
|
+
Many visual regression testing tools fail whenever they find a single-pixel
|
19
|
+
difference in a screenshot. Janus allows you to define a threshold within which
|
20
|
+
screenshots are still considered valid.
|
21
|
+
|
22
|
+
## Getting Started
|
23
|
+
|
24
|
+
To get started, install Janus by running:
|
25
|
+
|
26
|
+
$ gem install janus
|
27
|
+
|
28
|
+
Or by adding Janus to your Gemfile:
|
29
|
+
|
30
|
+
$ gem 'janus'
|
31
|
+
|
32
|
+
Once Janus is installed, run:
|
33
|
+
|
34
|
+
$ janus init
|
35
|
+
|
36
|
+
This will generate a sample configuration file in the current directory. See
|
37
|
+
[Configuring Janus](#configuring-janus) for more information about valid configuration
|
38
|
+
options. Once you've finishing adding tests to your configuration file, you are
|
39
|
+
ready to begin running tests:
|
40
|
+
|
41
|
+
$ janus record
|
42
|
+
|
43
|
+
This will generate screenshots for all combinations of tests and browsers located
|
44
|
+
in your configuration file. Commit these screenshots to source control alongside
|
45
|
+
your source code. Whenever you wish to verify your UI, running `janus validate`
|
46
|
+
will compare fresh screenshots against the screenshots you've previously recorded.
|
47
|
+
Re-run `janus record` to generate fresh screenshots at any time. See the [example](example)
|
48
|
+
directory for an example of Janus in action.
|
49
|
+
|
50
|
+
## Configuring Janus
|
51
|
+
|
52
|
+
**directory** (required)
|
53
|
+
|
54
|
+
The location where Janus screenshots are stored.
|
55
|
+
|
56
|
+
**url** (optional)
|
57
|
+
|
58
|
+
The base URL for all screenshots. All test URLs will be relative to this URL.
|
59
|
+
|
60
|
+
**threshold** (optional)
|
61
|
+
|
62
|
+
The percentage of change that is allowed in a screenshot. This value can be
|
63
|
+
overridden for each individual test.
|
64
|
+
|
65
|
+
**resolution** (optional)
|
66
|
+
|
67
|
+
The browser resolution at which screenshots should be taken. This value is limited
|
68
|
+
by the options available on Sauce Labs.
|
69
|
+
|
70
|
+
**browsers** (required)
|
71
|
+
|
72
|
+
An array of browsers to run your tests against. Each entry in the array contains
|
73
|
+
a platform, browser, and optional version. See the [Sauce Labs platform documentation](https://saucelabs.com/docs/platforms)
|
74
|
+
for more information on the valid browsers.
|
75
|
+
|
76
|
+
**tests** (required)
|
77
|
+
|
78
|
+
An array of screenshots to take. Each entry in the array contains a name, URL,
|
79
|
+
and optional threshold. All URLs are relative to the specified base URL. If a
|
80
|
+
threshold is defined, it will override the global theshold.
|
81
|
+
|
82
|
+
## Best Practices
|
83
|
+
|
84
|
+
- *Create tests for small units of your UI.* Just like with unit tests, create
|
85
|
+
screenshot tests for small components of your UI. This will help create a more
|
86
|
+
reliable test suite and help you catch visual regressions.
|
87
|
+
- *Create tests for larger combinations of your UI components.* Unfortunaly, "unit"
|
88
|
+
tests won't catch everything. Create larger "integration" tests that combine
|
89
|
+
individual UI components. This will help you test that all of your components play
|
90
|
+
well together.
|
91
|
+
- *Use per-test thresholds to keep variations small.* A global threshold is great,
|
92
|
+
but some tests have a higher than normal variance. Raising the global threshold
|
93
|
+
will increase the chances of missing regressions in your other tests. Instead,
|
94
|
+
simply add a threshold for the test that requires a larger variance.
|
95
|
+
|
96
|
+
## Inspiration
|
97
|
+
|
98
|
+
Janus was inspired by the following projects:
|
99
|
+
|
100
|
+
- [GreenOnion](http://intridea.github.io/green_onion)
|
101
|
+
- [huxley](https://github.com/facebook/huxley)
|
102
|
+
- [wraith](https://github.com/BBC-News/wraith)
|
103
|
+
|
104
|
+
## License
|
105
|
+
|
106
|
+
Janus is released under the [MIT License](LICENSE).
|
data/Rakefile
ADDED
data/bin/janus
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'colored'
|
4
|
+
require 'gli'
|
5
|
+
require 'janus/version'
|
6
|
+
require 'janus/command/initialize'
|
7
|
+
require 'janus/command/record'
|
8
|
+
require 'janus/command/validate'
|
9
|
+
require 'janus/configuration'
|
10
|
+
|
11
|
+
include GLI::App
|
12
|
+
|
13
|
+
program_desc 'Automated visual regression testing on Sauce Labs.'
|
14
|
+
version Janus::VERSION
|
15
|
+
|
16
|
+
desc 'Sauce Labs Username'
|
17
|
+
arg_name 'username'
|
18
|
+
flag [:u, :username]
|
19
|
+
|
20
|
+
desc 'Sauce Labs API Key'
|
21
|
+
arg_name 'access_key'
|
22
|
+
flag [:k, :access_key]
|
23
|
+
|
24
|
+
desc 'Create a Janus configuration file'
|
25
|
+
command :init do |c|
|
26
|
+
c.action do |global, options, args|
|
27
|
+
init = Janus::Command::Initialize.new
|
28
|
+
init.execute
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Generate screenshots for all tests'
|
33
|
+
command :record do |c|
|
34
|
+
c.action do |global, options, args|
|
35
|
+
record = Janus::Command::Record.new($configuration)
|
36
|
+
record.execute
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Validate screenshots for all tests'
|
41
|
+
command :validate do |c|
|
42
|
+
c.action do |global, options, args|
|
43
|
+
validate = Janus::Command::Validate.new($configuration)
|
44
|
+
validate.execute
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
pre do |global, command, options, args|
|
49
|
+
$configuration = Janus::Configuration.load(global, options) unless command.name == :init
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
on_error do |e|
|
54
|
+
puts e.message.red
|
55
|
+
end
|
56
|
+
|
57
|
+
exit run(ARGV)
|
data/janus.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path('../lib/janus/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'janus-cli'
|
6
|
+
spec.version = Janus::VERSION
|
7
|
+
spec.author = 'Brad Gignac'
|
8
|
+
spec.email = 'bgignac@bradgignac.com'
|
9
|
+
spec.description = 'Automated visual regression testing on Sauce Labs.'
|
10
|
+
spec.summary = 'Automated visual regression testing on Sauce Labs.'
|
11
|
+
spec.homepage = 'https://github.com/bradgignac/janus'
|
12
|
+
spec.license = 'MIT'
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.add_dependency('colored', '~> 1.2')
|
20
|
+
spec.add_dependency('gli', '~> 2.8')
|
21
|
+
spec.add_dependency('selenium-webdriver', '~> 2.37')
|
22
|
+
|
23
|
+
spec.add_development_dependency('bundler', '~> 1.3')
|
24
|
+
spec.add_development_dependency('guard', '~> 2.2')
|
25
|
+
spec.add_development_dependency('guard-rspec', '~> 4.0')
|
26
|
+
spec.add_development_dependency('rake', '~> 10.1')
|
27
|
+
spec.add_development_dependency('rspec', '~> 2.14')
|
28
|
+
spec.add_development_dependency('simplecov', '~> 0.8')
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Janus
|
4
|
+
module Command
|
5
|
+
class Initialize
|
6
|
+
def execute
|
7
|
+
if File.exists?('Janusfile')
|
8
|
+
raise 'A configuration file already exists!'
|
9
|
+
end
|
10
|
+
|
11
|
+
FileUtils.copy(File.expand_path('../../template/Janusfile', __FILE__), 'Janusfile')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'janus/screenshot'
|
2
|
+
|
3
|
+
module Janus
|
4
|
+
module Command
|
5
|
+
class Record
|
6
|
+
def initialize(configuration)
|
7
|
+
@configuration = configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
@configuration.tests.each do |test|
|
12
|
+
record_screenshot(test)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def record_screenshot(test)
|
17
|
+
screenshot = Janus::Screenshot.capture(test, username: @configuration.username, access_key: @configuration.access_key)
|
18
|
+
screenshot.save('output')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Janus
|
2
|
+
module Command
|
3
|
+
class Validate
|
4
|
+
def initialize(configuration)
|
5
|
+
@configuration = configuration
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute
|
9
|
+
@configuration.tests.each do |test|
|
10
|
+
validate_screenshot(test)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_screenshot(test)
|
15
|
+
original = Janus::Screenshot.load(test, path: 'output')
|
16
|
+
fresh = Janus::Screenshot.capture(test, username: @configuration.username, access_key: @configuration.access_key)
|
17
|
+
|
18
|
+
raise "#{test.name}: Screenshots did not match!" unless original.image == fresh.image
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'janus/test'
|
3
|
+
|
4
|
+
module Janus
|
5
|
+
class Configuration
|
6
|
+
def self.load(*args)
|
7
|
+
options = load_configuration_file
|
8
|
+
options = args.reduce(options) do |all, opts|
|
9
|
+
all.merge(opts)
|
10
|
+
end
|
11
|
+
|
12
|
+
Janus::Configuration.new(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def username
|
20
|
+
@options['username']
|
21
|
+
end
|
22
|
+
|
23
|
+
def access_key
|
24
|
+
@options['access_key']
|
25
|
+
end
|
26
|
+
|
27
|
+
def tests
|
28
|
+
@options['tests'].map do |test|
|
29
|
+
Janus::Test.new(test)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def self.load_configuration_file
|
36
|
+
if File.exists?('Janusfile')
|
37
|
+
YAML.load(IO.read('Janusfile'))
|
38
|
+
else
|
39
|
+
raise 'Could not find Janus configuration file!'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'selenium/webdriver'
|
3
|
+
|
4
|
+
module Janus
|
5
|
+
class Screenshot
|
6
|
+
attr_accessor :test, :image
|
7
|
+
|
8
|
+
def self.capture(test, options = {})
|
9
|
+
driver = Selenium::WebDriver.for(:remote, {
|
10
|
+
url: "http://#{options[:username]}:#{options[:access_key]}@ondemand.saucelabs.com/wd/hub",
|
11
|
+
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome
|
12
|
+
})
|
13
|
+
driver.get(test.url)
|
14
|
+
|
15
|
+
Screenshot.new(test: test, image: driver.screenshot_as(:png))
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.load(test, options = {})
|
19
|
+
path = File.join(options[:path], "#{test.name}.janus", 'screenshot.png')
|
20
|
+
image = IO.read(path, mode: 'rb')
|
21
|
+
|
22
|
+
Screenshot.new(test: test, image: image)
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(parameters = {})
|
26
|
+
@test = parameters[:test]
|
27
|
+
@image = parameters[:image]
|
28
|
+
end
|
29
|
+
|
30
|
+
def save(path)
|
31
|
+
directory = File.join(path, "#{test.name}.janus")
|
32
|
+
|
33
|
+
FileUtils.mkpath(directory) unless Dir.exists?(directory)
|
34
|
+
IO.write(File.join(directory, 'screenshot.png'), @image, mode: 'wb')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/janus/test.rb
ADDED
data/lib/janus.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'janus/configuration'
|
2
|
+
require 'janus/command/initialize'
|
3
|
+
|
4
|
+
describe Janus::Command::Initialize do
|
5
|
+
let(:command) { Janus::Command::Initialize.new }
|
6
|
+
|
7
|
+
describe '#execute' do
|
8
|
+
it 'writes samples configuration if file does not exist' do
|
9
|
+
File.stub(:exists?) { false }
|
10
|
+
|
11
|
+
source = File.expand_path('../../../../lib/janus/template/Janusfile', __FILE__)
|
12
|
+
destination = 'Janusfile'
|
13
|
+
FileUtils.should_receive(:copy).with(source, destination)
|
14
|
+
|
15
|
+
command.execute
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises error if file already exists' do
|
19
|
+
File.stub(:exists?) { true }
|
20
|
+
|
21
|
+
expect { command.execute }.to raise_error('A configuration file already exists!')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'janus/configuration'
|
2
|
+
require 'janus/test'
|
3
|
+
require 'janus/command/record'
|
4
|
+
|
5
|
+
describe Janus::Command::Record do
|
6
|
+
let(:config) { Janus::Configuration.new({}) }
|
7
|
+
let(:record) { Janus::Command::Record.new(config) }
|
8
|
+
|
9
|
+
describe '#execute' do
|
10
|
+
it 'records screenshot for each configured test' do
|
11
|
+
config.stub(:tests) { ['one', 'two'] }
|
12
|
+
|
13
|
+
record.should_receive(:record_screenshot).with('one')
|
14
|
+
record.should_receive(:record_screenshot).with('two')
|
15
|
+
|
16
|
+
record.execute
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#record_screenshot' do
|
21
|
+
let(:test) { Janus::Test.new({ name: 'name', url: 'ur' }) }
|
22
|
+
let(:screenshot) { double }
|
23
|
+
let(:recorder) { double }
|
24
|
+
|
25
|
+
it 'saves screenshot of test URL' do
|
26
|
+
config.stub(:username) { 'username' }
|
27
|
+
config.stub(:access_key) { 'access key' }
|
28
|
+
|
29
|
+
Janus::Screenshot.should_receive(:capture).with(test, username: 'username', access_key: 'access key').and_return(screenshot)
|
30
|
+
|
31
|
+
screenshot.should_receive(:save)
|
32
|
+
|
33
|
+
record.record_screenshot(test)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'janus/configuration'
|
2
|
+
require 'janus/screenshot'
|
3
|
+
require 'janus/command/validate'
|
4
|
+
|
5
|
+
describe Janus::Command::Validate do
|
6
|
+
let(:config) { Janus::Configuration.new({}) }
|
7
|
+
let(:validate) { Janus::Command::Validate.new(config) }
|
8
|
+
|
9
|
+
describe '#execute' do
|
10
|
+
it 'validates screenshots for each configured test' do
|
11
|
+
config.stub(:tests) { %w(one two) }
|
12
|
+
|
13
|
+
validate.should_receive(:validate_screenshot).with('one')
|
14
|
+
validate.should_receive(:validate_screenshot).with('two')
|
15
|
+
|
16
|
+
validate.execute
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#validate_screenshot' do
|
21
|
+
let(:test) { Janus::Test.new('name' => 'my test') }
|
22
|
+
let(:original) { Janus::Screenshot.new }
|
23
|
+
let(:fresh) { Janus::Screenshot.new }
|
24
|
+
|
25
|
+
before :each do
|
26
|
+
Janus::Screenshot.stub(:load) { original }
|
27
|
+
Janus::Screenshot.stub(:capture) { fresh }
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'raises exception when screenshots do not match' do
|
31
|
+
original.stub(:image) { 'original data' }
|
32
|
+
fresh.stub(:image) { 'changes' }
|
33
|
+
|
34
|
+
expect { validate.validate_screenshot(test) }.to raise_error('my test: Screenshots did not match!')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not raise exception when screenshots match' do
|
38
|
+
original.stub(:image) { 'original data' }
|
39
|
+
fresh.stub(:image) { 'original data' }
|
40
|
+
|
41
|
+
expect { validate.validate_screenshot(test) }.not_to raise_error
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'janus/configuration'
|
3
|
+
require 'janus/test'
|
4
|
+
|
5
|
+
describe Janus::Configuration do
|
6
|
+
describe '::load' do
|
7
|
+
it 'merges provided option hashes' do
|
8
|
+
a = { a: '' }
|
9
|
+
b = { b: '' }
|
10
|
+
File.stub(:exists?) { true }
|
11
|
+
IO.stub(:read) { YAML.dump({}) }
|
12
|
+
|
13
|
+
Janus::Configuration.should_receive(:new).with({ a: '', b: '' })
|
14
|
+
|
15
|
+
Janus::Configuration.load(a, b)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'includes options from YAML configuration when files exists' do
|
19
|
+
config = { b: '', c: '' }
|
20
|
+
IO.stub(:read) { YAML.dump(config) }
|
21
|
+
File.stub(:exists?) { |f| f == 'Janusfile' }
|
22
|
+
|
23
|
+
Janus::Configuration.should_receive(:new).with({ a: '', b: '', c: '' })
|
24
|
+
|
25
|
+
Janus::Configuration.load({ a: '' }, config)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#username' do
|
30
|
+
it 'returns username' do
|
31
|
+
configuration = Janus::Configuration.new('username' => 'username')
|
32
|
+
configuration.username.should == 'username'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#access_key' do
|
37
|
+
it 'returns access key' do
|
38
|
+
configuration = Janus::Configuration.new('access_key' => 'access_key')
|
39
|
+
configuration.access_key.should == 'access_key'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#tests' do
|
44
|
+
it 'creates test for each entry in configuration file' do
|
45
|
+
test_configuration = []
|
46
|
+
test_configuration << { 'name' => 'a', 'url' => 'a' }
|
47
|
+
test_configuration << { 'name' => 'b', 'url' => 'b' }
|
48
|
+
|
49
|
+
configuration = Janus::Configuration.new({ 'tests' => test_configuration })
|
50
|
+
|
51
|
+
configuration.tests.each_with_index do |test, i|
|
52
|
+
test.name.should == test_configuration[i]['name']
|
53
|
+
test.url.should == test_configuration[i]['url']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'janus/screenshot'
|
2
|
+
require 'janus/test'
|
3
|
+
|
4
|
+
describe Janus::Screenshot do
|
5
|
+
let(:image) { 'image data' }
|
6
|
+
let(:test) { Janus::Test.new({ 'name' => 'test-name', 'url' => 'this is my url' }) }
|
7
|
+
let(:screenshot) { Janus::Screenshot.new(test: test, image: image) }
|
8
|
+
|
9
|
+
describe '::capture' do
|
10
|
+
let(:png) { double }
|
11
|
+
let(:driver) { double }
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
Selenium::WebDriver.stub(:for) { driver }
|
15
|
+
|
16
|
+
driver.stub(:get)
|
17
|
+
driver.stub(:screenshot_as)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'builds driver for specified user' do
|
21
|
+
Selenium::WebDriver.should_receive(:for).with(:remote, {
|
22
|
+
url: 'http://username:access key@ondemand.saucelabs.com/wd/hub',
|
23
|
+
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome
|
24
|
+
}).and_return(driver)
|
25
|
+
|
26
|
+
Janus::Screenshot.capture(test, username: 'username', access_key: 'access key')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'takes screenshot of provided URL' do
|
30
|
+
driver.should_receive(:get).with('this is my url')
|
31
|
+
driver.should_receive(:screenshot_as).with(:png).and_return(png)
|
32
|
+
|
33
|
+
screenshot = Janus::Screenshot.capture(test)
|
34
|
+
screenshot.test.should be(test)
|
35
|
+
screenshot.image.should be(png)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '::load' do
|
40
|
+
it 'loads screenshot from disk' do
|
41
|
+
IO.stub(:read) do |path, mode|
|
42
|
+
'my image' if path == 'base/my test.janus/screenshot.png'
|
43
|
+
end
|
44
|
+
|
45
|
+
test = Janus::Test.new('name' => 'my test')
|
46
|
+
screenshot = Janus::Screenshot.load(test, path: 'base')
|
47
|
+
|
48
|
+
screenshot.test.should == test
|
49
|
+
screenshot.image.should == 'my image'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#save' do
|
54
|
+
it 'creates test directory if it does not exist' do
|
55
|
+
IO.stub(:write)
|
56
|
+
Dir.stub(:exists?) { |p| false }
|
57
|
+
|
58
|
+
FileUtils.should_receive(:mkpath).with('base/test-name.janus')
|
59
|
+
|
60
|
+
screenshot.save('base')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does not create test directory if it exists' do
|
64
|
+
IO.stub(:write)
|
65
|
+
Dir.stub(:exists?) { |p| p == 'base/test-name.janus' }
|
66
|
+
|
67
|
+
FileUtils.should_not_receive(:mkpath).with('base/test-name.janus')
|
68
|
+
|
69
|
+
screenshot.save('base')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'writes screenshot to disk' do
|
73
|
+
FileUtils.stub(:mkpath)
|
74
|
+
IO.should_receive(:write).with('base/test-name.janus/screenshot.png', image, mode: 'wb')
|
75
|
+
|
76
|
+
screenshot.save('base')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: janus-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brad Gignac
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colored
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: gli
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: selenium-webdriver
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.37'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.37'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.1'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.14'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.14'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.8'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ~>
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.8'
|
139
|
+
description: Automated visual regression testing on Sauce Labs.
|
140
|
+
email: bgignac@bradgignac.com
|
141
|
+
executables:
|
142
|
+
- janus
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- .gitignore
|
147
|
+
- .rspec
|
148
|
+
- .travis.yml
|
149
|
+
- Gemfile
|
150
|
+
- Guardfile
|
151
|
+
- LICENSE
|
152
|
+
- README.md
|
153
|
+
- Rakefile
|
154
|
+
- bin/janus
|
155
|
+
- janus.gemspec
|
156
|
+
- lib/janus.rb
|
157
|
+
- lib/janus/command/initialize.rb
|
158
|
+
- lib/janus/command/record.rb
|
159
|
+
- lib/janus/command/validate.rb
|
160
|
+
- lib/janus/configuration.rb
|
161
|
+
- lib/janus/screenshot.rb
|
162
|
+
- lib/janus/template/Janusfile
|
163
|
+
- lib/janus/test.rb
|
164
|
+
- lib/janus/version.rb
|
165
|
+
- spec/janus/command/initialize_spec.rb
|
166
|
+
- spec/janus/command/record_spec.rb
|
167
|
+
- spec/janus/command/validate_spec.rb
|
168
|
+
- spec/janus/configuration_spec.rb
|
169
|
+
- spec/janus/screenshot_spec.rb
|
170
|
+
- spec/janus/test_spec.rb
|
171
|
+
- spec/spec_helper.rb
|
172
|
+
homepage: https://github.com/bradgignac/janus
|
173
|
+
licenses:
|
174
|
+
- MIT
|
175
|
+
metadata: {}
|
176
|
+
post_install_message:
|
177
|
+
rdoc_options: []
|
178
|
+
require_paths:
|
179
|
+
- lib
|
180
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - '>='
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
requirements: []
|
191
|
+
rubyforge_project:
|
192
|
+
rubygems_version: 2.0.3
|
193
|
+
signing_key:
|
194
|
+
specification_version: 4
|
195
|
+
summary: Automated visual regression testing on Sauce Labs.
|
196
|
+
test_files:
|
197
|
+
- spec/janus/command/initialize_spec.rb
|
198
|
+
- spec/janus/command/record_spec.rb
|
199
|
+
- spec/janus/command/validate_spec.rb
|
200
|
+
- spec/janus/configuration_spec.rb
|
201
|
+
- spec/janus/screenshot_spec.rb
|
202
|
+
- spec/janus/test_spec.rb
|
203
|
+
- spec/spec_helper.rb
|