bugsnag-maze-runner 9.11.2 → 9.12.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: 8d720cd78e4048822fe49b967ff002b17569eb6919f4bcf63b2c7b261ffafb13
4
- data.tar.gz: eba331593b17b2670b83b3df6a6c947b0bb519c6d0542695a524bd44c1401b59
3
+ metadata.gz: 325db4804e14fcf97c4cb8f53782676a597d29975d1ead996810979e94466207
4
+ data.tar.gz: 9b63455da005c6e4a1db345c74301801538425573c1fc02737034b0717a81e46
5
5
  SHA512:
6
- metadata.gz: 761cbce7919681956370c78e7641eecee28592272446bbfaf8fbadd374ff0b910018cd6c2f60ae37f6ae29780f7e638adcaa5aa5b5a1590d55e22ac355f9e35a
7
- data.tar.gz: d29abfbdc4b50decb86214502f92b06d83cc16916fb3bf8b5137aebf489907f5b23889ac92b4199746adcfca72fb2c79b77ae8872ca6ef1ac5862492cc137bd0
6
+ metadata.gz: f7b981946519533317ff0f07782d12cc78cadda9e0f82227a6d7b7bc1d8ed4f0b52009040eab4fb5c399862e0b652583652f25e9921389fa64d996ea886d3c59
7
+ data.tar.gz: 9e0ee212669d3dbc3d78ef6ee29dd0843a6b0d0ee6ecb9282ed53761c5b6da180be2fe8fc7590db8d6012d2543c121c9cf9f27f3c631cfffc4fa85c5c3ba42e6
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Required libraries and dependencies
5
+ require_relative '../lib/maze'
6
+ require_relative '../lib/maze/loggers/logger'
7
+ require_relative '../lib/maze/client/bb_client_utils'
8
+ require 'optimist'
9
+ require 'net/http'
10
+ require 'json'
11
+ require 'uri'
12
+ require 'date'
13
+ require 'csv'
14
+
15
+ class BBFailedSessions
16
+ def start(args)
17
+ # Define and parse command-line options
18
+ p = Optimist::Parser.new do
19
+ text 'Get unsuccessful runs from BitBar Cloud'
20
+ text ''
21
+ text 'Requires BITBAR_API_KEY'
22
+ text ''
23
+ text 'Usage [OPTIONS]'
24
+ text ''
25
+ opt :help,
26
+ 'Print this help.'
27
+ opt :date,
28
+ "Date to filter the runs. Format: 'YYYY-MM-DD'",
29
+ :type => :string
30
+ opt :project,
31
+ "Name of the BitBar project",
32
+ :type => :string
33
+ opt :output,
34
+ "Path to the output CSV file",
35
+ :type => :string
36
+ end
37
+
38
+ # Parse the command-line arguments
39
+ opts = Optimist::with_standard_exception_handling p do
40
+ raise Optimist::HelpNeeded if ARGV.empty? # Show help screen if no arguments
41
+ p.parse ARGV
42
+ end
43
+
44
+ # Get the API key from environment variable
45
+ api_key = ENV['BITBAR_API_KEY']
46
+
47
+ # Check if BITBAR_API_KEY has been set
48
+ if api_key.nil?
49
+ $logger.warn "BITBAR_API_KEY has not been set"
50
+ Optimist::with_standard_exception_handling p do
51
+ raise Optimist::HelpNeeded
52
+ end
53
+ end
54
+
55
+ # if date is not provided, use today's date
56
+ opts[:date] ||= DateTime.now.strftime('%Y-%m-%d')
57
+
58
+ # Fetch project information from BitBar
59
+ project_info = Maze::Client::BitBarClientUtils.get_ids api_key, opts[:project]
60
+
61
+ # Iterate over each project and fetch unsuccessful runs
62
+ for id, name in project_info
63
+ $logger.info "Getting unsuccessful runs #{name} (#{id}) on #{opts[:date]}"
64
+ runs = Maze::Client::BitBarClientUtils.get_unsuccessful_runs api_key, id, opts[:date]
65
+
66
+ # Array to store the data to be written to the CSV
67
+ data = []
68
+
69
+ # Collect the data from each run
70
+ runs.each do |run|
71
+ data << [ name, DateTime.strptime(run['createTime'].to_s, '%Q'), run['displayName'], run['uiLink'], run['config']['files'][0]['file']['userEmail'] ]
72
+ end
73
+
74
+ # Define the CSV file path
75
+ csv_file_path = opts[:output] || "failed_sessions_#{name.gsub('-', '_')}_#{opts[:date].gsub('/', '_')}.csv"
76
+
77
+ $logger.info "Saving data to CSV file at #{csv_file_path}"
78
+
79
+ # Write the data to a CSV file
80
+ CSV.open(csv_file_path, 'w') do |csv|
81
+ # Write the headers
82
+ csv << ['Project', 'Date', 'Test Name', 'Dashboard Link', 'User Email']
83
+
84
+ # Write the data rows
85
+ data.each do |row|
86
+ csv << row
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ # Start the process with command-line arguments
94
+ BBFailedSessions.new.start(ARGV)
@@ -64,104 +64,6 @@ When('I set the device orientation to {orientation}') do |orientation|
64
64
  Maze.driver.set_rotation orientation
