rainforest-cli 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/.rubocop.yml +5 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +7 -1
- data/README.md +2 -0
- data/Rakefile +6 -4
- data/circle.yml +3 -0
- data/lib/rainforest/cli.rb +20 -16
- data/lib/rainforest/cli/constants.rb +4 -0
- data/lib/rainforest/cli/csv_importer.rb +6 -6
- data/lib/rainforest/cli/git_trigger.rb +2 -1
- data/lib/rainforest/cli/http_client.rb +50 -13
- data/lib/rainforest/cli/options.rb +71 -39
- data/lib/rainforest/cli/remote_tests.rb +49 -0
- data/lib/rainforest/cli/runner.rb +19 -17
- data/lib/rainforest/cli/test_files.rb +32 -14
- data/lib/rainforest/cli/test_importer.rb +35 -155
- data/lib/rainforest/cli/test_parser.rb +38 -14
- data/lib/rainforest/cli/uploader.rb +107 -0
- data/lib/rainforest/cli/validator.rb +158 -0
- data/lib/rainforest/cli/version.rb +2 -1
- data/rainforest-cli.gemspec +14 -12
- data/spec/cli_spec.rb +84 -90
- data/spec/csv_importer_spec.rb +13 -8
- data/spec/git_trigger_spec.rb +28 -15
- data/spec/http_client_spec.rb +57 -0
- data/spec/options_spec.rb +72 -70
- data/spec/rainforest-example/example_test.rfml +2 -1
- data/spec/remote_tests_spec.rb +22 -0
- data/spec/runner_spec.rb +17 -16
- data/spec/spec_helper.rb +16 -9
- data/spec/test_files_spec.rb +20 -24
- data/spec/uploader_spec.rb +54 -0
- data/spec/validation-examples/circular_embeds/test1.rfml +5 -0
- data/spec/validation-examples/circular_embeds/test2.rfml +5 -0
- data/spec/validation-examples/correct_embeds/embedded_test.rfml +6 -0
- data/spec/validation-examples/correct_embeds/test_with_embedded.rfml +8 -0
- data/spec/validation-examples/missing_embeds/correct_test.rfml +8 -0
- data/spec/validation-examples/missing_embeds/incorrect_test.rfml +8 -0
- data/spec/validation-examples/parse_errors/no_parse_errors.rfml +6 -0
- data/spec/validation-examples/parse_errors/no_question.rfml +5 -0
- data/spec/validation-examples/parse_errors/no_question_mark.rfml +6 -0
- data/spec/validation-examples/parse_errors/no_rfml_id.rfml +5 -0
- data/spec/validator_spec.rb +119 -0
- metadata +96 -16
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class RainforestCli::RemoteTests
|
3
|
+
def initialize(api_token = nil)
|
4
|
+
Rainforest.api_key = api_token
|
5
|
+
end
|
6
|
+
|
7
|
+
def api_token_set?
|
8
|
+
!Rainforest.api_key.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
def rfml_ids
|
12
|
+
@rfml_ids ||= tests.map(&:rfml_id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def tests
|
16
|
+
@tests ||= fetch_tests
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_tests
|
20
|
+
if api_token_set?
|
21
|
+
begin
|
22
|
+
logger.info 'Syncing tests...'
|
23
|
+
tests = Rainforest::Test.all(page_size: 1000)
|
24
|
+
logger.info 'Syncing completed.'
|
25
|
+
tests
|
26
|
+
rescue Rainforest::ApiError => e
|
27
|
+
logger.error "Encountered API Error: #{e.message}"
|
28
|
+
exit 4
|
29
|
+
end
|
30
|
+
else
|
31
|
+
logger.info ''
|
32
|
+
logger.info 'No API Token set. Using local tests only...'
|
33
|
+
logger.info ''
|
34
|
+
[]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def primary_key_dictionary
|
39
|
+
@primary_key_dictionary ||= {}.tap do |primary_key_dictionary|
|
40
|
+
tests.each do |rf_test|
|
41
|
+
primary_key_dictionary[rf_test.rfml_id] = rf_test.id
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def logger
|
47
|
+
RainforestCli.logger
|
48
|
+
end
|
49
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module RainforestCli
|
2
3
|
class Runner
|
3
4
|
attr_reader :options, :client
|
@@ -16,7 +17,7 @@ module RainforestCli
|
|
16
17
|
post_opts = make_create_run_options
|
17
18
|
|
18
19
|
logger.debug "POST options: #{post_opts.inspect}"
|
19
|
-
logger.info
|
20
|
+
logger.info 'Issuing run'
|
20
21
|
|
21
22
|
response = client.post('/runs', post_opts)
|
22
23
|
|
@@ -26,7 +27,7 @@ module RainforestCli
|
|
26
27
|
end
|
27
28
|
|
28
29
|
if options.foreground?
|
29
|
-
run_id = response.fetch(
|
30
|
+
run_id = response.fetch('id')
|
30
31
|
wait_for_run_completion(run_id)
|
31
32
|
else
|
32
33
|
true
|
@@ -37,12 +38,13 @@ module RainforestCli
|
|
37
38
|
running = true
|
38
39
|
while running
|
39
40
|
Kernel.sleep 5
|
40
|
-
response = client.get("/runs/#{run_id}")
|
41
|
+
response = client.get("/runs/#{run_id}", {}, retries_on_failures: true)
|
41
42
|
if response
|
42
43
|
state_details = response.fetch('state_details')
|
43
|
-
unless state_details.fetch(
|
44
|
-
|
45
|
-
|
44
|
+
unless state_details.fetch('is_final_state')
|
45
|
+
state, current_progress = response.values_at('state', 'current_progress')
|
46
|
+
logger.info "Run #{run_id} is #{state} and is #{current_progress['percent']}% complete"
|
47
|
+
running = false if response['result'] == 'failed' && options.failfast?
|
46
48
|
else
|
47
49
|
logger.info "Run #{run_id} is now #{response["state"]} and has #{response["result"]}"
|
48
50
|
running = false
|
@@ -50,11 +52,11 @@ module RainforestCli
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
if
|
54
|
-
logger.info "The detailed results are available at #{
|
55
|
+
if response['frontend_url']
|
56
|
+
logger.info "The detailed results are available at #{response['frontend_url']}"
|
55
57
|
end
|
56
58
|
|
57
|
-
if response[
|
59
|
+
if response['result'] != 'passed'
|
58
60
|
exit 1
|
59
61
|
end
|
60
62
|
end
|
@@ -62,28 +64,28 @@ module RainforestCli
|
|
62
64
|
def make_create_run_options
|
63
65
|
post_opts = {}
|
64
66
|
if options.git_trigger?
|
65
|
-
logger.debug
|
67
|
+
logger.debug 'Checking last git commit message:'
|
66
68
|
commit_message = GitTrigger.last_commit_message
|
67
69
|
logger.debug commit_message
|
68
70
|
|
69
71
|
# Show some messages to users about tests/tags being overriden
|
70
72
|
unless options.tags.empty?
|
71
|
-
logger.warn
|
73
|
+
logger.warn 'Specified tags are ignored when using --git-trigger'
|
72
74
|
else
|
73
|
-
logger.warn
|
75
|
+
logger.warn 'Specified tests are ignored when using --git-trigger'
|
74
76
|
end
|
75
77
|
|
76
78
|
if GitTrigger.git_trigger_should_run?(commit_message)
|
77
79
|
tags = GitTrigger.extract_hashtags(commit_message)
|
78
80
|
if tags.empty?
|
79
|
-
logger.error
|
81
|
+
logger.error 'Triggered via git, but no hashtags detected. Please use commit message format:'
|
80
82
|
logger.error "\t'some message. @rainforest #tag1 #tag2"
|
81
83
|
exit 2
|
82
84
|
else
|
83
85
|
post_opts[:tags] = [tags.join(',')]
|
84
86
|
end
|
85
87
|
else
|
86
|
-
logger.info
|
88
|
+
logger.info 'Not triggering as @rainforest was not mentioned in last commit message.'
|
87
89
|
exit 0
|
88
90
|
end
|
89
91
|
else
|
@@ -116,7 +118,7 @@ module RainforestCli
|
|
116
118
|
end
|
117
119
|
|
118
120
|
def list_generators
|
119
|
-
client.get(
|
121
|
+
client.get('/generators')
|
120
122
|
end
|
121
123
|
|
122
124
|
def delete_generator(name)
|
@@ -133,12 +135,12 @@ module RainforestCli
|
|
133
135
|
|
134
136
|
def get_environment_id url
|
135
137
|
unless url_valid?(url)
|
136
|
-
logger.fatal
|
138
|
+
logger.fatal 'The custom URL is invalid'
|
137
139
|
exit 2
|
138
140
|
end
|
139
141
|
|
140
142
|
env_post_body = { name: 'temporary-env-for-custom-url-via-CLI', url: url }
|
141
|
-
environment = client.post(
|
143
|
+
environment = client.post('/environments', env_post_body)
|
142
144
|
|
143
145
|
if environment['error']
|
144
146
|
# I am talking about a URL here because the environments are pretty
|
@@ -1,32 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
class RainforestCli::TestFiles
|
2
|
-
DEFAULT_TEST_FOLDER = './spec/rainforest'
|
3
|
-
|
3
|
+
DEFAULT_TEST_FOLDER = './spec/rainforest'
|
4
|
+
FILE_EXTENSION = '.rfml'
|
4
5
|
|
5
|
-
attr_reader :test_folder, :
|
6
|
+
attr_reader :test_folder, :test_data
|
6
7
|
|
7
8
|
def initialize(test_folder = nil)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
if test_folder.nil?
|
10
|
+
RainforestCli.logger.info "No test folder supplied. Using default folder: #{DEFAULT_TEST_FOLDER}"
|
11
|
+
@test_folder = File.expand_path(DEFAULT_TEST_FOLDER)
|
12
|
+
else
|
13
|
+
@test_folder = File.expand_path(test_folder)
|
12
14
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_paths
|
18
|
+
"#{@test_folder}/**/*#{FILE_EXTENSION}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_data
|
22
|
+
if @test_data.nil?
|
23
|
+
@test_data = []
|
24
|
+
if Dir.exist?(@test_folder)
|
25
|
+
Dir.glob(test_paths) do |file_name|
|
26
|
+
@test_data << RainforestCli::TestParser::Parser.new(file_name).process
|
27
|
+
end
|
17
28
|
end
|
18
29
|
end
|
30
|
+
@test_data
|
19
31
|
end
|
20
32
|
|
21
33
|
def file_extension
|
22
|
-
|
34
|
+
FILE_EXTENSION
|
23
35
|
end
|
24
36
|
|
25
37
|
def rfml_ids
|
26
|
-
|
38
|
+
test_data.map(&:rfml_id)
|
27
39
|
end
|
28
40
|
|
29
41
|
def count
|
30
|
-
|
42
|
+
test_data.count
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_dictionary
|
46
|
+
{}.tap do |dictionary|
|
47
|
+
test_data.each { |rfml_test| dictionary[rfml_test.rfml_id] = rfml_test }
|
48
|
+
end
|
31
49
|
end
|
32
50
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'securerandom'
|
2
3
|
require 'rainforest'
|
3
4
|
require 'parallel'
|
@@ -5,7 +6,6 @@ require 'ruby-progressbar'
|
|
5
6
|
|
6
7
|
class RainforestCli::TestImporter
|
7
8
|
attr_reader :options, :client, :test_files
|
8
|
-
THREADS = 32.freeze
|
9
9
|
|
10
10
|
SAMPLE_FILE = <<EOF
|
11
11
|
#! %s (Test ID - only edit if this test has not yet been uploaded)
|
@@ -33,13 +33,17 @@ EOF
|
|
33
33
|
RainforestCli.logger
|
34
34
|
end
|
35
35
|
|
36
|
+
def threads
|
37
|
+
RainforestCli::THREADS
|
38
|
+
end
|
39
|
+
|
36
40
|
def export
|
37
41
|
tests = Rainforest::Test.all(page_size: 1000)
|
38
42
|
p = ProgressBar.create(title: 'Rows', total: tests.count, format: '%a %B %p%% %t')
|
39
|
-
Parallel.each(tests, in_threads:
|
43
|
+
Parallel.each(tests, in_threads: threads, finish: lambda { |_item, _i, _result| p.increment }) do |test|
|
40
44
|
|
41
45
|
# File name
|
42
|
-
file_name = sprintf('%010d', test.id) +
|
46
|
+
file_name = sprintf('%010d', test.id) + '_' + test.title.strip.gsub(/[^a-z0-9 ]+/i, '').gsub(/ +/, '_').downcase
|
43
47
|
file_name = create_new(file_name)
|
44
48
|
File.truncate(file_name, 0)
|
45
49
|
|
@@ -64,7 +68,7 @@ EOF
|
|
64
68
|
index = _process_element(file, sub_element, index)
|
65
69
|
end
|
66
70
|
when 'step'
|
67
|
-
file.puts
|
71
|
+
file.puts '' unless index == 0
|
68
72
|
file.puts "# step #{index + 1}" if @options.debug
|
69
73
|
file.puts element[:element][:action]
|
70
74
|
file.puts element[:element][:response]
|
@@ -81,18 +85,26 @@ EOF
|
|
81
85
|
out = []
|
82
86
|
|
83
87
|
has_id = false
|
84
|
-
test.description.to_s.strip.lines.map(&:chomp).each_with_index do |line,
|
88
|
+
test.description.to_s.strip.lines.map(&:chomp).each_with_index do |line, _line_no|
|
85
89
|
line = line.gsub(/\#+$/, '').strip
|
86
90
|
|
87
91
|
# make sure the test has an ID
|
88
|
-
has_id = true if line[0] ==
|
92
|
+
has_id = true if line[0] == '!'
|
89
93
|
|
90
|
-
out <<
|
94
|
+
out << '#' + line
|
91
95
|
end
|
92
96
|
|
93
97
|
unless has_id
|
94
|
-
browsers = test.browsers.map {|b| b[:name] if b[:state] ==
|
95
|
-
out = [
|
98
|
+
browsers = test.browsers.map {|b| b[:name] if b[:state] == 'enabled' }.compact
|
99
|
+
out = [
|
100
|
+
"#! #{SecureRandom.uuid}",
|
101
|
+
"# title: #{test.title}",
|
102
|
+
"# start_uri: #{test.start_uri}",
|
103
|
+
"# tags: #{test.tags.join(", ")}",
|
104
|
+
"# browsers: #{browsers.join(", ")}",
|
105
|
+
'#',
|
106
|
+
' ',
|
107
|
+
] + out
|
96
108
|
end
|
97
109
|
|
98
110
|
out.compact.join("\n")
|
@@ -100,9 +112,9 @@ EOF
|
|
100
112
|
|
101
113
|
def _get_id test
|
102
114
|
id = nil
|
103
|
-
test.description.to_s.strip.lines.map(&:chomp).each_with_index do |line,
|
115
|
+
test.description.to_s.strip.lines.map(&:chomp).each_with_index do |line, _line_no|
|
104
116
|
line = line.gsub(/\#+$/, '').strip
|
105
|
-
if line[0] ==
|
117
|
+
if line[0] == '!'
|
106
118
|
id = line[1..-1].split(' ').first
|
107
119
|
break
|
108
120
|
end
|
@@ -110,57 +122,24 @@ EOF
|
|
110
122
|
id
|
111
123
|
end
|
112
124
|
|
113
|
-
def upload
|
114
|
-
# Prioritize embedded tests before other tests
|
115
|
-
upload_groups = []
|
116
|
-
unordered_tests = []
|
117
|
-
queued_tests = test_files.test_data.dup
|
118
|
-
|
119
|
-
until queued_tests.empty?
|
120
|
-
new_ordered_group = []
|
121
|
-
ordered_ids = upload_groups.flatten.map(&:rfml_id)
|
122
|
-
|
123
|
-
queued_tests.each do |rfml_test|
|
124
|
-
if (rfml_test.embedded_ids - ordered_ids).empty?
|
125
|
-
new_ordered_group << rfml_test
|
126
|
-
else
|
127
|
-
unordered_tests << rfml_test
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
upload_groups << new_ordered_group
|
132
|
-
queued_tests = unordered_tests
|
133
|
-
unordered_tests = []
|
134
|
-
end
|
135
|
-
|
136
|
-
logger.info "Uploading tests..."
|
137
|
-
|
138
|
-
# Upload in parallel if order doesn't matter
|
139
|
-
if upload_groups.count > 1
|
140
|
-
upload_groups_sequentially(upload_groups)
|
141
|
-
else
|
142
|
-
upload_group_in_parallel(upload_groups.first)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
125
|
def validate
|
147
126
|
tests = {}
|
148
127
|
has_errors = []
|
149
128
|
|
150
129
|
Dir.glob(test_files.test_paths).each do |file_name|
|
151
|
-
out = RainforestCli::TestParser::Parser.new(
|
130
|
+
out = RainforestCli::TestParser::Parser.new(file_name).process
|
152
131
|
|
153
132
|
tests[file_name] = out
|
154
133
|
has_errors << file_name if out.errors != {}
|
155
134
|
end
|
156
135
|
|
157
136
|
if !has_errors.empty?
|
158
|
-
logger.error
|
159
|
-
logger.error
|
137
|
+
logger.error 'Parsing errors:'
|
138
|
+
logger.error ''
|
160
139
|
has_errors.each do |file_name|
|
161
|
-
logger.error
|
162
|
-
tests[file_name].errors.each do |
|
163
|
-
logger.error "\t#{error
|
140
|
+
logger.error ' ' + file_name
|
141
|
+
tests[file_name].errors.each do |_line, error|
|
142
|
+
logger.error "\t#{error}"
|
164
143
|
end
|
165
144
|
end
|
166
145
|
|
@@ -168,7 +147,7 @@ EOF
|
|
168
147
|
end
|
169
148
|
|
170
149
|
if @options.debug
|
171
|
-
tests.each do |file_name,test|
|
150
|
+
tests.each do |file_name, test|
|
172
151
|
logger.debug test.inspect
|
173
152
|
logger.debug "#{file_name}"
|
174
153
|
logger.debug test.description
|
@@ -177,7 +156,7 @@ EOF
|
|
177
156
|
end
|
178
157
|
end
|
179
158
|
else
|
180
|
-
logger.info
|
159
|
+
logger.info '[VALID]'
|
181
160
|
end
|
182
161
|
|
183
162
|
return tests
|
@@ -191,112 +170,13 @@ EOF
|
|
191
170
|
uuid = SecureRandom.uuid
|
192
171
|
name = "#{uuid}#{ext}" unless name
|
193
172
|
name += ext unless name[-ext.length..-1] == ext
|
194
|
-
name = File.join([@test_files.test_folder, name])
|
195
173
|
|
196
|
-
|
174
|
+
FileUtils.mkdir_p(test_files.test_folder) unless Dir.exist?(test_files.test_folder)
|
175
|
+
name = File.join([test_files.test_folder, name])
|
176
|
+
|
177
|
+
File.open(name, 'w') { |file| file.write(sprintf(SAMPLE_FILE, uuid)) }
|
197
178
|
|
198
179
|
logger.info "Created #{name}" if file_name.nil?
|
199
180
|
name
|
200
181
|
end
|
201
|
-
|
202
|
-
private
|
203
|
-
|
204
|
-
def upload_groups_sequentially(upload_groups)
|
205
|
-
progress_bar = ProgressBar.create(title: 'Rows', total: test_files.count, format: '%a %B %p%% %t')
|
206
|
-
upload_groups.each_with_index do |rfml_tests, idx|
|
207
|
-
if idx == (rfml_tests.length - 1)
|
208
|
-
upload_group_in_parallel(rfml_tests, progress_bar)
|
209
|
-
else
|
210
|
-
rfml_tests.each { |rfml_test| upload_test(rfml_test) }
|
211
|
-
progress_bar.increment
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
def upload_group_in_parallel(rfml_tests, progress_bar = nil)
|
217
|
-
progress_bar ||= ProgressBar.create(title: 'Rows', total: rfml_tests.count, format: '%a %B %p%% %t')
|
218
|
-
Parallel.each(rfml_tests, in_threads: THREADS, finish: lambda { |item, i, result| progress_bar.increment }) do |rfml_test|
|
219
|
-
upload_test(rfml_test)
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def upload_test(rfml_test)
|
224
|
-
return unless rfml_test.steps.count > 0
|
225
|
-
|
226
|
-
if @options.debug
|
227
|
-
logger.debug "Starting: #{rfml_test.rfml_id}"
|
228
|
-
logger.debug "\t#{rfml_test.start_uri || "/"}"
|
229
|
-
end
|
230
|
-
|
231
|
-
test_obj = create_test_obj(rfml_test)
|
232
|
-
# Upload the test
|
233
|
-
begin
|
234
|
-
if rfml_id_mappings[rfml_test.rfml_id]
|
235
|
-
t = Rainforest::Test.update(rfml_id_mappings[rfml_test.rfml_id], test_obj)
|
236
|
-
|
237
|
-
logger.info "\tUpdated #{rfml_test.rfml_id} -- ##{t.id}" if @options.debug
|
238
|
-
else
|
239
|
-
t = Rainforest::Test.create(test_obj)
|
240
|
-
|
241
|
-
logger.info "\tCreated #{rfml_test.rfml_id} -- ##{t.id}" if @options.debug
|
242
|
-
rfml_id_mappings[rfml_test.rfml_id] = t.id
|
243
|
-
end
|
244
|
-
rescue => e
|
245
|
-
logger.fatal "Error: #{rfml_test.rfml_id}: #{e}"
|
246
|
-
exit 2
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
def rfml_id_mappings
|
251
|
-
if @_id_mappings.nil?
|
252
|
-
@_id_mappings = {}.tap do |id_mappings|
|
253
|
-
Rainforest::Test.all(page_size: 1000, rfml_ids: test_files.rfml_ids).each do |rf_test|
|
254
|
-
rfml_id = rf_test.rfml_id
|
255
|
-
next if rfml_id.nil?
|
256
|
-
|
257
|
-
id_mappings[rfml_id] = rf_test.id
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
@_id_mappings
|
262
|
-
end
|
263
|
-
|
264
|
-
def create_test_obj(rfml_test)
|
265
|
-
test_obj = {
|
266
|
-
start_uri: rfml_test.start_uri || "/",
|
267
|
-
title: rfml_test.title,
|
268
|
-
description: rfml_test.description,
|
269
|
-
tags: (["ro"] + rfml_test.tags).uniq,
|
270
|
-
rfml_id: rfml_test.rfml_id,
|
271
|
-
elements: rfml_test.steps.map do |step|
|
272
|
-
case step.type
|
273
|
-
when :step
|
274
|
-
{
|
275
|
-
type: 'step',
|
276
|
-
redirection: true,
|
277
|
-
element: {
|
278
|
-
action: step.action,
|
279
|
-
response: step.response
|
280
|
-
}
|
281
|
-
}
|
282
|
-
when :test
|
283
|
-
{
|
284
|
-
type: 'test',
|
285
|
-
redirection: true,
|
286
|
-
element: {
|
287
|
-
id: rfml_id_mappings[step.rfml_id]
|
288
|
-
}
|
289
|
-
}
|
290
|
-
end
|
291
|
-
end
|
292
|
-
}
|
293
|
-
|
294
|
-
unless rfml_test.browsers.empty?
|
295
|
-
test_obj[:browsers] = rfml_test.browsers.map {|b|
|
296
|
-
{'state' => 'enabled', 'name' => b}
|
297
|
-
}
|
298
|
-
end
|
299
|
-
|
300
|
-
test_obj
|
301
|
-
end
|
302
182
|
end
|