bugsnag-maze-runner 6.27.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.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/bin/bugsnag-print-load-paths +6 -0
  3. data/bin/download-logs +76 -0
  4. data/bin/maze-runner +136 -0
  5. data/bin/upload-app +56 -0
  6. data/lib/features/scripts/await-android-emulator.sh +11 -0
  7. data/lib/features/scripts/clear-android-app-data.sh +8 -0
  8. data/lib/features/scripts/force-stop-android-app.sh +8 -0
  9. data/lib/features/scripts/install-android-app.sh +15 -0
  10. data/lib/features/scripts/launch-android-app.sh +38 -0
  11. data/lib/features/scripts/launch-android-emulator.sh +15 -0
  12. data/lib/features/steps/android_steps.rb +51 -0
  13. data/lib/features/steps/app_automator_steps.rb +228 -0
  14. data/lib/features/steps/aws_sam_steps.rb +212 -0
  15. data/lib/features/steps/breadcrumb_steps.rb +50 -0
  16. data/lib/features/steps/browser_steps.rb +93 -0
  17. data/lib/features/steps/build_api_steps.rb +25 -0
  18. data/lib/features/steps/document_server_steps.rb +7 -0
  19. data/lib/features/steps/error_reporting_steps.rb +342 -0
  20. data/lib/features/steps/feature_flag_steps.rb +190 -0
  21. data/lib/features/steps/header_steps.rb +72 -0
  22. data/lib/features/steps/log_steps.rb +29 -0
  23. data/lib/features/steps/multipart_request_steps.rb +142 -0
  24. data/lib/features/steps/network_steps.rb +75 -0
  25. data/lib/features/steps/payload_steps.rb +234 -0
  26. data/lib/features/steps/proxy_steps.rb +34 -0
  27. data/lib/features/steps/query_parameter_steps.rb +31 -0
  28. data/lib/features/steps/request_assertion_steps.rb +107 -0
  29. data/lib/features/steps/runner_steps.rb +406 -0
  30. data/lib/features/steps/session_tracking_steps.rb +116 -0
  31. data/lib/features/steps/value_steps.rb +119 -0
  32. data/lib/features/support/env.rb +7 -0
  33. data/lib/features/support/internal_hooks.rb +260 -0
  34. data/lib/maze/appium_server.rb +112 -0
  35. data/lib/maze/assertions/request_set_assertions.rb +97 -0
  36. data/lib/maze/aws/sam.rb +112 -0
  37. data/lib/maze/bitbar_devices.rb +84 -0
  38. data/lib/maze/bitbar_utils.rb +112 -0
  39. data/lib/maze/browser_stack_devices.rb +160 -0
  40. data/lib/maze/browser_stack_utils.rb +164 -0
  41. data/lib/maze/browsers_bs.yml +220 -0
  42. data/lib/maze/browsers_cbt.yml +100 -0
  43. data/lib/maze/bugsnag_config.rb +42 -0
  44. data/lib/maze/capabilities.rb +126 -0
  45. data/lib/maze/checks/assert_check.rb +91 -0
  46. data/lib/maze/checks/noop_check.rb +34 -0
  47. data/lib/maze/compare.rb +161 -0
  48. data/lib/maze/configuration.rb +174 -0
  49. data/lib/maze/docker.rb +108 -0
  50. data/lib/maze/document_server.rb +46 -0
  51. data/lib/maze/driver/appium.rb +217 -0
  52. data/lib/maze/driver/browser.rb +138 -0
  53. data/lib/maze/driver/resilient_appium.rb +51 -0
  54. data/lib/maze/errors.rb +20 -0
  55. data/lib/maze/helper.rb +118 -0
  56. data/lib/maze/hooks/appium_hooks.rb +216 -0
  57. data/lib/maze/hooks/browser_hooks.rb +68 -0
  58. data/lib/maze/hooks/command_hooks.rb +9 -0
  59. data/lib/maze/hooks/hooks.rb +61 -0
  60. data/lib/maze/interactive_cli.rb +173 -0
  61. data/lib/maze/logger.rb +73 -0
  62. data/lib/maze/macos_utils.rb +14 -0
  63. data/lib/maze/network.rb +49 -0
  64. data/lib/maze/option/parser.rb +245 -0
  65. data/lib/maze/option/processor.rb +143 -0
  66. data/lib/maze/option/validator.rb +184 -0
  67. data/lib/maze/option.rb +64 -0
  68. data/lib/maze/plugins/bugsnag_reporting_plugin.rb +49 -0
  69. data/lib/maze/plugins/cucumber_report_plugin.rb +101 -0
  70. data/lib/maze/plugins/global_retry_plugin.rb +38 -0
  71. data/lib/maze/proxy.rb +114 -0
  72. data/lib/maze/request_list.rb +82 -0
  73. data/lib/maze/retry_handler.rb +76 -0
  74. data/lib/maze/runner.rb +149 -0
  75. data/lib/maze/sauce_labs_utils.rb +96 -0
  76. data/lib/maze/server.rb +207 -0
  77. data/lib/maze/servlets/base_servlet.rb +22 -0
  78. data/lib/maze/servlets/command_servlet.rb +44 -0
  79. data/lib/maze/servlets/log_servlet.rb +64 -0
  80. data/lib/maze/servlets/reflective_servlet.rb +69 -0
  81. data/lib/maze/servlets/servlet.rb +160 -0
  82. data/lib/maze/smart_bear_utils.rb +71 -0
  83. data/lib/maze/store.rb +15 -0
  84. data/lib/maze/terminating_server.rb +129 -0
  85. data/lib/maze/timers.rb +51 -0
  86. data/lib/maze/wait.rb +35 -0
  87. data/lib/maze.rb +27 -0
  88. metadata +371 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 508b197638d8f5af31b4018fecd9776cfa91071ba760c90ce6647cf720d0bfb0
