bugsnag-maze-runner 8.9.0 → 8.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03c53d6f8594ce559c2f2fb6296617d9b9f18227220b3a1148f297de154b8d60
4
- data.tar.gz: 3ce0a4585f6caac3ed1291f8a9ca8921926dbe551dd298ea6d8c8299136a67c5
3
+ metadata.gz: f0ea35795ffa2a45ce5190bde9317c508e631958504e47da4c8eaac20a5244b6
4
+ data.tar.gz: 90220645b3c2bcc5cfbb9823792bc8aee868e8fd6054fc7f6384dde01d55c5ea
5
5
  SHA512:
6
- metadata.gz: cf7ef0e05814ee96ddcc363de952c0f56cce6c98721ef3bf79ad7ade296d7390d5dc513efb1ac83645aba734a957c685fea9290d4980cf0de5986544340d34ae
7
- data.tar.gz: 7a967300d0dfcba750dfbce12c31a70e3793d98c822d35de70ec9838658e8436bad3962668bd70a50ff087236c74b174332b899406e906f42cbdf2475b643aea
6
+ metadata.gz: da920e3f04b2ae46e0c6eaae5796569c267ca59f1e3f8371af49109488fe5cbda31b68f36e3bd7b44cd9fac182afdc0d0ccc818872c01cda8fcf1d4b7722a705
7
+ data.tar.gz: 2379fbc274fffdd37834b5041393403036ff4f995bcc20845e462d51fe20672e0b0abb53172bb5e5059ec2a013af4ba2e0f3ca941d7522125b293438b6ca40f3
@@ -9,6 +9,7 @@ module Maze
9
9
 
10
10
  def initialize
11
11
  @session_ids = []
12
+ @start_attempts = 0
12
13
  end
13
14
 
14
15
  def start_session
@@ -47,51 +48,38 @@ module Maze
47
48
  raise 'Method not implemented by this class'
48
49
  end
49
50
 
50
- def start_driver(config)
51
- retry_failure = retry_start_driver?
52
- driver = nil
53
- until Maze.driver
54
- begin
55
-
56
-
57
- # Proc to start the driver
58
- start_driver_closure = Proc.new do
59
- begin
60
- config.capabilities = device_capabilities
61
- driver = Maze::Driver::Appium.new config.appium_server_url,
62
- config.capabilities,
63
- config.locator
64
-
65
- result = driver.start_driver
66
- if result
67
- # Log details of this session
68
- $logger.info "Created Appium session: #{driver.session_id}"
69
- @session_ids << driver.session_id
70
- udid = driver.session_capabilities['udid']
71
- $logger.info "Running on device: #{udid}" unless udid.nil?
72
- end
73
- result
74
- rescue => error
75
- Bugsnag.notify error
76
- $logger.error "Session creation failed: #{error}"
77
- false
78
- end
79
- end
51
+ def attempt_start_driver(config)
52
+ config.capabilities = device_capabilities
53
+ driver = Maze::Driver::Appium.new config.appium_server_url,
54
+ config.capabilities,
55
+ config.locator
56
+
57
+ result = driver.start_driver
58
+ if result
59
+ # Log details of this session
60
+ $logger.info "Created Appium session: #{driver.session_id}"
61
+ @session_ids << driver.session_id
62
+ udid = driver.session_capabilities['udid']
63
+ $logger.info "Running on device: #{udid}" unless udid.nil?
64
+ end
65
+ driver
66
+ end
80
67
 
68
+ def start_driver(config, max_attempts = 5)
81
69
 
82
- # Invoke the proc, with or without retries
83
- if retry_failure
84
- wait = Maze::Wait.new(interval: 10, timeout: 60)
85
- success = wait.until(&start_driver_closure)
86
- else
87
- success = start_driver_closure.call
88
- end
70
+ attempts = 0
89
71
 
