bugsnag-maze-runner 7.23.0 → 7.24.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: 278a8086385e122760909cdb546fe9a15d76e24d5d13948c45bb097d86427f4a
4
- data.tar.gz: 56a21399890869570fa4acffdbe962714fb423307e3b7575edc3bee14358d315
3
+ metadata.gz: f07c9dfdaab73bc584bf02c73a553e949851c700d2d1b54411b1886e936f9b3d
4
+ data.tar.gz: 8894d62125f81610660c6df39a05ad73c03b21cb12d8bff69888e9bc1bec3d1e
5
5
  SHA512:
6
- metadata.gz: bc3bca3a7e2471c755ec2e3ba6c7479fd62dc1cdcb46a503332ed31c148554f4c2bd664e43038af537930eedc1f322656baf718905242088fcaaa1f37e134e35
7
- data.tar.gz: 716512518c9dd9124137bd4e1a867c8799dbfdbfc9ae87eec12d38a9da0835e8e34d128999afe24020863cc6bfbb7ae1170ae9d60bd587e7ce973921a70c3420
6
+ metadata.gz: fe3934ed47df9f0c0c921f66802b8cccdd8aa06af1e17005079850009bc797107d13f612a4dcdb708868215ffd5bd3ab7b97a08f2e333f04feb9bf70d8728144
7
+ data.tar.gz: 59bf8a127529f30624586d86493f8db88c5b142ef42841dc58082890229925e7cf4e17946855222d0f10c7fd7a6845622d872f2de829c8d5bbcaa321fdaa3e7a
data/bin/maze-runner CHANGED
@@ -26,6 +26,7 @@ require_relative '../lib/maze/client/selenium/base_client'
26
26
  require_relative '../lib/maze/client/selenium/bb_client'
27
27
  require_relative '../lib/maze/client/selenium/bs_client'
28
28
  require_relative '../lib/maze/client/selenium/local_client'
29
+
29
30
  require_relative '../lib/maze/aws_public_ip'
30
31
  require_relative '../lib/maze/compare'
31
32
  require_relative '../lib/maze/docker'
@@ -82,6 +83,7 @@ require_relative '../lib/maze/plugins/bugsnag_reporting_plugin'
82
83
  require_relative '../lib/maze/plugins/cucumber_report_plugin'
83
84
  require_relative '../lib/maze/plugins/error_code_plugin'
84
85
  require_relative '../lib/maze/plugins/global_retry_plugin'
86
+ require_relative '../lib/maze/plugins/datadog_metrics_plugin'
85
87
 
86
88
  # Require monkey-patches after everything else
87
89
  require_relative '../lib/utils/selenium_money_patch'
data/bin/upload-app CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  require_relative '../lib/maze'
5
5
  require_relative '../lib/maze/client/bs_client_utils'
6
+ require_relative '../lib/maze/client/bb_client_utils'
6
7
  require_relative '../lib/maze/logger'
7
8
  require_relative '../lib/maze/helper'
8
9
  require 'optimist'
@@ -11,45 +12,70 @@ require 'net/http'
11
12
 
12
13
  class UploadAppEntry
13
14
  def start(args)
14
- p = Optimist::Parser.new do
15
- text 'Upload app files to BrowserStack'
16
- text ''
17
- text 'Requires BROWSER_STACK_USERNAME and BROWSER_STACK_ACCESS_KEY'
15
+ parser = Optimist::Parser.new do
16
+ text 'Upload app files to a device farm'
18
17
  text ''
19
18
  text 'Usage [OPTIONS]'
20
19
  text ''
21
20
  opt :help,
22
- 'Print this help.'
21
+ 'Print this help.'
23
22
  opt :app,
24
- 'The app to upload.',
25
- :type => :string
23
+ 'The app to upload.',
24
+ type: :string,
25
+ required: true
26
26
  opt :app_id_file,
27
- 'The file to write the uploaded app ID back to',
28
- :type => :string
27
+ 'The file to write the uploaded app ID back to',
28
+ type: :string
29
+ opt :farm,
30
+ 'The device farm to upload the app to, one of bb (BitBar) or bs (BrowserStack) (default)',
31
+ type: :string,
32
+ default: 'bs'
33
+ opt :username,
34
+ 'Device farm username. Defaults to BROWSER_STACK_DEVICES_USERNAME variable (required for BrowserStack)',
35
+ type: :string
36
+ opt :access_key,
37
+ 'Device farm access key. Defaults to BROWSER_STACK_DEVICES_ACCESS_KEY or BITBAR_ACCESS_KEY environment variables (required)',
38
+ type: :string
29
39
  end
30
40
 
31
- opts = Optimist::with_standard_exception_handling p do
41
+ options = Optimist::with_standard_exception_handling parser do
32
42
  raise Optimist::HelpNeeded if ARGV.empty? # show help screen