65
65
  end
66
66
 
67
- # Tests that the given payload value is correct for the target BrowserStack platform.
68
- # This step will assume the expected and payload values are strings.
69
- # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
70
- #
71
- # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
72
- # | android | Java.lang.RuntimeException |
73
- # | ios | NSException |
74
- #
75
- # If the expected value is set to "@skip", the check should be skipped
76
- # If the expected value is set to "@null", the check will be for null
77
- # If the expected value is set to "@not_null", the check will be for a non-null value
78
- #
79
- # @step_input request_type [String] The type of request (error, session, build, etc)
80
- # @step_input field_path [String] The field to test
81
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
82
- Then('the {request_type} payload field {string} equals the platform-dependent string:') do |request_type, field_path, platform_values|
83
- test_string_platform_values(request_type, field_path, platform_values)
84
- end
85
-
86
- # See `the error payload field {string} equals the platform-dependent string:`
87
- #
88
- # @step_input field_path [String] The field to test, prepended with "events.0"
89
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
90
- Then('the event {string} equals the platform-dependent string:') do |field_path, platform_values|
91
- test_string_platform_values('error', "events.0.#{field_path}", platform_values)
92
- end
93
-
94
- # Tests that the given payload value is correct for the target BrowserStack platform.
95
- # This step will assume the expected and payload values are numeric.
96
- # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
97
- #
98
- # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
99
- # | android | 1 |
100
- # | ios | 5.5 |
101
- #
102
- # If the expected value is set to "@skip", the check should be skipped
103
- # If the expected value is set to "@null", the check will be for null
104
- # If the expected value is set to "@not_null", the check will be for a non-null value
105
- #
106
- # @step_input request_type [String] The type of request (error, session, build, etc)
107
- # @step_input field_path [String] The field to test
108
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
109
- Then('the {request_type} payload field {string} equals the platform-dependent numeric:') do |request_type, field_path, platform_values|
110
- test_numeric_platform_values(request_type, field_path, platform_values)
111
- end
112
-
113
- # See `the payload field {string} equals the platform-dependent numeric:`
114
- #
115
- # @step_input field_path [String] The field to test, prepended with "events.0"
116
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
117
- Then('the event {string} equals the platform-dependent numeric:') do |field_path, platform_values|
118
- test_numeric_platform_values('error', "events.0.#{field_path}", platform_values)
119
- end
120
-
121
- # Tests that the given payload value is correct for the target BrowserStack platform.
122
- # This step will assume the expected and payload values are booleans.
123
- # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
124
- #
125
- # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
126
- # | android | 1 |
127
- # | ios | 5 |
128
- #
129
- # If the expected value is set to "@skip", the check should be skipped
130
- # If the expected value is set to "@null", the check will be for null
131
- # If the expected value is set to "@not_null", the check will be for a non-null value
132
- #
133
- # @step_input request_type [String] The type of request (error, session, build, etc)
134
- # @step_input field_path [String] The field to test
135
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
136
- Then('the {request_type} payload field {string} equals the platform-dependent boolean:') do |request_type, field_path, platform_values|
137
- test_boolean_platform_values(request_type, field_path, platform_values)
138
- end
139
-
140
- # See `the payload field {string} equals the platform-dependent boolean:`
141
- #
142
- # @step_input field_path [String] The field to test, prepended with "events.0"
143
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
144
- Then('the event {string} equals the platform-dependent boolean:') do |field_path, platform_values|
145
- test_boolean_platform_values('error', "events.0.#{field_path}", platform_values)
146
- end
147
-
148
- # See `the payload field {string} equals the platform-dependent string:`
149
- #
150
- # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0."
151
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
152
- Then('the exception {string} equals the platform-dependent string:') do |field_path, platform_values|
153
- test_string_platform_values('error', "events.0.exceptions.0.#{field_path}", platform_values)
154
- end
155
-
156
- # See `the payload field {string} equals the platform-dependent string:`
157
- #
158
- # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0.stacktrace.#!{num}"
159
- # @step_input num [Integer] The index of the stack frame to test
160
- # @step_input platform_values [DataTable] A table of acceptable values for each platform
161
- Then('the {string} of stack frame {int} equals the platform-dependent string:') do |field_path, num, platform_values|
162
- test_string_platform_values('error', "events.0.exceptions.0.stacktrace.#{num}.#{field_path}", platform_values)
163
- end
164
-
165
67
  # Sends keys to a given element, clearing it first