90
- unless success
91
- $logger.error 'Failed to create Appium driver, exiting'
92
- exit(::Maze::Api::ExitCode::SESSION_CREATION_FAILURE)
93
- end
72
+ while attempts < max_attempts && Maze.driver.nil?
73
+ attempts += 1
74
+ start_error = nil
75
+ begin
76
+ Maze.driver = attempt_start_driver(config)
77
+ rescue => error
78
+ $logger.error "Session creation failed: #{error}"
79
+ start_error = error
80
+ end
94
81
 
82
+ if Maze.driver
95
83
  # Infer OS version if necessary when running locally
96
84
  if Maze.config.farm == :local && Maze.config.os_version.nil?
97
85
  version = case Maze.config.os
@@ -103,23 +91,23 @@ module Maze
103
91
  $logger.info "Inferred OS version to be #{version}"
104
92
  Maze.config.os_version = version
105
93
  end
106
-
107
- Maze.driver = driver
108
- rescue ::Selenium::WebDriver::Error::UnknownError => original_exception
109
- $logger.warn "Attempt to acquire #{config.device} device from farm #{config.farm} failed"
110
- $logger.warn "Exception: #{original_exception.message}"
111
- if config.device_list.empty?
112
- $logger.error 'No further devices to try - raising original exception'
113
- raise original_exception
94
+ else
95
+ interval = handle_error(start_error)
96
+ if interval && attempts < max_attempts
97
+ $logger.warn "Failed to create Appium driver, retrying in #{interval} seconds"
98
+ Kernel::sleep interval
114
99
  else
115
- config.device = config.device_list.first
116
- config.device_list = config.device_list.drop(1)
117
- $logger.warn "Retrying driver initialisation using next device: #{config.device}"
100
+ $logger.error 'Failed to create Appium driver, exiting'
101
+ Kernel::exit(::Maze::Api::ExitCode::SESSION_CREATION_FAILURE)
118
102
  end
119
103
  end
120
104
  end
121
105
  end
122
106
 
107
+ def handle_error(error)
108
+ raise 'Method not implemented by this class'
109
+ end
110
+
123
111
  def start_scenario
124
112
  # Launch the app on macOS
125
113
  Maze.driver.get(Maze.config.app) if Maze.config.os == 'macos'
@@ -13,8 +13,29 @@ module Maze
13
13
  end
14
14
  end
15
15
 
16
- def retry_start_driver?
17
- false
16
+ def handle_error(error)
17
+ # Retry interval depends on the error message
18
+ return nil if error.nil?
19
+
20
+ interval = nil
21
+ notify = true
22
+
23
+ if error.message.include? 'no sessionId in returned payload'
24
+ # This will happen naturally due to a race condition in how we access devices
25
+ # Do not notify, but wait long enough for most ghost sessions on BitBar to terminate.
26
+ interval = 60
27
+ notify = false
28
+ elsif error.message.include? 'You reached the account concurrency limit'
29
+ # In theory this shouldn't happen, but back off if it does
30
+ interval = 300
31
+ elsif error.message.include? 'There are no devices available'
32
+ interval = 120
33
+ else
34
+ # Do not retry in any other case
35
+ end
36
+
37
+ Bugsnag.notify error if notify
38
+ interval
18
39
  end
19
40
 
20
41
  def start_scenario
@@ -29,12 +50,18 @@ module Maze
29
50
  end
30
51
 
31
52
  def device_capabilities
53
+ # Doubling up on capabilities in both the `appium:options` and `appium` sub dictionaries.
54
+ # See PLAT-11087
32
55
  config = Maze.config
