bugsnag-maze-runner 9.6.0 → 9.8.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: 7c5244250d40c6b3b44f775401c136e2f61e87779135858b5533e40875658190
4
- data.tar.gz: 9cab0c07bc4db58a9ec93e4b25157a7749f5bb53a03812e1420270da48f38729
3
+ metadata.gz: b6101c495b7debb939e4bb83f21dbc015c13f7bc58ce797d69fb90e618c6be6d
4
+ data.tar.gz: 69f5fdd5eec4c1f5bc8e9ed2aaa188531a6f54e80ec26471873ef93e7ecb1ecd
5
5
  SHA512:
6
- metadata.gz: b80d77bb8d388956f6acbefce51c3482b7450feb01dda66d655e9e682c89dc4b118f20d14bd63b0289092a27bce4dfb923332bf364a051e382b46e86ad8cf852
7
- data.tar.gz: 3ddc5d20186dee38db31c3db556e5454b9bd825caf6cef96ef18b92b3f503c2771f2f78afa8bf22d262fbdef0165d66e280daae764ab0b15d4db441811eac63e
6
+ metadata.gz: '0438524dc2173c1f31b323cca182e651ea1fc095727ee4658c5bb14baa986b5a17230fcd64460dd9eb9e805469c84eae2d3eadb85ae47668501a70dd1211e090'
7
+ data.tar.gz: bcf7dfcf91d8093099733839d06b38b1cea25548617eebad4f88a01910d8f64d6e0db26de0de5ebe38977e1cfa2b64d3fed80f8bc693d5ec6071c8dc633f5bb0
@@ -238,17 +238,21 @@ AfterAll do
238
238
  # Ensure the logger output is in the correct location
239
239
  Maze::Hooks::LoggerHooks.after_all
240
240
 
241
- maze_output = File.join(Dir.pwd, 'maze_output')
242
- maze_output_zip = File.join(Dir.pwd, 'maze_output.zip')
243
- # zip a folder with files and subfolders
244
- Zip::File.open(maze_output_zip, Zip::File::CREATE) do |zipfile|
245
- Dir["#{maze_output}/**/**"].each do |file|
246
- zipfile.add(file.sub(Dir.pwd + '/', ''), file)
241
+ if Maze.config.file_log
242
+ # create a zip file from the maze_output directory
243
+ maze_output = File.join(Dir.pwd, 'maze_output')
244
+ maze_output_zip = File.join(Dir.pwd, 'maze_output.zip')
245
+
246
+ # zip a folder with files and subfolders
247
+ Zip::File.open(maze_output_zip, Zip::File::CREATE) do |zipfile|
248
+ Dir["#{maze_output}/**/**"].each do |file|
249
+ zipfile.add(file.sub(Dir.pwd + '/', ''), file)
250
+ end
247
251
  end
248
- end
249
252
 
250
- # Move the zip file to the maze_output folder
251
- FileUtils.mv(maze_output_zip, maze_output)
253
+ # Move the zip file to the maze_output folder
254
+ FileUtils.mv(maze_output_zip, maze_output)
255
+ end
252
256
 
253
257
  metrics = Maze::MetricsProcessor.new(Maze::Server.metrics)
254
258
  metrics.process
@@ -34,6 +34,10 @@ module Maze
34
34
  interval = 10
35
35
  elsif error.message.include? 'Could not proxy command to the remote server'
36
36
  interval = 10
37
+ elsif error.message.include? 'Could not find a connected Android device'
38
+ interval = 10
39
+ elsif error.message.include? '\'platformVersion\' must be a valid version number.'
40
+ interval = 10
37
41
  else
38
42
  # Do not retry in any other case
39
43
  end
@@ -54,26 +58,24 @@ module Maze
54
58
  end
55
59
 
56
60
  def device_capabilities
57
- # Doubling up on capabilities in both the `appium:options` and `appium` sub dictionaries.
58
- # See PLAT-11087
59
61
  config = Maze.config
60
62
  common_caps = {
61
63
  'noReset' => true,
62
64
  'newCommandTimeout' => 600
63
65
  }
64
66
  capabilities = {
65
- 'appium:options' => common_caps,
66
- 'appium' => common_caps,
67
67
  'bitbar:options' => {
68
- # Some capabilities probably belong in the top level
69
- # of the hash, but BitBar picks them up from here.
70
68
  'apiKey' => config.access_key,
71
69
  'app' => config.app,
72
70
  'findDevice' => false,
73
71
  'testTimeout' => 7200
74
72
  }
75
73
  }
76
- capabilities.deep_merge! common_caps
74
+ if Maze.config.appium_version && Maze.config.appium_version.to_f < 2.0
75
+ capabilities.merge!(common_caps)
76
+ else
77
+ capabilities['appium:options'] = common_caps
78
+ end
77
79
  capabilities.deep_merge! BitBarClientUtils.dashboard_capabilities
78
80
  capabilities.deep_merge! BitBarDevices.get_available_device(config.device)
79
81
  capabilities['bitbar:options']['appiumVersion'] = config.appium_version unless config.appium_version.nil?