166
68
  # Requires a running Appium driver
167
69
  #
@@ -171,64 +73,3 @@ When('I clear and send the keys {string} to the element {string}') do |keys, ele
171
73
  Maze.driver.clear_and_send_keys_to_element(element_id, keys)
172
74
  end
173
75
 
174
- def get_expected_platform_value(platform_values)
175
- os = Maze::Helper.get_current_platform
176
- expected_value = Hash[platform_values.raw][os.downcase]
177
- raise("There is no expected value for the current platform \"#{os}\"") if expected_value.nil?
178
-
179
- expected_value
180
- end
181
-
182
- def should_skip_platform_check(expected_value)
183
- expected_value.eql?('@skip')
184
- end
185
-
186
- def test_string_platform_values(request_type, field_path, platform_values)
187
- expected_value = get_expected_platform_value(platform_values)
188
- return if should_skip_platform_check(expected_value)
189
-
190
- list = Maze::Server.list_for(request_type)
191
- payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
192
- assert_equal_with_nullability(expected_value, payload_value)
193
- end
194
-
195
- def test_boolean_platform_values(request_type, field_path, platform_values)
196
- expected_value = get_expected_platform_value(platform_values)
197
- return if should_skip_platform_check(expected_value)
198
-
199
- expected_bool = case expected_value.downcase
200
- when 'true'
201
- true
202
- when 'false'
203
- false
204
- else
205
- expected_value
206
- end
207
- list = Maze::Server.list_for(request_type)
208
- payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
209
- assert_equal_with_nullability(expected_bool, payload_value)
210
- end
211
-
212
- def test_numeric_platform_values(request_type, field_path, platform_values)
213
- expected_value = get_expected_platform_value(platform_values)
214
- return if should_skip_platform_check(expected_value)
215
-
216
- list = Maze::Server.list_for(request_type)
217
- payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
218
-
219
- # Need to do a little more processing here to allow floats
220
- special_value = expected_value.eql?('@null') || expected_value.eql?('@not_null')
221
- expectation = special_value ? expected_value : expected_value.to_f
222
- assert_equal_with_nullability(expectation, payload_value)
223
- end
224
-
225
- def assert_equal_with_nullability(expected_value, payload_value)
226
- case expected_value
227
- when '@null'
228
- Maze.check.nil(payload_value)
229
- when '@not_null'
230
- Maze.check.not_nil(payload_value)
231
- else
232
- Maze.check.equal(expected_value, payload_value)
233
- end
234
- end
@@ -0,0 +1,204 @@
1
+ # @!group Platform dependent steps
2
+
3
+ # Tests that the given payload value is correct for the target BrowserStack platform.
4
+ # This step will assume the expected and payload values are strings.
5
+ # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
6
+ #
7
+ # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
8
+ # | android | Java.lang.RuntimeException |
9
+ # | ios | NSException |
10
+ #
11
+ # If the expected value is set to "@skip", the check should be skipped
12
+ # If the expected value is set to "@null", the check will be for null
13
+ # If the expected value is set to "@not_null", the check will be for a non-null value
14
+ #
15
+ # @step_input request_type [String] The type of request (error, session, build, etc)
16
+ # @step_input field_path [String] The field to test
17
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
18
+ Then('the {request_type} payload field {string} equals the platform-dependent string:') do |request_type, field_path, platform_values|
19
+ test_string_platform_values(request_type, field_path, platform_values)
20
+ end
21
+
22
+ # See `the error payload field {string} equals the platform-dependent string:`
23
+ #
24
+ # @step_input field_path [String] The field to test, prepended with "events.0"
25
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
26
+ Then('the event {string} equals the platform-dependent string:') do |field_path, platform_values|
27
+ test_string_platform_values('error', "events.0.#{field_path}", platform_values)
28
+ end
29
+
30
+ # Tests that the given payload value is correct for the target BrowserStack platform.
31
+ # This step will assume the expected and payload values are numeric.
32
+ # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
33
+ #
34
+ # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
35
+ # | android | 1 |
36
+ # | ios | 5.5 |
37
+ #
38
+ # If the expected value is set to "@skip", the check should be skipped
39
+ # If the expected value is set to "@null", the check will be for null
40
+ # If the expected value is set to "@not_null", the check will be for a non-null value
41
+ #
42
+ # @step_input request_type [String] The type of request (error, session, build, etc)
43
+ # @step_input field_path [String] The field to test
44
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
45
+ Then('the {request_type} payload field {string} equals the platform-dependent numeric:') do |request_type, field_path, platform_values|
46
+ test_numeric_platform_values(request_type, field_path, platform_values)
47
+ end
48
+
49
+ # See `the payload field {string} equals the platform-dependent numeric:`
50
+ #
51
+ # @step_input field_path [String] The field to test, prepended with "events.0"
52
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
53
+ Then('the event {string} equals the platform-dependent numeric:') do |field_path, platform_values|
54
+ test_numeric_platform_values('error', "events.0.#{field_path}", platform_values)
55
+ end
56
+
57
+ # Tests that the given payload value is correct for the target BrowserStack platform.
58
+ # This step will assume the expected and payload values are booleans.
59
+ # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
60
+ #
61
+ # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
62
+ # | android | 1 |
63
+ # | ios | 5 |
64
+ #
65
+ # If the expected value is set to "@skip", the check should be skipped
66
+ # If the expected value is set to "@null", the check will be for null
67
+ # If the expected value is set to "@not_null", the check will be for a non-null value
68
+ #
69
+ # @step_input request_type [String] The type of request (error, session, build, etc)
70
+ # @step_input field_path [String] The field to test
71
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
72
+ Then('the {request_type} payload field {string} equals the platform-dependent boolean:') do |request_type, field_path, platform_values|
73
+ test_boolean_platform_values(request_type, field_path, platform_values)
74
+ end
75
+
76
+ # See `the payload field {string} equals the platform-dependent boolean:`
77
+ #
78
+ # @step_input field_path [String] The field to test, prepended with "events.0"
79
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
80
+ Then('the event {string} equals the platform-dependent boolean:') do |field_path, platform_values|
81
+ test_boolean_platform_values('error', "events.0.#{field_path}", platform_values)
82
+ end
83
+
84
+ # See `the payload field {string} equals the platform-dependent string:`
85
+ #
86
+ # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0."
87
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
88
+ Then('the exception {string} equals the platform-dependent string:') do |field_path, platform_values|
89
+ test_string_platform_values('error', "events.0.exceptions.0.#{field_path}", platform_values)
90
+ end
91
+
92
+ # See `the payload field {string} equals the platform-dependent string:`
93
+ #
94
+ # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0.stacktrace.#!{num}"
95
+ # @step_input num [Integer] The index of the stack frame to test
96
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
97
+ Then('the {string} of stack frame {int} equals the platform-dependent string:') do |field_path, num, platform_values|
98
+ test_string_platform_values('error', "events.0.exceptions.0.stacktrace.#{num}.#{field_path}", platform_values)
99
+ end
100
+
101
+ #
102
+ # Equality check routines
103
+ #
104
+ def test_string_platform_values(request_type, field_path, platform_values)
105
+ expected_value = get_expected_platform_value(platform_values)
106
+ return if should_skip_platform_check(expected_value)
107
+
108
+ list = Maze::Server.list_for(request_type)
109
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
110
+ assert_equal_with_nullability(expected_value, payload_value)
111
+ end
112
+
113
+ def test_boolean_platform_values(request_type, field_path, platform_values)
114
+ expected_value = get_expected_platform_value(platform_values)
115
+ return if should_skip_platform_check(expected_value)
116
+
117
+ expected_bool = case expected_value.downcase
118
+ when 'true'
119
+ true
120
+ when 'false'
121
+ false
122
+ else
123
+ expected_value
124
+ end
125
+ list = Maze::Server.list_for(request_type)
126
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
127
+ assert_equal_with_nullability(expected_bool, payload_value)
128
+ end
129
+
130
+ def test_numeric_platform_values(request_type, field_path, platform_values)
131
+ expected_value = get_expected_platform_value(platform_values)
132
+ return if should_skip_platform_check(expected_value)
133
+
134
+ list = Maze::Server.list_for(request_type)
135
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
136
+
137
+ # Need to do a little more processing here to allow floats
138
+ special_value = expected_value.eql?('@null') || expected_value.eql?('@not_null')
139
+ expectation = special_value ? expected_value : expected_value.to_f
140
+ assert_equal_with_nullability(expectation, payload_value)
141
+ end
142
+
143
+ def assert_equal_with_nullability(expected_value, payload_value)
144
+ case expected_value
145
+ when '@null'
146
+ Maze.check.nil(payload_value)
147
+ when '@not_null'
148
+ Maze.check.not_nil(payload_value)
149
+ else
150
+ Maze.check.equal(expected_value, payload_value)
151
+ end
152
+ end
153
+
154
+ def get_expected_platform_value(platform_values)
155
+ os = Maze::Helper.get_current_platform
156
+ expected_value = Hash[platform_values.raw][os.downcase]
157
+ raise("There is no expected value for the current platform \"#{os}\"") if expected_value.nil?
158
+
159
+ expected_value
160
+ end
161
+
162
+ def should_skip_platform_check(expected_value)
163
+ expected_value.eql?('@skip')
164
+ end
165
+
166
+ # @step_input request_type [String] The type of request (error, session, build, etc)
167
+ # @step_input field_path [String] The field to test
168
+ # @step_input platform_values [DataTable] A table of acceptable regexes for each platform
169
+ Then('the {request_type} payload field {string} matches the platform-dependent regex:') do |request_type, field_path, platform_regexes|
170
+ match_string_platform_regexes(request_type, field_path, platform_regexes)
171
+ end
172
+
173
+ # See `the error payload field {string} equals the platform-dependent string:`
174
+ #
175
+ # @step_input field_path [String] The field to test, prepended with "events.0"
176
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
177
+ Then('the event {string} matches the platform-dependent regex:') do |field_path, platform_regexes|
178
+ match_string_platform_regexes('error', "events.0.#{field_path}", platform_regexes)
179
+ end
180
+
181
+ # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0."
182
+ # @step_input platform_values [DataTable] A table of acceptable regexes for each platform
183
+ Then('the exception {string} matches the platform-dependent regex:') do |field_path, platform_regexes|
184
+ match_string_platform_regexes('error', "events.0.exceptions.0.#{field_path}", platform_regexes)
185
+ end
186
+
187
+ # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0.stacktrace.#!{num}"
188
+ # @step_input num [Integer] The index of the stack frame to test
189
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
190
+ Then('the {string} of stack frame {int} matches the platform-dependent regex:') do |field_path, num, platform_regexes|
191
+ match_string_platform_regexes('error', "events.0.exceptions.0.stacktrace.#{num}.#{field_path}", platform_regexes)
192
+ end
193
+
194
+ #
195
+ # Regex match routines
196
+ #
197
+ def match_string_platform_regexes(request_type, field_path, platform_values)
198
+ expected_regex = get_expected_platform_value(platform_values)
199
+ return if should_skip_platform_check(expected_regex)
200
+ list = Maze::Server.list_for(request_type)
201
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
202
+
203
+ Maze.check.match(expected_regex, payload_value)
204
+ end
@@ -175,6 +175,62 @@ module Maze
175
175
  }
