quke 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,6 @@
1
- require 'cucumber'
1
+ # frozen_string_literal: true
2
+
3
+ require "cucumber"
2
4
 
3
5
  module Quke #:nodoc:
4
6
 
@@ -39,8 +41,8 @@ module Quke #:nodoc:
39
41
  # replace the last part of that result (which we know will be lib/quke)
40
42
  # with lib/features. We then pass this full path to Cucumber so it can
41
43
  # correctly find the folder holding our predefined env.rb file.
42
- '-r', __dir__.sub!('lib/quke', 'lib/features'),
43
- '-r', features_folder
44
+ "-r", __dir__.sub!("lib/quke", "lib/features"),
45
+ "-r", features_folder
44
46
  ] + args
45
47
  end
46
48
 
@@ -50,7 +52,7 @@ module Quke #:nodoc:
50
52
  Cucumber::Cli::Main.new(@args).execute!
51
53
  rescue SystemExit => e
52
54
  # Cucumber calls @kernel.exit() killing your script unless you rescue
53
- raise StandardError, 'Cucumber exited in a failed state' unless e.success?
55
+ raise StandardError, "Cucumber exited in a failed state" unless e.success?
54
56
  end
55
57
 
56
58
  end
@@ -1,4 +1,6 @@
1
- require 'quke/configuration'
1
+ # frozen_string_literal: true
2
+
3
+ require "quke/configuration"
2
4
 
3
5
  module Quke #:nodoc:
4
6
 
@@ -105,9 +107,9 @@ module Quke #:nodoc:
105
107
  # mirror those you can actually supply on the command line.
106
108
  # http://phantomjs.org/api/command-line.html
107
109
  options = [
108
- '--load-images=no',
109
- '--disk-cache=false',
110
- '--ignore-ssl-errors=yes'
110
+ "--load-images=no",
111
+ "--disk-cache=false",
112
+ "--ignore-ssl-errors=yes"
111
113
  ]
112
114
 
113
115
  options.push("--proxy=#{config.proxy['host']}:#{config.proxy['port']}") if config.use_proxy?
@@ -140,22 +142,20 @@ module Quke #:nodoc:
140
142
  # switches: my_driver_config.chrome
141
143
  # )
142
144
  #
143
- # rubocop:disable Metrics/AbcSize
144
145
  def chrome
145
146
  result = []
146
147
 
147
- host = config.proxy['host']
148
- port = config.proxy['port']
149
- no_proxy = config.proxy['no_proxy'].tr(',', ';')
148
+ host = config.proxy["host"]
149
+ port = config.proxy["port"]
150
+ no_proxy = config.proxy["no_proxy"].tr(",", ";")
150
151
 
151
152
  result.push("--proxy-server=#{host}:#{port}") if config.use_proxy?
152
- result.push("--proxy-bypass-list=#{no_proxy}") unless config.proxy['no_proxy'].empty?
153
+ result.push("--proxy-bypass-list=#{no_proxy}") unless config.proxy["no_proxy"].empty?
153
154
 
154
155
  result.push("--user-agent=#{config.user_agent}") unless config.user_agent.empty?
155
156
 
156
157
  result
157
158
  end
158
- # rubocop:enable Metrics/AbcSize
159
159
 
160
160
  # Returns an instance of Selenium::WebDriver::Remote::Capabilities to be
161
161
  # used when registering an instance of Capybara::Selenium::Driver,
@@ -184,7 +184,6 @@ module Quke #:nodoc:
184
184
  # profile: my_driver_config.firefox
185
185
  # )
186
186
  #
187
- # rubocop:disable Metrics/AbcSize
188
187
  def firefox
189
188
  profile = Selenium::WebDriver::Firefox::Profile.new
190
189
 
@@ -192,15 +191,14 @@ module Quke #:nodoc:
192
191
 
193
192
  settings[:http] = "#{config.proxy['host']}:#{config.proxy['port']}" if config.use_proxy?
194
193
  settings[:ssl] = settings[:http] if config.use_proxy?
