fastlane 2.133.0 → 2.136.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 +4 -4
- data/README.md +78 -78
- data/fastlane/lib/fastlane/action.rb +1 -1
- data/fastlane/lib/fastlane/actions/actions_helper.rb +1 -1
- data/fastlane/lib/fastlane/actions/carthage.rb +7 -0
- data/fastlane/lib/fastlane/actions/cocoapods.rb +24 -2
- data/fastlane/lib/fastlane/actions/deploygate.rb +1 -1
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +38 -4
- data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +4 -2
- data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +26 -2
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +26 -3
- data/fastlane/lib/fastlane/actions/download_from_play_store.rb +1 -1
- data/fastlane/lib/fastlane/actions/get_version_number.rb +10 -4
- data/fastlane/lib/fastlane/actions/google_play_track_version_codes.rb +5 -1
- data/fastlane/lib/fastlane/actions/sonar.rb +16 -0
- data/fastlane/lib/fastlane/actions/testfairy.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_fastlane.rb +9 -49
- data/fastlane/lib/fastlane/actions/update_keychain_access_groups.rb +94 -0
- data/fastlane/lib/fastlane/environment_printer.rb +9 -3
- data/fastlane/lib/fastlane/fast_file.rb +3 -2
- data/fastlane/lib/fastlane/lane_manager.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +12 -2
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
- data/fastlane/lib/fastlane/runner.rb +2 -2
- data/fastlane/lib/fastlane/swift_fastlane_function.rb +9 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/Fastlane.swift +124 -36
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +2 -2
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +22 -2
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +3 -3
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +1 -1
- data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
- data/fastlane_core/lib/fastlane_core/swag.rb +1 -1
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +1 -1
- data/match/lib/match/importer.rb +1 -1
- data/scan/lib/scan/error_handler.rb +9 -4
- data/scan/lib/scan/runner.rb +1 -1
- data/screengrab/lib/screengrab/module.rb +2 -0
- data/screengrab/lib/screengrab/options.rb +33 -11
- data/screengrab/lib/screengrab/runner.rb +64 -24
- data/sigh/lib/assets/resign.sh +2 -2
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
- data/spaceship/lib/spaceship/client.rb +2 -2
- data/supply/lib/supply.rb +23 -0
- data/supply/lib/supply/.uploader.rb.swp +0 -0
- data/supply/lib/supply/client.rb +101 -55
- data/supply/lib/supply/options.rb +50 -14
- data/supply/lib/supply/release_listing.rb +18 -0
- data/supply/lib/supply/setup.rb +42 -34
- data/supply/lib/supply/uploader.rb +191 -93
- metadata +32 -37
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/gym/lib/gym/.runner.rb.swp +0 -0
- data/pilot/lib/pilot/.manager.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
@@ -91,7 +91,7 @@ protocol MatchfileProtocol: class {
|
|
91
91
|
extension MatchfileProtocol {
|
92
92
|
var type: String { return "development" }
|
93
93
|
var readonly: Bool { return false }
|
94
|
-
var generateAppleCerts: Bool { return
|
94
|
+
var generateAppleCerts: Bool { return false }
|
95
95
|
var skipProvisioningProfiles: Bool { return false }
|
96
96
|
var appIdentifier: [String] { return [] }
|
97
97
|
var username: String { return "" }
|
@@ -122,4 +122,4 @@ extension MatchfileProtocol {
|
|
122
122
|
|
123
123
|
// Please don't remove the lines below
|
124
124
|
// They are used to detect outdated files
|
125
|
-
// FastlaneRunnerAPIVersion [0.9.
|
125
|
+
// FastlaneRunnerAPIVersion [0.9.10]
|
@@ -39,6 +39,9 @@ protocol ScreengrabfileProtocol: class {
|
|
39
39
|
/// Return the device to this locale after running tests
|
40
40
|
var endingLocale: String { get }
|
41
41
|
|
42
|
+
/// Restarts the adb daemon using `adb root` to allow access to screenshots directories on device. Use if getting 'Permission denied' errors
|
43
|
+
var useAdbRoot: Bool { get }
|
44
|
+
|
42
45
|
/// The path to the APK for the app under test
|
43
46
|
var appApkPath: String? { get }
|
44
47
|
|
@@ -56,6 +59,18 @@ protocol ScreengrabfileProtocol: class {
|
|
56
59
|
|
57
60
|
/// Enabling this option will automatically uninstall the application before running it
|
58
61
|
var reinstallApp: Bool { get }
|
62
|
+
|
63
|
+
/// Add timestamp suffix to screenshot filename
|
64
|
+
var useTimestampSuffix: Bool { get }
|
65
|
+
|
66
|
+
/// Configure the host used by adb to connect, allows running on remote devices farm
|
67
|
+
var adbHost: String? { get }
|
68
|
+
|
69
|
+
/// Enabling this option will clean the status bar
|
70
|
+
var cleanStatusBar: Bool { get }
|
71
|
+
|
72
|
+
/// Specifies the configuration for the clean status bar
|
73
|
+
var cleanStatusBarConfig: [String : Any] { get }
|
59
74
|
}
|
60
75
|
|
61
76
|
extension ScreengrabfileProtocol {
|
@@ -70,16 +85,21 @@ extension ScreengrabfileProtocol {
|
|
70
85
|
var useTestsInPackages: [String]? { return nil }
|
71
86
|
var useTestsInClasses: [String]? { return nil }
|
72
87
|
var launchArguments: [String]? { return nil }
|
73
|
-
var testInstrumentationRunner: String { return "
|
88
|
+
var testInstrumentationRunner: String { return "androidx.test.runner.AndroidJUnitRunner" }
|
74
89
|
var endingLocale: String { return "en-US" }
|
90
|
+
var useAdbRoot: Bool { return false }
|
75
91
|
var appApkPath: String? { return nil }
|
76
92
|
var testsApkPath: String? { return nil }
|
77
93
|
var specificDevice: String? { return nil }
|
78
94
|
var deviceType: String { return "phone" }
|
79
95
|
var exitOnTestFailure: Bool { return true }
|
80
96
|
var reinstallApp: Bool { return false }
|
97
|
+
var useTimestampSuffix: Bool { return true }
|
98
|
+
var adbHost: String? { return nil }
|
99
|
+
var cleanStatusBar: Bool { return false }
|
100
|
+
var cleanStatusBarConfig: [String : Any] { return [:] }
|
81
101
|
}
|
82
102
|
|
83
103
|
// Please don't remove the lines below
|
84
104
|
// They are used to detect outdated files
|
85
|
-
// FastlaneRunnerAPIVersion [0.9.
|
105
|
+
// FastlaneRunnerAPIVersion [0.9.12]
|
@@ -93,9 +93,9 @@ module FastlaneCore
|
|
93
93
|
return if short_switch.nil?
|
94
94
|
|
95
95
|
UI.user_error!("Short option #{short_switch} already taken for key #{key}") if used_switches.include?(short_switch)
|
96
|
-
UI.user_error!("-v is already used for the version (key #{key})") if short_switch == "-v"
|
97
|
-
UI.user_error!("-h is already used for the help screen (key #{key})") if short_switch == "-h"
|
98
|
-
UI.user_error!("-t is already used for the trace screen (key #{key})") if short_switch == "-t"
|
96
|
+
UI.user_error!("-v is already used for the fastlane version (key #{key})") if short_switch == "-v"
|
97
|
+
UI.user_error!("-h is already used for the fastlane help screen (key #{key})") if short_switch == "-h"
|
98
|
+
UI.user_error!("-t is already used for the fastlane trace screen (key #{key})") if short_switch == "-t"
|
99
99
|
|
100
100
|
used_switches << short_switch
|
101
101
|
end
|
@@ -120,7 +120,7 @@ module FastlaneCore
|
|
120
120
|
index = @available_options.find_index { |item| item.key == conflicting_option_key }
|
121
121
|
conflicting_option = @available_options[index]
|
122
122
|
|
123
|
-
# ignore conflicts because
|
123
|
+
# ignore conflicts because value of conflict option is nil
|
124
124
|
next if @values[conflicting_option.key].nil?
|
125
125
|
|
126
126
|
if current.conflict_block
|
@@ -307,7 +307,7 @@ module FastlaneCore
|
|
307
307
|
logarchive_dst = File.join(logs_destination_dir, "system_logs-#{log_identity}.logarchive").shellescape
|
308
308
|
FileUtils.rm_rf(logarchive_dst)
|
309
309
|
FileUtils.mkdir_p(File.expand_path("..", logarchive_dst))
|
310
|
-
command = "xcrun simctl spawn #{device.udid} log collect --output #{logarchive_dst} 2>/dev/null"
|
310
|
+
command = "xcrun simctl spawn --standalone #{device.udid} log collect --output #{logarchive_dst} 2>/dev/null"
|
311
311
|
FastlaneCore::CommandExecutor.execute(command: command, print_all: false, print_command: true)
|
312
312
|
end
|
313
313
|
end
|
@@ -45,7 +45,7 @@ module FastlaneCore
|
|
45
45
|
|
46
46
|
def self.show_loader
|
47
47
|
return unless should_be_shown?
|
48
|
-
# sound is disabled as
|
48
|
+
# sound is disabled as I didn't find a royality free nice midi :(
|
49
49
|
@output = StringIO.new
|
50
50
|
# if FastlaneCore::Env.truthy?("FL_DO_SOUND")
|
51
51
|
# @sound_thr = Thread.new do
|
@@ -117,7 +117,7 @@ module Commander
|
|
117
117
|
abort(e.to_s)
|
118
118
|
end
|
119
119
|
end
|
120
|
-
rescue FastlaneCore::Interface::FastlaneCommonException => e # these are exceptions that we
|
120
|
+
rescue FastlaneCore::Interface::FastlaneCommonException => e # these are exceptions that we don't count as crashes
|
121
121
|
display_user_error!(e, e.to_s)
|
122
122
|
rescue FastlaneCore::Interface::FastlaneError => e # user_error!
|
123
123
|
rescue_fastlane_error(e)
|
data/match/lib/match/importer.rb
CHANGED
@@ -17,7 +17,7 @@ module Match
|
|
17
17
|
UI.user_error!("Certificate does not exist at path: #{cert_path}") unless File.exist?(cert_path)
|
18
18
|
UI.user_error!("Private key does not exist at path: #{p12_path}") unless File.exist?(p12_path)
|
19
19
|
|
20
|
-
# Base64
|
20
|
+
# Base64 encode contents to find match from API to find a cert ID
|
21
21
|
cert_contents_base_64 = Base64.strict_encode64(File.open(cert_path).read)
|
22
22
|
|
23
23
|
# Storage
|
@@ -6,8 +6,13 @@ module Scan
|
|
6
6
|
class << self
|
7
7
|
# @param [String] The output of the errored build
|
8
8
|
# This method should raise an exception in any case, as the return code indicated a failed build
|
9
|
-
def handle_build_error(output)
|
10
|
-
# The order of the handling below is
|
9
|
+
def handle_build_error(output, log_path)
|
10
|
+
# The order of the handling below is important
|
11
|
+
|
12
|
+
instruction = 'See the log'
|
13
|
+
location = Scan.config[:suppress_xcode_output] ? "here: '#{log_path}'" : "above"
|
14
|
+
details = "#{instruction} #{location}."
|
15
|
+
|
11
16
|
case output
|
12
17
|
when /US\-ASCII/
|
13
18
|
print("Your shell environment is not correctly configured")
|
@@ -23,7 +28,7 @@ module Scan
|
|
23
28
|
print("For more information visit this stackoverflow answer:")
|
24
29
|
print("https://stackoverflow.com/a/17031697/445598")
|
25
30
|
when /Testing failed/
|
26
|
-
UI.build_failure!("Error building the application
|
31
|
+
UI.build_failure!("Error building the application. #{details}")
|
27
32
|
when /Executed/, /Failing tests:/
|
28
33
|
# this is *really* important:
|
29
34
|
# we don't want to raise an exception here
|
@@ -38,7 +43,7 @@ module Scan
|
|
38
43
|
# followed by a list of tests that failed.
|
39
44
|
return
|
40
45
|
end
|
41
|
-
UI.build_failure!("Error building/testing the application
|
46
|
+
UI.build_failure!("Error building/testing the application. #{details}")
|
42
47
|
end
|
43
48
|
|
44
49
|
private
|
data/scan/lib/scan/runner.rb
CHANGED
@@ -67,7 +67,7 @@ module Scan
|
|
67
67
|
error: proc do |error_output|
|
68
68
|
begin
|
69
69
|
exit_status = $?.exitstatus
|
70
|
-
ErrorHandler.handle_build_error(error_output)
|
70
|
+
ErrorHandler.handle_build_error(error_output, @test_command_generator.xcodebuild_log_path)
|
71
71
|
rescue => ex
|
72
72
|
SlackPoster.new.run({
|
73
73
|
build_errors: 1
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fastlane_core/helper'
|
2
|
+
require 'fastlane/boolean'
|
2
3
|
require_relative 'detect_values'
|
3
4
|
|
4
5
|
module Screengrab
|
@@ -19,6 +20,7 @@ module Screengrab
|
|
19
20
|
|
20
21
|
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
21
22
|
UI = FastlaneCore::UI
|
23
|
+
Boolean = Fastlane::Boolean
|
22
24
|
ROOT = Pathname.new(File.expand_path('../../..', __FILE__))
|
23
25
|
DESCRIPTION = "Automated localized screenshots of your Android app on every device".freeze
|
24
26
|
end
|
@@ -32,7 +32,7 @@ module Screengrab
|
|
32
32
|
env_name: 'SCREENGRAB_CLEAR_PREVIOUS_SCREENSHOTS',
|
33
33
|
description: "Enabling this option will automatically clear previously generated screenshots before running screengrab",
|
34
34
|
default_value: false,
|
35
|
-
|
35
|
+
type: Boolean),
|
36
36
|
FastlaneCore::ConfigItem.new(key: :output_directory,
|
37
37
|
short_option: "-o",
|
38
38
|
env_name: "SCREENGRAB_OUTPUT_DIRECTORY",
|
@@ -43,7 +43,7 @@ module Screengrab
|
|
43
43
|
description: "Don't open the summary after running _screengrab_",
|
44
44
|
default_value: DEFAULT_SKIP_OPEN_SUMMARY,
|
45
45
|
default_value_dynamic: true,
|
46
|
-
|
46
|
+
type: Boolean),
|
47
47
|
FastlaneCore::ConfigItem.new(key: :app_package_name,
|
48
48
|
env_name: 'SCREENGRAB_APP_PACKAGE_NAME',
|
49
49
|
short_option: "-a",
|
@@ -68,22 +68,26 @@ module Screengrab
|
|
68
68
|
type: Array,
|
69
69
|
description: "Only run tests in these Java classes"),
|
70
70
|
FastlaneCore::ConfigItem.new(key: :launch_arguments,
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
env_name: 'SCREENGRAB_LAUNCH_ARGUMENTS',
|
72
|
+
optional: true,
|
73
|
+
short_option: "-e",
|
74
|
+
type: Array,
|
75
|
+
description: "Additional launch arguments"),
|
76
76
|
FastlaneCore::ConfigItem.new(key: :test_instrumentation_runner,
|
77
77
|
env_name: 'SCREENGRAB_TEST_INSTRUMENTATION_RUNNER',
|
78
78
|
optional: true,
|
79
|
-
default_value: '
|
79
|
+
default_value: 'androidx.test.runner.AndroidJUnitRunner',
|
80
80
|
description: "The fully qualified class name of your test instrumentation runner"),
|
81
81
|
FastlaneCore::ConfigItem.new(key: :ending_locale,
|
82
82
|
env_name: 'SCREENGRAB_ENDING_LOCALE',
|
83
83
|
optional: true,
|
84
|
-
is_string: true,
|
85
84
|
default_value: 'en-US',
|
86
85
|
description: "Return the device to this locale after running tests"),
|
86
|
+
FastlaneCore::ConfigItem.new(key: :use_adb_root,
|
87
|
+
env_name: 'SCREENGRAB_USE_ADB_ROOT',
|
88
|
+
description: "Restarts the adb daemon using `adb root` to allow access to screenshots directories on device. Use if getting 'Permission denied' errors",
|
89
|
+
default_value: false,
|
90
|
+
type: Boolean),
|
87
91
|
FastlaneCore::ConfigItem.new(key: :app_apk_path,
|
88
92
|
env_name: 'SCREENGRAB_APP_APK_PATH',
|
89
93
|
optional: true,
|
@@ -123,12 +127,30 @@ module Screengrab
|
|
123
127
|
env_name: 'EXIT_ON_TEST_FAILURE',
|
124
128
|
description: "Whether or not to exit Screengrab on test failure. Exiting on failure will not copy sceenshots to local machine nor open sceenshots summary",
|
125
129
|
default_value: true,
|
126
|
-
|
130
|
+
type: Boolean),
|
127
131
|
FastlaneCore::ConfigItem.new(key: :reinstall_app,
|
128
132
|
env_name: 'SCREENGRAB_REINSTALL_APP',
|
129
133
|
description: "Enabling this option will automatically uninstall the application before running it",
|
130
134
|
default_value: false,
|
131
|
-
|
135
|
+
type: Boolean),
|
136
|
+
FastlaneCore::ConfigItem.new(key: :use_timestamp_suffix,
|
137
|
+
env_name: 'SCREENGRAB_USE_TIMESTAMP_SUFFIX',
|
138
|
+
description: "Add timestamp suffix to screenshot filename",
|
139
|
+
default_value: true,
|
140
|
+
type: Boolean),
|
141
|
+
FastlaneCore::ConfigItem.new(key: :adb_host,
|
142
|
+
env_name: 'SCREENGRAB_ADB_HOST',
|
143
|
+
description: "Configure the host used by adb to connect, allows running on remote devices farm",
|
144
|
+
optional: true),
|
145
|
+
FastlaneCore::ConfigItem.new(key: :clean_status_bar,
|
146
|
+
env_name: 'SCREENGRAB_CLEAN_STATUS_BAR',
|
147
|
+
description: "Enabling this option will clean the status bar",
|
148
|
+
default_value: false,
|
149
|
+
type: Boolean),
|
150
|
+
FastlaneCore::ConfigItem.new(key: :clean_status_bar_config,
|
151
|
+
description: "Specifies the configuration for the clean status bar",
|
152
|
+
default_value: {},
|
153
|
+
type: Hash)
|
132
154
|
]
|
133
155
|
end
|
134
156
|
end
|
@@ -57,8 +57,13 @@ module Screengrab
|
|
57
57
|
|
58
58
|
device_screenshots_paths = [
|
59
59
|
determine_external_screenshots_path(device_serial),
|
60
|
-
|
61
|
-
]
|
60
|
+
determine_internal_screenshots_paths(@config[:app_package_name], @config[:locales])
|
61
|
+
].flatten
|
62
|
+
|
63
|
+
# Root is needed to access device paths at /data
|
64
|
+
if @config[:use_adb_root]
|
65
|
+
run_adb_command("root", print_all: false, print_command: true)
|
66
|
+
end
|
62
67
|
|
63
68
|
clear_device_previous_screenshots(device_serial, device_screenshots_paths)
|
64
69
|
|
@@ -67,6 +72,8 @@ module Screengrab
|
|
67
72
|
|
68
73
|
validate_apk(app_apk_path)
|
69
74
|
|
75
|
+
enable_clean_status_bar(device_serial, app_apk_path)
|
76
|
+
|
70
77
|
run_tests(device_serial, app_apk_path, tests_apk_path, test_classes_to_use, test_packages_to_use, @config[:launch_arguments])
|
71
78
|
|
72
79
|
number_of_screenshots = pull_screenshots_from_device(device_serial, device_screenshots_paths, device_type_dir_name)
|
@@ -77,7 +84,7 @@ module Screengrab
|
|
77
84
|
end
|
78
85
|
|
79
86
|
def select_device
|
80
|
-
devices = run_adb_command("
|
87
|
+
devices = run_adb_command("devices -l", print_all: true, print_command: true).split("\n")
|
81
88
|
# the first output by adb devices is "List of devices attached" so remove that and any adb startup output
|
82
89
|
devices.reject! do |device|
|
83
90
|
[
|
@@ -139,15 +146,19 @@ module Screengrab
|
|
139
146
|
# macOS evaluates $foo in `echo $foo` before executing the command,
|
140
147
|
# Windows doesn't - hence the double backslash vs. single backslash
|
141
148
|
command = Helper.windows? ? "shell echo \$EXTERNAL_STORAGE " : "shell echo \\$EXTERNAL_STORAGE"
|
142
|
-
device_ext_storage = run_adb_command("
|
149
|
+
device_ext_storage = run_adb_command("-s #{device_serial} #{command}",
|
143
150
|
print_all: true,
|
144
151
|
print_command: true)
|
145
152
|
device_ext_storage = device_ext_storage.strip
|
146
153
|
File.join(device_ext_storage, @config[:app_package_name], 'screengrab')
|
147
154
|
end
|
148
155
|
|
149
|
-
def
|
150
|
-
|
156
|
+
def determine_internal_screenshots_paths(app_package_name, locales)
|
157
|
+
locale_paths = locales.map do |locale|
|
158
|
+
"/data/user/0/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots"
|
159
|
+
end
|
160
|
+
|
161
|
+
return ["/data/data/#{app_package_name}/app_screengrab"] + locale_paths
|
151
162
|
end
|
152
163
|
|
153
164
|
def clear_device_previous_screenshots(device_serial, device_screenshots_paths)
|
@@ -155,7 +166,7 @@ module Screengrab
|
|
155
166
|
|
156
167
|
device_screenshots_paths.each do |device_path|
|
157
168
|
if_device_path_exists(device_serial, device_path) do |path|
|
158
|
-
run_adb_command("
|
169
|
+
run_adb_command("-s #{device_serial} shell rm -rf #{path}",
|
159
170
|
print_all: true,
|
160
171
|
print_command: true)
|
161
172
|
end
|
@@ -182,13 +193,13 @@ module Screengrab
|
|
182
193
|
|
183
194
|
def install_apks(device_serial, app_apk_path, tests_apk_path)
|
184
195
|
UI.message('Installing app APK')
|
185
|
-
apk_install_output = run_adb_command("
|
196
|
+
apk_install_output = run_adb_command("-s #{device_serial} install -t -r #{app_apk_path.shellescape}",
|
186
197
|
print_all: true,
|
187
198
|
print_command: true)
|
188
199
|
UI.user_error!("App APK could not be installed") if apk_install_output.include?("Failure [")
|
189
200
|
|
190
201
|
UI.message('Installing tests APK')
|
191
|
-
apk_install_output = run_adb_command("
|
202
|
+
apk_install_output = run_adb_command("-s #{device_serial} install -t -r #{tests_apk_path.shellescape}",
|
192
203
|
print_all: true,
|
193
204
|
print_command: true)
|
194
205
|
UI.user_error!("Tests APK could not be installed") if apk_install_output.include?("Failure [")
|
@@ -199,14 +210,14 @@ module Screengrab
|
|
199
210
|
|
200
211
|
if packages.include?(app_package_name.to_s)
|
201
212
|
UI.message('Uninstalling app APK')
|
202
|
-
run_adb_command("
|
213
|
+
run_adb_command("-s #{device_serial} uninstall #{app_package_name}",
|
203
214
|
print_all: true,
|
204
215
|
print_command: true)
|
205
216
|
end
|
206
217
|
|
207
218
|
if packages.include?(tests_package_name.to_s)
|
208
219
|
UI.message('Uninstalling tests APK')
|
209
|
-
run_adb_command("
|
220
|
+
run_adb_command("-s #{device_serial} uninstall #{tests_package_name}",
|
210
221
|
print_all: true,
|
211
222
|
print_command: true)
|
212
223
|
end
|
@@ -214,20 +225,16 @@ module Screengrab
|
|
214
225
|
|
215
226
|
def grant_permissions(device_serial)
|
216
227
|
UI.message('Granting the permission necessary to change locales on the device')
|
217
|
-
run_adb_command("
|
228
|
+
run_adb_command("-s #{device_serial} shell pm grant #{@config[:app_package_name]} android.permission.CHANGE_CONFIGURATION",
|
218
229
|
print_all: true,
|
219
230
|
print_command: true)
|
220
231
|
|
221
|
-
device_api_version
|
222
|
-
print_all: true,
|
223
|
-
print_command: true).to_i
|
224
|
-
|
225
|
-
if device_api_version >= 23
|
232
|
+
if device_api_version(device_serial) >= 23
|
226
233
|
UI.message('Granting the permissions necessary to access device external storage')
|
227
|
-
run_adb_command("
|
234
|
+
run_adb_command("-s #{device_serial} shell pm grant #{@config[:app_package_name]} android.permission.WRITE_EXTERNAL_STORAGE",
|
228
235
|
print_all: true,
|
229
236
|
print_command: true)
|
230
|
-
run_adb_command("
|
237
|
+
run_adb_command("-s #{device_serial} shell pm grant #{@config[:app_package_name]} android.permission.READ_EXTERNAL_STORAGE",
|
231
238
|
print_all: true,
|
232
239
|
print_command: true)
|
233
240
|
end
|
@@ -252,9 +259,10 @@ module Screengrab
|
|
252
259
|
def run_tests_for_locale(locale, device_serial, test_classes_to_use, test_packages_to_use, launch_arguments)
|
253
260
|
UI.message("Running tests for locale: #{locale}")
|
254
261
|
|
255
|
-
instrument_command = ["
|
262
|
+
instrument_command = ["-s #{device_serial} shell am instrument --no-window-animation -w",
|
256
263
|
"-e testLocale #{locale.tr('-', '_')}",
|
257
264
|
"-e endingLocale #{@config[:ending_locale].tr('-', '_')}"]
|
265
|
+
instrument_command << "-e appendTimestamp #{@config[:use_timestamp_suffix]}"
|
258
266
|
instrument_command << "-e class #{test_classes_to_use.join(',')}" if test_classes_to_use
|
259
267
|
instrument_command << "-e package #{test_packages_to_use.join(',')}" if test_packages_to_use
|
260
268
|
instrument_command << launch_arguments.map { |item| '-e ' + item }.join(' ') if launch_arguments
|
@@ -281,10 +289,11 @@ module Screengrab
|
|
281
289
|
|
282
290
|
# Make a temp directory into which to pull the screenshots before they are moved to their final location.
|
283
291
|
# This makes directory cleanup easier, as the temp directory will be removed when the block completes.
|
292
|
+
|
284
293
|
Dir.mktmpdir do |tempdir|
|
285
294
|
device_screenshots_paths.each do |device_path|
|
286
295
|
if_device_path_exists(device_serial, device_path) do |path|
|
287
|
-
run_adb_command("
|
296
|
+
run_adb_command("-s #{device_serial} pull #{path} #{tempdir}",
|
288
297
|
print_all: false,
|
289
298
|
print_command: true)
|
290
299
|
end
|
@@ -347,7 +356,7 @@ module Screengrab
|
|
347
356
|
# Some device commands fail if executed against a device path that does not exist, so this helper method
|
348
357
|
# provides a way to conditionally execute a block only if the provided path exists on the device.
|
349
358
|
def if_device_path_exists(device_serial, device_path)
|
350
|
-
return if run_adb_command("
|
359
|
+
return if run_adb_command("-s #{device_serial} shell ls #{device_path}",
|
351
360
|
print_all: false,
|
352
361
|
print_command: false).include?('No such file')
|
353
362
|
|
@@ -359,7 +368,7 @@ module Screengrab
|
|
359
368
|
|
360
369
|
# Return an array of packages that are installed on the device
|
361
370
|
def installed_packages(device_serial)
|
362
|
-
packages = run_adb_command("
|
371
|
+
packages = run_adb_command("-s #{device_serial} shell pm list packages",
|
363
372
|
print_all: true,
|
364
373
|
print_command: true)
|
365
374
|
packages.split("\n").map { |package| package.gsub("package:", "") }
|
@@ -367,7 +376,9 @@ module Screengrab
|
|
367
376
|
|
368
377
|
def run_adb_command(command, print_all: false, print_command: false)
|
369
378
|
adb_path = @android_env.adb_path.chomp("adb")
|
370
|
-
|
379
|
+
adb_host = @config[:adb_host]
|
380
|
+
host = adb_host.nil? ? '' : "-H #{adb_host} "
|
381
|
+
output = @executor.execute(command: adb_path + "adb " + host + command,
|
371
382
|
print_all: print_all,
|
372
383
|
print_command: print_command) || ''
|
373
384
|
output.lines.reject do |line|
|
@@ -375,5 +386,34 @@ module Screengrab
|
|
375
386
|
line.start_with?('adb: ')
|
376
387
|
end.join('') # Lines retain their newline chars
|
377
388
|
end
|
389
|
+
|
390
|
+
def device_api_version(device_serial)
|
391
|
+
run_adb_command("-s #{device_serial} shell getprop ro.build.version.sdk",
|
392
|
+
print_all: true, print_command: true).to_i
|
393
|
+
end
|
394
|
+
|
395
|
+
def enable_clean_status_bar(device_serial, app_apk_path)
|
396
|
+
return unless device_api_version(device_serial) >= 23
|
397
|
+
|
398
|
+
# Check if the app wants to use the clean status bar feature
|
399
|
+
badging_dump = @executor.execute(command: "#{@android_env.aapt_path} dump badging #{app_apk_path}",
|
400
|
+
print_all: true, print_command: true)
|
401
|
+
return unless badging_dump.include?('uses-feature: name=\'tools.fastlane.screengrab.cleanstatusbar\'')
|
402
|
+
|
403
|
+
UI.message('Enabling clean status bar')
|
404
|
+
|
405
|
+
# Make sure the app requests the DUMP permission
|
406
|
+
unless badging_dump.include?('uses-permission: name=\'android.permission.DUMP\'')
|
407
|
+
UI.user_error!("The clean status bar feature requires the android.permission.DUMP permission but it could not be found in your app APK")
|
408
|
+
end
|
409
|
+
|
410
|
+
# Grant the DUMP permission
|
411
|
+
run_adb_command("-s #{device_serial} shell pm grant #{@config[:app_package_name]} android.permission.DUMP",
|
412
|
+
print_all: true, print_command: true)
|
413
|
+
|
414
|
+
# Enable the SystemUI demo mode
|
415
|
+
run_adb_command("-s #{device_serial} shell settings put global sysui_demo_allowed 1",
|
416
|
+
print_all: true, print_command: true)
|
417
|
+
end
|
378
418
|
end
|
379
419
|
end
|