176
176
  end
177
177
 
178
+
179
+ def get_ids(api_key, project_name = nil)
180
+ base_url = 'https://cloud.bitbar.com/api/me/projects?limit=100'
181
+ url = project_name ? "#{base_url}&filter=name_eq_#{project_name}" : base_url
182
+
183
+ uri = URI.parse(url)
184
+ http = Net::HTTP.new(uri.host, uri.port)
185
+ http.use_ssl = true
186
+
187
+ request = Net::HTTP::Get.new(uri.request_uri)
188
+ request.basic_auth(api_key, '')
189
+
190
+ begin
191
+ response = http.request(request)
192
+ raise "HTTP request failed with code #{response.code}" unless response.is_a?(Net::HTTPSuccess)
193
+ json_body_data = JSON.parse(response.body)['data']
194
+ json_body_data.map { |project| [project['id'], project['name']] }
195
+ rescue JSON::ParserError
196
+ raise 'Failed to parse JSON response'
197
+ rescue StandardError => e
198
+ raise "An error occurred: #{e.message}"
199
+ end
200
+ end
201
+
202
+ def get_unsuccessful_runs(api_key, project_id, date)
203
+ new_date = date_to_milliseconds(date)
204
+ url = URI.parse("https://cloud.bitbar.com/api/me/projects/#{project_id}/runs?filter=successRatio_eq_0.0;d_createTime_on_#{new_date}")
205
+
206
+ http = Net::HTTP.new(url.host, url.port)
207
+ http.use_ssl = true
208
+
209
+ request = Net::HTTP::Get.new(url.request_uri)
210
+ request.basic_auth(api_key, '')
211
+
212
+ begin
213
+ response = http.request(request)
214
+ raise "HTTP request failed with code #{response.code}" unless response.is_a?(Net::HTTPSuccess)
215
+ JSON.parse(response.body)['data']
216
+ rescue JSON::ParserError
217
+ raise 'Failed to parse JSON response'
218
+ rescue StandardError => e
219
+ raise "An error occurred: #{e.message}"
220
+ end
221
+ end
222
+
223
+ def date_to_milliseconds(date_string)
224
+ begin
225
+ date_format = "%Y-%m-%d"
226
+ parsed_date = DateTime.strptime(date_string, date_format)
227
+ milliseconds = (parsed_date.to_time.to_f * 1000).to_i
228
+ milliseconds
229
+ rescue ArgumentError
230
+ raise "Invalid date format. Please use YYYY-MM-DD."
231
+ end
232
+ end
233
+
178
234
  private
