bugsnag-maze-runner 6.27.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/bugsnag-print-load-paths +6 -0
- data/bin/download-logs +76 -0
- data/bin/maze-runner +136 -0
- data/bin/upload-app +56 -0
- data/lib/features/scripts/await-android-emulator.sh +11 -0
- data/lib/features/scripts/clear-android-app-data.sh +8 -0
- data/lib/features/scripts/force-stop-android-app.sh +8 -0
- data/lib/features/scripts/install-android-app.sh +15 -0
- data/lib/features/scripts/launch-android-app.sh +38 -0
- data/lib/features/scripts/launch-android-emulator.sh +15 -0
- data/lib/features/steps/android_steps.rb +51 -0
- data/lib/features/steps/app_automator_steps.rb +228 -0
- data/lib/features/steps/aws_sam_steps.rb +212 -0
- data/lib/features/steps/breadcrumb_steps.rb +50 -0
- data/lib/features/steps/browser_steps.rb +93 -0
- data/lib/features/steps/build_api_steps.rb +25 -0
- data/lib/features/steps/document_server_steps.rb +7 -0
- data/lib/features/steps/error_reporting_steps.rb +342 -0
- data/lib/features/steps/feature_flag_steps.rb +190 -0
- data/lib/features/steps/header_steps.rb +72 -0
- data/lib/features/steps/log_steps.rb +29 -0
- data/lib/features/steps/multipart_request_steps.rb +142 -0
- data/lib/features/steps/network_steps.rb +75 -0
- data/lib/features/steps/payload_steps.rb +234 -0
- data/lib/features/steps/proxy_steps.rb +34 -0
- data/lib/features/steps/query_parameter_steps.rb +31 -0
- data/lib/features/steps/request_assertion_steps.rb +107 -0
- data/lib/features/steps/runner_steps.rb +406 -0
- data/lib/features/steps/session_tracking_steps.rb +116 -0
- data/lib/features/steps/value_steps.rb +119 -0
- data/lib/features/support/env.rb +7 -0
- data/lib/features/support/internal_hooks.rb +260 -0
- data/lib/maze/appium_server.rb +112 -0
- data/lib/maze/assertions/request_set_assertions.rb +97 -0
- data/lib/maze/aws/sam.rb +112 -0
- data/lib/maze/bitbar_devices.rb +84 -0
- data/lib/maze/bitbar_utils.rb +112 -0
- data/lib/maze/browser_stack_devices.rb +160 -0
- data/lib/maze/browser_stack_utils.rb +164 -0
- data/lib/maze/browsers_bs.yml +220 -0
- data/lib/maze/browsers_cbt.yml +100 -0
- data/lib/maze/bugsnag_config.rb +42 -0
- data/lib/maze/capabilities.rb +126 -0
- data/lib/maze/checks/assert_check.rb +91 -0
- data/lib/maze/checks/noop_check.rb +34 -0
- data/lib/maze/compare.rb +161 -0
- data/lib/maze/configuration.rb +174 -0
- data/lib/maze/docker.rb +108 -0
- data/lib/maze/document_server.rb +46 -0
- data/lib/maze/driver/appium.rb +217 -0
- data/lib/maze/driver/browser.rb +138 -0
- data/lib/maze/driver/resilient_appium.rb +51 -0
- data/lib/maze/errors.rb +20 -0
- data/lib/maze/helper.rb +118 -0
- data/lib/maze/hooks/appium_hooks.rb +216 -0
- data/lib/maze/hooks/browser_hooks.rb +68 -0
- data/lib/maze/hooks/command_hooks.rb +9 -0
- data/lib/maze/hooks/hooks.rb +61 -0
- data/lib/maze/interactive_cli.rb +173 -0
- data/lib/maze/logger.rb +73 -0
- data/lib/maze/macos_utils.rb +14 -0
- data/lib/maze/network.rb +49 -0
- data/lib/maze/option/parser.rb +245 -0
- data/lib/maze/option/processor.rb +143 -0
- data/lib/maze/option/validator.rb +184 -0
- data/lib/maze/option.rb +64 -0
- data/lib/maze/plugins/bugsnag_reporting_plugin.rb +49 -0
- data/lib/maze/plugins/cucumber_report_plugin.rb +101 -0
- data/lib/maze/plugins/global_retry_plugin.rb +38 -0
- data/lib/maze/proxy.rb +114 -0
- data/lib/maze/request_list.rb +82 -0
- data/lib/maze/retry_handler.rb +76 -0
- data/lib/maze/runner.rb +149 -0
- data/lib/maze/sauce_labs_utils.rb +96 -0
- data/lib/maze/server.rb +207 -0
- data/lib/maze/servlets/base_servlet.rb +22 -0
- data/lib/maze/servlets/command_servlet.rb +44 -0
- data/lib/maze/servlets/log_servlet.rb +64 -0
- data/lib/maze/servlets/reflective_servlet.rb +69 -0
- data/lib/maze/servlets/servlet.rb +160 -0
- data/lib/maze/smart_bear_utils.rb +71 -0
- data/lib/maze/store.rb +15 -0
- data/lib/maze/terminating_server.rb +129 -0
- data/lib/maze/timers.rb +51 -0
- data/lib/maze/wait.rb +35 -0
- data/lib/maze.rb +27 -0
- 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
|
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,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
|