bugsnag-maze-runner 10.5.0 → 10.7.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: 26d2aaea7ff0a765fd06e46247a51dfb467a5ced471753a5e5fab232ac2f584a
4
- data.tar.gz: 8e0606052630e861d959127ba8c4461f19f2431e9de1ef1c7dfe238369ad9e32
3
+ metadata.gz: 62f2cbd9dc34f1d4bbf49ccb87c121895c763803bfc7fcf91ecae92899f7e163
4
+ data.tar.gz: ff5ee29b4d0d756d19138780bab0d1241e23a055d2549480ce93716dea1e11d5
5
5
  SHA512:
6
- metadata.gz: 341ddb3af26761202dc718118ce192664d8853202d15244bafe282579ebb0cffc0c953a754870119ae651461a008fcb00b2dff2984d132508a485008a80afdb3
7
- data.tar.gz: 2354d453f2f4e68a89c61a08c07f514fc210185f3709e84b587d0b668b98efde72cce8921d4c6b24e29162a577b2f75bf6b15467ff02fecb9a1d5cd277d0703d
6
+ metadata.gz: 8eb87c1d5d81dc49bcd707cdae472945003056a86d1e20a9f3cce6b316770dfbc94ecfc5e8589d327878d40afb1f621100775aae6cdb190d0f93feef69dbaf2e
7
+ data.tar.gz: 5184fccde87ef1950406af328f5ae9cb5aab4502699df6e9524e5c8f790741261a119817b8f33c3896553f1cd15a3601dcccfd6883586e96cbb2d19dffd476e0
@@ -0,0 +1,184 @@
1
+ # @!group Span steps
2
+
3
+ # Disable timestamp validation for spans
4
+ #
5
+ When('I disable timestamp validation for spans') do
6
+ Maze.config.span_timestamp_validation = false
7
+ end
8
+
9
+ # Waits for a given number of spans to be received, which may be spread across one or more trace requests.
10
+ #
11
+ # @step_input span_count [Integer] The number of spans to wait for
12
+ Then('I wait to receive {int} span(s)') do |span_count|
13
+ SpanSupport.assert_received_span_count span_count
14
+ end
15
+
16
+ # Waits for a minimum number of spans to be received, which may be spread across one or more trace requests.
17
+ # If more spans than requested are received, this step will still pass.
18
+ #
19
+ # @step_input span_min [Integer] The minimum number of spans to wait for
20
+ Then('I wait to receive at least {int} span(s)') do |span_min|
21
+ SpanSupport.assert_received_minimum_span_count span_min
22
+ end
23
+
24
+ # Waits for a minimum number of spans to be received, which may be spread across one or more trace requests.
25
+ # If more spans than the maximum requested number of spans are received, this step will fail.
26
+ #
27
+ # @step_input span_min [Integer] The minimum number of spans to wait for
28
+ # @step_input span_max [Integer] The maximum number of spans to receive before failure
29
+ Then('I wait to receive between {int} and {int} span(s)') do |span_min, span_max|
30
+ SpanSupport.assert_received_ranged_span_count span_min, span_max
31
+ end
32
+
33
+ # Waits for a minimum number of spans to be received, which may be spread across one or more trace requests.
34
+ # If more spans than the maximum requested number of spans are received, this step will fail.
35
+ #
36
+ # @step_input span_min [Integer] The minimum number of spans to wait for
37
+ # @step_input span_max [Integer] The maximum number of spans to receive before failure
38
+ Then('I wait to receive a span named {string}') do |span_name|
39
+ SpanSupport.assert_received_named_span span_name
40
+ end
41
+
42
+ Then('I should have received no spans') do
43
+ sleep Maze.config.receive_no_requests_wait
44
+ Maze.check.equal SpanSupport.spans_from_request_list(Maze::Server.traces).size, 0
45
+ end
46
+
47
+ Then('a span {word} equals {string}') do |attribute, expected|
48
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
49
+ selected_attributes = spans.map { |span| span[attribute] }
50
+ Maze.check.includes selected_attributes, expected
51
+ end
52
+
53
+ Then('every span field {string} equals {string}') do |key, expected|
54
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
55
+ selected_keys = spans.map { |span| span[key] == expected }
56
+ Maze.check.not_includes selected_keys, false
57
+ end
58
+
59
+ Then('every span field {string} matches the regex {string}') do |key, pattern|
60
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
61
+ spans.map { |span| Maze.check.match pattern, span[key] }
62
+ end
63
+
64
+ Then('every span string attribute {string} exists') do |attribute|
65
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
66
+ spans.map { |span| Maze.check.not_nil span['attributes'].find { |a| a['key'] == attribute }['value']['stringValue'] }
67
+ end
68
+
69
+ Then('every span string attribute {string} equals {string}') do |attribute, expected|
70
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
71
+ spans.map { |span| Maze.check.equal expected, span['attributes'].find { |a| a['key'] == attribute }['value']['stringValue'] }
72
+ end
73
+
74
+ Then('every span string attribute {string} matches the regex {string}') do |attribute, pattern|
75
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
76
+ spans.map { |span| Maze.check.match pattern, span['attributes'].find { |a| a['key'] == attribute }['value']['stringValue'] }
77
+ end
78
+
79
+ Then('every span integer attribute {string} is greater than {int}') do |attribute, expected|
80
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
81
+ spans.map { |span| Maze::check.true span['attributes'].find { |a| a['key'] == attribute }['value']['intValue'].to_i > expected }
82
+ end
83
+
84
+ Then('every span bool attribute {string} is true') do |attribute|
85
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
86
+ spans.map { |span| Maze::check.true span['attributes'].find { |a| a['key'] == attribute }['value']['boolValue'] }
87
+ end
88
+
89
+ Then('a span string attribute {string} exists') do |attribute|
90
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
91
+ selected_attributes = spans.map { |span| span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('stringValue') } }.compact
92
+ Maze.check.false(selected_attributes.empty?)
93
+ end
94
+
95
+ Then('a span string attribute {string} equals {string}') do |attribute, expected|
96
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
97
+ selected_attributes = spans.map { |span| span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('stringValue') } }.compact
98
+ attribute_values = selected_attributes.map { |a| a['value']['stringValue'] }
99
+ Maze.check.includes attribute_values, expected
100
+ end
101
+
102
+ Then('a span field {string} equals {string}') do |key, expected|
103
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
104
+ selected_keys = spans.map { |span| span[key] }
105
+ Maze.check.includes selected_keys, expected
106
+ end
107
+
108
+ Then('a span field {string} equals {int}') do |key, expected|
109
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
110
+ selected_keys = spans.map { |span| span[key] }
111
+ Maze.check.includes selected_keys, expected
112
+ end
113
+
114
+ Then('a span field {string} matches the regex {string}') do |attribute, pattern|
115
+ regex = Regexp.new pattern
116
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
117
+ selected_attributes = spans.select { |span| regex.match? span[attribute] }
118
+
119
+ Maze.check.false(selected_attributes.empty?)
120
+ end
121
+
122
+ Then('a span named {string} contains the attributes:') do |span_name, table|
123
+ named_spans = SpanSupport.get_named_spans(span_name)
124
+ expected_attributes = table.hashes
125
+
126
+ match = false
127
+ named_spans.each do |span|
128
+ matches = expected_attributes.map do |expected_attribute|
129
+ span['attributes'].find_all { |attribute| attribute['key'].eql?(expected_attribute['attribute']) }
130
+ .any? { |attribute| attribute_value_matches?(attribute['value'], expected_attribute['type'], expected_attribute['value']) }
131
+ end
132
+ if matches.all? && !matches.empty?
133
+ match = true
134
+ break
135
+ end
136
+ end
137
+
138
+ unless match
139
+ raise Test::Unit::AssertionFailedError.new "No spans were found containing all of the given attributes"
140
+ end
141
+ end
142
+
143
+ Then('a span named {string} has a parent named {string}') do |child_name, parent_name|
144
+ spans = SpanSupport.spans_from_request_list(Maze::Server.traces)
145
+ child_spans = spans.find_all { |span| span['name'].eql?(child_name) }
146
+ raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{child_name}" if child_spans.empty?
147
+ parent_spans = spans.find_all { |span| span['name'].eql?(parent_name) }
148
+ raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{parent_name}" if parent_spans.empty?
149
+
150
+ expected_parent_ids = child_spans.map { |span| span['parentSpanId'] }
151
+ parent_ids = parent_spans.map { |span| span['spanId'] }
152
+ match = expected_parent_ids.any? { |expected_id| parent_ids.include?(expected_id) }
153
+
154
+ unless match
155
+ raise Test::Unit::AssertionFailedError.new "No child span named #{child_name} was found with a parent named #{parent_name}"
156
+ end
157
+ end
158
+
159
+ Then('a span named {string} has the following properties:') do |span_name, table|
160
+ named_spans = SpanSupport.get_named_spans(span_name)
161
+ expected_properties = table.hashes
162
+
163
+ match = false
164
+ named_spans.each do |span|
165
+ matches = expected_properties.map do |expected_property|
166
+ property = Maze::Helper.read_key_path(span, expected_property['property'])
167
+ expected_property['value'].eql?(property.to_s)
168
+ end
169
+ if matches.all? && !matches.empty?
170
+ match = true
171
+ break
172
+ end
173
+ end
174
+
175
+ unless match
176
+ raise Test::Unit::AssertionFailedError.new "No spans were found containing all of the given properties"
177
+ end
178
+ end
179
+
180
+ Then('the {string} field of the span named {string} is stored as the value {string}') do |field, span_name, store_key|
181
+ SpanSupport.store_named_span_field(span_name, field, store_key)
182
+ end
183
+
184
+
@@ -1,40 +1,5 @@
1
1
  # @!group Trace steps