179
235
 
180
236
  def start_tunnel_thread(cmd)
@@ -81,15 +81,41 @@ module Maze
81
81
  $logger.warn "StaleElementReferenceError occurred: #{e}"
82
82
  false
83
83
  end
84
+ rescue Selenium::WebDriver::Error::ServerError => e
85
+ # Assume the remote appium session has stopped, so crash out of the session
86
+ Maze.driver = nil
87
+ raise e
84
88
  else
85
89
  true
86
90
  end
87
91
 
92
+ # A wrapper around launch_app adding extra error handling
93
+ def launch_app
94
+ super
95
+ rescue Selenium::WebDriver::Error::ServerError => e
96
+ # Assume the remote appium session has stopped, so crash out of the session
97
+ Maze.driver = nil
98
+ raise e
99
+ end
100
+
101
+ # A wrapper around close_app adding extra error handling
102
+ def close_app
103
+ super
104
+ rescue Selenium::WebDriver::Error::ServerError => e
105
+ # Assume the remote appium session has stopped, so crash out of the session
106
+ Maze.driver = nil
107
+ raise e
108
+ end
109
+
88
110
  # A wrapper around find_element adding timer functionality
89
111
  def find_element_timed(element_id)
90
112
  @find_element_timer.time do
91
113
  find_element(@element_locator, element_id)