33
- p.parse ARGV
43
+ parser.parse ARGV
34
44
  end
35
45
 
36
- # Get browserstack username and access key from the environment
37
- username = ENV['BROWSER_STACK_USERNAME']
38
- access_key = ENV['BROWSER_STACK_ACCESS_KEY']
46
+ # Get username and access key from the environment
47
+ case options[:farm]
48
+ when 'bs'
49
+ options[:username] ||= ENV['BROWSER_STACK_DEVICES_USERNAME'] || ENV['BROWSER_STACK_USERNAME']
50
+ options[:access_key] ||= ENV['BROWSER_STACK_DEVICES_ACCESS_KEY'] ||ENV['BROWSER_STACK_ACCESS_KEY']
51
+ if options[:username].nil?
52
+ $logger.warn 'Browserstack requires username option to be set'
53
+ Optimist::with_standard_exception_handling parser do
54
+ raise Optimist::HelpNeeded
55
+ end
56
+ end
57
+ when 'bb'
58
+ options[:access_key] ||= ENV['BITBAR_ACCESS_KEY']
59
+ end
39
60
 
40
- # Check if BROWSER_STACK_USERNAME or BROWSER_STACK_ACCESS_KEY has been set
41
- if username.nil? || access_key.nil?
42
- $logger.warn "BROWSER_STACK_USERNAME or BROWSER_STACK_ACCESS_KEY has not been set"
43
- Optimist::with_standard_exception_handling p do
61
+ if options[:access_key].nil?
62
+ $logger.warn 'An access_key is required to upload the app'
63
+ Optimist::with_standard_exception_handling parser do
44
64
  raise Optimist::HelpNeeded
45
65
  end
46
66
  end
47
67
 
48
- Maze::Client::BrowserStackClientUtils.upload_app username,
49
- access_key,
50
- opts[:app],
51
- opts[:app_id_file]
52
-
68
+ case options[:farm]
69
+ when 'bs'
70
+ Maze::Client::BrowserStackClientUtils.upload_app options[:username],
71
+ options[:access_key],
72
+ options[:app],
73
+ options[:app_id_file]
74
+ when 'bb'
75
+ Maze::Client::BitBarClientUtils.upload_app options[:access_key],
76
+ options[:app],
77
+ options[:app_id_file]
78
+ end
53
79
  end
54
80
  end
55
81
 
@@ -103,7 +103,7 @@ end
103
103
  # @step_input url [String] The URL to open.
104
104
  When('I open the URL {string}') do |url|
105
105
  begin
106
- open(url, &:read)
106
+ URI.open(url, &:read)
107
107
  rescue OpenURI::HTTPError
108
108
  $logger.debug $!.inspect
109
109
  end
@@ -148,6 +148,12 @@ Then('a span field {string} equals {string}') do |key, expected|
148
148
  Maze.check.includes selected_keys, expected
149
149
  end
150
150
 
151
+ Then('a span field {string} equals {int}') do |key, expected|
152
+ spans = spans_from_request_list(Maze::Server.list_for('traces'))
153
+ selected_keys = spans.map { |span| span[key] }
154
+ Maze.check.includes selected_keys, expected
155
+ end
156
+
151
157
  Then('a span field {string} matches the regex {string}') do |attribute, pattern|
152
158
  regex = Regexp.new pattern
153
159
  spans = spans_from_request_list(Maze::Server.list_for('traces'))
@@ -65,6 +65,9 @@ BeforeAll do
65
65
  # Start document server, if asked for
66
66
  # This must happen after any client hooks have run, so that they can set the server root
67
67
  Maze::DocumentServer.start unless Maze.config.document_server_root.nil?
68
+
69
+ # An initial setup for total success status
70
+ $success = true
68
71
  end
69
72
 
70
73
  # @param config The Cucumber config
@@ -141,6 +144,9 @@ After do |scenario|
141
144
  output_received_requests('invalid requests')
142
145
  end
143
146
 
147
+ # Keep a global record of the total test status for reporting purposes
148
+ $success = !scenario.failed?
149
+
144
150
  # Log all received requests to file
145
151
  Maze::MazeOutput.new(scenario).write_requests if Maze.config.file_log
146
152
 
@@ -70,25 +70,37 @@ module Maze
70
70
  #
71
71
  # @return [Hash] A hash containing the capabilities.
72
72
  def dashboard_capabilities
73
- # Attempt to use the current git repo as the project name
74
- output, status = Maze::Runner.run_command('git rev-parse --show-toplevel')
75
- if status == 0
76
- project = File.basename(output[0].strip)
73
+
74
+ # Determine project name
75
+ if ENV['BUILDKITE']
76
+ $logger.info 'Using BUILDKITE_PIPELINE_SLUG for BitBar project name'
77
+ project = ENV['BUILDKITE_PIPELINE_SLUG']
77
78
  else