@@ -18,22 +18,44 @@ module Maze
18
18
  if device_group_ids
19
19
  # Device group found - find a free device in it
20
20
  $logger.trace "Got group ids #{device_group_ids} for #{device_or_group_names}"
21
- group_count, device = api_client.find_device_in_groups(device_group_ids)
22
- if device.nil?
23
- raise 'There are no devices available'
21
+ if device_group_ids.size > 1
22
+ group_id = false
23
+ group_count, device = api_client.find_device_in_groups(device_group_ids)
24
+ if device.nil?
25
+ raise 'There are no devices available'
26
+ else
27
+ $logger.info "#{group_count} device(s) currently available in group(s) '#{device_or_group_names}'"
28
+ end
24
29
  else
25
- $logger.info "#{group_count} device(s) currently available in group(s) '#{device_or_group_names}'"
30
+ # Since there is only one group, we can use it verbatim
31
+ $logger.info "Using device group #{device_or_group_names}"
32
+ group_id = true
33
+ device_name = device_group_ids.first
26
34
  end
27
35
  else
28
36
  # See if there is a device with the given name
29
37
  device = api_client.find_device device_or_group_names
30
38
  end
31
39
 
32
- device_name = device['displayName']
33
- platform = device['platform'].downcase
34
- platform_version = device['softwareVersion']['releaseVersion']
40
+ # If a single device has been identified use that to determine other characteristics
41
+ if device
42
+ device_name = device['displayName']
43
+ platform = device['platform'].downcase
44
+ platform_version = device['softwareVersion']['releaseVersion']
35
45
 
36
- $logger.info "Selected device: #{device_name} (#{platform} #{platform_version})"
46
+ $logger.info "Selected device: #{device_name} (#{platform} #{platform_version})"
47
+ else
48
+ # If a device group has been identified, extrapolate characteristics from the group name
49
+ if android_match = Regexp.new('(ANDROID|android)_(\d{1,2})').match(device_or_group_names)
50
+ platform = 'android'
51
+ platform_version = android_match[2]
52
+ elsif ios_match = Regexp.new('(IOS|ios)_(\d{1,2})').match(device_or_group_names)
53
+ platform = 'ios'
54
+ platform_version = ios_match[2]
55
+ end
56
+
57
+ $logger.info "Selected device group: #{device_or_group_names} (#{platform} #{platform_version})"
58
+ end
37
59
 
38
60
  # TODO: Setting the config here is rather a side effect and factoring it out would be better.
39
61
  # For now, though, it means not having to provide the --os and --os-version options on the command line.
@@ -42,9 +64,9 @@ module Maze
42
64
 
43
65
  case platform
44
66
  when 'android'
45
- make_android_hash(device_name)
67
+ make_android_hash(device_name, group_id)
46
68
  when 'ios'
47
- make_ios_hash(device_name)
69
+ make_ios_hash(device_name, group_id)
48
70
  else
49
71
  throw "Invalid device platform specified #{platform}"
50
72
  end
@@ -90,9 +112,7 @@ module Maze
90
112
  end
91
113
  end
92
114
 
