fastlane-plugin-maestro 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5676179fdda08179eea220ae3c503606b9dedc66bfbd86a8a11dc133de10ee0c
4
- data.tar.gz: 9220392212f0ed8a3d9302b3068248a9a5c10bf0f809c68a9a74188eca6c7ae4
3
+ metadata.gz: 2a1fc0b3506dd9206f5d85dc27dde08cf15e6a1cfa74e4cec322f5e1beb2c223
4
+ data.tar.gz: 78b3e47e9499fedd2fc5645c31d22248fd4ffcf6bea4ed243dbc1838d4d9e782
5
5
  SHA512:
6
- metadata.gz: a70a33566e95bec30f3be1c96b9a58883a56ea1a07009795aed698a9893022b4522eb52ac946a3afce9109371a8150c5ded8db978c1962ab08a4b80d29eeb785
7
- data.tar.gz: c79ead391d334c620bf78558e1ccc7109e7d1f6984b3c2fbcf6400742494f4597993c9d2171f9eb69e47adad58dee70b95d67631182b0ad99588a06e3a4ac102
6
+ metadata.gz: 9735ddf0518738f9051ec4b37458875d6b058a1da4d584b97607e0b0e4d9d0d5f4c3b0ac1a04745a6d29e3bdfe7dc32a9b472ae043c59490395896e3ed83ce4f
7
+ data.tar.gz: 84f3fe4905a746afb5376cebc8834ad515aac28fe6d3017a10b9c04a889c9156744d44e7a68d8bdd7df5d066da8e45b80bb25952b7e9f1d26277580fb0d7685c
data/README.md CHANGED
@@ -14,7 +14,7 @@ gem "fastlane-plugin-maestro", git: "https://github.com/inf2381/fastlane-plugin-
14
14
  ## About this plugin
15
15
 