2
2
 
3
- # Disable timestamp validation for spans
4
- #
5
- When('I disable timestamp validation for spans') do
6
- Maze.config.span_timestamp_validation = false
7
- end
8
-
9
- # Waits for a given number of spans to be received, which may be spread across one or more trace requests.
10
- #
11
- # @step_input span_count [Integer] The number of spans to wait for
12
- Then('I wait to receive {int} span(s)') do |span_count|
13
- assert_received_span_count Maze::Server.list_for('traces'), span_count
14
- end
15
-
16
- # Waits for a minimum number of spans to be received, which may be spread across one or more trace requests.
17
- # If more spans than requested are received, this step will still pass.
18
- #
19
- # @step_input span_min [Integer] The minimum number of spans to wait for
20
- Then('I wait to receive at least {int} span(s)') do |span_min|
21
- assert_received_minimum_span_count Maze::Server.list_for('traces'), span_min
22
- end
23
-
24
- # Waits for a minimum number of spans to be received, which may be spread across one or more trace requests.
25
- # If more spans than the maximum requested number of spans are received, this step will fail.
26
- #
27
- # @step_input span_min [Integer] The minimum number of spans to wait for
28
- # @step_input span_max [Integer] The maximum number of spans to receive before failure
29
- Then('I wait to receive between {int} and {int} span(s)') do |span_min, span_max|
30
- assert_received_ranged_span_count Maze::Server.list_for('traces'), span_min, span_max
31
- end
32
-
33
- Then('I should have received no spans') do
34
- sleep Maze.config.receive_no_requests_wait
35
- Maze.check.equal spans_from_request_list(Maze::Server.list_for('traces')).size, 0
36
- end
37
-
38
3
  Then('I enter unmanaged traces mode') do
39
4
  Maze.config.unmanaged_traces_mode = true
40
5
  end
@@ -110,154 +75,6 @@ Then('the trace payload field {string} double attribute {string} equals {float}'
110
75
  check_attribute_equal field, attribute, 'doubleValue', expected
111
76
  end
112
77
 
113
- # @!group Span steps
114
- Then('a span {word} equals {string}') do |attribute, expected|
115
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
116
- selected_attributes = spans.map { |span| span[attribute] }
117
- Maze.check.includes selected_attributes, expected
118
- end
119
-
120
- Then('every span field {string} equals {string}') do |key, expected|
121
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
122
- selected_keys = spans.map { |span| span[key] == expected }
123
- Maze.check.not_includes selected_keys, false
124
- end
125
-
126
- Then('every span field {string} matches the regex {string}') do |key, pattern|
127
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
128
- spans.map { |span| Maze.check.match pattern, span[key] }
129
- end
130
-
131
- Then('every span string attribute {string} exists') do |attribute|
132
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
133
- spans.map { |span| Maze.check.not_nil span['attributes'].find { |a| a['key'] == attribute }['value']['stringValue'] }
134
- end
135
-
136
- Then('every span string attribute {string} equals {string}') do |attribute, expected|
137
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
138
- spans.map { |span| Maze.check.equal expected, span['attributes'].find { |a| a['key'] == attribute }['value']['stringValue'] }
139
- end
140
-
141
- Then('every span string attribute {string} matches the regex {string}') do |attribute, pattern|
142
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
143
- spans.map { |span| Maze.check.match pattern, span['attributes'].find { |a| a['key'] == attribute }['value']['stringValue'] }
144
- end
145
-
146
- Then('every span integer attribute {string} is greater than {int}') do |attribute, expected|
147
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
148
- spans.map { |span| Maze::check.true span['attributes'].find { |a| a['key'] == attribute }['value']['intValue'].to_i > expected }
149
- end
150
-
151
- Then('every span bool attribute {string} is true') do |attribute|
152
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
153
- spans.map { |span| Maze::check.true span['attributes'].find { |a| a['key'] == attribute }['value']['boolValue'] }
154
- end
155
-
156
- Then('a span string attribute {string} exists') do |attribute|
157
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
158
- selected_attributes = spans.map { |span| span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('stringValue') } }.compact
159
- Maze.check.false(selected_attributes.empty?)
160
- end
161
-
162
- Then('a span string attribute {string} equals {string}') do |attribute, expected|
163
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
164
- selected_attributes = spans.map { |span| span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('stringValue') } }.compact
165
- attribute_values = selected_attributes.map { |a| a['value']['stringValue'] }
166
- Maze.check.includes attribute_values, expected
167
- end
168
-
169
- Then('a span field {string} equals {string}') do |key, expected|
170
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
171
- selected_keys = spans.map { |span| span[key] }
172
- Maze.check.includes selected_keys, expected
173
- end
174
-
175
- Then('a span field {string} equals {int}') do |key, expected|
176
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
177
- selected_keys = spans.map { |span| span[key] }
178
- Maze.check.includes selected_keys, expected
179
- end
180
-
181
- Then('a span field {string} matches the regex {string}') do |attribute, pattern|
182
- regex = Regexp.new pattern
183
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
184
- selected_attributes = spans.select { |span| regex.match? span[attribute] }
185
-
186
- Maze.check.false(selected_attributes.empty?)
187
- end
188
-
189
- Then('a span named {string} contains the attributes:') do |span_name, table|
190
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
191
- named_spans = spans.find_all { |span| span['name'].eql?(span_name) }
192
- raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{span_name}" if named_spans.empty?
193
-
194
- expected_attributes = table.hashes
195
-
196
- match = false
197
- named_spans.each do |span|
198
- matches = expected_attributes.map do |expected_attribute|
199
- span['attributes'].find_all { |attribute| attribute['key'].eql?(expected_attribute['attribute']) }
200
- .any? { |attribute| attribute_value_matches?(attribute['value'], expected_attribute['type'], expected_attribute['value']) }
201
- end
202
- if matches.all? && !matches.empty?
203
- match = true
204
- break
205
- end
206
- end
207
-
208
- unless match
209
- raise Test::Unit::AssertionFailedError.new "No spans were found containing all of the given attributes"
210
- end
211
- end
212
-
213
- Then('a span named {string} has a parent named {string}') do |child_name, parent_name|
214
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
215
- child_spans = spans.find_all { |span| span['name'].eql?(child_name) }
216
- raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{child_name}" if child_spans.empty?
217
- parent_spans = spans.find_all { |span| span['name'].eql?(parent_name) }
218
- raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{parent_name}" if parent_spans.empty?
219
-
220
- expected_parent_ids = child_spans.map { |span| span['parentSpanId'] }
221
- parent_ids = parent_spans.map { |span| span['spanId'] }
222
- match = expected_parent_ids.any? { |expected_id| parent_ids.include?(expected_id) }
223
-
224
- unless match
225
- raise Test::Unit::AssertionFailedError.new "No child span named #{child_name} was found with a parent named #{parent_name}"
226
- end
227
- end
228
-
229
- Then('a span named {string} has the following properties:') do |span_name, table|
230
- spans = spans_from_request_list(Maze::Server.list_for('traces'))
231
- found_spans = spans.find_all { |span| span['name'].eql?(span_name) }
232
- raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{span_name}" if found_spans.empty?
233
-
234
- expected_properties = table.hashes
235
-
236
- match = false
237
- found_spans.each do |span|
238
- matches = expected_properties.map do |expected_property|
239
- property = Maze::Helper.read_key_path(span, expected_property['property'])
240
- expected_property['value'].eql?(property.to_s)
241
- end
242
- if matches.all? && !matches.empty?
243
- match = true
244
- break
245
- end
246
- end
247
-
248
- unless match
249
- raise Test::Unit::AssertionFailedError.new "No spans were found containing all of the given properties"
250
- end
251
- end
252
-
253
- def spans_from_request_list list
254
- return list.remaining
255
- .flat_map { |req| req[:body]['resourceSpans'] }
256
- .flat_map { |r| r['scopeSpans'] }
257
- .flat_map { |s| s['spans'] }
258
- .select { |s| !s.nil? }
259
- end
260
-
261
78
  def attribute_value_matches?(attribute_value, expected_type, expected_value)