92
114
  end
115
+ rescue Selenium::WebDriver::Error::ServerError => e
116
+ # Assume the remote appium session has stopped, so crash out of the session
117
+ Maze.driver = nil
118
+ raise e
93
119
  end
94
120
 
95
121
  # Clicks a given element
@@ -100,6 +126,10 @@ module Maze
100
126
  @click_element_timer.time do
101
127
  element.click
102
128
  end
129
+ rescue Selenium::WebDriver::Error::ServerError => e
130
+ # Assume the remote appium session has stopped, so crash out of the session
131
+ Maze.driver = nil
132
+ raise e
103
133
  end
104
134
 
105
135
  # Clicks a given element, ignoring any NoSuchElementError
@@ -114,6 +144,10 @@ module Maze
114
144
  true
115
145
  rescue Selenium::WebDriver::Error::NoSuchElementError
116
146
  false
147
+ rescue Selenium::WebDriver::Error::ServerError => e
148
+ # Assume the remote appium session has stopped, so crash out of the session
149
+ Maze.driver = nil
150
+ raise e
117
151
  end
118
152
 
119
153
  # Clears a given element
@@ -124,6 +158,10 @@ module Maze
124
158
  @clear_element_timer.time do
125
159
  element.clear
126
160
  end
161
+ rescue Selenium::WebDriver::Error::ServerError => e
162
+ # Assume the remote appium session has stopped, so crash out of the session
163
+ Maze.driver = nil
164
+ raise e
127
165
  end