195
- settings[:no_proxy] = config.proxy['no_proxy'] unless config.proxy['no_proxy'].empty?
194
+ settings[:no_proxy] = config.proxy["no_proxy"] unless config.proxy["no_proxy"].empty?
196
195
 
197
196
  profile.proxy = Selenium::WebDriver::Proxy.new(settings) if config.use_proxy?
198
197
 
199
- profile['general.useragent.override'] = config.user_agent unless config.user_agent.empty?
198
+ profile["general.useragent.override"] = config.user_agent unless config.user_agent.empty?
200
199
 
201
200
  profile
202
201
  end
203
- # rubocop:enable Metrics/AbcSize
204
202
 
205
203
  # Returns an instance of Selenium::WebDriver::Remote::Capabilities to be
206
204
  # used when registering an instance of Capybara::Selenium::Driver,
@@ -1,6 +1,8 @@
1
- require 'quke/configuration'
2
- require 'capybara/poltergeist'
3
- require 'selenium/webdriver'
1
+ # frozen_string_literal: true
2
+
3
+ require "quke/configuration"
4
+ require "capybara/poltergeist"
5
+ require "selenium/webdriver"
4
6
 
5
7
  module Quke #:nodoc:
6
8
 
@@ -29,11 +31,11 @@ module Quke #:nodoc:
29
31
  # When called registers with Capybara the driver specified.
30
32
  def register(driver)
31
33
  case driver
32
- when 'firefox'
34
+ when "firefox"
33
35
  firefox
34
- when 'chrome'
36
+ when "chrome"
35
37
  chrome
36
- when 'browserstack'
38
+ when "browserstack"
37
39
  browserstack
38
40
  else
39
41
  phantomjs
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Quke #:nodoc:
2
- VERSION = '0.6.0'.freeze
4
+ VERSION = "0.7.0"
3
5
  end
