fastlane-plugin-flutter_tests 0.1.0 → 0.2.2

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: 562ded41eefa236b1db186681fe484aec6643c64160107a0e29c9a055e658e7f
4
- data.tar.gz: 7c7e8561a0bdd1e80495642c2aad38601371e68a59ab6e3c74c3edab48179e00
3
+ metadata.gz: e134b3e53ea1a6aa94cb983cfb66ae0843b6f0bc2263eade128e99f979d80639
4
+ data.tar.gz: 1384cfda230ccfe2e055f9c2801fe90db559c947390c02842dac720c39305c81
5
5
  SHA512:
6
- metadata.gz: 3b83d6ed1199bd3fecae918e80b0f0b1cf1617e7fb857111344960e91f760ce8c914d920103253d8033ac40c7fda2e5a6f153d8d73ac87ed9e66f3d42b3d5ee4
7
- data.tar.gz: 9d8c086f8806dcf94d27b50862cebaa98e780a48795c64f7a0abee02ca1fc870d12a6af0fc4b3e6195e2205fc5dd99815ad98ad5f1e0c3115107f358fa9a2216
6
+ metadata.gz: c4b7dd57f2ea4d4e3a3b228a1494c6f0d8fad4ac6c2d055523a95f73368441fc04c66f39dfe93ac56c3873edbf21dcdff51be11d26b3d8d2c72a3800c4f3be68
7
+ data.tar.gz: 07b55a3475e471e8a499d97576f71773b773dd87d992be4f2f87bd158f4663671515370a5a86faaca32479349b3c35ca202fcaa40e75120dbab733d299cad234
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # flutter_tests plugin
2
2
 
3
3
  [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-flutter_tests)
