bugsnag-maze-runner 9.2.0 → 9.3.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: 942d00360efa6ebec4240233c3892ff48c636e7b922c042b0d7ab1be48a20c20
4
- data.tar.gz: 4dd00352e475110bed75c7dd3eb1bbd7927c21035de6e4e9b1b6f8d42375f8cb
3
+ metadata.gz: dacde3d4eb35539a0dbaf40020e42b1d08cac2a20a733a7b03588168677bda74
4
+ data.tar.gz: c9a60049b25661b69885754b9dc11cd44024af2abc7131c719b7d67d94754ee0
5
5
  SHA512:
6
- metadata.gz: 104c7589d0b7dae3ff2859ffa4984ab85d01468faaf2d1bc81cc4774ab852356c2c2bc13edfeeee0106c0cf76de28b7f549d45f7a95016cae8b2351c1de67fdb
7
- data.tar.gz: 945d305ac5910cb739c5905bed3663edbbe6e58932a67d69662b71670fde9d6ada6375544fea33469ac93b59a9a26ec3c92b8b0b6f96ad6ba3cb114e797fa60d
6
+ metadata.gz: 12688ef4e48762c83b9535529ddc5881f30ea19f1779eb475e447d7046d6f80f98ccdbf1cb4b5319b943758e07e0dda9ed79bf1bfb2ae039f2d108d2d5f13715
7
+ data.tar.gz: b8e56857f38a47bf60474deb504b7a90fe9661f06f8597ec95948bfd47c76ff1b6a904953c5498eb1a592bec886cb4d9ce79320d7779b69a4be977661ab7b601
@@ -74,7 +74,7 @@ end
74
74
  # @step_input json_fixture [String] A path to the JSON fixture to compare against
75
75
  Then('the event contains a breadcrumb matching the JSON fixture in {string}') do |json_fixture|
76
76
  breadcrumbs = Maze::Helper.read_key_path(Maze::Server.errors.current[:body], 'events.0.breadcrumbs')
77
- expected = JSON.parse(open(json_fixture, &:read))
77
+ expected = JSON.parse(File.open(json_fixture, &:read))
78
78
  match = breadcrumbs.any? { |breadcrumb| Maze::Compare.value(expected, breadcrumb).equal? }
79
79
  Maze.check.true(match, 'No breadcrumbs in the event matched the given breadcrumb')
80
80
  end
