fastlane-plugin-maestro 0.0.3 → 0.0.5

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: 4ddf938129d4e0385bc14555c532053b5e736a27fc2082da740ea727a1313d3f
4
- data.tar.gz: a05a596cad7786aa095f7464dfe820300e72a74df3e75b187376cb7e4009bbef
3
+ metadata.gz: 0103c17face38cbcd796b2dfe0bd3def13bdc168725147c5762fa3a9d82bfc5b
4
+ data.tar.gz: 755c3ce2fac773ab52e85be741e7bd10c387f953a2160f6c24d9f23b54cd0d48
5
5
  SHA512:
6
- metadata.gz: 272b6143ae66f487269004a2cdf2441bbd7c9a40490210e93cc48840f193a08523c0eaad987bff9714930ec4528e0036489e47933c416a59d05a047e2848880d
7
- data.tar.gz: 2d4c37eea7e99f172f50f0b49c63d4d487133721c6ab3b8e9d11389751b3c7fc4a6561971ef2c94ae3cbc0055e39124ec13e4c78cf33631e12f2852ff5b97259
6
+ metadata.gz: '0923e9a98ee7ea40c064edf8b30712209a4f359c6e4a21ed6a0188b4e9171f96c19854711ce5fb5fb9b4a20ba03c736566a112d6a7708601010e8f5ab9c4be63'
7
+ data.tar.gz: dbf92fd9cba26dbce68fd233f9c2e744f93aa66fb12a49c8512146dad354dbd7269c5e828608360d727c9b26622e5c6d20897fb61a197c965c69c5d56c9115d1
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,53 @@ 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
+ return existing_device
30
+ elsif existing_device.state == :shutdown
31
+ UI.message("Device #{device_name} is shutdown. Booting device…")
32
+ existing_device.boot
33
+ existing_device.wait { |d| d.state == :booted }
34
+ patch_device_settings(existing_device, params)
35
+ return existing_device
36
+ end
37
+ end
38
+
39
+ # Create and boot the device if it doesn't exist
19
40
  UI.message("Creating device #{device_name} with runtime #{runtime_name}…")
41
+ device_type = SimCtl.devicetype(name: params[:device_name])
20
42
  device = SimCtl.create_device(device_name, device_type, runtime)
21
-
22
43
  device.boot
23
44
 
24
45
  UI.message("Waiting for device to boot")
25
46
  device.wait { |d| d.state == :booted }
47
+ patch_device_settings(device, params)
26
48
 
49
+ UI.message("Installing app #{params[:app_path]} on the simulator")
50
+ device.install(params[:app_path])
51
+
52
+ return device
53
+ end
54
+
55
+ def self.patch_device_settings(device, params)
27
56
  unless params[:language].nil? || params[:language].empty?
28
57
  UI.message("Setting device language to #{params[:language]}")
29
58
  device.settings.set_language(params[:language])
@@ -31,10 +60,9 @@ module Fastlane
31
60
  end
32
61
 
33
62
  UI.message("Patching device settings for tests")
34
- time = Time.new(2007, 1, 9, 9, 41, 0)
35
63
  device.status_bar.clear
36
64
  device.status_bar.override(
37
- time: time.iso8601,
65
+ time: '9:41', # Time.new(2007, 1, 9, 9, 41, 0).iso8601 not possible as of iOS 18.2
38
66
  dataNetwork: '5g',
39
67
  wifiMode: 'active',
40
68
  cellularMode: 'active',
@@ -42,13 +70,7 @@ module Fastlane
42
70
  batteryLevel: 100
43
71
  )
44
72
  device.settings.disable_keyboard_helpers
45
-
46
73
  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
74
  end
53
75
 
54
76
  def self.description
@@ -95,9 +117,6 @@ module Fastlane
95
117
  end
96
118
 
97
119
  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
120
  [:ios].include?(platform)
102
121
  end
103
122
  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
 
@@ -25,7 +79,7 @@ module Fastlane
25
79
  # Make sure that the output folder is available
26
80
  FileUtils.mkdir_p(File.dirname(options[:output]))
27
81
  end
28
- unless options[:env_vars].empty? || options[:env_vars].nil?
82
+ unless options[:env_vars].nil? || options[:env_vars].empty?
29
83
  options[:env_vars].each do |key, value|
30
84
  command.push("-e", "#{key}=#{value}")
31
85
  end
@@ -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.3"
3
+ VERSION = "0.0.5"
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.3
4
+ version: 0.0.5
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-05-24 00:00:00.000000000 Z
11
+ date: 2024-12-12 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