4
+ data.tar.gz: 3f47abb96bfa76e64a569b06c58d13b229305405e74142da6b9709a5a655d27e
5
+ SHA512:
6
+ metadata.gz: 5ad71748e2a4ee9a83c65b1192ebd3a5cbfe6c7ee31ef63cdff5ea78674c130315946cd784004c8a0b0f0bfaf21fbf4e71c8277ca94b9a036bf88f7b36781538
7
+ data.tar.gz: bec09abd2c07c745d561a3ffc84653b07d792614a5070af2b7fbecc88f5f4a2b720e0bdae2a4e430d872a86885432e3552837b6f1542e92c9e0226949362ad7d
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ CUKE_LOAD_DIR = File.expand_path(File.dirname(File.dirname(__FILE__)))
4
+
5
+ paths = Dir.glob("#{CUKE_LOAD_DIR}/lib/features/**/*.rb")
6
+ print paths.join(" ")
data/bin/download-logs ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/maze'
5
+ require_relative '../lib/maze/browser_stack_utils'
6
+ require_relative '../lib/maze/logger'
7
+ require 'net/http'
8
+ require 'json'
9
+ require 'uri'
10
+ require 'optimist'
11
+ require 'fileutils'
12
+
13
+ class DownloadLogEntry
14
+ def start(args)
15
+ p = Optimist::Parser.new do
16
+ text 'Download device sessions logs from BrowserStack using the build ID'
17
+ text ''
18
+ text 'Requires BROWSER_STACK_USERNAME and BROWSER_STACK_ACCESS_KEY'
19
+ text ''
20
+ text 'Usage [OPTIONS] <filenames>'
21
+ text ''
22
+ opt :help,
23
+ 'Print this help.'
24
+ opt :build_id,
25
+ "ID of the BrowserStack build",
26
+ :type => :string
27
+ end
28
+
29
+ opts = Optimist::with_standard_exception_handling p do
30
+ raise Optimist::HelpNeeded if ARGV.empty? # show help screen
31
+ p.parse ARGV
32
+ end
33
+
34
+ # Get browserstack username and access key from the environment
35
+ username = ENV['BROWSER_STACK_USERNAME']
36
+ access_key = ENV['BROWSER_STACK_ACCESS_KEY']
37
+
38
+ # Check if BROWSER_STACK_USERNAME or BROWSER_STACK_ACCESS_KEY has been set
39
+ if username.nil? || access_key.nil?
40
+ $logger.warn "BROWSER_STACK_USERNAME or BROWSER_STACK_ACCESS_KEY has not been set"
41
+ Optimist::with_standard_exception_handling p do
42
+ raise Optimist::HelpNeeded
43
+ end
44
+ end
45
+
46
+
47
+ build_info = Maze::BrowserStackUtils.build_info username,
48
+ access_key,
49
+ opts[:build_id]
50
+
51
+ $logger.info "Getting logs for build: #{opts[:build_id]}"
52
+
53
+ build_info.each_with_index do |session, index|
54
+ $logger.info "Downloading Device Logs for Session: #{index + 1} to #{Dir.pwd}/maze_output"
55
+
56
+ log_name = "#{opts[:build_id]}-#{index + 1}"
57
+
58
+ Maze::BrowserStackUtils.download_log username,
59
+ access_key,
60
+ log_name,
61
+ session['automation_session']['device_logs_url'],
62
+ :device
63
+
64
+ $logger.info "Downloading Appium Logs for Session: #{index + 1}"
65
+ Maze::BrowserStackUtils.download_log username,
66
+ access_key,
67
+ log_name,
68
+ session['automation_session']['appium_logs_url'],
69
+ :appium
70
+
71
+
72
+ end
73
+ end
74
+ end
75
+
76
+ DownloadLogEntry.new.start(ARGV)
data/bin/maze-runner ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'cucumber/cli/main'
5
+
6
+ require_relative '../lib/maze'
7
+
8
+ require_relative '../lib/maze/appium_server'
9
+ require_relative '../lib/maze/bitbar_utils'
10
+ require_relative '../lib/maze/bitbar_devices'
11
+ require_relative '../lib/maze/browser_stack_devices'
12
+ require_relative '../lib/maze/browser_stack_utils'
13
+ require_relative '../lib/maze/bugsnag_config'
14
+ require_relative '../lib/maze/capabilities'
15
+ require_relative '../lib/maze/compare'
16
+ require_relative '../lib/maze/docker'
17
+ require_relative '../lib/maze/document_server'
18
+ require_relative '../lib/maze/errors'
19
+ require_relative '../lib/maze/helper'
20
+ require_relative '../lib/maze/logger'
21
+ require_relative '../lib/maze/macos_utils'
22
+ require_relative '../lib/maze/network'
23
+ require_relative '../lib/maze/proxy'
24
+ require_relative '../lib/maze/retry_handler'
25
+ require_relative '../lib/maze/runner'
26
+ require_relative '../lib/maze/sauce_labs_utils'
27
+ require_relative '../lib/maze/smart_bear_utils'
28
+ require_relative '../lib/maze/terminating_server'
29
+
30
+ require_relative '../lib/maze/servlets/base_servlet'
31
+ require_relative '../lib/maze/servlets/command_servlet'
32
+ require_relative '../lib/maze/servlets/servlet'
33
+ require_relative '../lib/maze/servlets/log_servlet'
34
+ require_relative '../lib/maze/servlets/reflective_servlet'
35
+ require_relative '../lib/maze/server'
36
+
37
+ require_relative '../lib/maze/store'
38
+ require_relative '../lib/maze/timers'
39
+
40
+ require_relative '../lib/maze/checks/noop_check'
41
+ require_relative '../lib/maze/checks/assert_check'
42
+
43
+ require_relative '../lib/maze/option'
44
+ require_relative '../lib/maze/option/parser'
45
+ require_relative '../lib/maze/option/processor'
46
+ require_relative '../lib/maze/option/validator'
47
+
48
+
49
+ require_relative '../lib/maze/assertions/request_set_assertions'
50
+
51
+ require_relative '../lib/maze/hooks/hooks'
52
+ require_relative '../lib/maze/hooks/appium_hooks'
53
+ require_relative '../lib/maze/hooks/browser_hooks'
54
+ require_relative '../lib/maze/hooks/command_hooks'
55
+
56
+ require_relative '../lib/maze/driver/appium'
57
+ require_relative '../lib/maze/driver/browser'
58
+ require_relative '../lib/maze/driver/resilient_appium'
59
+
60
+ require_relative '../lib/maze/plugins/bugsnag_reporting_plugin'
61
+ require_relative '../lib/maze/plugins/cucumber_report_plugin'
62
+ require_relative '../lib/maze/plugins/global_retry_plugin'
63
+
64
+ # Encapsulates the MazeRunner entry point
65
+ class MazeRunnerEntry
66
+
67
+ # Removes Maze Runner specific args from the array, as these will cause Cucumber to error.
68
+ def remove_maze_runner_args
69
+ Maze::Option.constants.each do |opt|
70
+ name = Maze::Option.const_get(opt)
71
+ @args.reject! { |arg| arg == "--#{name}" || (arg.start_with? "--#{name}=") || arg == "--no-#{name}" }
72
+ end
73
+ end
74
+
75
+ # Adds arguments to Cucumber
76
+ def add_cucumber_args
77
+ @args << 'features' if @args.empty?
78
+ @args << '--publish-quiet'
79
+ @args << '--color'
80
+
81
+ # Pass strict mode options through to cucumber if present
82
+ # If not we default to strict for undefined and pending results,
83
+ # but no-strict for flaky in order to allow retries
84
+ regex = /--(no-)?strict(-(undefined|pending|flaky))?/
85
+ if @args.all? { |arg| regex.match(arg).nil? }
86
+ @args << '--strict-undefined' << '--strict-pending' << '--no-strict-flaky'
87
+ end
88
+
89
+ # Load internal steps and helper functions
90
+ load_dir = File.expand_path(File.dirname(File.dirname(__FILE__))).freeze
91
+ paths = Dir.glob("#{load_dir}/lib/features/**/*.rb")
92
+
93
+ # Load project-specific steps and helper functions
94
+ paths += Dir.glob('features/{support,steps}/*.rb')
95
+ paths.each { |path| @args << '-r' << path }
96
+ end
97
+
98
+ # List devices for the given device farm, or all otherwise
99
+
100
+ def start(args)
101
+ $logger.info "Maze Runner v#{Maze::VERSION}"
102
+
103
+ # Parse args, processing any Maze Runner specific options
104
+ @args = args.dup
105
+ options = Maze::Option::Parser.parse args
106
+
107
+ if options[Maze::Option::LIST_DEVICES]
108
+ case options[Maze::Option::FARM]
109
+ when :bs
110
+ Maze::BrowserStackDevices.list_devices('ios')
111
+ Maze::BrowserStackDevices.list_devices('android')
112
+ else
113
+ Maze::BrowserStackDevices.list_devices('ios')
114
+ Maze::BrowserStackDevices.list_devices('android')
115
+ end
116
+ exit 0
117
+ end
118
+
119
+ # Validate CL options
120
+ errors = Maze::Option::Validator.new.validate options
121
+ unless errors.empty?
122
+ puts errors
123
+ exit 1
124
+ end
125
+
126
+ Maze::Option::Processor.populate Maze.config, options
127
+
128
+ # Adjust CL options before calling down to Cucumber
129
+ remove_maze_runner_args
130
+ add_cucumber_args
131
+
132
+ Cucumber::Cli::Main.new(@args).execute!
133
+ end
134
+ end
135
+
136
+ MazeRunnerEntry.new.start(ARGV)
data/bin/upload-app ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/maze'
5
+ require_relative '../lib/maze/browser_stack_utils'
6
+ require_relative '../lib/maze/logger'
7
+ require_relative '../lib/maze/helper'
8
+ require 'optimist'
9
+ require 'uri'
10
+ require 'net/http'
11
+
12
+ class UploadAppEntry
13
+ 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'
18
+ text ''
19
+ text 'Usage [OPTIONS]'
20
+ text ''
21
+ opt :help,
22
+ 'Print this help.'
23
+ opt :app,
24
+ 'The app to upload.',
25
+ :type => :string
26
+ opt :app_id_file,
27
+ 'The file to write the uploaded app ID back to',
28
+ :type => :string
29
+ end
30
+
31
+ opts = Optimist::with_standard_exception_handling p do
32
+ raise Optimist::HelpNeeded if ARGV.empty? # show help screen
33
+ p.parse ARGV
34
+ end
35
+
36
+ # Get browserstack username and access key from the environment
37
+ username = ENV['BROWSER_STACK_USERNAME']
38
+ access_key = ENV['BROWSER_STACK_ACCESS_KEY']
39
+
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
44
+ raise Optimist::HelpNeeded
45
+ end
46
+ end
47
+
48
+ Maze::BrowserStackUtils.upload_app username,
49
+ access_key,
50
+ opts[:app],
51
+ opts[:app_id_file]
52
+
53
+ end
54
+ end
55
+
56
+ UploadAppEntry.new.start(ARGV)
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Wait for device to finish booting
4
+ `adb wait-for-device`
5
+
6
+ while `adb shell getprop sys.boot_completed`.strip != "1"
7
+ puts "Awaiting boot completion..."
8
+ sleep 1
9
+ end
10
+
11
+ puts "Device Ready!"
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ -z "$APP_BUNDLE" ]; then
4
+ echo APP_BUNDLE environment variable is not set
5
+ exit 1
6
+ fi
7
+
8
+ adb shell pm clear $APP_BUNDLE
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ -z "$APP_BUNDLE" ]; then
4
+ echo APP_BUNDLE environment variable is not set
5
+ exit 1
6
+ fi
7
+
8
+ adb shell am force-stop $APP_BUNDLE
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ -z "$APP_BUNDLE" ]; then
4
+ echo APP_BUNDLE environment variable is not set
5
+ exit 1
6
+ fi
7
+ if [ -z "$APK_PATH" ]; then
8
+ echo APK_PATH environment variable is not set
9
+ exit 1
10
+ fi
11
+
12
+ echo "Uninstalling '$APP_BUNDLE'"
13
+ adb uninstall "$APP_BUNDLE"
14
+ echo "Installing '$APK_PATH'"
15
+ adb install "$APK_PATH"
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ -z "$APP_BUNDLE" ]; then
4
+ echo APP_BUNDLE environment variable is not set
5
+ exit 1
6
+ fi
7
+
8
+ if [ -z "$APP_ACTIVITY" ]; then
9
+ echo APP_ACTIVITY environment variable is not set
10
+ exit 1
11
+ fi
12
+
13
+ if [ -z "$EVENT_TYPE" ]; then
14
+ echo EVENT_TYPE environment variable is not set
15
+ exit 1
16
+ fi
17
+
18
+ if [ -z "$EVENT_METADATA" ]; then
19
+ EVENT_METADATA="none"
20
+ fi
21
+
22
+ if [ -z "$MOCK_API_PORT" ]; then
23
+ echo MOCK_API_PORT environment variable is not set
24
+ exit 1
25
+ fi
26
+
27
+ if [ -z "$BUGSNAG_API_KEY" ]; then
28
+ echo BUGSNAG_API_KEY environment variable is not set
29
+ exit 1
30
+ fi
31
+ echo "Launching MainActivity with '$EVENT_TYPE'"
32
+ adb shell am start -n "$APP_BUNDLE/$APP_ACTIVITY" \
33
+ --es EVENT_TYPE "$EVENT_TYPE" \
34
+ --es EVENT_METADATA "$EVENT_METADATA" \
35
+ --es BUGSNAG_PORT "$MOCK_API_PORT" \
36
+ --es BUGSNAG_API_KEY "$BUGSNAG_API_KEY"
37
+
38
+ echo "Ran Android Test case"
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [ -z "$ANDROID_EMULATOR" ]; then
4
+ echo EMULATOR environment variable is not set
5
+ exit 1
6
+ fi
7
+
8
+ if [ -z "$ANDROID_HOME" ]; then
9
+ echo ANDROID_HOME environment variable is not set
10
+ exit 1
11
+ fi
12
+
13
+ echo "Launching $ANDROID_EMULATOR emulator"
14
+ $ANDROID_HOME/emulator/emulator @$ANDROID_EMULATOR -no-boot-anim -noaudio -no-snapshot
15
+
@@ -0,0 +1,51 @@
1
+ # @!group Android steps
2
+
3
+ # Starts an Android emulator available within the local environment
4
+ #
5
+ # @step_input emulator [String] The name of the emulator to start
6
+ When("I start Android emulator {string}") do |emulator|
7
+ steps %Q{
8
+ When I set environment variable "ANDROID_EMULATOR" to "#{emulator}"
9
+ And I run the script "launch-android-emulator.sh"
10
+ And I run the script "await-android-emulator.sh" synchronously
11
+ }
12
+ end
13
+
14
+ # Synchronously clears the data for the test application
15
+ # Requires an ADB connection
16
+ When("I clear the Android app data") do
17
+ step('I run the script "clear-android-app-data.sh" synchronously')
18
+ end
19
+
20
+ # Force stops the test application
21
+ # Requires an ADB connection
22
+ When("I force stop the Android app") do
23
+ step('I run the script "force-stop-android-app.sh" synchronously')
24
+ end
25
+
26
+ # Installs a given bundle from an APK onto a device
27
+ # Requires an ADB connection
28
+ #
29
+ # @step_input bundle [String] The bundle to be installed
30
+ # @step_input filepath [String] The path to the application's .apk
31
+ When("I install the {string} Android app from {string}") do |bundle, filepath|
32
+ steps %Q{
33
+ When I set environment variable "APP_BUNDLE" to "#{bundle}"
34
+ And I set environment variable "APK_PATH" to "#{filepath}"
35
+ And I run the script "install-android-app.sh" synchronously
36
+ }
37
+ end
38
+
39
+ # Starts a specific activity for a given app
40
+ # Requires an ADB connection
41
+ #
42
+ # @step_input app [String] The application name
43
+ # @step_input activity [String] The activity to start
44
+ When("I start the {string} Android app using the {string} activity") do |app, activity|
45
+ steps %Q{
46
+ When I set environment variable "APP_BUNDLE" to "#{app}"
47
+ When I set environment variable "APP_ACTIVITY" to "#{activity}"
48
+ And I run the script "launch-android-app.sh" synchronously
49
+ And I wait for 4 seconds
50
+ }
51
+ end
@@ -0,0 +1,228 @@
1
+ # @!group App Automator steps
2
+
3
+ # Checks a UI element is present
4
+ # Requires a running Appium driver
5
+ #
6
+ # @step_input element_id [String] The locator id
7
+ Given('the element {string} is present') do |element_id|
8
+ present = Maze.driver.wait_for_element(element_id)
9
+ raise Maze::Error::AppiumElementNotFoundError.new("The element #{element_id} could not be found", element_id) unless present
10
+ end
11
+
12
+ # Checks a UI element is present within a specified number of seconds
13
+ # Requires a running Appium driver
14
+ #
15
+ # @step_input element_id [String] The locator id
16
+ # @step_input timeout [Int] The number of seconds to wait before timing out
17
+ Given('the element {string} is present within {int} seconds') do |element_id, timeout|
18
+ present = Maze.driver.wait_for_element(element_id, timeout)
19
+ raise Maze::Error::AppiumElementNotFoundError.new("The element #{element_id} could not be found", element_id) unless present
20
+ end
21
+
22
+ # Clicks a given element
23
+ # Requires a running Appium driver
24
+ #
25
+ # @step_input element_id [String] The locator id
26
+ When('I click the element {string}') do |element_id|
27
+ Maze.driver.click_element(element_id)
28
+ end
29
+
30
+ # Sends the app to the background indefinitely
31
+ # Requires a running Appium driver
32
+ When('I send the app to the background') do
33
+ Maze.driver.background_app(-1)
34
+ end
35
+
36
+ # Sends the app to the background for a number of seconds
37
+ # Requires a running Appium driver
38
+ #
39
+ # @step_input timeout [Integer] The amount of time the app is in the background in seconds
40
+ When('I send the app to the background for {int} second(s)') do |timeout|
41
+ Maze.driver.background_app(timeout)
42
+ end
43
+
44
+ # Clears a given element
45
+ # Requires a running Appium driver
46
+ #
47
+ # @step_input element_id [String] The locator id
48
+ When('I clear the element {string}') do |element_id|
49
+ Maze.driver.clear_element(element_id)
50
+ end
51
+
52
+ # Sends keys to a given element
53
+ # Requires a running Appium driver
54
+ #
55
+ # @step_input keys [String] The keys to send to the element
56
+ # @step_input element_id [String] The locator id
57
+ When('I send the keys {string} to the element {string}') do |keys, element_id|
58
+ Maze.driver.send_keys_to_element(element_id, keys)
59
+ end
60
+
61
+ # Tests that the given payload value is correct for the target BrowserStack platform.
62
+ # This step will assume the expected and payload values are strings.
63
+ # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
64
+ #
65
+ # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
66
+ # | android | Java.lang.RuntimeException |
67
+ # | ios | NSException |
68
+ #
69
+ # If the expected value is set to "@skip", the check should be skipped
70
+ # If the expected value is set to "@null", the check will be for null
71
+ # If the expected value is set to "@not_null", the check will be for a non-null value
72
+ #
73
+ # @step_input request_type [String] The type of request (error, session, build, etc)
74
+ # @step_input field_path [String] The field to test
75
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
76
+ Then('the {word} payload field {string} equals the platform-dependent string:') do |request_type, field_path, platform_values|
77
+ test_string_platform_values(request_type, field_path, platform_values)
78
+ end
79
+
80
+ # See `the error payload field {string} equals the platform-dependent string:`
81
+ #
82
+ # @step_input field_path [String] The field to test, prepended with "events.0"
83
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
84
+ Then('the event {string} equals the platform-dependent string:') do |field_path, platform_values|
85
+ test_string_platform_values('error', "events.0.#{field_path}", platform_values)
86
+ end
87
+
88
+ # Tests that the given payload value is correct for the target BrowserStack platform.
89
+ # This step will assume the expected and payload values are numeric.
90
+ # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
91
+ #
92
+ # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
93
+ # | android | 1 |
94
+ # | ios | 5.5 |
95
+ #
96
+ # If the expected value is set to "@skip", the check should be skipped
97
+ # If the expected value is set to "@null", the check will be for null
98
+ # If the expected value is set to "@not_null", the check will be for a non-null value
99
+ #
100
+ # @step_input request_type [String] The type of request (error, session, build, etc)
101
+ # @step_input field_path [String] The field to test
102
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
103
+ Then('the {word} payload field {string} equals the platform-dependent numeric:') do |request_type, field_path, platform_values|
104
+ test_numeric_platform_values(request_type, field_path, platform_values)
105
+ end
106
+
107
+ # See `the payload field {string} equals the platform-dependent numeric:`
108
+ #
109
+ # @step_input field_path [String] The field to test, prepended with "events.0"
110
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
111
+ Then('the event {string} equals the platform-dependent numeric:') do |field_path, platform_values|
112
+ test_numeric_platform_values('error', "events.0.#{field_path}", platform_values)
113
+ end
114
+
115
+ # Tests that the given payload value is correct for the target BrowserStack platform.
116
+ # This step will assume the expected and payload values are booleans.
117
+ # If the step is invoked when a remote BrowserStack device is not in use this step will fail.
118
+ #
119
+ # The DataTable used for this step should have `ios` and `android` in the same row as their expected value:
120
+ # | android | 1 |
121
+ # | ios | 5 |
122
+ #
123
+ # If the expected value is set to "@skip", the check should be skipped
124
+ # If the expected value is set to "@null", the check will be for null
125
+ # If the expected value is set to "@not_null", the check will be for a non-null value
126
+ #
127
+ # @step_input request_type [String] The type of request (error, session, build, etc)
128
+ # @step_input field_path [String] The field to test
129
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
130
+ Then('the {word} payload field {string} equals the platform-dependent boolean:') do |request_type, field_path, platform_values|
131
+ test_boolean_platform_values(request_type, field_path, platform_values)
132
+ end
133
+
134
+ # See `the payload field {string} equals the platform-dependent boolean:`
135
+ #
136
+ # @step_input field_path [String] The field to test, prepended with "events.0"
137
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
138
+ Then('the event {string} equals the platform-dependent boolean:') do |field_path, platform_values|
139
+ test_boolean_platform_values('error', "events.0.#{field_path}", platform_values)
140
+ end
141
+
142
+ # See `the payload field {string} equals the platform-dependent string:`
143
+ #
144
+ # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0."
145
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
146
+ Then('the exception {string} equals the platform-dependent string:') do |field_path, platform_values|
147
+ test_string_platform_values('error', "events.0.exceptions.0.#{field_path}", platform_values)
148
+ end
149
+
150
+ # See `the payload field {string} equals the platform-dependent string:`
151
+ #
152
+ # @step_input field_path [String] The field to test, prepended with "events.0.exceptions.0.stacktrace.#!{num}"
153
+ # @step_input num [Integer] The index of the stack frame to test
154
+ # @step_input platform_values [DataTable] A table of acceptable values for each platform
155
+ Then('the {string} of stack frame {int} equals the platform-dependent string:') do |field_path, num, platform_values|
156
+ test_string_platform_values('error', "events.0.exceptions.0.stacktrace.#{num}.#{field_path}", platform_values)
157
+ end
158
+
159
+ # Sends keys to a given element, clearing it first
160
+ # Requires a running Appium driver
161
+ #
162
+ # @step_input keys [String] The keys to send to the element
163
+ # @step_input element_id [String] The locator id
164
+ When('I clear and send the keys {string} to the element {string}') do |keys, element_id|
165
+ Maze.driver.clear_and_send_keys_to_element(element_id, keys)
166
+ end
167
+
168
+ def get_expected_platform_value(platform_values)
169
+ os = Maze::Helper.get_current_platform
170
+ expected_value = Hash[platform_values.raw][os.downcase]
171
+ raise("There is no expected value for the current platform \"#{os}\"") if expected_value.nil?
172
+
173
+ expected_value
174
+ end
175
+
176
+ def should_skip_platform_check(expected_value)
177
+ expected_value.eql?('@skip')
178
+ end
179
+
180
+ def test_string_platform_values(request_type, field_path, platform_values)
181
+ expected_value = get_expected_platform_value(platform_values)
182
+ return if should_skip_platform_check(expected_value)
183
+
184
+ list = Maze::Server.list_for(request_type)
185
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
186
+ assert_equal_with_nullability(expected_value, payload_value)
187
+ end
188
+
189
+ def test_boolean_platform_values(request_type, field_path, platform_values)
190
+ expected_value = get_expected_platform_value(platform_values)
191
+ return if should_skip_platform_check(expected_value)
192
+
193
+ expected_bool = case expected_value.downcase
194
+ when 'true'
195
+ true
196
+ when 'false'
197
+ false
198
+ else
199
+ expected_value
200
+ end
201
+ list = Maze::Server.list_for(request_type)
202
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
203
+ assert_equal_with_nullability(expected_bool, payload_value)
204
+ end
205
+
206
+ def test_numeric_platform_values(request_type, field_path, platform_values)
207
+ expected_value = get_expected_platform_value(platform_values)
208
+ return if should_skip_platform_check(expected_value)
209
+
210
+ list = Maze::Server.list_for(request_type)
211
+ payload_value = Maze::Helper.read_key_path(list.current[:body], field_path)
212
+
213
+ # Need to do a little more processing here to allow floats
214
+ special_value = expected_value.eql?('@null') || expected_value.eql?('@not_null')
215
+ expectation = special_value ? expected_value : expected_value.to_f
216
+ assert_equal_with_nullability(expectation, payload_value)
217
+ end
218
+
219
+ def assert_equal_with_nullability(expected_value, payload_value)
220
+ case expected_value
221
+ when '@null'
222
+ Maze.check.nil(payload_value)
223
+ when '@not_null'
224
+ Maze.check.not_nil(payload_value)
225
+ else
226
+ Maze.check.equal(expected_value, payload_value)
227
+ end
228
+ end