@@ -0,0 +1,262 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Quke::BrowserstackConfiguration do
6
+ describe "instantiating" do
7
+ context "when `.config.yml` is blank or contains no browserstack section" do
8
+ let(:config) do
9
+ Quke::Configuration.file_location = data_path(".no_file.yml")
10
+ Quke::Configuration.new
11
+ end
12
+ subject { Quke::BrowserstackConfiguration.new(config) }
13
+
14
+ it "returns an instance defaulted to blank values" do
15
+ expect(subject.username).to eq("")
16
+ expect(subject.auth_key).to eq("")
17
+ expect(subject.local_key).to eq("")
18
+ expect(subject.capabilities).to eq({})
19
+ end
20
+
21
+ end
22
+
23
+ context "when `.config.yml` contains a browserstack section" do
24
+ let(:config) do
25
+ Quke::Configuration.file_location = data_path(".simple.yml")
26
+ Quke::Configuration.new
27
+ end
28
+ subject { Quke::BrowserstackConfiguration.new(config) }
29
+
30
+ it "returns an instance with properties that match the input" do
31
+ expect(subject.username).to eq("jdoe")
32
+ expect(subject.auth_key).to eq("123456789ABCDE")
33
+ expect(subject.local_key).to eq("123456789ABCDE")
34
+ expect(subject.capabilities).to eq(
35
+ "build" => "Version 1",
36
+ "project" => "Adding browserstack support",
37
+ "browserstack.local" => true
38
+ )
39
+ end
40
+
41
+ end
42
+
43
+ context "when `.config.yml` contains a browserstack section but credentials are in env vars" do
44
+ let(:config) do
45
+ Quke::Configuration.file_location = data_path(".browserstack_no_credentials.yml")
46
+ Quke::Configuration.new
47
+ end
48
+ subject do
49
+ stub_const(
50
+ "ENV",
51
+ "BROWSERSTACK_USERNAME" => "tstark",
52
+ "BROWSERSTACK_AUTH_KEY" => "123456789VWXYZ",
53
+ "BROWSERSTACK_LOCAL_KEY" => "123456789REDRU"
54
+ )
55
+ Quke::BrowserstackConfiguration.new(config)
56
+ end
57
+
58
+ it "returns an instance with properties that match the input" do
59
+ expect(subject.username).to eq("tstark")
60
+ expect(subject.auth_key).to eq("123456789VWXYZ")
61
+ expect(subject.local_key).to eq("123456789REDRU")
62
+ expect(subject.capabilities).to eq(
63
+ "build" => "Version 1",
64
+ "project" => "Adding browserstack support",
65
+ "browserstack.local" => true
66
+ )
67
+ end
68
+
69
+ end
70
+ end
71
+
72
+ describe "#test_locally?" do
73
+ context "when `.config.yml` is blank or contains no browserstack section" do
74
+ let(:config) do
75
+ Quke::Configuration.file_location = data_path(".no_file.yml")
76
+ Quke::Configuration.new
77
+ end
78
+ subject { Quke::BrowserstackConfiguration.new(config) }
79
+
80
+ it "returns false" do
81
+ expect(subject.test_locally?).to eq(false)
82
+ end
83
+
84
+ end
85
+
86
+ context "when the driver is not set to 'browserstack' in `.config.yml`" do
87
+ let(:config) do
88
+ Quke::Configuration.file_location = data_path(".simple.yml")
89
+ Quke::Configuration.new
90
+ end
91
+ subject { Quke::BrowserstackConfiguration.new(config) }
92
+
93
+ it "returns false" do
94
+ expect(subject.test_locally?).to eq(false)
95
+ end
96
+
97
+ end
98
+
99
+ # Unlike some aspects of Quke's configuration where we handle users mixing
100
+ # strings and booleans ('true' and true) for setting values, because the
101
+ # browserstack capabilities are passed straight through we return false
102
+ # in this scenario to reflect what browserstack's behaviour would be
103
+ # i.e. it would fail to recognise that running locally is needed.
104
+ context "when the driver is 'browserstack' and use local testing is set to 'true' (a string) in `.config.yml`" do
105
+ let(:config) do
106
+ Quke::Configuration.file_location = data_path(".as_string.yml")
107
+ Quke::Configuration.new
108
+ end
109
+ subject { Quke::BrowserstackConfiguration.new(config) }
110
+
111
+ it "returns false" do
112
+ expect(subject.test_locally?).to eq(false)
113
+ end
114
+
115
+ end
116
+
117
+ context "when the driver is 'browserstack' and use local testing is set to true in `.config.yml`" do
118
+ let(:config) do
119
+ Quke::Configuration.file_location = data_path(".browserstack.yml")
120
+ Quke::Configuration.new
121
+ end
122
+ subject { Quke::BrowserstackConfiguration.new(config) }
123
+
124
+ it "returns true" do
125
+ expect(subject.test_locally?).to eq(true)
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ describe "local_testing_args" do
132
+ context "when `.config.yml` is blank or contains no browserstack section" do
133
+ let(:config) do
134
+ Quke::Configuration.file_location = data_path(".no_file.yml")
135
+ Quke::Configuration.new
136
+ end
137
+ subject { Quke::BrowserstackConfiguration.new(config) }
138
+
139
+ it "defaults to a blank key, and our standard args for the local binary" do
140
+ expect(subject.local_testing_args).to eq(
141
+ "key" => "",
142
+ "force" => "true",
143
+ "onlyAutomate" => "true",
144
+ "v" => "true",
145
+ "logfile" => File.join(Dir.pwd, "/tmp/bowerstack_local_log.txt")
146
+ )
147
+ end
148
+
149
+ end
150
+
151
+ context "when `.config.yml` contains just proxy details" do
152
+ let(:config) do
153
+ Quke::Configuration.file_location = data_path(".proxy_basic.yml")
154
+ Quke::Configuration.new
155
+ end
156
+ subject { Quke::BrowserstackConfiguration.new(config) }
157
+
158
+ it "defaults to a blank key, our standard args for the local binary, plus the proxy values" do
159
+ expect(subject.local_testing_args).to eq(
160
+ "key" => "",
161
+ "force" => "true",
162
+ "onlyAutomate" => "true",
163
+ "v" => "true",
164
+ "logfile" => File.join(Dir.pwd, "/tmp/bowerstack_local_log.txt"),
165
+ "proxyHost" => "10.10.2.70",
166
+ "proxyPort" => "8080"
167
+ )
168
+ end
169
+ end
170
+
171
+ context "when `.config.yml` contains both browserstack and proxy details" do
172
+ let(:config) do
173
+ Quke::Configuration.file_location = data_path(".browserstack.yml")
174
+ Quke::Configuration.new
175
+ end
176
+ subject { Quke::BrowserstackConfiguration.new(config) }
177
+
178
+ it "defaults to a blank key, our standard args for the local binary, plus the proxy values" do
179
+ expect(subject.local_testing_args).to eq(
180
+ "key" => "123456789ABCDE",
181
+ "force" => "true",
182
+ "onlyAutomate" => "true",
183
+ "v" => "true",
184
+ "logfile" => File.join(Dir.pwd, "/tmp/bowerstack_local_log.txt"),
185
+ "proxyHost" => "10.10.2.70",
186
+ "proxyPort" => "8080"
187
+ )
188
+ end
189
+
190
+ end
191
+ end
192
+
193
+ describe "#using_browserstack?" do
194
+ context "when `.config.yml` is blank" do
195
+ let(:config) do
196
+ Quke::Configuration.file_location = data_path(".no_file.yml")
197
+ Quke::Configuration.new
198
+ end
199
+ subject { Quke::BrowserstackConfiguration.new(config) }
200
+
201
+ it "returns false" do
202
+ expect(subject.using_browserstack?).to eq(false)
203
+ end
204
+
205
+ end
206
+
207
+ context "when `.config.yml` DOES NOT specify 'browserstack' as the driver" do
208
+ let(:config) do
209
+ Quke::Configuration.file_location = data_path(".simple.yml")
210
+ Quke::Configuration.new
211
+ end
212
+ subject { Quke::BrowserstackConfiguration.new(config) }
213
+
214
+ it "returns false" do
215
+ expect(subject.using_browserstack?).to eq(false)
216
+ end
217
+ end
218
+
219
+ context "when `.config.yml` specifies 'browserstack' as the driver" do
220
+ let(:config) do
221
+ Quke::Configuration.file_location = data_path(".browserstack.yml")
222
+ Quke::Configuration.new
223
+ end
224
+ subject { Quke::BrowserstackConfiguration.new(config) }
225
+
226
+ it "returns true" do
227
+ expect(subject.using_browserstack?).to eq(true)
228
+ end
229
+
230
+ end
231
+ end
232
+
233
+ describe "#url" do
234
+
235
+ context "when `.config.yml` is blank or contains no browserstack section" do
236
+ let(:config) do
237
+ Quke::Configuration.file_location = data_path(".no_file.yml")
238
+ Quke::Configuration.new
239
+ end
240
+ subject { Quke::BrowserstackConfiguration.new(config) }
241
+
242
+ it "returns nil" do
243
+ expect(subject.url).to eq(nil)
244
+ end
245
+ end
246
+
247
+ context "when `.config.yml` contains a browserstack section" do
248
+ let(:config) do
249
+ Quke::Configuration.file_location = data_path(".browserstack.yml")
250
+ Quke::Configuration.new
251
+ end
252
+ subject { Quke::BrowserstackConfiguration.new(config) }
253
+
254
+ it "returns a string for the url to browserstack including the username and password" do
255
+ expect(subject.url).to eq(
256
+ "http://jdoe:123456789ABCDE@hub.browserstack.com/wd/hub"
257
+ )
258
+ end
259
+ end
260
+
261
+ end
262
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Quke::BrowserstackStatusReporter do
6
+ subject do
7
+ Quke::Configuration.file_location = data_path(".no_file.yml")
8
+ config = Quke::BrowserstackConfiguration.new(Quke::Configuration.new)
9
+ Quke::BrowserstackStatusReporter.new(config)
10
+ end
11
+
12
+ describe "#passed" do
13
+ context "when the session_id is null" do
14
+ it "raises an ArgumentError" do
15
+ expect { subject.passed }.to raise_error(ArgumentError)
16
+ end
17
+ end
18
+
19
+ context "when the session_id is valid" do
20
+ before(:each) do
21
+ stub_request(:put, /browserstack/)
22
+ .with(
23
+ body: /passed/,
24
+ headers: {
25
+ "Accept" => "*/*",
26
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
27
+ "Authorization" => /Basic/,
28
+ "Content-Type" => "application/json",
29
+ "Host" => "www.browserstack.com",
30
+ "User-Agent" => "Ruby"
31
+ }
32
+ )
33
+ .to_return(status: 200, body: "", headers: {})
34
+ end
35
+
36
+ it "succesfully updates the status to 'passed'" do
37
+ expect { subject.passed("6a22fe36d84d90ef18858f90f2c9cd2882eb082f") }.not_to raise_error
38
+ end
39
+
40
+ it "returns a message stating a given session's status was set to 'passed'" do
41
+ result = subject.passed("6a22fe36d84d90ef18858f90f2c9cd2882eb082f")
42
+ expect(result).to eq("Browserstack session 6a22fe36d84d90ef18858f90f2c9cd2882eb082f status set to \e[32mpassed\e[0m 😀")
43
+ end
44
+ end
45
+
46
+ context "when the request fails" do
47
+ before(:each) do
48
+ stub_request(:put, /browserstack/)
49
+ .with(
50
+ body: /passed/,
51
+ headers: {
52
+ "Accept" => "*/*",
53
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
54
+ "Authorization" => /Basic/,
55
+ "Content-Type" => "application/json",
56
+ "Host" => "www.browserstack.com",
57
+ "User-Agent" => "Ruby"
58
+ }
59
+ )
60
+ .to_return(status: 500, body: "", headers: {})
61
+ end
62
+
63
+ it "raises an error" do
64
+ expect { subject.passed("6a22fe36d84d90ef18858f90f2c9cd2882eb082f") }.to raise_error(StandardError)
65
+ end
66
+
67
+ end
68
+ end
69
+
70
+ describe "#failed" do
71
+ context "when the session_id is null" do
72
+ it "raises an ArgumentError" do
73
+ expect { subject.failed }.to raise_error(ArgumentError)
74
+ end
75
+ end
76
+
77
+ context "when the session_id is valid" do
78
+ before(:each) do
79
+ stub_request(:put, /browserstack/)
80
+ .with(
81
+ body: /failed/,
82
+ headers: {
83
+ "Accept" => "*/*",
84
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
85
+ "Authorization" => /Basic/,
86
+ "Content-Type" => "application/json",
87
+ "Host" => "www.browserstack.com",
88
+ "User-Agent" => "Ruby"
89
+ }
90
+ )
91
+ .to_return(status: 200, body: "", headers: {})
92
+ end
93
+
94
+ it "succesfully updates the status to 'failed'" do
95
+ expect { subject.failed("6a22fe36d84d90ef18858f90f2c9cd2882eb082f") }.not_to raise_error
96
+ end
97
+
98
+ it "returns a message stating a given session's status was set to 'failed'" do
99
+ result = subject.failed("6a22fe36d84d90ef18858f90f2c9cd2882eb082f")
100
+ expect(result).to eq("Browserstack session 6a22fe36d84d90ef18858f90f2c9cd2882eb082f status set to \e[31mfailed\e[0m 😢")
101
+ end
102
+
103
+ end
104
+
105
+ context "when the request fails" do
106
+ before(:each) do
107
+ stub_request(:put, /browserstack/)
108
+ .with(
109
+ body: /passed/,
110
+ headers: {
111
+ "Accept" => "*/*",
112
+ "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
113
+ "Authorization" => /Basic/,
114
+ "Content-Type" => "application/json",
115
+ "Host" => "www.browserstack.com",
116
+ "User-Agent" => "Ruby"
117
+ }
118
+ )
119
+ .to_return(status: 500, body: "", headers: {})
120
+ end
121
+
122
+ it "raises an error" do
123
+ expect { subject.passed("6a22fe36d84d90ef18858f90f2c9cd2882eb082f") }.to raise_error(StandardError)
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+ end