78
- if ENV['BUILDKITE']
79
- project = ENV['BUILDKITE_PIPELINE_SLUG']
79
+ # Attempt to use the current git repo
80
+ output, status = Maze::Runner.run_command('git rev-parse --show-toplevel')
81
+ if status == 0
82
+ project = File.basename(output[0].strip)
80
83
  else
81
84
  $logger.warn 'Unable to determine project name, consider running Maze Runner from within a Git repository'
82
85
  project = 'Unknown'
83
86
  end
84
87
  end
85
88
 
89
+ # Test run
86
90
  if ENV['BUILDKITE']
87
- test_run = "#{ENV['BUILDKITE_BUILD_NUMBER']} - #{ENV['BUILDKITE_LABEL']}"
91
+ bk_retry = ENV['BUILDKITE_RETRY_COUNT']
92
+ retry_string = if !bk_retry.nil? && bk_retry.to_i > 1
93
+ " (#{bk_retry})"
94
+ else
95
+ ''
96
+ end
97
+ test_run = "#{ENV['BUILDKITE_BUILD_NUMBER']} - #{ENV['BUILDKITE_LABEL']}#{retry_string}"
88
98
  else
89
99
  test_run = Maze.run_uuid
90
100
  end
91
101
 
102
+ $logger.info "BitBar project name: #{project}"
103
+ $logger.info "BitBar test run: #{test_run}"
92
104
  {
93
105
  'bitbar:options' => {
94
106
  bitbar_project: project,
@@ -41,7 +41,9 @@ module Maze
41
41
  all_devices = query_api(path, query)
42
42
 
43
43
  $logger.debug "All available devices in group #{device_group_id}: #{JSON.pretty_generate(all_devices)}"
44
+ Maze::Plugins::DatadogMetricsPlugin.send_gauge('bitbar.device.available', all_devices['data'].size, [Maze.config.device])
44
45
  filtered_devices = all_devices['data'].reject { |device| device['locked'] }
46
+ Maze::Plugins::DatadogMetricsPlugin.send_gauge('bitbar.device.unlocked', filtered_devices.size, [Maze.config.device])
45
47
  return filtered_devices.size, filtered_devices.sample
46
48
  end
47
49
 
@@ -17,7 +17,8 @@ module Maze
17
17
  # Uploads an app to BitBar for later consumption
18
18
  # @param api_key [String] The BitBar API key
19
19
  # @param app [String] A path to the application file
20
- def upload_app(api_key, app)
20
+ # @param app_id_file [String] the file to write the uploaded app url to BitBar
21
+ def upload_app(api_key, app, app_id_file=nil)
21
22
  uuid_regex = /\A[0-9]+\z/
22
23
 
23
24
  if uuid_regex.match? app
@@ -53,6 +54,12 @@ module Maze
53
54
  raise
54
55
  end
55
56
  end
57
+
58
+ unless app_id_file.nil?
59
+ $logger.info "Writing uploaded app id to #{app_id_file}"
60
+ File.write(Maze::Helper.expand_path(app_id_file), app_uuid)
61
+ end
62
+
56
63
  app_uuid
57
64
  end
58
65
 
@@ -6,6 +6,10 @@ module Maze
6
6
  raise 'Method not implemented by this class'
7
7
  end
8
8
 
9
+ def log_run_outro
10
+ raise 'Method not implemented by this class'
11
+ end
12
+
9
13
  def stop_session
10
14
  Maze.driver&.driver_quit
11
15
  end
@@ -27,6 +27,15 @@ module Maze
27
27
  Maze.driver.start_driver
28
28
  end
29
29
 
30
+ def log_run_outro
31
+ api_client = BitBarApiClient.new(Maze.config.access_key)
32
+
33
+ $logger.info 'Selenium session created:'
34
+ id = Maze.driver.session_id
35
+ link = api_client.get_device_session_ui_link(id)
36
+ $logger.info Maze::LogUtil.linkify link, 'BitBar session(s)' if link
37
+ end
38
+
30
39
  def stop_session
31
40
  super
32
41
  Maze::Client::BitBarClientUtils.stop_local_tunnel
@@ -59,6 +59,10 @@ module Maze
59
59
  Maze::Client::BrowserStackClientUtils.stop_local_tunnel
60
60
  end
61
61
 
62
+ def log_run_outro
63
+ log_session_info
64
+ end
65
+
62
66
  private
63
67
 
64
68
  # Determines and returns sensible project and build capabilities
@@ -92,6 +92,13 @@ module Maze
92
92
  end
93
93
  end
94
94
 
95
+ # Returns the driver session ID
96
+ #
97
+ # @returns [String] The session ID of the selenium session
98
+ def session_id
99
+ @driver.session_id
100
+ end
101
+
95
102
  private
96
103
 
97
104
  # Creates and starts the selenium driver
@@ -6,6 +6,7 @@ module Maze
6
6
  @client
7
7
 
8
8
  def before_all
9
+ Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_started')
9
10
  @client = Maze::Client::Appium.start
10
11
  end
11
12
 
@@ -30,6 +31,11 @@ module Maze
30
31
 
31
32
  def after_all
32
33
  @client&.log_run_outro
34
+ if $success
35
+ Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_succeeded')
36
+ else
37
+ Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_failed')
38
+ end
33
39
  end
34
40
 
35
41
  def at_exit
@@ -7,8 +7,12 @@ module Maze
7
7
  @client = Maze::Client::Selenium.start
8
8
  end
9
9
 
10
+ def after_all
11
+ @client&.log_run_outro
12
+ end
13
+
10
14
  def at_exit
11
- @client.stop_session
15
+ @client&.stop_session
12
16
  end
13
17
  end
14
18
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'datadog/statsd'
4
+
5
+ module Maze
6
+ module Plugins
7
+ # Enables metrics to be reported to Datadog via a StatsD proxy
8
+ class DatadogMetricsPlugin
9
+
10
+ class << self
11
+ # Sends a gauge metric to Datadog
12
+ #
13
+ # @param metric [String] The identifier of the metric
14
+ # @param value [Integer] The value of the metric
15
+ # @param tags [Array] An array of strings with which to tag the metric
16
+ def send_gauge(metric, value, tags=[])
17
+ return unless logging?
18
+ stats_dog.gauge(metric, value, tags: tags)
19
+ end
20
+
21
+ # Sends an increment metric to Datadog
22
+ #
23
+ # @param metric [String] The identifier of the metric
24
+ # @param tags [Array] An array of strings with which to tag the metric
25
+ def send_increment(metric, tags=[])
26
+ return unless logging?
27
+ stats_dog.increment(metric, tags: tags)
28
+ end
29
+
30
+ private
31
+
32
+ # Whether metrics should be delivered to Datadog
33
+ #
34
+ # @returns [Boolean] Whether metrics should be sent
35
+ def logging?
36
+ ENV['BUILDKITE']
37
+ end
38
+
39
+ # Returns or initialises the DogStatsD instance
40
+ #
41
+ # @returns [Datadog::Statsd] The DogStatsD instance
42
+ def stats_dog
43
+ @stats_dog ||= initialize_stats_dog
44
+ end
45
+
46
+ # Initializes the DogStatsD instance, connecting to the buildkite agent Datadog agent
47
+ #
48
+ # @returns [Datadog::Statsd] The newly created DogStatsD instance
49
+ def initialize_stats_dog
50
+ tags = []
51
+ tags << Maze.config.device.to_s if Maze.config.device
52
+ tags << Maze.config.farm.to_s if Maze.config.farm
53
+ @stats_dog = Datadog::Statsd.new(aws_instance_ip, 8125, tags: tags, namespace: 'maze-runner')
54
+
55
+ at_exit do
56
+ @stats_dog.close
57
+ end
58
+
59
+ @stats_dog
60
+ end
61
+
62
+ # Retrieves the internal ipv4 address of the AWS buildkite instance the maze-runner container is run upon
63
+ #
64
+ # @returns [String] The local ipv4 address the Datadog agent is running on
65
+ def aws_instance_ip
66
+ `curl --silent -XGET http://169.254.169.254/latest/meta-data/local-ipv4`
67
+ end
68
+ end
69
+ end
70
+ end
71
+ 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 = '7.23.0'
10
+ VERSION = '7.24.0'
11
11
 
12
12
  class << self
13
13
  attr_accessor :check, :driver, :internal_hooks, :mode, :start_time, :dynamic_retry, :public_address, :run_uuid
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: 7.23.0
4
+ version: 7.24.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-03-20 00:00:00.000000000 Z
11
+ date: 2023-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 0.9.6
167
+ - !ruby/object:Gem::Dependency
168
+ name: dogstatsd-ruby
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 5.5.0
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 5.5.0
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: optimist
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -401,6 +415,7 @@ files:
401
415
  - lib/maze/option/validator.rb
402
416
  - lib/maze/plugins/bugsnag_reporting_plugin.rb
403
417
  - lib/maze/plugins/cucumber_report_plugin.rb
418
+ - lib/maze/plugins/datadog_metrics_plugin.rb
404
419
  - lib/maze/plugins/error_code_plugin.rb
405
420
  - lib/maze/plugins/global_retry_plugin.rb
406
421
  - lib/maze/proxy.rb