4
+ [![Gem Version](https://badge.fury.io/rb/fastlane-plugin-flutter_tests.svg)](https://badge.fury.io/rb/fastlane-plugin-flutter_tests)
4
5
 
5
6
  ## Getting Started
6
7
 
@@ -1,123 +1,36 @@
1
1
  require 'fastlane/action'
2
- require_relative '../helper/flutter_tests_helper'
2
+ require_relative '../helper/flutter_unit_test_helper'
3
+ require_relative '../helper/flutter_integration_test_helper'
3
4
  require 'open3'
4
5
  require 'json'
6
+ require_relative '../model/test_item'
5
7
 
6
8
  module Fastlane
7
9
  module Actions
8
10
  class FlutterTestsAction < Action
9
- # Class that represents a single test that has been run
10
- class Test
11
- def initialize(id, name)
12
- @test_id = id
13
- @test_name = name
14
- @test_done = false
15
- @test_successful = ''
16
- @test_error = nil
17
- @test_stacktrace = nil
18
- end
19
-
20
- def mark_as_done(success, error, stacktrace)
21
- @test_done = true
22
- @test_successful = success
23
- @test_error = error
24
- unless stacktrace.nil?
25
- stacktrace = stacktrace.gsub(/ {2,}/, "\n")
26
- @test_stacktrace = stacktrace
27
- end
28
- end
29
-
30
- def get_name
31
- @test_name
32
- end
33
-
34
- def get_id
35
- @test_id
11
+ def self.run(params)
12
+ test_type = params[:test_type]
13
+ if %w[all unit].include? test_type
14
+ Helper::FlutterUnitTestHelper.new.run(params[:flutter_command], params[:print_only_failed], params[:print_stats])
36
15
  end
16
+ if %w[all integration].include? test_type
37
17
 
38
- def _generate_message(print_errors)
39
- default_message = "[#{@test_successful}] #{@test_name}"
40
- if print_errors and @test_successful != 'success'
41
- default_message += "\n[ERROR] -> #{@test_error}\n[STACKTRACE]\n#{@test_stacktrace}"
18
+ if params[:driver_path].nil? || params[:integration_tests].nil?
19
+ UI.user_error!("If launching integration tests, 'driver_path' and 'integration_tests' parameters must be inserted")
20
+ exit(1)
42
21
  end
43
22
 
44
- if %w[success error].include?(@test_successful)
45
- color = @test_successful == 'success' ? 32 : 31
23
+ platform = params[:platform]
46
24
 
47
- "\e[#{color}m#{default_message}\e[0m"
48
- else
49
- default_message
25
+ if params[:reuse_build] && platform != 'android'
26
+ UI.error("If 'reuse_build' is set to true, the platform must be android")
27
+ platform = 'android'
50
28
  end
51
- end
52
29
 
53
- def print(print_errors)
54
- UI.message(_generate_message(print_errors))
30
+ Helper::FlutterIntegrationTestHelper.new(params[:driver_path], params[:integration_tests], params[:flutter_command]).run(platform, params[:force_launch], params[:reuse_build])
55
31
  end
56
32
  end
57
33
 
58
- class TestRunner
59
- def initialize
60
- @launched_tests = Hash.new { |hash, key| hash[key] = nil }
61
- end
62
-
63
- # Launches all the unit tests contained in the project
64
- # folder
65
- def run(flutter_command, print_errors)
66
- Open3.popen3("#{flutter_command} test --machine") do |stdin, stdout, stderr, thread|
67
- stdout.each_line do |line|
68
- parse_json_output(line, print_errors)
69
- end
70
- end
71
- end
72
-
73
- # Parses the json output given by [self.run]
74
- def parse_json_output(line, print_errors)
75
- unless line.to_s.strip.empty?
76
- output = JSON.parse(line)
77
- unless output.kind_of?(Array)
78
- type = output['type']
79
- case type
80
- when 'testStart'
81
- id = output['test']['id']
82
- name = output['test']['name']
83
- if name.include?('loading')
84
- return
85
- end
86
-
87
- test_item = Test.new(id, name)
88
- @launched_tests[test_item.get_id] = test_item
89
- when 'testDone'
90
- test_id = output['testID']
91
- test_item = @launched_tests[test_id]
92
- unless test_item.nil?
93
- @launched_tests.delete(test_id)
94
- test_item.mark_as_done(output['result'], nil, nil)
95
- test_item.print(print_errors)
96
- end
97
- when 'error'
98
- test_id = output['testID']
99
- test_item = @launched_tests[test_id]
100
- unless test_item.nil?
101
- @launched_tests.delete(test_id)
102
- test_item.mark_as_done('error', output['error'], output['stackTrace'])
103
- test_item.print(print_errors)
104
- end
105
- else
106
- # ignored
107
- end
108
- end
109
- end
110
- rescue StandardError => e
111
- UI.error("Got error during parse_json: #{e.message}")
112
- UI.error(e.backtrace.join('\n'))
113
- exit(1)
114
- end
115
- end
116
-
117
- def self.run(params)
118
- TestRunner.new.run(params[:flutter_command], params[:print_errors])
119
- end
120
-
121
34
  def self.description
122
35
  "Extension that helps to run flutter tests"
123
36
  end
@@ -145,11 +58,69 @@ module Fastlane
145
58
  type: String
146
59
  ),
147
60
  FastlaneCore::ConfigItem.new(
148
- key: :print_errors,
61
+ key: :print_only_failed,
149
62
  default_value: true,
150
- description: 'Specifies if it should print the error of failed tests',
63
+ description: 'Specifies if it should only print the failed and the skipped tests',
151
64
  optional: false,
152
65
  type: Boolean
66
+ ),
67
+ FastlaneCore::ConfigItem.new(
68
+ key: :print_stats,
69
+ default_value: true,
70
+ description: 'If defined, it will print how many tests were done/skipped/failed',
71
+ optional: false,
72
+ type: Boolean
73
+ ),
74
+ FastlaneCore::ConfigItem.new(
75
+ key: :test_type,
76
+ default_value: 'all',
77
+ description: "Specifies which tests should be run. Accepted values",
78
+ verify_block: proc do |value|
79
+ UI.user_error!("Wrong value, #{value} not accepted. Should be 'unit','integration' or 'all'.") unless %w[unit integration all].include? value
80
+ end,
81
+ optional: false,
82
+ type: String,
83
+ ),
84
+ FastlaneCore::ConfigItem.new(
85
+ key: :driver_path,
86
+ description: "Specifies the path of the driver file",
87
+ optional: true,
88
+ type: String,
89
+ verify_block: proc do |value|
90
+ UI.user_error!("Driver file doesn't exists") unless File.file?(value)
91
+ end
92
+ ),
93
+ FastlaneCore::ConfigItem.new(
94
+ key: :integration_tests,
95
+ description: "Specifies the path of the folder containing all the integration tests",
96
+ optional: true,
97
+ type: String,
98
+ verify_block: proc do |value|
99
+ UI.user_error!("Integration test folder doesn't exists") unless File.exist?(value) && File.directory?(value)
100
+ end
101
+ ),
102
+ FastlaneCore::ConfigItem.new(
103
+ key: :platform,
104
+ description: "Specifies the os on which the tests should run on",
105
+ optional: false,
106
+ type: String,
107
+ verify_block: proc do |value|
108
+ UI.user_error!("Platform #{value} is not supported") unless %w[android ios].include? value.to_s.downcase
109
+ end
110
+ ),
111
+ FastlaneCore::ConfigItem.new(
112
+ key: :force_launch,
113
+ description: "If true, the plugin will try to launch an emulator in case it's not already running",
114
+ optional: false,
115
+ type: Boolean,
116
+ default_value: true,
117
+ ),
118
+ FastlaneCore::ConfigItem.new(
119
+ key: :reuse_build,
120
+ description: "If true, builds the app only for the first time then the other integration tests are run on the same build (much faster)",
121
+ default_value: false,
122
+ optional: false,
123
+ type: Boolean,
153
124
  )
154
125
  ]