33
56
  capabilities = {
34
57
  'appium:options' => {
35
58
  'noReset' => true,
36
59
  'newCommandTimeout' => 600
37
60
  },
61
+ 'appium' => {
62
+ 'noReset' => true,
63
+ 'newCommandTimeout' => 600
64
+ },
38
65
  'bitbar:options' => {
39
66
  # Some capabilities probably belong in the top level
40
67
  # of the hash, but BitBar picks them up from here.
@@ -20,8 +20,7 @@ module Maze
20
20
  $logger.trace "Got group ids #{device_group_ids} for #{device_or_group_names}"
21
21
  group_count, device = api_client.find_device_in_groups(device_group_ids)
22
22
  if device.nil?
23
- # TODO: Retry rather than fail, see PLAT-7377
24
- Maze::Helper.error_exit 'There are no devices available'
23
+ raise 'There are no devices available'
25
24
  else
26
25
  $logger.info "#{group_count} device(s) currently available in group(s) '#{device_or_group_names}'"
27
26
  end
@@ -92,6 +91,8 @@ module Maze
92
91
  end
93
92
 
94
93
  def make_android_hash(device)
94
+ # Doubling up on capabilities in both the `appium:options` and `appium` sub dictionaries.
95
+ # See PLAT-11087
95
96
  hash = {
96
97
  'platformName' => 'Android',
97
98
  'deviceName' => 'Android Phone',
@@ -100,6 +101,11 @@ module Maze
100
101
  'autoGrantPermissions' => true,
101
102
  'uiautomator2ServerInstallTimeout' => 60000
102
103
  },
104
+ 'appium' => {
105
+ 'automationName' => 'UiAutomator2',
106
+ 'autoGrantPermissions' => true,
107
+ 'uiautomator2ServerInstallTimeout' => 60000
108
+ },
103
109
  'bitbar:options' => {
104
110
  'device' => device,
105
111
  }
@@ -108,6 +114,8 @@ module Maze
108
114
  end
109
115
 
110
116
  def make_ios_hash(device)
117
+ # Doubling up on capabilities in both the `appium:options` and `appium` sub dictionaries.
118
+ # See PLAT-11087
111
119
  {
112
120
  'platformName' => 'iOS',
113
121
  'deviceName' => 'iPhone device',
@@ -115,6 +123,10 @@ module Maze
115
123
  'automationName' => 'XCUITest',
116
124
  'shouldTerminateApp' => 'true'
117
125
  },
126
+ 'appium' => {
127
+ 'automationName' => 'XCUITest',
128
+ 'shouldTerminateApp' => 'true'
129
+ },
118
130
  'bitbar:options' => {
119
131
  'device' => device
120
132
  }
@@ -15,8 +15,18 @@ module Maze
15
15
  end
16
16
  end
17
17
 
18
- def retry_start_driver?
19
- Maze.config.device_list.nil? || Maze.config.device_list.empty?
18
+ # On BrowserStack, wait 10 seconds before retrying if there is another device in the list
19
+ def handle_error(error)
20
+ Bugsnag.notify error unless error.nil?
21
+ if Maze.config.device_list.nil? || config.device_list.empty?
22
+ $logger.error 'No further devices to try'
23
+ nil
24
+ else
25
+ config.device = config.device_list.first
26
+ config.device_list = config.device_list.drop(1)
27
+ $logger.warn "Retrying driver initialisation using next device: #{config.device}"
28
+ 10
29
+ end
20
30
  end
21
31
 
22
32
  def start_scenario
@@ -48,6 +48,10 @@ module Maze
48
48
  capabilities
49
49
  end
50
50
 
51
+ def retry_start_driver?
52
+ false
53
+ end
54
+
51
55
  def log_run_intro
52
56
  # Nothing to do
53
57
  end
data/lib/maze.rb CHANGED
@@ -7,7 +7,7 @@ require_relative 'maze/timers'
7
7
  # Glues the various parts of MazeRunner together that need to be accessed globally,
8
8
  # providing an alternative to the proliferation of global variables or singletons.
9
9
  module Maze
10
- VERSION = '8.9.0'
10
+ VERSION = '8.10.0'
11
11
 
12
12
  class << self
13
13
  attr_accessor :check, :driver, :internal_hooks, :mode, :start_time, :dynamic_retry, :public_address,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag-maze-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.9.0
4
+ version: 8.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Kirkland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-19 00:00:00.000000000 Z
11
+ date: 2023-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber