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 +4 -4
- data/README.md +1 -0
- data/lib/fastlane/plugin/flutter_tests/actions/flutter_tests_action.rb +76 -105
- data/lib/fastlane/plugin/flutter_tests/helper/flutter_integration_test_helper.rb +153 -0
- data/lib/fastlane/plugin/flutter_tests/helper/flutter_unit_test_helper.rb +109 -0
- data/lib/fastlane/plugin/flutter_tests/model/test_item.rb +71 -0
- data/lib/fastlane/plugin/flutter_tests/utils/utilities.rb +26 -0
- data/lib/fastlane/plugin/flutter_tests/version.rb +1 -1
- metadata +6 -3
- data/lib/fastlane/plugin/flutter_tests/helper/flutter_tests_helper.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e134b3e53ea1a6aa94cb983cfb66ae0843b6f0bc2263eade128e99f979d80639
|
4
|
+
data.tar.gz: 1384cfda230ccfe2e055f9c2801fe90db559c947390c02842dac720c39305c81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
[](https://rubygems.org/gems/fastlane-plugin-flutter_tests)
|
4
|
+
[](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/
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
45
|
-
color = @test_successful == 'success' ? 32 : 31
|
23
|
+
platform = params[:platform]
|
46
24
|
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
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: :
|
61
|
+
key: :print_only_failed,
|
149
62
|
default_value: true,
|
150
|
-
description: 'Specifies if it should print the
|
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
|
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.
|
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-
|
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/
|
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
|