262
79
  # Check that the required value type key is present
263
80
  unless attribute_value.keys.include?(expected_type)
@@ -284,42 +101,6 @@ def attribute_value_matches?(attribute_value, expected_type, expected_value)
284
101
  end
285
102
  end
286
103
 
287
- def assert_received_span_count(list, count)
288
- assert_received_spans(list, count, count)
289
- end
290
-
291
- def assert_received_minimum_span_count(list, minimum)
292
- assert_received_spans(list, minimum)
293
- end
294
-
295
- def assert_received_ranged_span_count(list, minimum, maximum)
296
- assert_received_spans(list, minimum, maximum)
297
- end
298
-
299
- def assert_received_spans(list, min_received, max_received = nil)
300
- timeout = Maze.config.receive_requests_wait
301
- wait = Maze::Wait.new(timeout: timeout)
302
-
303
- received = wait.until { spans_from_request_list(list).size >= min_received }
304
- received_count = spans_from_request_list(list).size
305
-
306
- unless received
307
- raise Test::Unit::AssertionFailedError.new <<-MESSAGE
308
- Expected #{min_received} spans but received #{received_count} within the #{timeout}s timeout.
309
- This could indicate that:
310
- - Bugsnag crashed with a fatal error.
311
- - Bugsnag did not make the requests that it should have done.
312
- - The requests were made, but not deemed to be valid (e.g. missing integrity header).
313
- - The requests made were prevented from being received due to a network or other infrastructure issue.
314
- Please check the Maze Runner and device logs to confirm.)
315
- MESSAGE
316
- end
317
-
318
- Maze.check.operator(max_received, :>=, received_count, "#{received_count} spans received") if max_received
319
-
320
- Maze::Schemas::Validator.validate_payload_elements(list, 'trace')
321
- end
322
-
323
104
  def get_attribute_value(field, attribute, attr_type)
