sauce_bindings 1.2.1 → 1.3.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 +4 -4
- data/.rubocop.yml +12 -6
- data/CHANGES.md +12 -0
- data/LICENSE.txt +1 -1
- data/README.md +11 -87
- data/Rakefile +8 -6
- data/lib/sauce_bindings/capybara_session.rb +0 -3
- data/lib/sauce_bindings/errors.rb +7 -0
- data/lib/sauce_bindings/logger.rb +20 -0
- data/lib/sauce_bindings/options.rb +22 -4
- data/lib/sauce_bindings/session.rb +92 -18
- data/lib/sauce_bindings/version.rb +1 -1
- data/lib/sauce_bindings.rb +8 -0
- data/sauce_bindings.gemspec +6 -6
- data/spec/integration/desktop_spec.rb +25 -5
- data/spec/spec_helper.rb +39 -1
- data/spec/unit/capybara_session_spec.rb +10 -20
- data/spec/unit/deprecated_options_spec.rb +479 -456
- data/spec/unit/options_spec.rb +120 -153
- data/spec/unit/session_spec.rb +437 -84
- metadata +30 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6fa82b7cd3b5e29fcfdb6e77f98f9dd7cb309d51523427de63e586b6094ac75
|
4
|
+
data.tar.gz: 8e8b4147c5a77459710f52cb36e927018050c34b4fff186960ddbb433ada23a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b0970705b477b0df8ad01f5f162b8e64731b76396cbe6c2038f10a501a4d5769aedfa00e33429ca8f0fc2e905a0efd6187b09f3d4e2ceb9262334183f596bbc
|
7
|
+
data.tar.gz: d4336f5ef88d197a1995142fb7ceb36c6dfe69038d8ac2204cd9fe3e04e82eeef2ad810279c9403977b1b27014f56f72ac6805d4dc5299a5917e6bbf386e4e1c
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.5
|
2
|
+
TargetRubyVersion: 2.7.5
|
3
3
|
|
4
4
|
require:
|
5
5
|
- rubocop-rspec
|
@@ -9,7 +9,7 @@ Layout/SpaceInsideHashLiteralBraces:
|
|
9
9
|
EnforcedStyle: no_space
|
10
10
|
|
11
11
|
Metrics/AbcSize:
|
12
|
-
Max:
|
12
|
+
Max: 27
|
13
13
|
|
14
14
|
Metrics/BlockLength:
|
15
15
|
Exclude:
|
@@ -22,14 +22,13 @@ Metrics/PerceivedComplexity:
|
|
22
22
|
Max: 11
|
23
23
|
|
24
24
|
Metrics/ClassLength:
|
25
|
-
|
26
|
-
- 'lib/sauce_bindings/options.rb'
|
25
|
+
Enabled: false
|
27
26
|
|
28
27
|
Metrics/LineLength:
|
29
28
|
Max: 120
|
30
29
|
|
31
30
|
Metrics/MethodLength:
|
32
|
-
Max:
|
31
|
+
Max: 20
|
33
32
|
|
34
33
|
Metrics/ModuleLength:
|
35
34
|
CountComments: false
|
@@ -55,4 +54,11 @@ RSpec/MultipleExpectations:
|
|
55
54
|
Enabled: false
|
56
55
|
|
57
56
|
RSpec/DescribedClass:
|
58
|
-
EnforcedStyle: explicit
|
57
|
+
EnforcedStyle: explicit
|
58
|
+
|
59
|
+
Lint/ConstantDefinitionInBlock:
|
60
|
+
Exclude:
|
61
|
+
- 'spec/spec_helper.rb'
|
62
|
+
|
63
|
+
Style/BlockDelimiters:
|
64
|
+
EnforcedStyle: braces_for_chaining
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
### 1.3.0 - June 15, 2022
|
2
|
+
|
3
|
+
* Fix links to work all data centers
|
4
|
+
* Manage credentials in Options instead of Session
|
5
|
+
* Deprecate using magic strings for stopping a session
|
6
|
+
* Implement pausing — `Session#pause`
|
7
|
+
* Implement commenting in Sauce command list — `Session#annotate`
|
8
|
+
* Implement logging control — `Session#enable_logs`, `Session#disable_logs`
|
9
|
+
* Implement network control — `Session#stop_network`, `Session#start_network`
|
10
|
+
* Implement updating test information — `Session#change_name`, `Session#tags=`
|
11
|
+
* Require Selenium 4 and Ruby 2.7
|
12
|
+
|
1
13
|
### 1.2.1 - March 1, 2022
|
2
14
|
|
3
15
|
* Added latest Windows and Mac platforms
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,23 +1,13 @@
|
|
1
1
|
# Sauce Bindings
|
2
|
+
|
2
3
|
## A library for interacting with Sauce Labs using Ruby
|
3
4
|
|
4
5
|
This gem is intended as a way to interact with Sauce Labs in an obvious and straightforward way.
|
5
6
|
|
6
|
-
## Installation
|
7
|
-
|
8
|
-
Add this line to your application's Gemfile:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
gem 'sauce_bindings'
|
12
|
-
```
|
13
|
-
|
14
|
-
And then execute:
|
7
|
+
## User Installation & Usage
|
15
8
|
|
16
|
-
|
17
|
-
|
18
|
-
Or install it yourself as:
|
19
|
-
|
20
|
-
$ gem install sauce_bindings
|
9
|
+
Please see the [documentation on our website](https://opensource.saucelabs.com/sauce_bindings),
|
10
|
+
and select the "Ruby" tab for code examples.
|
21
11
|
|
22
12
|
## Running Tests
|
23
13
|
|
@@ -25,79 +15,13 @@ To run tests for the Ruby Sauce Bindings, execute
|
|
25
15
|
|
26
16
|
$ bundle exec rake
|
27
17
|
|
28
|
-
##
|
29
|
-
|
30
|
-
`
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
If you want the default settings (the latest Chrome version on Windows 10) with no other settings,
|
36
|
-
this is all the code you need:
|
37
|
-
```
|
38
|
-
sauce_opts = SauceBindings::Options.new
|
39
|
-
```
|
40
|
-
To specify additional
|
41
|
-
[Sauce Labs supported settings](https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options),
|
42
|
-
simply pass these in as a `Hash`, or use an accessor:
|
43
|
-
```
|
44
|
-
sauce_options = {screen_resolution: '1080x720',
|
45
|
-
browser_name: 'Firefox',
|
46
|
-
platform_name: 'Mac OS'}
|
47
|
-
sauce_opts = SauceBindings::Options.new(sauce_options)
|
48
|
-
sauce_opts.idle_timeout = 100
|
49
|
-
```
|
50
|
-
if you have additional browser specific settings, or
|
51
|
-
[webdriver w3c spec compliant settings](http://w3c.github.io/webdriver/webdriver-spec.html#capabilities), in
|
52
|
-
Selenium 3.x you need to generate each of these separately; see the `Session` class below for how to use it:
|
53
|
-
```
|
54
|
-
sauce_options = SauceBindings::Options.new(screen_resolution: '1080x720',
|
55
|
-
browser_name: 'Firefox',
|
56
|
-
platform_name: 'Mac OS')
|
57
|
-
|
58
|
-
selenium_options = Selenium::WebDriver::Remote::Capabilities.new(accept_insecure_certs: false,
|
59
|
-
page_load_strategy: 'eager'}
|
60
|
-
|
61
|
-
browser_options = Selenium::WebDriver::Firefox::Options.new('args' => ['-foo'])
|
62
|
-
```
|
63
|
-
|
64
|
-
### Session class
|
65
|
-
#### Initializing a Session
|
66
|
-
`Session` class gets initialized with an `Options` instance. If you want the
|
67
|
-
default settings (latest Chrome version on Windows 10), you don't even need to use an `Options` instance:
|
68
|
-
```ruby
|
69
|
-
@session = SauceBindings::Session.new
|
70
|
-
```
|
71
|
-
If you want something other than the default, create a Sauce `Option` instance (as generated in the section above,
|
72
|
-
then pass it into the constructor:
|
73
|
-
```ruby
|
74
|
-
@session = SauceBindings::Session.new(sauce_opts)
|
75
|
-
```
|
76
|
-
If you also have Selenium or Browser options as described above, then you pass them in with an `Array` like so:
|
77
|
-
```ruby
|
78
|
-
@session = SauceBindings::Session.new([sauce_opts, se_opts, browser_opts])
|
79
|
-
```
|
80
|
-
|
81
|
-
#### Creating a driver instance
|
82
|
-
The `#start` method is required, and will return a `Selenium::WebDriver::<Browser>::Driver` instance,
|
83
|
-
and the `#stop` method will automatically quit the driver as well as ending the Sauce Labs session.
|
84
|
-
```ruby
|
85
|
-
session = SauceBindings::Session.new
|
86
|
-
driver = session.start
|
87
|
-
# Use the driver
|
88
|
-
session.stop
|
89
|
-
```
|
90
|
-
Note that the `Driver` instance can also be obtained at any time with the `#driver` method:
|
91
|
-
```ruby
|
92
|
-
session = SauceBindings::Session.new
|
93
|
-
session.start
|
94
|
-
driver = session.driver
|
95
|
-
# Use the driver
|
96
|
-
session.stop
|
97
|
-
```
|
98
|
-
#### Additional Session methods
|
99
|
-
We have a number of features we plan to add; stay tuned to see what additional features are made available. If you
|
100
|
-
have any request, please contact the Sauce Labs Solution Architect team.
|
18
|
+
## Building and Releasing
|
19
|
+
|
20
|
+
Use `gem` instead of `rake` so that it isn't auto-tagged on github
|
21
|
+
|
22
|
+
* Bump `SauceBindings::VERSION`
|
23
|
+
* `$ gem build sauce_bindings.gemspec`
|
24
|
+
* `$ gem push pkg/sauce_bindings-<VERSION>.gem`
|
101
25
|
|
102
26
|
## Contributing
|
103
27
|
|
data/Rakefile
CHANGED
@@ -5,16 +5,18 @@ require 'rspec/core/rake_task'
|
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
|
-
|
9
|
-
spec.pattern = 'spec/examples/*_spec.rb'
|
10
|
-
end
|
8
|
+
task default: %i[examples unit integration]
|
11
9
|
|
12
10
|
RSpec::Core::RakeTask.new(:unit) do |spec|
|
13
11
|
spec.pattern = 'spec/unit/*_spec.rb'
|
14
12
|
end
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
desc 'Run examples in parallel'
|
15
|
+
task :examples do
|
16
|
+
system 'parallel_split_test spec/examples/*_spec.rb'
|
18
17
|
end
|
19
18
|
|
20
|
-
|
19
|
+
desc 'Run integration tests in parallel'
|
20
|
+
task :integration do
|
21
|
+
system 'parallel_split_test spec/integration/*_spec.rb'
|
22
|
+
end
|
@@ -15,9 +15,6 @@ module SauceBindings
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def start
|
18
|
-
raise ArgumentError, "needs username; use `ENV['SAUCE_USERNAME']` or `Session#username=`" unless @username
|
19
|
-
raise ArgumentError, "needs access_key; use `ENV['SAUCE_ACCESS_KEY']` or `Session#access_key=`" unless @access_key
|
20
|
-
|
21
18
|
@capybara_driver = Capybara.current_session.driver
|
22
19
|
@driver = @capybara_driver.browser
|
23
20
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SauceBindings
|
4
|
+
#
|
5
|
+
# @example Enable full logging
|
6
|
+
# SauceBindings.logger.level = :debug
|
7
|
+
#
|
8
|
+
# @example Log to file
|
9
|
+
# SauceBindings.logger.output = 'webdrivers.log'
|
10
|
+
#
|
11
|
+
# @example Use logger manually
|
12
|
+
# SauceBindings.logger.info('This is info message')
|
13
|
+
# SauceBindings.logger.warn('This is warning message')
|
14
|
+
#
|
15
|
+
class Logger < Selenium::WebDriver::Logger
|
16
|
+
def initialize
|
17
|
+
super('SauceBindings')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -66,8 +66,9 @@ module SauceBindings
|
|
66
66
|
valid_options = opts.delete(:valid_options)
|
67
67
|
if valid_options.nil?
|
68
68
|
valid_options = SAUCE + W3C
|
69
|
-
|
70
|
-
|
69
|
+
SauceBindings.logger.deprecate('Using `Options.new(opts)` directly',
|
70
|
+
'static methods for desired browser',
|
71
|
+
id: :options_init) { '(e.g., `Options.chrome(opts)`)' }
|
71
72
|
end
|
72
73
|
|
73
74
|
create_variables(valid_options, opts)
|
@@ -86,7 +87,13 @@ module SauceBindings
|
|
86
87
|
value = parse_w3c_key(key)
|
87
88
|
caps[self.class.camel_case(key)] = value unless value.nil?
|
88
89
|
end
|
90
|
+
|
89
91
|
caps['sauce:options'] = {}
|
92
|
+
caps['sauce:options']['username'] = ENV['SAUCE_USERNAME'] ||
|
93
|
+
raise(ArgumentError, "needs username; use `ENV['SAUCE_USERNAME']`")
|
94
|
+
caps['sauce:options']['accessKey'] = ENV['SAUCE_ACCESS_KEY'] ||
|
95
|
+
raise(ArgumentError, "needs access key; use `ENV['SAUCE_ACCESS_KEY']`")
|
96
|
+
|
90
97
|
SAUCE.each do |key|
|
91
98
|
value = parse_sauce_key(key)
|
92
99
|
caps['sauce:options'][self.class.camel_case(key)] = value unless value.nil?
|
@@ -105,6 +112,14 @@ module SauceBindings
|
|
105
112
|
end
|
106
113
|
end
|
107
114
|
|
115
|
+
def mac?
|
116
|
+
@platform_name.include?('mac') || @platform_name.include?('OS X')
|
117
|
+
end
|
118
|
+
|
119
|
+
def windows?
|
120
|
+
@platform_name.include?('Windows')
|
121
|
+
end
|
122
|
+
|
108
123
|
private
|
109
124
|
|
110
125
|
def key_value(key)
|
@@ -120,8 +135,11 @@ module SauceBindings
|
|
120
135
|
value.as_json
|
121
136
|
elsif key == :timeouts
|
122
137
|
if value
|
123
|
-
|
124
|
-
|
138
|
+
SauceBindings.logger.deprecate(':timeouts',
|
139
|
+
':implicit_wait_timeout, :page_load_timeout or :script_timeout;',
|
140
|
+
id: :timeouts) do
|
141
|
+
'(ensure the values are set as seconds not milliseconds)'
|
142
|
+
end
|
125
143
|
value.transform_keys do |old_key|
|
126
144
|
self.class.camel_case(old_key)
|
127
145
|
end
|
@@ -6,13 +6,13 @@ require 'selenium-webdriver'
|
|
6
6
|
|
7
7
|
module SauceBindings
|
8
8
|
class Session
|
9
|
-
DATA_CENTERS = {US_WEST: '
|
10
|
-
US_EAST: '
|
11
|
-
EU_CENTRAL: '
|
12
|
-
APAC_SOUTHEAST: '
|
9
|
+
DATA_CENTERS = {US_WEST: 'us-west-1',
|
10
|
+
US_EAST: 'us-east-1',
|
11
|
+
EU_CENTRAL: 'eu-central-1',
|
12
|
+
APAC_SOUTHEAST: 'apac-southeast-1'}.freeze
|
13
13
|
|
14
14
|
attr_writer :url
|
15
|
-
attr_reader :driver, :options, :data_center
|
15
|
+
attr_reader :driver, :options, :data_center, :session_id
|
16
16
|
attr_accessor :http_client, :listener
|
17
17
|
|
18
18
|
def initialize(options = nil, data_center: nil, http_client: nil, listener: nil)
|
@@ -20,27 +20,25 @@ module SauceBindings
|
|
20
20
|
@http_client = http_client
|
21
21
|
@listener = listener
|
22
22
|
|
23
|
-
@username = ENV['SAUCE_USERNAME']
|
24
|
-
@access_key = ENV['SAUCE_ACCESS_KEY']
|
25
23
|
self.data_center = data_center || :US_WEST
|
26
24
|
end
|
27
25
|
|
28
26
|
def start
|
29
|
-
raise ArgumentError, "needs username; use `ENV['SAUCE_USERNAME']`" unless @username
|
30
|
-
raise ArgumentError, "needs access_key; use `ENV['SAUCE_ACCESS_KEY']`" unless @access_key
|
31
|
-
|
32
27
|
@driver = Selenium::WebDriver.for :remote, to_selenium
|
28
|
+
@session_id = @driver.session_id
|
29
|
+
@driver
|
33
30
|
end
|
34
31
|
|
35
32
|
def stop(result)
|
36
33
|
return if @driver.nil?
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
unless result.is_a?(TrueClass) || result.is_a?(FalseClass)
|
36
|
+
raise ArgumentError, 'Result must be a boolean value representing whether a test has passed'
|
37
|
+
end
|
38
|
+
|
39
|
+
SauceWhisk::Jobs.change_status(@session_id, result)
|
40
|
+
print_results
|
41
|
+
|
44
42
|
@driver.quit
|
45
43
|
end
|
46
44
|
|
@@ -55,19 +53,95 @@ module SauceBindings
|
|
55
53
|
end
|
56
54
|
|
57
55
|
def accessibility_results(js_lib: nil, frames: true, cross_origin: false)
|
56
|
+
validate_session_started('accessibility_results')
|
58
57
|
sa11y = Sa11y::Analyze.new(driver, js_lib: js_lib, frames: frames, cross_origin: cross_origin)
|
59
58
|
sa11y.results
|
60
59
|
end
|
61
60
|
|
61
|
+
def annotate(comment)
|
62
|
+
validate_session_started('annotate')
|
63
|
+
driver.execute_script("sauce:context=#{comment}")
|
64
|
+
end
|
65
|
+
|
66
|
+
def pause
|
67
|
+
validate_session_started('pause')
|
68
|
+
driver.execute_script('sauce: break')
|
69
|
+
puts "\nThis test has been stopped; no more driver commands will be accepted"
|
70
|
+
puts "\nYou can take manual control of the test from the Sauce Labs UI here: #{test_link}"
|
71
|
+
@driver = nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def disable_logging
|
75
|
+
validate_session_started('disable_logging')
|
76
|
+
driver.execute_script('sauce: disable log')
|
77
|
+
end
|
78
|
+
|
79
|
+
def enable_logging
|
80
|
+
validate_session_started('enable_logging')
|
81
|
+
driver.execute_script('sauce: enable log')
|
82
|
+
end
|
83
|
+
|
84
|
+
def stop_network
|
85
|
+
validate_session_started('stop_network')
|
86
|
+
unless options.mac?
|
87
|
+
error = "Can only start or stop the network on a Mac; current platform is: #{options.platform_name}"
|
88
|
+
raise InvalidPlatformError, error
|
89
|
+
end
|
90
|
+
|
91
|
+
driver.execute_script('sauce: stop network')
|
92
|
+
end
|
93
|
+
|
94
|
+
def start_network
|
95
|
+
validate_session_started('start_network')
|
96
|
+
unless options.mac?
|
97
|
+
error = "Can only start or stop the network on a Mac; current platform is: #{options.platform_name}"
|
98
|
+
raise InvalidPlatformError, error
|
99
|
+
end
|
100
|
+
|
101
|
+
driver.execute_script('sauce: start network')
|
102
|
+
end
|
103
|
+
|
104
|
+
def change_name(name)
|
105
|
+
validate_session_started('change_name')
|
106
|
+
|
107
|
+
driver.execute_script("sauce:job-name=#{name}")
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_tags(tags)
|
111
|
+
tags = Array(tags)
|
112
|
+
validate_session_started('tags=')
|
113
|
+
@driver.execute_script("sauce:job-tags=#{tags.join(',')}")
|
114
|
+
end
|
115
|
+
|
62
116
|
def url
|
63
|
-
@url ||= "https
|
117
|
+
@url ||= "https://ondemand.#{DATA_CENTERS[data_center]}.saucelabs.com/wd/hub"
|
64
118
|
end
|
65
119
|
|
66
120
|
def to_selenium
|
67
|
-
caps = {url: url,
|
121
|
+
caps = {url: url, capabilities: Selenium::WebDriver::Remote::Capabilities.new(options.capabilities)}
|
68
122
|
caps[:listener] = listener if listener
|
69
123
|
caps[:http_client] = http_client if http_client
|
70
124
|
caps
|
71
125
|
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def test_link
|
130
|
+
dc = data_center == :US_WEST ? '' : "#{DATA_CENTERS[data_center]}."
|
131
|
+
"https://app.#{dc}saucelabs.com/tests/#{@session_id}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def validate_session_started(method)
|
135
|
+
raise SessionNotStartedError, "session must be started before executing ##{method}" unless @driver
|
136
|
+
end
|
137
|
+
|
138
|
+
def print_results
|
139
|
+
# Add output for the Sauce OnDemand Jenkins plugin
|
140
|
+
# The first print statement will automatically populate links on Jenkins to Sauce
|
141
|
+
# The second print statement will output the job link to logging/console
|
142
|
+
puts "SauceOnDemandSessionID=#{@session_id} job-name=#{@options.name}"
|
143
|
+
|
144
|
+
puts "Test Job Link: #{test_link}"
|
145
|
+
end
|
72
146
|
end
|
73
147
|
end
|
data/lib/sauce_bindings.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'sauce_bindings/version'
|
4
4
|
require 'sauce_bindings/options'
|
5
|
+
require 'sauce_bindings/errors'
|
5
6
|
require 'sauce_bindings/session'
|
6
7
|
require 'sauce_bindings/base_configurations'
|
7
8
|
require 'sauce_bindings/vdc_configurations'
|
@@ -10,3 +11,10 @@ require 'sauce_bindings/edge_configurations'
|
|
10
11
|
require 'sauce_bindings/firefox_configurations'
|
11
12
|
require 'sauce_bindings/ie_configurations'
|
12
13
|
require 'sauce_bindings/safari_configurations'
|
14
|
+
require 'sauce_bindings/logger'
|
15
|
+
|
16
|
+
module SauceBindings
|
17
|
+
def self.logger
|
18
|
+
@logger ||= Logger.new
|
19
|
+
end
|
20
|
+
end
|
data/sauce_bindings.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = SauceBindings::VERSION
|
10
10
|
spec.authors = ['Titus Fortner']
|
11
11
|
spec.email = ['titusfortner@gmail.com']
|
12
|
-
spec.required_ruby_version = '>= 2.
|
12
|
+
spec.required_ruby_version = '>= 2.7.0'
|
13
13
|
|
14
14
|
spec.summary = 'Simple interface for interacting with Sauce Labs.'
|
15
15
|
spec.description = 'Reduces complexity in user code for running Selenium tests on Sauce Labs'
|
@@ -22,14 +22,14 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
24
24
|
spec.add_development_dependency 'capybara', '~> 3.16'
|
25
|
-
spec.add_development_dependency '
|
25
|
+
spec.add_development_dependency 'climate_control', '~> 1.1'
|
26
|
+
spec.add_development_dependency 'parallel_split_test', '~> 0.10'
|
27
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
26
28
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
-
spec.add_development_dependency 'rubocop', '~> 1.0'
|
28
|
-
spec.add_development_dependency 'rubocop-performance'
|
29
29
|
spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
|
30
30
|
spec.add_development_dependency 'webmock', '~> 3.5'
|
31
31
|
|
32
32
|
spec.add_runtime_dependency 'sa11y', '~> 0.2.0'
|
33
|
-
spec.add_runtime_dependency 'sauce_whisk'
|
34
|
-
spec.add_runtime_dependency 'selenium-webdriver', '
|
33
|
+
spec.add_runtime_dependency 'sauce_whisk', '~> 0.3.2'
|
34
|
+
spec.add_runtime_dependency 'selenium-webdriver', '~> 4.0'
|
35
35
|
end
|
@@ -4,9 +4,9 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
module SauceBindings
|
6
6
|
describe Session do
|
7
|
-
|
8
|
-
before { WebMock.allow_net_connect! }
|
7
|
+
before { WebMock.allow_net_connect! }
|
9
8
|
|
9
|
+
describe '#data_center=' do
|
10
10
|
it 'defaults to US West' do
|
11
11
|
@session = Session.new
|
12
12
|
driver = @session.start
|
@@ -17,7 +17,8 @@ module SauceBindings
|
|
17
17
|
|
18
18
|
it 'executes on US East' do
|
19
19
|
options = Options.chrome(platform_name: 'Linux')
|
20
|
-
@session = Session.new(options
|
20
|
+
@session = Session.new(options)
|
21
|
+
@session.data_center = :US_EAST
|
21
22
|
driver = @session.start
|
22
23
|
|
23
24
|
expect(driver).not_to be_nil
|
@@ -25,7 +26,8 @@ module SauceBindings
|
|
25
26
|
end
|
26
27
|
|
27
28
|
it 'executes on EU Central' do
|
28
|
-
@session = Session.new
|
29
|
+
@session = Session.new
|
30
|
+
@session.data_center = :EU_CENTRAL
|
29
31
|
driver = @session.start
|
30
32
|
|
31
33
|
expect(driver).not_to be_nil
|
@@ -34,12 +36,30 @@ module SauceBindings
|
|
34
36
|
|
35
37
|
it 'executes on APAC' do
|
36
38
|
pending 'Adding Data Center to Sauce Whisk'
|
37
|
-
@session = Session.new
|
39
|
+
@session = Session.new
|
40
|
+
@session.data_center = :APAC_SOUTHEAST
|
38
41
|
driver = @session.start
|
39
42
|
|
40
43
|
expect(driver).not_to be_nil
|
41
44
|
expect(@session.url).to include('apac-southeast-1')
|
42
45
|
end
|
43
46
|
end
|
47
|
+
|
48
|
+
describe '#stop_network' do
|
49
|
+
it 'stops and starts the network' do
|
50
|
+
@session = Session.new(Options.safari)
|
51
|
+
driver = @session.start
|
52
|
+
|
53
|
+
@session.stop_network
|
54
|
+
driver.get('https://www.saucedemo.com')
|
55
|
+
|
56
|
+
expect(driver.title).to eq 'Failed to open page'
|
57
|
+
|
58
|
+
@session.start_network
|
59
|
+
driver.get('https://www.saucedemo.com')
|
60
|
+
|
61
|
+
expect(driver.title).to eq 'Swag Labs'
|
62
|
+
end
|
63
|
+
end
|
44
64
|
end
|
45
65
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,13 +3,51 @@
|
|
3
3
|
require 'sauce_bindings'
|
4
4
|
require 'rspec'
|
5
5
|
require 'webmock/rspec'
|
6
|
+
require 'climate_control'
|
6
7
|
|
7
8
|
RSpec.configure do |config|
|
8
9
|
config.expect_with :rspec do |c|
|
9
10
|
c.syntax = :expect
|
10
11
|
end
|
11
12
|
|
13
|
+
config.before(:suite) do
|
14
|
+
BUILD_ENV = {BUILD_TAG: '', BUILD_NAME: 'TEMP BUILD', BUILD_NUMBER: '11'}.freeze
|
15
|
+
SAUCE_ACCESS = {SAUCE_USERNAME: 'foo', SAUCE_ACCESS_KEY: '123'}.freeze
|
16
|
+
end
|
17
|
+
|
12
18
|
config.after do |example|
|
13
|
-
@session&.stop(!example.exception)
|
19
|
+
@session&.stop(!example.exception) if @session&.session_id != '0'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
DEPRECATION_WARNINGS = %i[options_init timeouts].freeze
|
24
|
+
|
25
|
+
DEPRECATION_WARNINGS.each do |deprecation|
|
26
|
+
RSpec::Matchers.define "have_deprecated_#{deprecation}" do
|
27
|
+
match do |actual|
|
28
|
+
return actual.call if ENV['IGNORE_DEPRECATIONS']
|
29
|
+
|
30
|
+
warning = /\[DEPRECATION\] \[:#{deprecation}/
|
31
|
+
expect {
|
32
|
+
actual.call
|
33
|
+
@stdout_message = File.read $stdout if $stdout.is_a?(File)
|
34
|
+
}.to output(warning).to_stdout_from_any_process
|
35
|
+
end
|
36
|
+
|
37
|
+
failure_message do |_actual|
|
38
|
+
return 'unexpected exception in the custom matcher block' unless @stdout_message
|
39
|
+
|
40
|
+
deprecations_found = @stdout_message[/WARN Watir \[DEPRECATION\] ([^.*\ ]*)/, 1]
|
41
|
+
but_message = if deprecations_found.nil?
|
42
|
+
'no Warnings were found'
|
43
|
+
else
|
44
|
+
"deprecation Warning of #{deprecations_found} was found instead"
|
45
|
+
end
|
46
|
+
"expected Warning message of \"#{deprecation}\" being deprecated, but #{but_message}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def supports_block_expectations?
|
50
|
+
true
|
51
|
+
end
|
14
52
|
end
|
15
53
|
end
|