16
16
  fastlane plugin for [maestro](https://github.com/mobile-dev-inc/maestro).
17
- You can directly pass the options to maestro or provide them in the file `fastlane/Maestrofile`
17
+ You can directly pass the options to maestro or provide them in the file `fastlane/Maestrofile` when using the action `maestro_test`
18
18
 
19
19
  Additionally to the maestro action, this plugin provides an action to start an iOS simulator and install a given .app
20
20
  file to it.
@@ -36,10 +36,14 @@ device = launch_simulator(
36
36
  Run all flows defined in the folder .maestro/screenshot
37
37
 
38
38
  ```ruby
39
- maestro(
40
- command: 'test',
41
- tests: '.maestro/screenshot',
42
- report_type: 'junit'
39
+ maestro_test(
40
+ device: "EMULATOR_42",
41
+ tests: "test_dir",
42
+ debug_output: "my_output_dir",
43
+ env_vars: {
44
+ "USERNAME" => "testuser",
45
+ "PASSWORD" => "test123"
46
+ }
43
47
  )
44
48
  ```
45
49
 
@@ -59,6 +63,15 @@ maestro(
59
63
  )
60
64
  ```
61
65
 
66
+ Generically call maestro
67
+
68
+ ```ruby
69
+ maestro(
70
+ command: 'start-device',
71
+ flags: '--device-locale "de_DE"'
72
+ )
73
+ ```
74
+
62
75
  For other examples, please have a look at the [Fastfile of this repository](./fastlane/Fastfile)
63
76
 
64
77
  ## Issues and Feedback
@@ -6,24 +6,57 @@ module Fastlane
6
6
  module Actions
7
7
  class LaunchSimulatorAction < Action
8
8
  def self.run(params)
9
- device_type = SimCtl.devicetype(name: params[:device_name])
9
+ FastlaneCore::PrintTable.print_values(config: params,
10
+ title: "Summary for launch_simulator #{Fastlane::Maestro::VERSION}")
10
11
  device_name = "Maestro - #{params[:device_name]}"
12
+ runtime_name = params[:ios_version].nil? || params[:ios_version].empty? ? SimCtl.list_runtimes()[0].name : "iOS #{params[:ios_version]}"
13
+ runtime = SimCtl.runtime(name: runtime_name)
11
14
 
12
- runtime_name = ''
13
- if params[:ios_version].nil? || params[:ios_version].empty?
14
- runtime_name = SimCtl.list_runtimes()[0].name
15
- else
16
- runtime_name = "iOS #{params[:ios_version]}"
15
+ # Verify runtime identifier
16
+ if runtime.nil?
17
+ UI.user_error!("Could not find a runtime matching #{runtime_name}")
17
18
  end
18
- runtime = SimCtl.runtime(name: runtime_name)
19
+
20
+ # List available devices
21
+ available_devices = SimCtl.list_devices
22
+
23
+ # Manually filter devices
24
+ existing_device = available_devices.find { |d| d.name == device_name && d.os == runtime.identifier }
25
+ if existing_device
26
+ if existing_device.state == :booted
27
+ UI.message("Device #{device_name} is already running. Patching settings…")
28
+ patch_device_settings(existing_device, params)
29
+ UI.message("Installing app #{params[:app_path]} on the simulator")
30
+ device.install(params[:app_path])
31
+ return existing_device
32
+ elsif existing_device.state == :shutdown
33
+ UI.message("Device #{device_name} is shutdown. Booting device…")
34
+ existing_device.boot
35
+ existing_device.wait { |d| d.state == :booted }
36
+ patch_device_settings(existing_device, params)
37
+ UI.message("Installing app #{params[:app_path]} on the simulator")
38
+ device.install(params[:app_path])
39
+ return existing_device
40
+ end
41
+ end
42
+
43
+ # Create and boot the device if it doesn't exist
19
44
  UI.message("Creating device #{device_name} with runtime #{runtime_name}…")
45
+ device_type = SimCtl.devicetype(name: params[:device_name])
20
46
  device = SimCtl.create_device(device_name, device_type, runtime)
21
-
22
47
  device.boot
23
48
 
24
49
  UI.message("Waiting for device to boot")
25
50
  device.wait { |d| d.state == :booted }
51
+ patch_device_settings(device, params)
26
52
 
53
+ UI.message("Installing app #{params[:app_path]} on the simulator")
54
+ device.install(params[:app_path])
55
+
56
+ return device
57
+ end
58
+
59
+ def self.patch_device_settings(device, params)
27
60
  unless params[:language].nil? || params[:language].empty?
28
61
  UI.message("Setting device language to #{params[:language]}")
29
62
  device.settings.set_language(params[:language])
@@ -31,10 +64,9 @@ module Fastlane
31
64
  end
32
65
 
33
66
  UI.message("Patching device settings for tests")
34
- time = Time.new(2007, 1, 9, 9, 41, 0)
35
67
  device.status_bar.clear
36
68
  device.status_bar.override(
37
- time: time.iso8601,
69
+ time: '9:41', # Time.new(2007, 1, 9, 9, 41, 0).iso8601 not possible as of iOS 18.2
38
70
  dataNetwork: '5g',
39
71
  wifiMode: 'active',
40
72
  cellularMode: 'active',
@@ -42,13 +74,7 @@ module Fastlane
42
74
  batteryLevel: 100
43
75
  )
44
76
  device.settings.disable_keyboard_helpers
45
-
46
77
  device.launch
47
-
48
- UI.message("Installing app #{params[:app_path]} on the simulator")
49
- device.install(params[:app_path])
50
-
51
- return device
52
78
  end
53
79
 
54
80
  def self.description
@@ -95,9 +121,6 @@ module Fastlane
95
121
  end
96
122
 
97
123
  def self.is_supported?(platform)
98
- # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
99
- # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
100
- #
101
124
  [:ios].include?(platform)
102
125
  end
103
126
  end
@@ -7,42 +7,21 @@ module Fastlane
7
7
  module Actions
8
8
  class MaestroAction < Action
9
9
  def self.run(params)
10
- params.load_configuration_file("Maestrofile")
11
- FastlaneCore::PrintTable.print_values(config: params,
12
- title: "Summary for maestro #{Fastlane::Maestro::VERSION}")
13
-
14
10
  case params[:command]
15
11
  when "install"
16
12
  Maestro::Runner.install
17
- when "test"
18
- platform = (ENV['FASTLANE_PLATFORM_NAME'] ? ENV['FASTLANE_PLATFORM_NAME'].to_s : '')
19
- if platform == 'ios'
20
- self.check_ios_dependencies!
21
- end
22
- Maestro::Runner.run(params)
23
13
  when "download_samples"
24
14
  Maestro::Runner.download_samples
15
+ when "test"
16
+ UI.important("The `maestro(command: 'test')` action is deprecated. Please use `maestro_test` instead.")
17
+ Maestro::Runner.run_deprecated(params)
18
+ else
19
+ Maestro::Runner.run_generic(params[:command], params[:flags])
25
20
  end
26
21
  end
27
22
 
28
- def self.check_ios_dependencies!
29
- UI.message("Making sure you installed the dependencies to run Maestro…")
30
-
31
- return if Maestro::Runner.command?("idb_companion")
32
-
33
- UI.error("You have to install idb companion to use `maestro` with iOS simulators")
34
- UI.error("")
35
- UI.error("Install it via brew:")
36
- UI.command("brew tap facebook/fb")
37
- UI.command("brew install idb-companion")
38
-
39
- UI.error("If you don't have homebrew, visit https://github.com/facebook/idb")
40
-
41
- UI.user_error!("Please install idb companion and start your lane again.")
42
- end
43
-
44
23
  def self.description
45
- 'Runs Maestro test'
24
+ 'Runs the Maestro CLI'
46
25
  end
47
26
 
48
27
  def self.authors
@@ -60,7 +39,7 @@ module Fastlane
60
39
  [
61
40
  FastlaneCore::ConfigItem.new(key: :command,
62
41
  env_name: 'FL_MAESTRO_COMMAND',
63
- description: 'Command to be executed (`download_samples`, `install`, or `test`)',
42
+ description: 'Command to be executed (`download_samples`, `install`)',
64
43
  type: String,
65
44
  default_value: 'test',
66
45
  verify_block: proc do |value|
@@ -68,6 +47,11 @@ module Fastlane
68
47
  UI.user_error!("Unsupported value '#{value}' for parameter ':command'! \nAvailable options: `download_samples`, `install`, `test`")
69
48
  end
70
49
  end),
50
+ FastlaneCore::ConfigItem.new(key: :flags,
51
+ description: 'Allows to pass additional flags',
52
+ optional: true,
53
+ type: String,
54
+ default_value: ''),
71
55
  FastlaneCore::ConfigItem.new(key: :report_type,
72
56
  env_name: 'FL_MAESTRO_FORMAT',
73
57
  description: 'Format of the generated report (`junit`)',
@@ -79,32 +63,32 @@ module Fastlane
79
63
  UI.user_error!("Unsupported value '#{value}' for parameter ':format'! Available options: `junit`")
80
64
  end
81
65
  end),
82
- FastlaneCore::ConfigItem.new(key: :output,
83
- env_name: 'FL_MAESTRO_OUTPUT',
84
- description: 'Allows to override the report filename. Requires parameter :format to be set as well',
85
- optional: true,
86
- type: String,
87
- default_value: ''),
88
- FastlaneCore::ConfigItem.new(key: :device,
89
- env_name: 'FL_MAESTRO_DEVICE',
90
- description: 'iOS UDID or Android device name to be used for running the tests ',
91
- optional: true,
92
- type: String,
93
- default_value: ''),
94
- FastlaneCore::ConfigItem.new(key: :tests,
95
- env_name: 'FL_MAESTRO_TESTS',
96
- description: 'Maestro flow (or folder containing flows) to be executed',
97
- optional: true,
98
- type: String,
99
- verify_block: proc do |value|
100
- v = File.expand_path(value.to_s)
101
- UI.user_error!("No file or directory found with path '#{v}'") unless File.exist?(v)
102
- end),
103
- FastlaneCore::ConfigItem.new(key: :env_vars,
104
- env_name: 'FL_MAESTRO_ENV_VARIABLES',
105
- description: 'Allows to pass variables that the flow(s) might be using',
106
- optional: true,
107
- type: Hash)
66
+ FastlaneCore::ConfigItem.new(key: :output,
67
+ env_name: 'FL_MAESTRO_OUTPUT',
68
+ description: 'Allows to override the report filename. Requires parameter :format to be set as well',
69
+ optional: true,
70
+ type: String,
71
+ default_value: ''),
72
+ FastlaneCore::ConfigItem.new(key: :device,
73
+ env_name: 'FL_MAESTRO_DEVICE',
74
+ description: 'iOS UDID or Android device name to be used for running the tests ',
75
+ optional: true,
76
+ type: String,
77
+ default_value: ''),
78
+ FastlaneCore::ConfigItem.new(key: :tests,
79
+ env_name: 'FL_MAESTRO_TESTS',
80
+ description: 'Maestro flow (or folder containing flows) to be executed',
81
+ optional: true,
82
+ type: String,
83
+ verify_block: proc do |value|
84
+ v = File.expand_path(value.to_s)
85
+ UI.user_error!("No file or directory found with path '#{v}'") unless File.exist?(v)
86
+ end),
87
+ FastlaneCore::ConfigItem.new(key: :env_vars,
88
+ env_name: 'FL_MAESTRO_ENV_VARIABLES',
89
+ description: 'Allows to pass variables that the flow(s) might be using',
90
+ optional: true,
91
+ type: Hash)
108
92
  ]
109
93
  end
110
94
 
@@ -0,0 +1,136 @@
1
+ require 'fastlane/action'
2
+ require 'fileutils'
3
+
4
+ require_relative '../helper/runner'
5
+
6
+ module Fastlane
7
+ module Actions
8
+ class MaestroTestAction < Action
9
+ def self.run(params)
10
+ params.load_configuration_file("Maestrofile")
11
+ FastlaneCore::PrintTable.print_values(config: params,
12
+ title: "Summary for maestro #{Fastlane::Maestro::VERSION}")
13
+ platform = (ENV['FASTLANE_PLATFORM_NAME'] ? ENV['FASTLANE_PLATFORM_NAME'].to_s : '')
14
+ if platform == 'ios'
15
+ self.check_ios_dependencies!
16
+ end
17
+ Maestro::Runner.run(params)
18
+ end
19
+
20
+ def self.check_ios_dependencies!
21
+ UI.message("Making sure you installed the dependencies to run Maestro…")
22
+
23
+ return if Maestro::Runner.command?("idb_companion")
24
+
25
+ UI.error("You have to install idb companion to use `maestro` with iOS simulators")
26
+ UI.error("")
27
+ UI.error("Install it via brew:")
28
+ UI.command("brew tap facebook/fb")
29
+ UI.command("brew install idb-companion")
30
+
31
+ UI.error("If you don't have homebrew, visit https://github.com/facebook/idb")
32
+
33
+ UI.user_error!("Please install idb companion and start your lane again.")
34
+ end
35
+
36
+ def self.description
37
+ 'Runs Maestro test'
38
+ end
39
+
40
+ def self.authors
41
+ ['Marc Bormeth']
42
+ end
43
+
44
+ def self.return_value
45
+ end
46
+
47
+ def self.details
48
+ 'Runs maestro test'
49
+ end
50
+
51
+ def self.available_options
52
+ [
53
+ FastlaneCore::ConfigItem.new(key: :continuous,
54
+ env_name: 'FL_MAESTRO_CONTINUOUS',
55
+ description: 'Run in continuous mode',
56
+ is_string: false,
57
+ optional: true),
58
+ FastlaneCore::ConfigItem.new(key: :config,
59
+ env_name: 'FL_MAESTRO_CONFIG',
60
+ description: 'Optional YAML configuration file for the workspace (defaults to <workspace_path>/config.yaml)',
61
+ optional: true,
62
+ type: String),
63
+ FastlaneCore::ConfigItem.new(key: :debug_output,
64
+ env_name: 'FL_MAESTRO_DEBUG_OUTPUT',
65
+ description: 'Configures the debug output in this path, instead of default',
66
+ optional: true,
67
+ type: String),
68
+ FastlaneCore::ConfigItem.new(key: :env_vars,
69
+ env_name: 'FL_MAESTRO_ENV_VARIABLES',
70
+ description: 'Allows to pass variables that the flow(s) might be using',
71
+ optional: true,
72
+ type: Hash),
73
+ FastlaneCore::ConfigItem.new(key: :exclude_tags,
74
+ env_name: 'FL_MAESTRO_EXCLUDE_TAGS',
75
+ description: 'List of tags that will remove the Flows containing the provided tags',
76
+ optional: true,
77
+ type: Array),
78
+ FastlaneCore::ConfigItem.new(key: :flatten_debug_output,
79
+ env_name: 'FL_MAESTRO_FLATTEN_DEBUG_OUTPUT',
80
+ description: 'All file outputs from the test case are created in the folder without subfolders or timestamps for each run',
81
+ is_string: false,
82
+ optional: true),
83
+ FastlaneCore::ConfigItem.new(key: :report_type,
84
+ env_name: 'FL_MAESTRO_FORMAT',
85
+ description: 'Format of the generated report (`junit`)',
86
+ optional: true,
87
+ type: String,
88
+ default_value: 'NOOP',
89
+ verify_block: proc do |value|
90
+ unless ["", "junit", "HTML", "NOOP"].include?(value)
91
+ UI.user_error!("Unsupported value '#{value}' for parameter ':format'! Available options: `junit`")
92
+ end
93
+ end),
94
+ FastlaneCore::ConfigItem.new(key: :include_tags,
95
+ env_name: 'FL_MAESTRO_INCLUDE_TAGS',
96
+ description: 'List of tags that will remove the Flows that does not have the provided tags',
97
+ optional: true,
98
+ type: Array),
99
+ FastlaneCore::ConfigItem.new(key: :output,
100
+ env_name: 'FL_MAESTRO_OUTPUT',
101
+ description: 'Allows to override the report filename. Requires parameter :format to be set as well',
102
+ optional: true,
103
+ type: String,
104
+ default_value: ''),
105
+ FastlaneCore::ConfigItem.new(key: :device,
106
+ env_name: 'FL_MAESTRO_DEVICE',
107
+ description: 'iOS UDID or Android device name to be used for running the tests (can also be a comma-separated list of devices)',
108
+ optional: true,
109
+ type: String,
110
+ default_value: ''),
111
+ FastlaneCore::ConfigItem.new(key: :tests,
112
+ env_name: 'FL_MAESTRO_TESTS',
113
+ description: 'Maestro flow (or folder containing flows) to be executed',
114
+ optional: true,
115
+ type: String,
116
+ verify_block: proc do |value|
117
+ v = File.expand_path(value.to_s)
118
+ UI.user_error!("No file or directory found with path '#{v}'") unless File.exist?(v)
119
+ end)
120
+ ]
121
+ end
122
+
123
+ def self.is_supported?(platform)
124
+ # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
125
+ # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
126
+ #
127
+ [:ios, :android].include?(platform)
128
+
129
+ end
130
+
131
+ def self.category
132
+ :testing
133
+ end
134
+ end
135
+ end
136
+ end
@@ -6,6 +6,60 @@ module Fastlane
6
6
  class Runner
7
7
 
8
8
  def self.run(options)
9
+ maestro_path = ENV["HOME"] + "/.maestro/bin/maestro"
10
+ command = [maestro_path]
11
+
12
+ unless options[:device].empty? || options[:device].nil?
13
+ command.push("--device", options[:device])
14
+ end
15
+
16
+ command.push("test")
17
+
18
+ # Flags with a value
19
+ {
20
+ config: "--config",
21
+ debug_output: "--debug-output",
22
+ exclude_tags: "--exclude-tags",
23
+ report_type: "--format",
24
+ include_tags: "--include-tags",
25
+ output: "--output"
26
+ }.each do |key, flag|
27
+ value = options[key]
28
+ next if value.nil? || value.empty?
29
+
30
+ command.push(flag, value)
31
+
32
+ # Make sure the directory exists for output files
33
+ FileUtils.mkdir_p(File.dirname(value)) if [:debug_output, :output].include?(key)
34
+ end
35
+
36
+ # Boolean flags
37
+ {
38
+ continuous: "--continuous",
39
+ flatten_debug_output: "--flatten-debug-output"
40
+ }.each do |key, flag|
41
+ value = options[key]
42
+ next if value.nil? || value.empty? || value == false
43
+
44
+ command.push(flag)
45
+ end
46
+
47
+ unless options[:env_vars].nil? || options[:env_vars].empty?
48
+ options[:env_vars].each do |key, value|
49
+ command.push("-e", "#{key}=\"#{value}\"")
50
+ end
51
+ end
52
+
53
+ command.push("#{options[:tests]}")
54
+ command_string = command.join(" ")
55
+ UI.message("Running command: #{command_string}")
56
+ Dir.chdir(ENV["PWD"]) do
57
+ # TODO: set exception based on parameter `failRun`
58
+ system(command_string, out: $stdout, err: :out, exception: true)
59
+ end
60
+ end
61
+
62
+ def self.run_deprecated(options)
9
63
  # TODO: add possibility to specify maestro path
10
64
  maestro_path = ENV["HOME"] + "/.maestro/bin/maestro"
11
65
 
@@ -51,6 +105,13 @@ module Fastlane
51
105
  end
52
106
  end
53
107
 
108
+ def self.run_generic(cmd, flags)
109
+ maestro_path = ENV["HOME"] + "/.maestro/bin/maestro"
110
+ command = [maestro_path]
111
+ command.push(cmd)
112
+ command.push(flags)
113
+ end
114
+
54
115
  def self.command?(name)
55
116
  `which #{name}`
56
117
  $?.success?
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Maestro
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.6"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-maestro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Bormeth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-15 00:00:00.000000000 Z
11
+ date: 2024-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -161,6 +161,7 @@ files:
161
161
  - lib/fastlane/plugin/maestro.rb
162
162
  - lib/fastlane/plugin/maestro/actions/launch_simulator.rb
163
163
  - lib/fastlane/plugin/maestro/actions/maestro.rb
164
+ - lib/fastlane/plugin/maestro/actions/maestro_test.rb
164
165
  - lib/fastlane/plugin/maestro/helper/runner.rb
165
166
  - lib/fastlane/plugin/maestro/version.rb
166
167
  homepage: https://github.com/inf2381/fastlane-plugin-maestro
@@ -182,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
183
  - !ruby/object:Gem::Version
183
184
  version: '0'
184
185
  requirements: []
185
- rubygems_version: 3.3.7
186
+ rubygems_version: 3.5.16
186
187
  signing_key:
187
188
  specification_version: 4
188
189
  summary: Running maestro test commands from fastlane