324
105
  list = Maze::Server.list_for 'trace'
325
106
  attributes = Maze::Helper.read_key_path list.current[:body], "#{field}.attributes"
@@ -69,6 +69,11 @@ Then('the {request_type} payload field {string} does not equal the stored value
69
69
  Maze.check.false(result.equal?, "Payload value: #{payload_value} equals stored value: #{stored_value}")
70
70
  end
71
71
 
72
+ Then('the stored value {string} equals {string}') do |key, value|
73
+ stored_value = Maze::Store.values[key]
74
+ Maze.check.equal(value, stored_value)
75
+ end
76
+
72
77
  # Tests whether a payload field is a number (Numeric according to Ruby)
73
78
  #
74
79
  # @step_input request_type [String] The type of request (error, session, build, etc)
@@ -292,7 +292,7 @@ AfterAll do
292
292
  Maze.timers.report
293
293
  end
294
294
 
295
- $stdout.puts '+++ All scenarios complete'
295
+ $stdout.puts '+++ Test run complete'
296
296
 
297
297
  # Stop the mock server
298
298
  Maze::Server.stop
@@ -0,0 +1,93 @@
1
+ class SpanSupport
2
+ class << self
3
+ def spans_from_request_list(list)
4
+ list.remaining
5
+ .flat_map { |req| req[:body]['resourceSpans'] }
6
+ .flat_map { |r| r['scopeSpans'] }
7
+ .flat_map { |s| s['spans'] }
8
+ .select { |s| !s.nil? }
9
+ end
10
+
11
+ def get_named_spans(span_name)
12
+ spans = spans_from_request_list(Maze::Server.traces)
13
+ named_spans = spans.find_all { |span| span['name'].eql?(span_name) }
14
+ raise Test::Unit::AssertionFailedError.new "No spans were found with the name #{span_name}" if named_spans.empty?
15
+ named_spans
16
+ end
17
+
18
+ def named_span_exists?(span_name)
19
+ spans = spans_from_request_list(Maze::Server.traces)
20
+ named_spans = spans.find_all { |span| span['name'].eql?(span_name) }
21
+ !named_spans.empty?
22
+ end
23
+
24
+ def assert_received_span_count(count)
25
+ assert_received_spans(count, count)
26
+ end
27
+
28
+ def assert_received_minimum_span_count(minimum)
29
+ assert_received_spans(minimum)
30
+ end
31
+
32
+ def assert_received_ranged_span_count(minimum, maximum)
33
+ assert_received_spans(minimum, maximum)
34
+ end
35
+
36
+ def assert_received_named_span(span_name)
37
+ timeout = Maze.config.receive_requests_wait
38
+ wait = Maze::Wait.new(timeout: timeout)
39
+
40
+ received = wait.until { SpanSupport.named_span_exists?(span_name) }
41
+
42
+ list = Maze::Server.traces
43
+ received_count = SpanSupport.spans_from_request_list(list).size
44
+
45
+ unless received
46
+ raise Test::Unit::AssertionFailedError.new <<-MESSAGE
47
+ Expected span with name #{span_name} not received within the #{timeout}s timeout (#{received_count} spans were received)}.
48
+ This could indicate that:
49
+ - Bugsnag crashed with a fatal error.
50
+ - Bugsnag did not make the requests that it should have done.
51
+ - The requests were made, but not deemed to be valid (e.g. missing integrity header).
52
+ - The requests made were prevented from being received due to a network or other infrastructure issue.
53
+ Please check the Maze Runner and device logs to confirm.)
54
+ MESSAGE
55
+ end
56
+
57
+ Maze::Schemas::Validator.validate_payload_elements(list, 'trace')
58
+ end
59
+
60
+ def assert_received_spans(min_received, max_received = nil)
61
+ timeout = Maze.config.receive_requests_wait
62
+ wait = Maze::Wait.new(timeout: timeout)
63
+ list = Maze::Server.traces
64
+ received = wait.until { SpanSupport.spans_from_request_list(list).size >= min_received }
65
+ received_count = SpanSupport.spans_from_request_list(list).size
66
+
67
+ unless received
68
+ raise Test::Unit::AssertionFailedError.new <<-MESSAGE
69
+ Expected #{min_received} spans but received #{received_count} within the #{timeout}s timeout.
70
+ This could indicate that:
71
+ - Bugsnag crashed with a fatal error.
72
+ - Bugsnag did not make the requests that it should have done.
73
+ - The requests were made, but not deemed to be valid (e.g. missing integrity header).
74
+ - The requests made were prevented from being received due to a network or other infrastructure issue.
75
+ Please check the Maze Runner and device logs to confirm.)
76
+ MESSAGE
77
+ end
78
+
79
+ Maze.check.operator(max_received, :>=, received_count, "#{received_count} spans received") if max_received
80
+
81
+ Maze::Schemas::Validator.validate_payload_elements(list, 'trace')
82
+ end
83
+
84
+ def store_named_span_field(span_name, field, store_key)
85
+ spans = SpanSupport.get_named_spans(span_name)
86
+ values = spans.map { |span| span[field] }.compact
87
+ raise Test::Unit::AssertionFailedError.new "Expected 1 span named #{span_name}, found #{values.size}" unless values.size == 1
88
+
89
+ value = Maze::Helper.read_key_path(spans[0], field)
90
+ Maze::Store.values[store_key] = value.dup
91
+ end
92
+ end
93
+ end
@@ -14,7 +14,7 @@ module Maze
14
14
  # Tests that payloads for a specific path pass any additional validation checks