@@ -78,7 +78,7 @@ Then('the {request_type} multipart body does not match the JSON file in {string}
78
78
  payload_list = Maze::Server.list_for request_type
79
79
  raw_payload_value = payload_list.current[:body]
80
80
  payload_value = parse_multipart_body(raw_payload_value)
81
- expected_value = JSON.parse(open(json_path, &:read))
81
+ expected_value = JSON.parse(File.open(json_path, &:read))
82
82
  result = Maze::Compare.value(expected_value, payload_value)
83
83
  Maze.check.false(result.equal?, "Payload:\n#{payload_value}\nExpected:#{expected_value}")
84
84
  end
@@ -93,7 +93,7 @@ Then('the {request_type} multipart body matches the JSON file in {string}') do |
93
93
  payload_list = Maze::Server.list_for request_type
94
94
  raw_payload_value = payload_list.current[:body]
95
95
  payload_value = parse_multipart_body(raw_payload_value)
96
- expected_value = JSON.parse(open(json_path, &:read))
96
+ expected_value = JSON.parse(File.open(json_path, &:read))
97
97
  result = Maze::Compare.value(expected_value, payload_value)
98
98
  Maze.check.true(result.equal?, "The payload field '#{result.keypath}' does not match the fixture:\n #{result.reasons.join('\n')}")
99
99
  end
@@ -108,7 +108,7 @@ Then('the {request_type} multipart field {string} matches the JSON file in {stri
108
108
  Maze.check.true(File.exist?(json_path), "'#{json_path}' does not exist")
109
109
  payload_list = Maze::Server.list_for request_type
110
110
  payload_value = JSON.parse(payload_list.current[:body][field_path].to_s)
111
- expected_value = JSON.parse(open(json_path, &:read))
111
+ expected_value = JSON.parse(File.open(json_path, &:read))
112
112
  result = Maze::Compare.value(expected_value, payload_value)
113
113
  Maze.check.true(result.equal?, "The multipart field '#{result.keypath}' does not match the fixture:\n #{result.reasons.join('\n')}")
114
114
  end
@@ -95,7 +95,7 @@ end
95
95
  # @step_input url [String] The URL to open.
96
96
  When('I open the URL {string}') do |url|
97
97
  begin
98
- URI.open(url, &:read)
98
+ URI(url).open(&:read)
99
99
  rescue OpenURI::HTTPError
100
100
  $logger.debug $!.inspect
101
101
  end
@@ -8,7 +8,7 @@
8
8
  # @step_input fixture_path [String] Path to a JSON fixture
9
9
  Then('the {request_type} payload body does not match the JSON fixture in {string}') do |request_type, fixture_path|
10
10
  payload_value = Maze::Server.list_for(request_type).current[:body]
11
- expected_value = JSON.parse(open(fixture_path, &:read))
11
+ expected_value = JSON.parse(File.open(fixture_path, &:read))
12
12
  result = Maze::Compare.value(expected_value, payload_value)
13
13
  Maze.check.false(result.equal?, "Payload:\n#{payload_value}\nExpected:#{expected_value}")
14
14
  end
@@ -19,7 +19,7 @@ end
19
19
  # @step_input fixture_path [String] Path to a JSON fixture
20
20
  Then('the {request_type} payload body matches the JSON fixture in {string}') do |request_type, fixture_path|
21
21
  payload_value = Maze::Server.list_for(request_type).current[:body]
22
- expected_value = JSON.parse(open(fixture_path, &:read))
22
+ expected_value = JSON.parse(File.open(fixture_path, &:read))
23
23
  result = Maze::Compare.value(expected_value, payload_value)
24
24
  Maze.check.true(result.equal?,
25
25
  "The payload field '#{result.keypath}' does not match the fixture:\n #{result.reasons.join('\n')}")
@@ -34,7 +34,7 @@ Then('the {request_type}(|a b) payload field {string} matches the JSON fixture i
34
34
  do |request_type, field_path, fixture_path|
35
35
  list = Maze::Server.list_for(request_type)
36
36
  payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
37
- expected_value = JSON.parse(open(fixture_path, &:read))
37
+ expected_value = JSON.parse(File.open(fixture_path, &:read))
38
38
  result = Maze::Compare.value(expected_value, payload_value)
39
39
  Maze.check.true(result.equal?,
40
40
  "The payload field '#{result.keypath}' does not match the fixture:\n #{result.reasons.join('\n')}")
@@ -22,7 +22,10 @@ module Maze
22
22
  when 'android'
23
23
  Maze.driver.session_capabilities['appPackage']
24
24
  when 'ios'
25
- Maze.driver.session_capabilities['CFBundleIdentifier'] # Present on BS and locally
25
+ unless app_id = Maze.driver.session_capabilities['CFBundleIdentifier']
26
+ app_id = Maze.driver.session_capabilities['bundleID']
27
+ end
28
+ app_id
26
29
  end
27
30
 
28
31
  # Ensure the device is unlocked
@@ -32,6 +32,8 @@ module Maze
32
32
  interval = 120
33
33
  elsif error.message.include? 'Appium Settings app is not running'
34
34
  interval = 10
35
+ elsif error.message.include? 'Could not proxy command to the remote server'
36
+ interval = 10
35
37
  else
36
38
  # Do not retry in any other case
37
39
  end
@@ -32,7 +32,12 @@ module Maze
32
32
 
33
33
  # Reset the server to ensure that test fixtures cannot fetch
34
34
  # commands from the previous scenario (in idempotent mode).
35
- Maze.driver.terminate_app Maze.driver.app_id
35
+ begin
36
+ Maze.driver.terminate_app Maze.driver.app_id
37
+ rescue Selenium::WebDriver::Error::UnknownError
38
+ $logger.warn 'terminate_app failed, using the slower but more forceful close_app instead'
39
+ Maze.driver.close_app
40
+ end
36
41
  Maze::Server.reset!
37
42
  Maze.driver.activate_app Maze.driver.app_id
38
43
  end
@@ -9,6 +9,7 @@ module Maze
9
9
  HEX_STRING_32 = '^[A-Fa-f0-9]{32}$'
10
10
  SAMPLING_HEADER_ENTRY = '((1(.0)?|0(\.[0-9]+)?):[0-9]+)'
11
11
  SAMPLING_HEADER = "^#{SAMPLING_HEADER_ENTRY}(;#{SAMPLING_HEADER_ENTRY})*$"
12
+ HOUR_TOLERANCE = 60 * 60 * 1000 * 1000 * 1000 # 1 hour in nanoseconds
12
13
 
13
14
  # Contains a set of pre-defined validations for ensuring traces are correct
14
15
  class TraceValidator
@@ -38,15 +39,40 @@ module Maze
38
39
  element_int_in_range('resourceSpans.0.scopeSpans.0.spans.0.kind', 0..5)
39
40
  regex_comparison('resourceSpans.0.scopeSpans.0.spans.0.startTimeUnixNano', '^[0-9]+$')
40
41
  regex_comparison('resourceSpans.0.scopeSpans.0.spans.0.endTimeUnixNano', '^[0-9]+$')
42
+ element_contains('resourceSpans.0.resource.attributes', 'service.version')
43
+ element_contains('resourceSpans.0.resource.attributes', 'device.id')
44
+ each_element_contains('resourceSpans.0.scopeSpans.0.spans', 'attributes', 'bugsnag.sampling.p')
41
45
  element_contains('resourceSpans.0.resource.attributes', 'deployment.environment')
42
46
  element_contains('resourceSpans.0.resource.attributes', 'telemetry.sdk.name')
43
47
  element_contains('resourceSpans.0.resource.attributes', 'telemetry.sdk.version')
48
+ validate_timestamp('resourceSpans.0.scopeSpans.0.spans.0.startTimeUnixNano', HOUR_TOLERANCE)
49
+ validate_timestamp('resourceSpans.0.scopeSpans.0.spans.0.endTimeUnixNano', HOUR_TOLERANCE)
44
50
  element_a_greater_or_equal_element_b(
45
51
  'resourceSpans.0.scopeSpans.0.spans.0.endTimeUnixNano',
46
52
  'resourceSpans.0.scopeSpans.0.spans.0.startTimeUnixNano'
47
53
  )
48
54
  end
49
55
 
56
+ def validate_timestamp(path, tolerance)
57
+ timestamp = Maze::Helper.read_key_path(@body, path)
58
+ unless timestamp.kind_of?(String)
59
+ @success = false
60
+ @errors << "Timestamp was expected to be a string, was '#{timestamp.class.name}'"
61
+ return
62
+ end
63
+ parsed_timestamp = timestamp.to_i
64
+ unless parsed_timestamp > 0
65
+ @success = false
66
+ @errors << "Timestamp was expected to be a positive integer, was '#{parsed_timestamp}'"
67
+ return
68
+ end
69
+ time_in_nanos = Time.now.to_i * 1000000000
70
+ unless (time_in_nanos - parsed_timestamp).abs < tolerance
71
+ @success = false
72
+ @errors << "Timestamp was expected to be within #{tolerance} nanoseconds of the current time (#{time_in_nanos}), was '#{parsed_timestamp}'"
73
+ end
74
+ end
75
+
50
76
  def validate_header(name)
51
77
  value = @headers[name]
52
78
  if value.nil? || value.size > 1
@@ -133,6 +159,18 @@ module Maze
133
159
  end
134
160
  end
135
161
 
162
+ def each_element_contains(container_path, attribute_path, key_value)
163
+ container = Maze::Helper.read_key_path(@body, container_path)
164
+ if container.nil? || !container.kind_of?(Array)
165
+ @success = false
166
+ @errors << "Element '#{container_path}' was expected to be an array, was '#{container}'"
167
+ return
168
+ end
169
+ container.each_with_index do |_item, index|
170
+ element_contains("#{container_path}.#{index}.#{attribute_path}", key_value)
171
+ end
172
+ end
173
+
136
174
  def element_a_greater_or_equal_element_b(path_a, path_b)
137
175
  element_a = Maze::Helper.read_key_path(@body, path_a)
138
176
  element_b = Maze::Helper.read_key_path(@body, path_b)
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.2.0'
10
+ VERSION = '9.3.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.2.0
4
+ version: 9.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Kirkland
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-15 00:00:00.000000000 Z
11
+ date: 2024-02-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -454,11 +454,11 @@ files:
454
454
  - lib/maze/wait.rb
455
455
  - lib/utils/deep_merge.rb
456
456
  - lib/utils/selenium_money_patch.rb
457
- homepage:
457
+ homepage:
458
458
  licenses:
459
459
  - MIT
460
460
  metadata: {}
461
- post_install_message:
461
+ post_install_message:
462
462
  rdoc_options: []
463
463
  require_paths:
464
464
  - lib
@@ -474,7 +474,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
474
474
  version: '0'
475
475
  requirements: []
476
476
  rubygems_version: 3.1.6
477
- signing_key:
477
+ signing_key:
478
478
  specification_version: 4
479
479
  summary: Bugsnag API request validation harness
480
480
  test_files: []