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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7512f163c74551644149ae5452bf7e8f72977cef83e90134c26bd3c1a07f352c
4
- data.tar.gz: 87248ccb9a002564dc97f05380db06e55ee4cb0fb6599d5fb9fcc0dca7ee27e4
3
+ metadata.gz: d6fa82b7cd3b5e29fcfdb6e77f98f9dd7cb309d51523427de63e586b6094ac75
4
+ data.tar.gz: 8e8b4147c5a77459710f52cb36e927018050c34b4fff186960ddbb433ada23a7
5
5
  SHA512:
6
- metadata.gz: 796b7da1beb7307122675d78f8b2fd698ab71c5b5ce20f887cb288a14d880e3abc1a0a2f9219962d6b3040b33c7ab26c97dc8977e04b6681da1159ca3f0ab85f
7
- data.tar.gz: cafb5b1b25caf038eb537b15a552ba6242ab2493c2005c71ca8a2e15424c364ab81ca3a9a183e4606d94be7de55b06cec356e7249c78653c4f29d0a42d0f8595
6
+ metadata.gz: 2b0970705b477b0df8ad01f5f162b8e64731b76396cbe6c2038f10a501a4d5769aedfa00e33429ca8f0fc2e905a0efd6187b09f3d4e2ceb9262334183f596bbc
7
+ data.tar.gz: d4336f5ef88d197a1995142fb7ceb36c6dfe69038d8ac2204cd9fe3e04e82eeef2ad810279c9403977b1b27014f56f72ac6805d4dc5299a5917e6bbf386e4e1c
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.5.3
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: 25
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
- Exclude:
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: 17
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
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019 Titus Fortner
3
+ Copyright (c) 2019-2022 Sauce Labs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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
- $ bundle
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
- ## Usage
29
-
30
- `SauceBindings` is broken into two main components, `Options` and `Session`
31
-
32
- ### Options class
33
- `Options` provides an easy interface to the Sauce Labs specific settings you want in your tests.
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
- RSpec::Core::RakeTask.new(:examples) do |spec|
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
- RSpec::Core::RakeTask.new(:integration) do |spec|
17
- spec.pattern = 'spec/integration/*_spec.rb'
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
- task default: %i[examples unit integration]
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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SauceBindings
4
+ class SessionNotStartedError < RuntimeError; end
5
+
6
+ class InvalidPlatformError < RuntimeError; end
7
+ 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
- warn 'Using `Options.new(opts)` directly is deprecated, use static methods for desired browser instead; ' \
70
- 'e.g., `Options.chrome(opts)` or `Options.safari(opts)'
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
- warn ':timeouts is deprecated, use :implicit_wait_timeout, :page_load_timeout or :script_timeout directly; ' \
124
- '(ensure the values are set as seconds not milliseconds)'
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: 'ondemand.us-west-1.saucelabs.com',
10
- US_EAST: 'ondemand.us-east-1.saucelabs.com',
11
- EU_CENTRAL: 'ondemand.eu-central-1.saucelabs.com',
12
- APAC_SOUTHEAST: 'ondemand.apac-southeast-1.saucelabs.com'}.freeze
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
- SauceWhisk::Jobs.change_status(@driver.session_id, result)
39
- # Add output for the Sauce OnDemand Jenkins plugin
40
- # The first print statement will automatically populate links on Jenkins to Sauce
41
- # The second print statement will output the job link to logging/console
42
- puts "SauceOnDemandSessionID=#{@driver.session_id} job-name=#{@options.name}"
43
- puts "Test Job Link: https://app.saucelabs.com/tests/#{@driver.session_id}"
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://#{@username}:#{@access_key}@#{DATA_CENTERS[data_center]}:443/wd/hub"
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, desired_capabilities: options.capabilities}
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SauceBindings
4
- VERSION = '1.2.1'
4
+ VERSION = '1.3.0'
5
5
  end
@@ -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
@@ -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.5.0'
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 'rake', '>= 12.3.3'
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', '>= 3.142.7'
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
- describe 'starts with data center' do
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, data_center: :US_EAST)
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(data_center: :EU_CENTRAL)
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(data_center: :APAC_SOUTHEAST)
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