128
166
 
129
167
  # Gets the application hierarchy XML
@@ -145,6 +183,10 @@ module Maze
145
183
  @send_keys_timer.time do
146
184
  element.send_keys(text)
147
185
  end
186
+ rescue Selenium::WebDriver::Error::ServerError => e
187
+ # Assume the remote appium session has stopped, so crash out of the session
188
+ Maze.driver = nil
189
+ raise e
148
190
  end
149
191
 
150
192
  # Sets the rotation of the device
@@ -178,6 +220,10 @@ module Maze
178
220
  @send_keys_timer.time do
179
221
  element.send_keys(text)
180
222
  end
223
+ rescue Selenium::WebDriver::Error::ServerError => e
224
+ # Assume the remote appium session has stopped, so crash out of the session
225
+ Maze.driver = nil
226
+ raise e
181
227
  end
182
228
 
183
229
  # Reset the currently running application after a given timeout
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.11.2'
10
+ VERSION = '9.12.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.11.2
4
+ version: 9.12.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-07-18 00:00:00.000000000 Z
11
+ date: 2024-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -322,6 +322,7 @@ description: Automation steps and mock server to validaterequest payloads respon
322
322
  email:
323
323
  - steve@bugsnag.com
324
324
  executables:
325
+ - bb-failed-sessions
325
326
  - bugsnag-print-load-paths
326
327
  - download-logs
327
328
  - maze-runner
@@ -330,6 +331,7 @@ executables:
330
331
  extensions: []
331
332
  extra_rdoc_files: []
332
333
  files:
334
+ - bin/bb-failed-sessions
333
335
  - bin/bugsnag-print-load-paths
334
336
  - bin/download-logs
335
337
  - bin/maze-runner
@@ -356,6 +358,7 @@ files:
356
358
  - lib/features/steps/multipart_request_steps.rb
357
359
  - lib/features/steps/network_steps.rb
358
360
  - lib/features/steps/payload_steps.rb
361
+ - lib/features/steps/platform_dependent_steps.rb
359
362
  - lib/features/steps/proxy_steps.rb
360
363
  - lib/features/steps/query_parameter_steps.rb
361
364
  - lib/features/steps/request_assertion_steps.rb