155
126
  end
@@ -0,0 +1,153 @@
1
+ require 'fastlane/action'
2
+ require 'open3'
3
+ require_relative '../utils/utilities.rb'
4
+
5
+ module Fastlane
6
+ module Helper
7
+ class FlutterIntegrationTestHelper
8
+ # Initialize the helper that launches the integration tests
9
+ #
10
+ # @param driver [String] the path to the file that will be used as driver
11
+ # @param test_folder [String] the path to the folder that contains the
12
+ # @param flutter_command [String] the command to launch flutter
13
+ # integration tests
14
+ def initialize(driver, test_folder, flutter_command)
15
+ @driver = driver
16
+ @integration_tests = _load_files(test_folder)
17
+ @flutter_command = flutter_command
18
+ end
19
+
20
+ # Loads all the integration test files
21
+ #
22
+ # @param test_folder [String] the path that contains the test files
23
+ # @return [Array] An array containing all the paths to the files found
24
+ def _load_files(test_folder)
25
+ test_files = Dir.glob("#{test_folder}/**/*").reject do |f|
26
+ File.directory?(f) || !f.end_with?('_test.dart')
27
+ end
28
+ UI.message("Found #{test_files.length} test files")
29
+ test_files
30
+ end
31
+
32
+ # Launches the tests sequentially
33
+ #
34
+ # @param platform [String] Specifies on which platform the tests should be run
35
+ # @param force_launch [Boolean] If it's true and there aren't any devices ready, the plugin will try to start one for the given platform
36
+ # @param reuse_build [Boolean] If it's true, it will run the build only for the first integration test
37
+ # @return [Integer] Value 0 or 1 if all tests were run correctly or not
38
+ def run(platform, force_launch, reuse_build)
39
+ UI.message("Checking for running devices")
40
+ device_id = _run_test_device(platform, force_launch)
41
+ if !device_id.nil?
42
+ _launch_tests(device_id, reuse_build)
43
+ else
44
+ UI.error("Failed to find a device to launch the tests on")
45
+ exit(1)
46
+ end
47
+ end
48
+
49
+ # Executes the tests found on the device_id
50
+ #
51
+ # @param device_id [String] the id of the device previously found
52
+ # @param reuse_build [Boolean] If it's true, it will run the build only for the first integration test
53
+ # @return [Integer] Value 0 or 1 if all tests were run correctly or not
54
+ def _launch_tests(device_id, reuse_build)
55
+ apk_path = nil
56
+ if reuse_build
57
+ UI.message("Building apk")
58
+ out, err, status = Open3.capture3("#{@flutter_command} build apk")
59
+ if _get_exit_code(status) != '0'
60
+ UI.error("Failed to build apk")
61
+ puts err
62
+ exit(1)
63
+ else
64
+ apk_path = _get_apk_path(out)
65
+ if !apk_path.nil? && File.file?(apk_path)
66
+ UI.message("Build apk at path #{apk_path}")
67
+ #TODO
68
+ else
69
+ UI.error("Apk path not found or it's not accessible")
70
+ exit(1)
71
+ end
72
+
73
+ end
74
+ end
75
+
76
+ count = 0
77
+
78
+ tests = {
79
+ "successful" => 0,
80
+ "failed" => 0,
81
+ }
82
+
83
+ @integration_tests.each do |test|
84
+ UI.message("Launching test #{count}/#{@integration_tests.length}: #{test.split("/").last}")
85
+ _, __, status = Open3.capture3("#{@flutter_command} drive --target #{@driver} --driver #{test} -d #{device_id} #{reuse_build ? "--use-application-binary #{apk_path}" : ''}")
86
+ successful = _get_exit_code(status) == '0'
87
+ color = successful ? 'green' : 'red'
88
+ tests[successful ? 'successful' : 'failed'] += 1
89
+
90
+ UI.message(Utilities.new.colorize("Test #{test.split("/").last} #{successful ? 'terminated correctly' : 'failed'}", color))
91
+ count += 1
92
+ end
93
+
94
+ unless tests['failed'] == 0
95
+ UI.user_error!("There are some integration tests that fail")
96
+ end
97
+ end
98
+
99
+ # Returns the exit code of a process
100
+ #
101
+ # @param exit_status [String] status given back by [Open3]
102
+ # @return The exit code (0|1) as string
103
+ def _get_exit_code(exit_status)
104
+ exit_status.to_s.split(' ').last
105
+ end
106
+
107
+ # Parse the flutter build output looking for a .apk path
108
+ #
109
+ # @param message [String] the stdout of flutter build process
110
+ # @return the path to the apk that has been built
111
+ def _get_apk_path(message)
112
+ components = message.split(/\n/).last.split(' ')
113
+ if components.any? { |line| line.end_with? '.apk' }
114
+ components.detect { |c| c.end_with? '.apk' }
115
+ else
116
+ UI.warn('Apk path not found in the stdout')
117
+ nil
118
+ end
119
+ end
120
+
121
+ # Checks if there's a device running and gets its id
122
+ # @param platform [String] Specifies the type of device that should be found
123
+ # @param force_launch [Boolean] If it's true and there aren't any devices ready, the plugin will try to start one for the given platform
124
+ # @return The deviceId if the device exists or [nil]
125
+ def _run_test_device(platform, force_launch)
126
+ out, _ = Open3.capture2("#{@flutter_command} devices | grep #{platform}")
127
+ device_id = nil
128
+ if out.to_s.strip.empty? && force_launch
129
+ out, _ = Open3.capture2("#{@flutter_command} emulators | grep #{platform}")
130
+ if out.to_s.strip.empty?
131
+ UI.error("No emulators found for platform #{platform}")
132
+ exit(1)
133
+ end
134
+
135
+ emulator_id = out.to_s.split('•')[0]
136
+ Open3.capture2("#{@flutter_command} emulators --launch #{emulator_id}")
137
+
138
+ out, _ = Open3.capture2("#{@flutter_command} devices | grep #{platform}")
139
+ else
140
+ device_id = (out.to_s.split("•")[1]).strip
141
+ UI.message("Found already running device: #{device_id}")
142
+ end
143
+
144
+ unless out.to_s.strip.empty?
145
+ device_id = (out.to_s.split("•")[1]).strip
146
+ UI.message("Got device id #{device_id}")
147
+ end
148
+
149
+ device_id.nil? ? nil : device_id
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,109 @@
1
+ require 'fastlane/action'
2
+ require_relative '../utils/utilities'
3
+
4
+ module Fastlane
5
+
6
+ module Helper
7
+ class FlutterUnitTestHelper
8
+ def initialize
9
+ @launched_tests = Hash.new { |hash, key| hash[key] = nil }
10
+ end
11
+
12
+ # Launches all the unit tests contained in the project
13
+ # folder
14
+ #
15
+ # @param flutter_command [String] Contains the command to launch flutter
16
+ # @param print_only_failed [Boolean] If true, prints only skipped and failed tests
17
+ # @param print_stats [Boolean] If true, it prints a table containing the info about
18
+ # the launched tests
19
+ def run(flutter_command, print_only_failed, print_stats)
20
+ Open3.popen3("#{flutter_command} test --machine") do |stdin, stdout, stderr, thread|
21
+ stdout.each_line do |line|
22
+ parse_json_output(line, print_only_failed)
23
+ end
24
+ end
25
+
26
+ if print_stats
27
+ stats = Hash.new { |hash, key| hash[key] = 0 }
28
+ @launched_tests.values.each do |item|
29
+ unless item.nil?
30
+ stats[item.get_status] += 1
31
+ end
32
+ end
33
+
34
+ skipped_tests = stats['skipped'].nil? ? 0 : stats['skipped']
35
+ failed_tests = stats['error'].nil? ? 0 : stats['error']
36
+ successful_tests = stats['success'].nil? ? 0 : stats['success']
37
+ table = [
38
+ %w[Successful Failed Skipped],
39
+ [successful_tests, failed_tests, skipped_tests]
40
+ ]
41
+
42
+ messages = ["Ran #{@launched_tests.values.count { |e| !e.nil? }} tests"]
43
+ colors = { 0 => 'green', 1 => 'red', 2 => 'blue' }
44
+ max_length = 0
45
+ (0..2).each do |i|
46
+ msg = "#{table[0][i]}:\t#{table[1][i]}"
47
+ max_length = [max_length, msg.length].max
48
+ messages.append(Utilities.new.colorize(msg, colors[i]))
49
+ end
50
+
51
+ UI.message('-' * max_length)
52
+ messages.each { |m| UI.message(m) }
53
+ UI.message('-' * max_length)
54
+
55
+ unless failed_tests == 0
56
+ UI.user_error!("There are some unitTests that fail")
57
+ end
58
+ end
59
+ end
60
+
61
+ # Parses the json output given by [self.run]
62
+ #
63
+ # @param line [String] The json as string that has to be parsed
64
+ # @param print_only_failed [Boolean] See definition on run
65
+ def parse_json_output(line, print_only_failed)
66
+ unless line.to_s.strip.empty?
67
+ output = JSON.parse(line)
68
+ unless output.kind_of?(Array)
69
+ type = output['type']
70
+ case type
71
+ when 'testStart'
72
+ id = output['test']['id']
73
+ name = output['test']['name']
74
+ if name.include?('loading')
75
+ return
76
+ end
77
+
78
+ test_item = Test.new(id, name)
79
+ @launched_tests[test_item.get_id] = test_item
80
+ when 'testDone'
81
+ test_id = output['testID']
82
+ test_item = @launched_tests[test_id]
83
+ if !test_item.nil? && test_item.can_print
84
+ was_skipped = output['skipped']
85
+ test_item.mark_as_done(output['result'], was_skipped, nil, nil)
86
+ if was_skipped || !print_only_failed
87
+ UI.message(test_item.generate_message)
88
+ end
89
+ end
90
+ when 'error'
91
+ test_id = output['testID']
92
+ test_item = @launched_tests[test_id]
93
+ if !test_item.nil? && test_item.can_print
94
+ test_item.mark_as_done('error', false, output['error'], output['stackTrace'])
95
+ UI.message(test_item.generate_message)
96
+ end
97
+ else
98
+ # ignored
99
+ end
100
+ end
101
+ end
102
+ rescue StandardError => e
103
+ UI.error("Got error during parse_json: #{e.message}")
104
+ UI.error(e.backtrace.join('\n'))
105
+ exit(1)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,71 @@
1
+ # Class that represents a single test that has been run
2
+ class Test
3
+ def initialize(id, name)
4
+ @test_id = id
5
+ @test_name = name
6
+ @test_done = false
7
+ @test_successful = ''
8
+ @test_error = nil
9
+ @test_stacktrace = nil
10
+ @test_was_skipped = false
11
+ @test_was_printed = false
12
+ end
13
+
14
+ def mark_as_done(success, skipped, error, stacktrace)
15
+ @test_done = true
16
+ @test_successful = success
17
+ @test_was_skipped = skipped
18
+ @test_error = error
19
+ unless stacktrace.nil?
20
+ stacktrace = stacktrace.gsub(/ {2,}/, "\n")
21
+ @test_stacktrace = stacktrace
22
+ end
23
+ end
24
+
25
+ def get_name
26
+ @test_name
27
+ end
28
+
29
+ def get_id
30
+ @test_id
31
+ end
32
+
33
+ def can_print
34
+ !@test_was_printed
35
+ end
36
+
37
+ def get_status
38
+ if @test_was_skipped
39
+ 'skipped'
40
+ else
41
+ @test_successful
42
+ end
43
+ end
44
+
45
+ # Generates a loggable message for the given test
46
+ #
47
+ # @return message [String] the message to print
48
+ def generate_message
49
+ @test_was_printed = true
50
+ tag = @test_was_skipped ? 'skipped' : @test_successful
51
+
52
+ default_message = "[#{tag}] #{@test_name}"
53
+ if @test_successful != 'success'
54
+ default_message += "\n[ERROR] -> #{@test_error}\n[STACKTRACE]\n#{@test_stacktrace}"
55
+ end
56
+
57
+ if %w[success error].include?(@test_successful) || @test_was_skipped
58
+ color = if @test_was_skipped
59
+ 34 # Skipped tests are displayed in blue
60
+ else
61
+ # Successful tests are in green and the failed in red
62
+ @test_successful == 'success' ? 32 : 31
63
+ end
64
+
65
+ "\e[#{color}m#{default_message}\e[0m"
66
+ else
67
+ default_message
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,26 @@
1
+ class Utilities
2
+
3
+ def initialize
4
+ @colors = {
5
+ 'blue' => 34,
6
+ 'green' => 32,
7
+ 'red' => 31,
8
+ }
9
+ end
10
+
11
+ # Colorize a message. If the color specified doesn't exists, returns the default
12
+ # message
13
+ #
14
+ # @param message [String] the message that has to be colorized before printing
15
+ # @param color [String] the name of the color
16
+ # @return [String] the message wrapped in a new color
17
+ def colorize(message, color)
18
+ if @colors.has_key? color
19
+ color_code = @colors[color]
20
+ "\e[#{color_code}m#{message}\e[0m"
21
+ else
22
+ message
23
+ end
24
+ end
25
+
26
+ end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module FlutterTests
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-flutter_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - smaso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-16 00:00:00.000000000 Z
11
+ date: 2022-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -160,7 +160,10 @@ files:
160
160
  - README.md
161
161
  - lib/fastlane/plugin/flutter_tests.rb
162
162
  - lib/fastlane/plugin/flutter_tests/actions/flutter_tests_action.rb
163
- - lib/fastlane/plugin/flutter_tests/helper/flutter_tests_helper.rb
163
+ - lib/fastlane/plugin/flutter_tests/helper/flutter_integration_test_helper.rb
164
+ - lib/fastlane/plugin/flutter_tests/helper/flutter_unit_test_helper.rb
165
+ - lib/fastlane/plugin/flutter_tests/model/test_item.rb
166
+ - lib/fastlane/plugin/flutter_tests/utils/utilities.rb
164
167
  - lib/fastlane/plugin/flutter_tests/version.rb
165
168
  homepage: https://github.com/smsimone/fastlane_flutter_tests.git
166
169
  licenses:
@@ -1,16 +0,0 @@
1
- require 'fastlane_core/ui/ui'
2
-
3
- module Fastlane
4
- UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
5
-
6
- module Helper
7
- class FlutterTestsHelper
8
- # class methods that you define here become available in your action
9
- # as `Helper::FlutterTestsHelper.your_method`
10
- #
11
- def self.show_message
12
- UI.message("Hello from the flutter_tests plugin helper!")
13
- end
14
- end
15
- end
16
- end