15
15
  # Throws an AssertionFailedError with a list of issues on failure
16
16
  #
17
- # @param list [Array] An array of received requests
17
+ # @param list [Maze::RequestList] An array of received requests
18
18
  # @param list_name [String] The name of the payload list for received requests
19
19
  def validate_payload_elements(list, list_name)
20
20
  # Test to see if a custom validator exists for the list
data/lib/maze.rb CHANGED
@@ -8,7 +8,7 @@ require_relative 'maze/timers'
8
8
  # providing an alternative to the proliferation of global variables or singletons.
9
9
  module Maze
10
10
 
11
- VERSION = '10.5.0'
11
+ VERSION = '10.7.0'
12
12
 
13
13
  class << self
14
14
  attr_accessor :check, :driver, :internal_hooks, :mode, :start_time, :dynamic_retry, :public_address,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag-maze-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.5.0
4
+ version: 10.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Kirkland
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-10-20 00:00:00.000000000 Z
12
+ date: 2025-10-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cucumber
@@ -422,12 +422,14 @@ files:
422
422
  - lib/features/steps/request_assertion_steps.rb
423
423
  - lib/features/steps/runner_steps.rb
424
424
  - lib/features/steps/session_tracking_steps.rb
425
+ - lib/features/steps/span_steps.rb
425
426
  - lib/features/steps/trace_steps.rb
426
427
  - lib/features/steps/value_steps.rb
427
428
  - lib/features/support/cucumber_types.rb
428
429
  - lib/features/support/env.rb
429
430
  - lib/features/support/error_config_support.rb
430
431
  - lib/features/support/internal_hooks.rb
432
+ - lib/features/support/span_support.rb
431
433
  - lib/maze.rb
432
434
  - lib/maze/api/appium/app_manager.rb
433
435
  - lib/maze/api/appium/device_manager.rb