shoot 1.1.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4331d59d5b33ac9a34a36c7274543815c9227959
4
- data.tar.gz: 4d5a81d84d44a5ce417ff9e7947e4c28b3ba8b8f
3
+ metadata.gz: 675f708a7fe175d332fea879546b0b1f3da65b01
4
+ data.tar.gz: 6503def1d598f295ed6cd8c32c36cfb14bb5b786
5
5
  SHA512:
6
- metadata.gz: f56bed5a01c1cc3a3cdc718be79ea17b210dc466f7b933def485766bb20f110ddff156e22efaa29f525c7828e27205886add3027f2233f67909f340aa7212477
7
- data.tar.gz: 3ab3a44aa10da24e97b62414b63ca3a2e70a4bde8c87d87124b6b9d087eb02f067a4b8bea4ab93fa739398533735abf5c576b3efd1bdcb3c618618945835420c
6
+ metadata.gz: 50f3f4c3492cba7e62ed7cdd839bf126b3b2b05e5e1f8770e3e8af28380797ec4f9b67bbc65c5b363d863efd704b8f2bfd2502090e988226feccc8af3562ab66
7
+ data.tar.gz: a0ae49e4ce89ea9ccfc782e84a1974d30bd21b4bc8a2fa7ce21a33999b277fdaa37c4b18e32a8a8e2ad742f1a55698bc31eb8df55a1fdc337e51d55a8dfc4a13
data/Changelog.md ADDED
@@ -0,0 +1,21 @@
1
+ # 2.0.0
2
+
3
+ - Adds interactive mode (`shoot -i`);
4
+ - Increases performance by using curb (based on BrowserStack's docs);
5
+ - Activate and deactivate accepts a list of ids (instead of 1 or a range);
6
+ - Adds time elapsed for each test and for the whole suite;
7
+ - Adds update command to download all browsers again (`shoot update`);
8
+ - Allow to execute a whole folder (`shoot scenario folder/`);
9
+
10
+ # 1.1.0
11
+
12
+ - Allows to take shots inside methods, with the `shoot` method;
13
+ - Changes the folder structure it saves screenshots. Now it is `.screenshots/BROWSER/CLASS/METHOD/SHOT.png`, where SHOT is the param passed to shoot, or `finish` – taken in the end of the method – or `failed`, taken when the method fails (it helps debugging);
14
+ - Improves a lot the visual output of executions;
15
+
16
+ # 1.0.0
17
+
18
+ - Adds `test` command, allowing to run all scenarios locally against phantomjs (poltergeist);
19
+ - Adds minimally decent error treatment: if something fails doesn't stop all execution, only specific test;
20
+ - Adds `open` command, to open all screenshots (Mac only);
21
+ - Adds version commands (`version`, `-v` or `--v`);
data/lib/shoot/cli.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'thor'
2
2
  require 'json'
3
- require 'colorize'
3
+ require 'highline/import'
4
4
 
5
5
  module Shoot
6
6
  class CLI < Thor
@@ -8,12 +8,42 @@ module Shoot
8
8
  FileUtils::mkdir_p '.screenshots'
9
9
  BROWSERS_PATH = '.screenshots/.browsers.json'
10
10
  map %w[--version -v] => :version
11
+ map %w[--interactive -i] => :interactive
11
12
 
12
13
  desc 'version, --version, -v', 'Shoot version'
13
14
  def version
14
15
  puts Shoot::VERSION
15
16
  end
16
17
 
18
+ desc 'interactive, --interactive, -i', 'Activate one platform, based on ID or interval'
19
+ def interactive
20
+ @exit = false
21
+
22
+ available_commands = {
23
+ active: ->(_) { active },
24
+ activate: ->(params){ activate(*params.split(" ")) },
25
+ deactivate: ->(params){ deactivate(*params.split(" ")) },
26
+ deactivate_all: ->(_) { deactivate_all },
27
+ list: ->(params){ list(params) },
28
+ open: ->(_) { open },
29
+ test: ->(params){ test(params) },
30
+ scenario: ->(params){ scenario(params) },
31
+ update: ->(_) { update },
32
+ exit: ->(_) { @exit = true }
33
+ }
34
+
35
+ while ! @exit
36
+ choose do |menu|
37
+ menu.layout = :menu_only
38
+ menu.shell = true
39
+
40
+ available_commands.each do |command_name, command_action|
41
+ menu.choice(command_name, desc(command_name)){|_, details| command_action.call(details) }
42
+ end
43
+ end
44
+ end
45
+ end
46
+
17
47
  desc 'open', 'Opens all screenshots taken'
18
48
  def open
19
49
  open_all_screenshots
@@ -29,31 +59,37 @@ module Shoot
29
59
  table _active
30
60
  end
31
61
 
32
- desc 'scenario', 'Runs the given scenario on all active platforms or one platform, based on ID'
33
- def scenario(file, id = nil)
34
- runners = id ? [json[id.to_i]] : _active
35
- runners.each {|config| run file, config }
62
+ desc 'scenario', 'Runs the given scenario or all files in a directory on all active platforms'
63
+ def scenario(path)
64
+ files = File.directory?(path) ? Dir.glob("#{path}/*.rb") : [path]
65
+
66
+ elapsed_time do
67
+ _active.each do |config|
68
+ files.each do |file|
69
+ run file, config
70
+ end
71
+ end
72
+ print set_color("\nAll tests finished", :blue)
73
+ end
36
74
  end
37
75
 
38
76
  desc 'test', 'Runs the given scenario or all files in a directory on a local phantomjs'
39
77
  def test(path)
40
78
  files = File.directory?(path) ? Dir.glob("#{path}/*.rb") : [path]
41
- files.each{|file| run file }
79
+ elapsed_time do
80
+ files.each{|file| run file, nil }
81
+ print set_color("\nAll tests finished", :blue)
82
+ end
42
83
  end
43
84
 
44
- desc 'activate', 'Activate one platform, based on ID or interval'
45
- def activate(from_id, to_id = from_id)
46
- ids = (from_id.to_i..to_id.to_i).to_a
47
- ids.each { |id| json[id]['active'] = true }
48
- save_json
49
- table json[from_id.to_i - 2, ids.size + 4]
85
+ desc 'activate ID', 'Activate platforms, based on IDs'
86
+ def activate(*ids)
87
+ _activate(ids)
50
88
  end
51
89
 
52
- desc 'deactivate', 'Deactivate one platform, based on ID'
53
- def deactivate(id)
54
- json[id.to_i]['active'] = false
55
- save_json
56
- table json[id.to_i - 2, 5]
90
+ desc 'deactivate', 'Deactivate platforms, based on IDs'
91
+ def deactivate(*ids)
92
+ _deactivate(ids)
57
93
  end
58
94
 
59
95
  desc 'deactivate_all', 'Deactivate all the platforms'
@@ -64,25 +100,60 @@ module Shoot
64
100
  save_json
65
101
  end
66
102
 
103
+ desc 'update', 'Update browser list (WARNING: will override active browsers)'
104
+ def update
105
+ update_json
106
+ list
107
+ end
108
+
67
109
  no_commands do
110
+ def elapsed_time
111
+ require 'benchmark'
112
+
113
+ elapsed_time = Benchmark.measure do
114
+ yield
115
+ end
116
+ print set_color " (#{elapsed_time.real.to_i}s)\n", :blue
117
+ end
118
+
119
+ def desc(command)
120
+ CLI.commands[command.to_s].description rescue nil
121
+ end
122
+
123
+ def _activate(ids)
124
+ return puts "No ids provided, e.g. 'activate 123'" if ids.empty?
125
+ ids.map!(&:to_i)
126
+ ids.each { |id| json[id]['active'] = true }
127
+ save_json
128
+ table json.select{|item| ids.include?(item['id']) }
129
+ end
130
+
131
+ def _deactivate(ids)
132
+ return puts "No ids provided, e.g. 'deactivate 123'" if ids.empty?
133
+ ids.map!(&:to_i)
134
+ ids.each { |id| json[id]['active'] = false }
135
+ save_json
136
+ table json.select{|item| ids.include?(item['id']) }
137
+ end
138
+
68
139
  def open_all_screenshots
69
140
  `open #{Dir.glob(".screenshots/**/*.png").join(" ")}`
70
141
  end
71
142
 
72
- def run(file, config=nil)
143
+ def run(file, config = nil)
73
144
  klass = get_const_from_file(file)
74
145
  instance = klass.new(config)
75
146
  puts set_color instance.platform_name, :white, :bold
76
147
  klass.instance_methods(false).each do |method|
77
148
  print set_color " ➥ #{klass}##{method} ... ", :white, :bold
149
+ error = nil
78
150
 
79
- ok, error = instance.run(method)
80
- if ok
81
- print set_color "OK\n", :green
82
- else
83
- print set_color "FAILED\n", :red
84
- puts set_color " ⚠ #{error}", :red
151
+ elapsed_time do
152
+ ok, error = instance.run(method)
153
+
154
+ print ok ? set_color("OK", :green) : set_color("FAILED", :red)
85
155
  end
156
+ puts set_color " ⚠ #{error}", :red if error
86
157
  end
87
158
  instance.ok
88
159
  end
@@ -110,15 +181,19 @@ module Shoot
110
181
 
111
182
  def to_row(p)
112
183
  [
113
- p['id'].to_s.colorize(p['active'] ? :green : :red),
184
+ set_color(p['id'].to_s, p['active'] ? :green : :red),
114
185
  "#{p['os']} #{p['os_version']}",
115
186
  "#{p['browser']} #{p['browser_version']}",
116
187
  p['device']
117
188
  ]
118
189
  end
119
190
 
191
+ def update_json
192
+ File.write(BROWSERS_PATH, JSON.dump(fetch_json_and_prepare))
193
+ end
194
+
120
195
  def json
121
- File.write(BROWSERS_PATH, JSON.dump(fetch_json_and_prepare)) unless File.exist?(BROWSERS_PATH)
196
+ update_json unless File.exist?(BROWSERS_PATH)
122
197
  @json ||= JSON.parse(File.read(BROWSERS_PATH))
123
198
  end
124
199
 
@@ -2,6 +2,25 @@ require 'selenium-webdriver'
2
2
  require 'capybara'
3
3
  require 'timeout'
4
4
 
5
+ require 'selenium/webdriver/remote/http/curb'
6
+
7
+ module Selenium
8
+ module WebDriver
9
+ module Remote
10
+ class Bridge
11
+ attr_accessor :http_curb
12
+ def http
13
+ unless @http_curb
14
+ @http_curb = Http::Curb.new
15
+ @http_curb.server_url = @http.send(:server_url)
16
+ end
17
+ @http_curb
18
+ end
19
+ end # Bridge
20
+ end # Remote
21
+ end # WebDriver
22
+ end # Selenium
23
+
5
24
  class Shoot::Scenario
6
25
  URL = sprintf 'http://%s:%s@hub.browserstack.com/wd/hub',
7
26
  ENV['BROWSERSTACK_USER'],
data/lib/shoot/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Shoot
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/shoot.gemspec CHANGED
@@ -25,7 +25,8 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency "selenium-webdriver", "~> 2"
26
26
  spec.add_dependency "capybara", "~> 2"
27
27
  spec.add_dependency "thor", "~> 0.19"
28
- spec.add_dependency "colorize", "~> 0.7"
29
28
  spec.add_dependency "rest-client", "~> 1.7"
30
29
  spec.add_dependency "poltergeist", "~> 1.6"
30
+ spec.add_dependency "highline", "~> 1.7"
31
+ spec.add_dependency "curb", "~> 0.8.8"
31
32
  end
data/spec/cli_spec.rb CHANGED
@@ -89,8 +89,9 @@ describe 'Shoot::CLI' do
89
89
 
90
90
  it 'runs scenario' do
91
91
  cli.scenario('foo.rb')
92
- expect(cli).to have_received(:run)
92
+ expect(cli).to have_received(:run).with("foo.rb", "foo")
93
93
  end
94
+
94
95
  end
95
96
 
96
97
  describe 'test' do
@@ -101,7 +102,7 @@ describe 'Shoot::CLI' do
101
102
 
102
103
  it 'runs scenario' do
103
104
  cli.test('foo.rb')
104
- expect(cli).to have_received(:run).with("foo.rb")
105
+ expect(cli).to have_received(:run).with("foo.rb", nil)
105
106
  end
106
107
  end
107
108
 
@@ -114,8 +115,8 @@ describe 'Shoot::CLI' do
114
115
 
115
116
  it 'runs scenario' do
116
117
  cli.test('foo')
117
- expect(cli).to have_received(:run).with("foo/bar.rb")
118
- expect(cli).to have_received(:run).with("foo/baz.rb")
118
+ expect(cli).to have_received(:run).with("foo/bar.rb", nil)
119
+ expect(cli).to have_received(:run).with("foo/baz.rb", nil)
119
120
  end
120
121
  end
121
122
  end
@@ -126,15 +127,15 @@ describe 'Shoot::CLI' do
126
127
  def initialize(config); end
127
128
  def method; end
128
129
  end
129
-
130
- allow_any_instance_of(Foo).to receive(:run)
130
+ allow_any_instance_of(Foo).to receive(:run).and_return([true, ""])
131
+ allow_any_instance_of(Foo).to receive(:platform_name)
131
132
  expect_any_instance_of(Foo).to receive(:ok)
132
133
 
133
134
  allow(cli).to receive(:get_const_from_file).with("foo.rb").and_return(Foo)
134
135
  end
135
136
 
136
137
  it 'runs scenario' do
137
- cli.run('foo.rb', foo: :bar)
138
+ cli.run('foo.rb', {foo: :bar})
138
139
  end
139
140
  end
140
141
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Lulkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-21 00:00:00.000000000 Z
11
+ date: 2015-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -95,21 +95,35 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.19'
97
97
  - !ruby/object:Gem::Dependency
98
- name: colorize
98
+ name: rest-client
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.7'
103
+ version: '1.7'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.7'
110
+ version: '1.7'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rest-client
112
+ name: poltergeist
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.6'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.6'
125
+ - !ruby/object:Gem::Dependency
126
+ name: highline
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - "~>"
@@ -123,19 +137,19 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '1.7'
125
139
  - !ruby/object:Gem::Dependency
126
- name: poltergeist
140
+ name: curb
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '1.6'
145
+ version: 0.8.8
132
146
  type: :runtime
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '1.6'
152
+ version: 0.8.8
139
153
  description: A helper to take shots on BrowserStack. Run the shoot binary for more
140
154
  info.
141
155
  email:
@@ -146,6 +160,7 @@ extensions: []
146
160
  extra_rdoc_files: []
147
161
  files:
148
162
  - ".gitignore"
163
+ - Changelog.md
149
164
  - Gemfile
150
165
  - LICENSE
151
166
  - LICENSE.txt