bugsnag-maze-runner 8.20.3 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/download-logs +1 -1
- data/bin/maze-runner +1 -4
- data/bin/purge-projects +1 -1
- data/bin/upload-app +1 -1
- data/lib/features/support/internal_hooks.rb +6 -18
- data/lib/maze/api/exit_code.rb +0 -2
- data/lib/maze/bugsnag_config.rb +1 -23
- data/lib/maze/client/appium/base_client.rb +1 -4
- data/lib/maze/client/appium/bb_client.rb +1 -7
- data/lib/maze/client/appium/bs_client.rb +1 -1
- data/lib/maze/client/appium/bs_devices.rb +18 -2
- data/lib/maze/client/selenium/bb_client.rb +1 -1
- data/lib/maze/client/selenium/bs_client.rb +1 -1
- data/lib/maze/driver/appium.rb +1 -1
- data/lib/maze/hooks/appium_hooks.rb +6 -9
- data/lib/maze/logger.rb +117 -0
- data/lib/maze/option/parser.rb +1 -1
- data/lib/maze/plugins/bugsnag_reporting_plugin.rb +0 -3
- data/lib/maze/server.rb +1 -1
- data/lib/maze.rb +1 -1
- metadata +8 -13
- data/lib/maze/hooks/logger_hooks.rb +0 -28
- data/lib/maze/loggers/file_logger.rb +0 -32
- data/lib/maze/loggers/log_util.rb +0 -59
- data/lib/maze/loggers/logger.rb +0 -61
- data/lib/maze/loggers/stdout_logger.rb +0 -34
- data/lib/maze/plugins/logging_scenarios_plugin.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7294cf169ef0a66ead9789be570496771a20734bb793340653b4235aa016f07
|
4
|
+
data.tar.gz: 30bfe8f408345f79524c37165e9760b97a9acfb1c546628a1cac3b0aa3063f1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec4f97ffe50aa33479d9c3f36748ffe72932798d165e71f25072c69613cbb30c485a2efe0aec792aac6c50149ee885d9ecc52dc11a71c813313e79d7b2bfb4d5
|
7
|
+
data.tar.gz: dd0e9a17df5d6298b59d5932777f423486ab8aed01b95625c47e72450325b61a71df0b417c984cf73a9c3fe029f29ec383defa29fd168270a0658abec418ff19
|
data/bin/download-logs
CHANGED
data/bin/maze-runner
CHANGED
@@ -40,6 +40,7 @@ require_relative '../lib/maze/errors'
|
|
40
40
|
require_relative '../lib/maze/generator'
|
41
41
|
require_relative '../lib/maze/helper'
|
42
42
|
require_relative '../lib/maze/http_request'
|
43
|
+
require_relative '../lib/maze/logger'
|
43
44
|
require_relative '../lib/maze/macos_utils'
|
44
45
|
require_relative '../lib/maze/maze_output'
|
45
46
|
require_relative '../lib/maze/metrics_processor'
|
@@ -52,8 +53,6 @@ require_relative '../lib/maze/repeaters/bugsnag_repeater'
|
|
52
53
|
require_relative '../lib/maze/runner'
|
53
54
|
require_relative '../lib/maze/terminating_server'
|
54
55
|
|
55
|
-
require_relative '../lib/maze/loggers/logger'
|
56
|
-
|
57
56
|
require_relative '../lib/maze/servlets/base_servlet'
|
58
57
|
require_relative '../lib/maze/servlets/all_commands_servlet'
|
59
58
|
require_relative '../lib/maze/servlets/command_servlet'
|
@@ -86,7 +85,6 @@ require_relative '../lib/maze/hooks/appium_hooks'
|
|
86
85
|
require_relative '../lib/maze/hooks/browser_hooks'
|
87
86
|
require_relative '../lib/maze/hooks/command_hooks'
|
88
87
|
require_relative '../lib/maze/hooks/error_code_hook'
|
89
|
-
require_relative '../lib/maze/hooks/logger_hooks'
|
90
88
|
|
91
89
|
require_relative '../lib/maze/driver/appium'
|
92
90
|
require_relative '../lib/maze/driver/browser'
|
@@ -95,7 +93,6 @@ require_relative '../lib/maze/plugins/bugsnag_reporting_plugin'
|
|
95
93
|
require_relative '../lib/maze/plugins/error_code_plugin'
|
96
94
|
require_relative '../lib/maze/plugins/global_retry_plugin'
|
97
95
|
require_relative '../lib/maze/plugins/datadog_metrics_plugin'
|
98
|
-
require_relative '../lib/maze/plugins/logging_scenarios_plugin'
|
99
96
|
|
100
97
|
# Require monkey-patches after everything else
|
101
98
|
require_relative '../lib/utils/selenium_money_patch'
|
data/bin/purge-projects
CHANGED
@@ -6,7 +6,7 @@ require 'em/pure_ruby'
|
|
6
6
|
|
7
7
|
require_relative '../lib/maze'
|
8
8
|
require_relative '../lib/maze/client/bb_api_client'
|
9
|
-
require_relative '../lib/maze/
|
9
|
+
require_relative '../lib/maze/logger'
|
10
10
|
require_relative '../lib/maze/helper'
|
11
11
|
require 'optimist'
|
12
12
|
require 'uri'
|
data/bin/upload-app
CHANGED
@@ -7,7 +7,7 @@ require 'em/pure_ruby'
|
|
7
7
|
require_relative '../lib/maze'
|
8
8
|
require_relative '../lib/maze/client/bs_client_utils'
|
9
9
|
require_relative '../lib/maze/client/bb_client_utils'
|
10
|
-
require_relative '../lib/maze/
|
10
|
+
require_relative '../lib/maze/logger'
|
11
11
|
require_relative '../lib/maze/helper'
|
12
12
|
require 'optimist'
|
13
13
|
require 'uri'
|
@@ -92,11 +92,8 @@ InstallPlugin do |config|
|
|
92
92
|
# Only add the retry plugin if --retry is not used on the command line
|
93
93
|
config.filters << Maze::Plugins::GlobalRetryPlugin.new(config) if config.options[:retry].zero?
|
94
94
|
|
95
|
-
#
|
96
|
-
config.filters << Maze::Plugins::
|
97
|
-
|
98
|
-
# Add bugsnag failed scenario reporting only if ENV['MAZE_SCENARIO_BUGSNAG_API_KEY'] is present
|
99
|
-
config.filters << Maze::Plugins::BugsnagReportingPlugin.new(config) unless ENV['MAZE_SCENARIO_BUGSNAG_API_KEY'].nil?
|
95
|
+
# TODO: Reporting of test failures as errors deactivated pending PLAT-10963
|
96
|
+
#config.filters << Maze::Plugins::BugsnagReportingPlugin.new(config)
|
100
97
|
end
|
101
98
|
|
102
99
|
# Before each scenario
|
@@ -116,9 +113,6 @@ Before do |scenario|
|
|
116
113
|
|
117
114
|
# Call any blocks registered by the client
|
118
115
|
Maze.hooks.call_before scenario
|
119
|
-
|
120
|
-
# Invoke the logger hook for the scenario
|
121
|
-
Maze::Hooks::LoggerHooks.before scenario
|
122
116
|
end
|
123
117
|
|
124
118
|
# General processing to be run after each scenario
|
@@ -128,9 +122,6 @@ After do |scenario|
|
|
128
122
|
Maze::MacosUtils.capture_screen(scenario)
|
129
123
|
end
|
130
124
|
|
131
|
-
# Invoke the logger hook for the scenario
|
132
|
-
Maze::Hooks::LoggerHooks.after scenario
|
133
|
-
|
134
125
|
# Call any blocks registered by the client
|
135
126
|
Maze.hooks.call_after scenario
|
136
127
|
|
@@ -193,17 +184,17 @@ def output_received_requests(request_type)
|
|
193
184
|
$stdout.puts "--- #{request_type} #{number} of #{count}"
|
194
185
|
|
195
186
|
$logger.info 'Request body:'
|
196
|
-
Maze::
|
187
|
+
Maze::LogUtil.log_hash(Logger::Severity::INFO, request[:body])
|
197
188
|
|
198
189
|
$logger.info 'Request headers:'
|
199
|
-
Maze::
|
190
|
+
Maze::LogUtil.log_hash(Logger::Severity::INFO, request[:request].header)
|
200
191
|
|
201
192
|
$logger.info 'Request digests:'
|
202
|
-
Maze::
|
193
|
+
Maze::LogUtil.log_hash(Logger::Severity::INFO, request[:digests])
|
203
194
|
|
204
195
|
$logger.info "Response body: #{request[:response].body}"
|
205
196
|
$logger.info 'Response headers:'
|
206
|
-
Maze::
|
197
|
+
Maze::LogUtil.log_hash(Logger::Severity::INFO, request[:response].header)
|
207
198
|
end
|
208
199
|
end
|
209
200
|
end
|
@@ -235,9 +226,6 @@ end
|
|
235
226
|
|
236
227
|
# After all tests
|
237
228
|
AfterAll do
|
238
|
-
# Ensure the logger output is in the correct location
|
239
|
-
Maze::Hooks::LoggerHooks.after_all
|
240
|
-
|
241
229
|
maze_output = File.join(Dir.pwd, 'maze_output')
|
242
230
|
maze_output_zip = File.join(Dir.pwd, 'maze_output.zip')
|
243
231
|
# zip a folder with files and subfolders
|
data/lib/maze/api/exit_code.rb
CHANGED
@@ -12,8 +12,6 @@ module Maze
|
|
12
12
|
TUNNEL_FAILURE = 101
|
13
13
|
SESSION_CREATION_FAILURE = 102
|
14
14
|
APPIUM_SESSION_FAILURE = 103
|
15
|
-
# A catch-all for certain errors related to Appium failures when the app is running app hang or ANR tests
|
16
|
-
APPIUM_APP_HANG_FAILURE = 104
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
data/lib/maze/bugsnag_config.rb
CHANGED
@@ -11,6 +11,7 @@ module Maze
|
|
11
11
|
Bugsnag.configure do |config|
|
12
12
|
config.api_key = ENV['MAZE_BUGSNAG_API_KEY']
|
13
13
|
config.app_version = Maze::VERSION
|
14
|
+
config.discard_classes << 'Test::Unit::AssertionFailedError'
|
14
15
|
config.add_metadata(:'test driver', {
|
15
16
|
'driver type': Maze.driver.class,
|
16
17
|
'device farm': Maze.config.farm,
|
@@ -31,7 +32,6 @@ module Maze
|
|
31
32
|
metadata['job url'] = ENV['BUILDKITE_BUILD_URL'] + "#" + ENV['BUILDKITE_JOB_ID']
|
32
33
|
end
|
33
34
|
end
|
34
|
-
config.middleware.use(AssertErrorMiddleware)
|
35
35
|
config.add_metadata(:'buildkite', metadata)
|
36
36
|
config.project_root = Dir.pwd
|
37
37
|
end
|
@@ -45,27 +45,5 @@ module Maze
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
49
|
-
class AssertErrorMiddleware
|
50
|
-
IGNORE_CLASS_NAME = 'Test::Unit::AssertionFailedError'
|
51
|
-
|
52
|
-
# @param middleware [#call] The next middleware to call
|
53
|
-
def initialize(middleware)
|
54
|
-
@middleware = middleware
|
55
|
-
end
|
56
|
-
|
57
|
-
def call(report)
|
58
|
-
# Only ignore automated notifies with assertion errors
|
59
|
-
automated = report.unhandled
|
60
|
-
|
61
|
-
class_match = report.raw_exceptions.any? do |ex|
|
62
|
-
ex.class.name.eql?(IGNORE_CLASS_NAME)
|
63
|
-
end
|
64
|
-
|
65
|
-
report.ignore! if automated && class_match
|
66
|
-
|
67
|
-
@middleware.call(report)
|
68
|
-
end
|
69
|
-
end
|
70
48
|
end
|
71
49
|
end
|
@@ -22,10 +22,7 @@ module Maze
|
|
22
22
|
when 'android'
|
23
23
|
Maze.driver.session_capabilities['appPackage']
|
24
24
|
when 'ios'
|
25
|
-
|
26
|
-
app_id = Maze.driver.session_capabilities['bundleID']
|
27
|
-
end
|
28
|
-
app_id
|
25
|
+
Maze.driver.session_capabilities['CFBundleIdentifier'] # Present on BS and locally
|
29
26
|
end
|
30
27
|
|
31
28
|
# Ensure the device is unlocked
|
@@ -30,10 +30,6 @@ module Maze
|
|
30
30
|
interval = 300
|
31
31
|
elsif error.message.include? 'There are no devices available'
|
32
32
|
interval = 120
|
33
|
-
elsif error.message.include? 'Appium Settings app is not running'
|
34
|
-
interval = 10
|
35
|
-
elsif error.message.include? 'Could not proxy command to the remote server'
|
36
|
-
interval = 10
|
37
33
|
else
|
38
34
|
# Do not retry in any other case
|
39
35
|
end
|
@@ -77,9 +73,7 @@ module Maze
|
|
77
73
|
}
|
78
74
|
capabilities.deep_merge! BitBarClientUtils.dashboard_capabilities
|
79
75
|
capabilities.deep_merge! BitBarDevices.get_available_device(config.device)
|
80
|
-
capabilities['bitbar:options']['appiumVersion'] = config.appium_version unless config.appium_version.nil?
|
81
76
|
capabilities.deep_merge! JSON.parse(config.capabilities_option)
|
82
|
-
|
83
77
|
capabilities
|
84
78
|
end
|
85
79
|
|
@@ -93,7 +87,7 @@ module Maze
|
|
93
87
|
$logger.info 'Appium session(s) created:'
|
94
88
|
@session_ids.each do |id|
|
95
89
|
link = api_client.get_device_session_ui_link(id)
|
96
|
-
$logger.info Maze::
|
90
|
+
$logger.info Maze::LogUtil.linkify(link, "BitBar session: #{id}") if link
|
97
91
|
end
|
98
92
|
end
|
99
93
|
|
@@ -68,7 +68,7 @@ module Maze
|
|
68
68
|
def log_run_intro
|
69
69
|
# Log a link to the BrowserStack session search dashboard
|
70
70
|
url = "https://app-automate.browserstack.com/dashboard/v2/search?query=#{Maze.run_uuid}&type=builds"
|
71
|
-
$logger.info Maze::
|
71
|
+
$logger.info Maze::LogUtil.linkify(url, 'BrowserStack session(s)')
|
72
72
|
end
|
73
73
|
|
74
74
|
def log_run_outro
|
@@ -82,10 +82,12 @@ module Maze
|
|
82
82
|
# iOS devices
|
83
83
|
'IOS_17' => make_ios_hash('iPhone 15', '17'),
|
84
84
|
'IOS_16' => make_ios_hash('iPhone 14', '16'),
|
85
|
-
'IOS_15' => make_ios_hash('iPhone
|
85
|
+
'IOS_15' => make_ios_hash('iPhone 11 Pro', '15'),
|
86
86
|
'IOS_14' => make_ios_hash('iPhone 11', '14'),
|
87
|
-
'IOS_13' => make_ios_hash('iPhone
|
87
|
+
'IOS_13' => make_ios_hash('iPhone 8', '13'),
|
88
88
|
'IOS_12' => make_ios_hash('iPhone 8', '12'),
|
89
|
+
'IOS_11' => make_ios_hash('iPhone 8', '11'),
|
90
|
+
'IOS_10' => make_ios_hash('iPhone 7', '10')
|
89
91
|
}
|
90
92
|
|
91
93
|
# Specific Android devices
|
@@ -98,8 +100,10 @@ module Maze
|
|
98
100
|
|
99
101
|
add_android 'Google Pixel 2', '9.0', hash # ANDROID_9_0_GOOGLE_PIXEL_2
|
100
102
|
add_android 'Samsung Galaxy Note 9', '8.1', hash # ANDROID_8_1_SAMSUNG_GALAXY_NOTE_9
|
103
|
+
add_android 'Samsung Galaxy J7 Prime', '8.1', hash # ANDROID_8_1_SAMSUNG_GALAXY_J7_PRIME
|
101
104
|
add_android 'Samsung Galaxy Tab S4', '8.1', hash # ANDROID_8_1_SAMSUNG_GALAXY_TAB_S4
|
102
105
|
add_android 'Samsung Galaxy Tab S3', '8.0', hash # ANDROID_8_0_SAMSUNG_GALAXY_TAB_S3
|
106
|
+
add_android 'Google Pixel 2', '8.0', hash # ANDROID_8_0_GOOGLE_PIXEL_2
|
103
107
|
add_android 'Samsung Galaxy S9', '8.0', hash # ANDROID_8_0_SAMSUNG_GALAXY_S9
|
104
108
|
add_android 'Samsung Galaxy S9 Plus', '8.0', hash # ANDROID_8_0_SAMSUNG_GALAXY_S9_PLUS
|
105
109
|
|
@@ -115,6 +119,18 @@ module Maze
|
|
115
119
|
add_ios 'iPhone 14 Pro', '16.0', hash # IOS_16_0_IPHONE_14_PRO
|
116
120
|
add_ios 'iPhone 14 Pro Max', '16.0', hash # IOS_16_0_IPHONE_14_PRO_MAX
|
117
121
|
|
122
|
+
add_ios 'iPhone 8 Plus', '11.0', hash # IOS_11_0_IPHONE_8_PLUS
|
123
|
+
add_ios 'iPhone X', '11.0', hash # IOS_11_0_IPHONE_X
|
124
|
+
add_ios 'iPhone SE', '11.0', hash # IOS_11_0_IPHONE_SE
|
125
|
+
add_ios 'iPhone 6', '11.0', hash # IOS_11_0_IPHONE_6
|
126
|
+
add_ios 'iPhone 6S', '11.0', hash # IOS_11_0_IPHONE_6S
|
127
|
+
add_ios 'iPhone 6S Plus', '11.0', hash # IOS_11_0_IPHONE_6S_PLUS
|
128
|
+
add_ios 'iPad 5th', '11.0', hash # IOS_11_0_IPAD_5TH
|
129
|
+
add_ios 'iPad Mini 4', '11.0', hash # IOS_11_0_IPAD_MINI_4
|
130
|
+
add_ios 'iPad Pro 9.7 2016', '11.0', hash # IOS_11_0_IPAD_PRO_9_7_2016
|
131
|
+
add_ios 'iPad 6th', '11.0', hash # IOS_11_0_IPAD_6TH
|
132
|
+
add_ios 'iPad Pro 12.9', '11.0', hash # IOS_11_0_IPAD_PRO_12_9
|
133
|
+
|
118
134
|
hash
|
119
135
|
end
|
120
136
|
end
|
@@ -34,7 +34,7 @@ module Maze
|
|
34
34
|
$logger.info 'Selenium session created:'
|
35
35
|
id = Maze.driver.session_id
|
36
36
|
link = api_client.get_device_session_ui_link(id)
|
37
|
-
$logger.info Maze::
|
37
|
+
$logger.info Maze::LogUtil.linkify link, 'BitBar session(s)' if link
|
38
38
|
end
|
39
39
|
|
40
40
|
def stop_session
|
@@ -85,7 +85,7 @@ module Maze
|
|
85
85
|
def log_session_info
|
86
86
|
# Log a link to the BrowserStack session search dashboard
|
87
87
|
url = "https://automate.browserstack.com/dashboard/v2/search?query=#{Maze.run_uuid}&type=builds"
|
88
|
-
$logger.info Maze::
|
88
|
+
$logger.info Maze::LogUtil.linkify url, 'BrowserStack session(s)'
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
data/lib/maze/driver/appium.rb
CHANGED
@@ -30,14 +30,11 @@ module Maze
|
|
30
30
|
elsif [:bb, :bs, :local].include? Maze.config.farm
|
31
31
|
write_device_logs(scenario) if scenario.failed?
|
32
32
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
else
|
39
|
-
Maze.driver.reset
|
40
|
-
end
|
33
|
+
# Reset the server to ensure that test fixtures cannot fetch
|
34
|
+
# commands from the previous scenario (in idempotent mode).
|
35
|
+
Maze.driver.terminate_app Maze.driver.app_id
|
36
|
+
Maze::Server.reset!
|
37
|
+
Maze.driver.activate_app Maze.driver.app_id
|
41
38
|
end
|
42
39
|
rescue => error
|
43
40
|
# Notify and re-raise for Cucumber to handle
|
@@ -46,6 +43,7 @@ module Maze
|
|
46
43
|
end
|
47
44
|
|
48
45
|
def after_all
|
46
|
+
@client&.log_run_outro
|
49
47
|
if $success
|
50
48
|
Maze::Plugins::DatadogMetricsPlugin.send_increment('appium.test_succeeded')
|
51
49
|
else
|
@@ -59,7 +57,6 @@ module Maze
|
|
59
57
|
|
60
58
|
def at_exit
|
61
59
|
if @client
|
62
|
-
@client.log_run_outro
|
63
60
|
$logger.info 'Stopping the Appium session'
|
64
61
|
@client.stop_session
|
65
62
|
end
|
data/lib/maze/logger.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bugsnag'
|
4
|
+
require 'logger'
|
5
|
+
require 'singleton'
|
6
|
+
|
7
|
+
# Monkey patch a 'trace' log level into the standard Logger
|
8
|
+
class Logger
|
9
|
+
remove_const(:SEV_LABEL)
|
10
|
+
SEV_LABEL = {
|
11
|
+
-1 => 'TRACE',
|
12
|
+
0 => 'DEBUG',
|
13
|
+
1 => 'INFO',
|
14
|
+
2 => 'WARN',
|
15
|
+
3 => 'ERROR',
|
16
|
+
4 => 'FATAL',
|
17
|
+
5 => 'ANY'
|
18
|
+
}
|
19
|
+
|
20
|
+
module Severity
|
21
|
+
TRACE=-1
|
22
|
+
end
|
23
|
+
|
24
|
+
def trace(name = nil, &block)
|
25
|
+
add(TRACE, nil, name, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def trace?
|
29
|
+
@level <= TRACE
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Logger classes
|
34
|
+
module Maze
|
35
|
+
# A logger, with level configured according to the environment
|
36
|
+
class Logger < Logger
|
37
|
+
include Singleton
|
38
|
+
|
39
|
+
attr_accessor :datetime_format
|
40
|
+
|
41
|
+
def initialize
|
42
|
+
if ENV['TRACE']
|
43
|
+
super(STDOUT, level: Logger::TRACE)
|
44
|
+
elsif ENV['DEBUG']
|
45
|
+
super(STDOUT, level: Logger::DEBUG)
|
46
|
+
elsif ENV['QUIET']
|
47
|
+
super(STDOUT, level: Logger::ERROR)
|
48
|
+
else
|
49
|
+
super(STDOUT, level: Logger::INFO)
|
50
|
+
end
|
51
|
+
|
52
|
+
@datetime_format = '%H:%M:%S'
|
53
|
+
|
54
|
+
@formatter = proc do |severity, time, _name, message|
|
55
|
+
formatted_time = time.strftime(@datetime_format)
|
56
|
+
|
57
|
+
"\e[2m[#{formatted_time}]\e[0m #{severity.rjust(5)}: #{message}\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
$logger = Maze::Logger.instance
|
63
|
+
|
64
|
+
# A collection of logging utilities
|
65
|
+
class LogUtil
|
66
|
+
class << self
|
67
|
+
# Logs Hash-based data, accounting for things like file upload requests that are too big to log meaningfully.
|
68
|
+
#
|
69
|
+
# @param severity [Integer] A constant from Logger::Severity
|
70
|
+
# @param data [Hash] The data to log (currently needs to be a Hash)
|
71
|
+
def log_hash(severity, data)
|
72
|
+
return unless data.is_a? Hash
|
73
|
+
|
74
|
+
# Try to pretty print as JSON, if not too big
|
75
|
+
begin
|
76
|
+
json = JSON.pretty_generate data
|
77
|
+
if json.length < 128 * 1024
|
78
|
+
$logger.add severity, json
|
79
|
+
else
|
80
|
+
log_hash_by_field severity, data
|
81
|
+
end
|
82
|
+
rescue Encoding::UndefinedConversionError => error
|
83
|
+
# Just give up, we don't want to risk a further error trying to log garbage
|
84
|
+
Bugsnag.notify error
|
85
|
+
$logger.error 'Unable to log hash as JSON'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Logs a hash field by field,
|
90
|
+
#
|
91
|
+
# @param severity [Integer] A Logger::Severity
|
92
|
+
# @param hash [Hash] The Hash
|
93
|
+
def log_hash_by_field(severity, hash)
|
94
|
+
hash.keys.each do |key|
|
95
|
+
value = hash[key].to_s
|
96
|
+
if value.length < 1024
|
97
|
+
$logger.add severity, " #{key}: #{value}"
|
98
|
+
else
|
99
|
+
$logger.add severity, " #{key} (length): #{value.length}"
|
100
|
+
$logger.add severity, " #{key} (start): #{value[0, 1024]}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Produces a clickable link when logged in Buildkite
|
106
|
+
# @param url [String] Link URL
|
107
|
+
# @param text [String] Link text
|
108
|
+
def linkify(url, text)
|
109
|
+
if ENV['BUILDKITE']
|
110
|
+
"\033]1339;url='#{url}';content='#{text}'\a"
|
111
|
+
else
|
112
|
+
"#{text}: #{url}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/maze/option/parser.rb
CHANGED
@@ -42,7 +42,7 @@ module Maze
|
|
42
42
|
default: true
|
43
43
|
|
44
44
|
opt Option::BUGSNAG,
|
45
|
-
'Enables reporting to Bugsnag on scenario failure (requires MAZE_BUGSNAG_API_KEY
|
45
|
+
'Enables reporting to Bugsnag on scenario failure (requires MAZE_BUGSNAG_API_KEY)',
|
46
46
|
type: :boolean,
|
47
47
|
short: :none,
|
48
48
|
default: true
|
@@ -25,9 +25,6 @@ module Maze
|
|
25
25
|
next unless event.test_case.eql?(test_case) && event.result.failed?
|
26
26
|
|
27
27
|
Bugsnag.notify(event.result.exception) do |bsg_event|
|
28
|
-
|
29
|
-
bsg_event.api_key = ENV['MAZE_SCENARIO_BUGSNAG_API_KEY']
|
30
|
-
|
31
28
|
unless @last_test_step.nil?
|
32
29
|
|
33
30
|
repo = ENV['BUILDKITE_PIPELINE_SLUG']
|
data/lib/maze/server.rb
CHANGED
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 = '
|
10
|
+
VERSION = '9.0.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:
|
4
|
+
version: 9.0.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-
|
11
|
+
date: 2024-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -409,13 +409,9 @@ files:
|
|
409
409
|
- lib/maze/hooks/command_hooks.rb
|
410
410
|
- lib/maze/hooks/error_code_hook.rb
|
411
411
|
- lib/maze/hooks/hooks.rb
|
412
|
-
- lib/maze/hooks/logger_hooks.rb
|
413
412
|
- lib/maze/http_request.rb
|
414
413
|
- lib/maze/interactive_cli.rb
|
415
|
-
- lib/maze/
|
416
|
-
- lib/maze/loggers/log_util.rb
|
417
|
-
- lib/maze/loggers/logger.rb
|
418
|
-
- lib/maze/loggers/stdout_logger.rb
|
414
|
+
- lib/maze/logger.rb
|
419
415
|
- lib/maze/macos_utils.rb
|
420
416
|
- lib/maze/maze_output.rb
|
421
417
|
- lib/maze/metrics_processor.rb
|
@@ -428,7 +424,6 @@ files:
|
|
428
424
|
- lib/maze/plugins/datadog_metrics_plugin.rb
|
429
425
|
- lib/maze/plugins/error_code_plugin.rb
|
430
426
|
- lib/maze/plugins/global_retry_plugin.rb
|
431
|
-
- lib/maze/plugins/logging_scenarios_plugin.rb
|
432
427
|
- lib/maze/proxy.rb
|
433
428
|
- lib/maze/repeaters/aspecto_repeater.rb
|
434
429
|
- lib/maze/repeaters/bugsnag_repeater.rb
|
@@ -454,11 +449,11 @@ files:
|
|
454
449
|
- lib/maze/wait.rb
|
455
450
|
- lib/utils/deep_merge.rb
|
456
451
|
- lib/utils/selenium_money_patch.rb
|
457
|
-
homepage:
|
452
|
+
homepage:
|
458
453
|
licenses:
|
459
454
|
- MIT
|
460
455
|
metadata: {}
|
461
|
-
post_install_message:
|
456
|
+
post_install_message:
|
462
457
|
rdoc_options: []
|
463
458
|
require_paths:
|
464
459
|
- lib
|
@@ -473,8 +468,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
473
468
|
- !ruby/object:Gem::Version
|
474
469
|
version: '0'
|
475
470
|
requirements: []
|
476
|
-
rubygems_version: 3.
|
477
|
-
signing_key:
|
471
|
+
rubygems_version: 3.1.6
|
472
|
+
signing_key:
|
478
473
|
specification_version: 4
|
479
474
|
summary: Bugsnag API request validation harness
|
480
475
|
test_files: []
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Maze
|
4
|
-
module Hooks
|
5
|
-
# Hooks for Browser mode use
|
6
|
-
class LoggerHooks
|
7
|
-
class << self
|
8
|
-
def before(scenario)
|
9
|
-
location = "\"# #{scenario.location}\""
|
10
|
-
$logger.trace ''
|
11
|
-
$logger.trace "\n--- Begin Scenario: #{scenario.name} #{location}"
|
12
|
-
end
|
13
|
-
|
14
|
-
def after(scenario)
|
15
|
-
location = "\"# #{scenario.location}\""
|
16
|
-
$logger.trace "--- End Scenario: #{scenario.name} #{location}"
|
17
|
-
$logger.trace ''
|
18
|
-
end
|
19
|
-
|
20
|
-
def after_all
|
21
|
-
if ENV['BUILDKITE']
|
22
|
-
FileUtils.mv("#{Dir.pwd}/#{Maze::Loggers::FileLogger::LOG_LOCATION}", "#{Dir.pwd}/maze_output/maze-runner.log")
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
module Maze
|
6
|
-
module Loggers
|
7
|
-
# A logger to file, always logging at TRACE level
|
8
|
-
class FileLogger < Logger
|
9
|
-
|
10
|
-
LOG_LOCATION = 'maze-runner.log'
|
11
|
-
|
12
|
-
include Singleton
|
13
|
-
|
14
|
-
attr_accessor :datetime_format
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
# Remove the previous log file if it exists
|
18
|
-
File.delete(LOG_LOCATION) if File.exist?(LOG_LOCATION)
|
19
|
-
|
20
|
-
super(LOG_LOCATION, level: ::Logger::TRACE)
|
21
|
-
|
22
|
-
@datetime_format = '%H:%M:%S'
|
23
|
-
|
24
|
-
@formatter = proc do |severity, time, _name, message|
|
25
|
-
formatted_time = time.strftime(@datetime_format)
|
26
|
-
|
27
|
-
"\e[2m[#{formatted_time}]\e[0m #{severity.rjust(5)}: #{message}\n"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Maze
|
4
|
-
module Loggers
|
5
|
-
# A collection of logging utilities
|
6
|
-
class LogUtil
|
7
|
-
class << self
|
8
|
-
# Logs Hash-based data, accounting for things like file upload requests that are too big to log meaningfully.
|
9
|
-
#
|
10
|
-
# @param severity [Integer] A constant from Logger::Severity
|
11
|
-
# @param data [Hash] The data to log (currently needs to be a Hash)
|
12
|
-
def log_hash(severity, data)
|
13
|
-
return unless data.is_a? Hash
|
14
|
-
|
15
|
-
# Try to pretty print as JSON, if not too big
|
16
|
-
begin
|
17
|
-
json = JSON.pretty_generate data
|
18
|
-
if json.length < 128 * 1024
|
19
|
-
$logger.add severity, json
|
20
|
-
else
|
21
|
-
log_hash_by_field severity, data
|
22
|
-
end
|
23
|
-
rescue Encoding::UndefinedConversionError => error
|
24
|
-
# Just give up, we don't want to risk a further error trying to log garbage
|
25
|
-
Bugsnag.notify error
|
26
|
-
$logger.error 'Unable to log hash as JSON'
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Logs a hash field by field,
|
31
|
-
#
|
32
|
-
# @param severity [Integer] A Logger::Severity
|
33
|
-
# @param hash [Hash] The Hash
|
34
|
-
def log_hash_by_field(severity, hash)
|
35
|
-
hash.keys.each do |key|
|
36
|
-
value = hash[key].to_s
|
37
|
-
if value.length < 1024
|
38
|
-
$logger.add severity, " #{key}: #{value}"
|
39
|
-
else
|
40
|
-
$logger.add severity, " #{key} (length): #{value.length}"
|
41
|
-
$logger.add severity, " #{key} (start): #{value[0, 1024]}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Produces a clickable link when logged in Buildkite
|
47
|
-
# @param url [String] Link URL
|
48
|
-
# @param text [String] Link text
|
49
|
-
def linkify(url, text)
|
50
|
-
if ENV['BUILDKITE']
|
51
|
-
"\033]1339;url='#{url}';content='#{text}'\a"
|
52
|
-
else
|
53
|
-
"#{text}: #{url}"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
data/lib/maze/loggers/logger.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bugsnag'
|
4
|
-
require 'logger'
|
5
|
-
require 'singleton'
|
6
|
-
require_relative 'file_logger'
|
7
|
-
require_relative 'log_util'
|
8
|
-
require_relative 'stdout_logger'
|
9
|
-
|
10
|
-
# Monkey patch a 'trace' log level into the standard Logger
|
11
|
-
class Logger
|
12
|
-
remove_const(:SEV_LABEL)
|
13
|
-
SEV_LABEL = {
|
14
|
-
-1 => 'TRACE',
|
15
|
-
0 => 'DEBUG',
|
16
|
-
1 => 'INFO',
|
17
|
-
2 => 'WARN',
|
18
|
-
3 => 'ERROR',
|
19
|
-
4 => 'FATAL',
|
20
|
-
5 => 'ANY'
|
21
|
-
}
|
22
|
-
|
23
|
-
module Severity
|
24
|
-
TRACE=-1
|
25
|
-
end
|
26
|
-
|
27
|
-
def trace(name = nil, &block)
|
28
|
-
add(TRACE, nil, name, &block)
|
29
|
-
end
|
30
|
-
|
31
|
-
def trace?
|
32
|
-
@level <= TRACE
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
module Maze
|
37
|
-
module Loggers
|
38
|
-
class Logger
|
39
|
-
include Singleton
|
40
|
-
|
41
|
-
attr_accessor :stdout_logger, :file_logger
|
42
|
-
|
43
|
-
def initialize
|
44
|
-
@stdout_logger = Maze::Loggers::STDOUTLogger.instance
|
45
|
-
@file_logger = Maze::Loggers::FileLogger.instance
|
46
|
-
end
|
47
|
-
|
48
|
-
# Attempts to forward all method calls to both loggers
|
49
|
-
def method_missing(method, *args, &block)
|
50
|
-
if @stdout_logger.respond_to?(method) && @file_logger.respond_to?(method)
|
51
|
-
@stdout_logger.send(method, *args, &block)
|
52
|
-
@file_logger.send(method, *args, &block)
|
53
|
-
else
|
54
|
-
super
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
$logger = Maze::Loggers::Logger.instance
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
module Maze
|
6
|
-
module Loggers
|
7
|
-
# A logger to STDOUT, with level configured according to the environment
|
8
|
-
class STDOUTLogger < Logger
|
9
|
-
include Singleton
|
10
|
-
|
11
|
-
attr_accessor :datetime_format
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
if ENV['TRACE']
|
15
|
-
super(STDOUT, level: ::Logger::TRACE)
|
16
|
-
elsif ENV['DEBUG']
|
17
|
-
super(STDOUT, level: ::Logger::DEBUG)
|
18
|
-
elsif ENV['QUIET']
|
19
|
-
super(STDOUT, level: ::Logger::ERROR)
|
20
|
-
else
|
21
|
-
super(STDOUT, level: ::Logger::INFO)
|
22
|
-
end
|
23
|
-
|
24
|
-
@datetime_format = '%H:%M:%S'
|
25
|
-
|
26
|
-
@formatter = proc do |severity, time, _name, message|
|
27
|
-
formatted_time = time.strftime(@datetime_format)
|
28
|
-
|
29
|
-
"\e[2m[#{formatted_time}]\e[0m #{severity.rjust(5)}: #{message}\n"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bugsnag'
|
4
|
-
require 'cucumber/core/filter'
|
5
|
-
|
6
|
-
module Maze
|
7
|
-
module Plugins
|
8
|
-
class LoggingScenariosPlugin < Cucumber::Core::Filter.new(:configuration)
|
9
|
-
|
10
|
-
def test_case(test_case)
|
11
|
-
configuration.on_event(:test_step_started) do |event|
|
12
|
-
$logger.trace "Step started: #{event.test_step.to_s}"
|
13
|
-
end
|
14
|
-
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|