93
- def make_android_hash(device)
94
- # Tripling up on capabilities in the `appium:options`, `appium` sub dictionaries and base dictionary.
95
- # See PLAT-11087
115
+ def android_base_hash
96
116
  appium_options = {
97
117
  'automationName' => 'UiAutomator2',
98
118
  'autoGrantPermissions' => true,
@@ -103,20 +123,31 @@ module Maze
103
123
  appium_options['appPackage'] = Maze.config.app_package unless Maze.config.app_package.nil?
104
124
  hash = {
105
125
  'platformName' => 'Android',
106
- 'deviceName' => 'Android Phone',
107
- 'appium:options' => appium_options,
108
- 'appium' => appium_options,
109
- 'bitbar:options' => {
110
- 'device' => device,
111
- }
126
+ 'deviceName' => 'Android Phone'
112
127
  }
113
- hash.merge!(appium_options)
128
+ if Maze.config.appium_version && Maze.config.appium_version.to_f < 2.0
129
+ hash.merge!(appium_options)
130
+ else
131
+ hash['appium:options'] = appium_options
132
+ end
133
+ hash.dup
134
+ end
135
+
136
+ def make_android_hash(device, group_id = false)
137
+ hash = android_base_hash
138
+ if group_id
139
+ hash['bitbar:options'] = {
140
+ 'deviceGroupId' => device
141
+ }
142
+ else
143
+ hash['bitbar:options'] = {
144
+ 'device' => device
145
+ }
146
+ end
114
147
  hash.freeze
115
148
  end
116
149
 
117
- def make_ios_hash(device)
118
- # Tripling up on capabilities in the `appium:options`, `appium` sub dictionaries and base dictionary.
119
- # See PLAT-11087
150
+ def ios_base_hash
120
151
  appium_options = {
121
152
  'automationName' => 'XCUITest',
122
153
  'shouldTerminateApp' => 'true',
@@ -125,13 +156,26 @@ module Maze
125
156
  hash = {
126
157
  'platformName' => 'iOS',
127
158
  'deviceName' => 'iPhone device',
128
- 'appium:options' => appium_options,
129
- 'appium' => appium_options,
130
- 'bitbar:options' => {
159
+ }
160
+ if Maze.config.appium_version && Maze.config.appium_version.to_f < 2.0
161
+ hash.merge!(appium_options)
162
+ else
163
+ hash['appium:options'] = appium_options
164
+ end
165
+ hash.dup
166
+ end
167
+
168
+ def make_ios_hash(device, group_id = false)
169
+ hash = ios_base_hash
170
+ if group_id
171
+ hash['bitbar:options'] = {
172
+ 'deviceGroupId' => device
173
+ }
174
+ else
175
+ hash['bitbar:options'] = {
131
176
  'device' => device
132
177
  }
133
- }
134
- hash.merge!(appium_options)
178
+ end
135
179
  hash.freeze
136
180
  end
137
181
  end
data/lib/maze/server.rb CHANGED
@@ -15,6 +15,12 @@ module Maze
15
15
  DEFAULT_STATUS_CODE = 200
16
16
 
17
17
  class << self
18
+
19
+ # Records the previous command UUID sent to the test fixture
20
+ #
21
+ # @return [String] The UUID of the last command sent
22
+ attr_accessor :last_command_uuid
23
+
18
24
  # Sets the response delay generator.
19
25
  #
20
26
  # @param generator [Maze::Generator] The new generator
@@ -236,6 +242,7 @@ module Maze
236
242
  server.mount '/logs', Servlets::LogServlet
237
243
  server.mount '/metrics', Servlets::Servlet, :metrics
238
244
  server.mount '/reflect', Servlets::ReflectiveServlet
245
+ server.mount '/docs', WEBrick::HTTPServlet::FileHandler, Maze.config.document_server_root unless Maze.config.document_server_root.nil?
239
246
  server.start
240
247
  rescue StandardError => e
241
248
  Bugsnag.notify e
@@ -19,17 +19,7 @@ module Maze
19
19
 
20
20
  if request.query.empty?
21
21
  # Non-idempotent mode - return the "current" command
22
- commands = Maze::Server.commands
23
-
24
- if commands.size_remaining == 0
25
- response.body = NOOP_COMMAND
26
- response.status = 200
27
- else
28
- command = commands.current
29
- response.body = JSON.pretty_generate(command)
30
- response.status = 200
31
- commands.next
32
- end
22
+ send_current_command(response)
33
23
  else
34
24
  # Idempotent mode
35
25
  after_uuid = request.query['after']
@@ -44,6 +34,21 @@ module Maze
44
34
  response.header['Access-Control-Allow-Origin'] = '*'
45
35
  end
46
36
 
37
+ def send_current_command(response)
38
+ commands = Maze::Server.commands
39
+
40
+ if commands.size_remaining == 0
41
+ response.body = NOOP_COMMAND
42
+ response.status = 200
43
+ else
44
+ command = commands.current
45
+ Server.last_command_uuid = command[:uuid]
46
+ response.body = JSON.pretty_generate(command)
47
+ response.status = 200
48
+ commands.next
49
+ end
50
+ end
51
+
47
52
  def command_after(uuid, response)
48
53
  commands = Maze::Server.commands
49
54
  if uuid.empty?
@@ -52,14 +57,20 @@ module Maze
52
57
  index = commands.all.find_index {|command| command[:uuid] == uuid }
53
58
  end
54
59
  if index.nil?
55
- msg = "Request invalid - there is no command with a UUID of #{uuid} to follow on from"
56
- $logger.error msg
57
- response.body = msg
58
- response.status = 400
60
+ # If the UUID given matches the last UUID sent by the server, we can assume the fixture has failed to reset
61
+ if uuid.eql?(Server.last_command_uuid)
62
+ send_current_command(response)
63
+ else
64
+ msg = "Request invalid - there is no command with a UUID of #{uuid} to follow on from"
65
+ $logger.error msg
66
+ response.body = msg
67
+ response.status = 400
68
+ end
59
69
  else
60
70
  if index + 1 < commands.size_all
61
71
  # Respond with the next command in the queue
62
72
  command = commands.get(index + 1)
73
+ Server.last_command_uuid = command[:uuid]
63
74
  command_json = JSON.pretty_generate(command)
64
75
  response.body = command_json
65
76
  response.status = 200
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 = '9.6.0'
10
+ VERSION = '9.8.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: 9.6.0
4
+ version: 9.8.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: 2024-04-03 00:00:00.000000000 Z
11
+ date: 2024-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -240,14 +240,14 @@ dependencies:
240
240
  requirements:
241
241
  - - "~>"
242
242
  - !ruby/object:Gem::Version
243
- version: 6.12.0
243
+ version: '7.0'
244
244
  type: :development
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
- version: 6.12.0
250
+ version: '7.0'
251
251
  - !ruby/object:Gem::Dependency
252
252
  name: markdown
253
253
  requirement: !ruby/object:Gem::Requirement