hiptest-publisher 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9917743576cd4e61c3005e0a9535b676bdaa3e8
4
- data.tar.gz: ae0187d7a2438b75d5369d0231e66bae458c7c00
3
+ metadata.gz: f62cf6aaf55b81aad2d311374fc50eee0f21ae64
4
+ data.tar.gz: 9ccd226707291c53a08a1adb56a36b1faa08c3fb
5
5
  SHA512:
6
- metadata.gz: 76bca6131d95f2302981d3bf6c0c74ee9d17f34bad68a369b37eb60a583b9e4132d332c6d8cb4283d180f844131e1b023829ae723e03c81250caff9ef47b2eaf
7
- data.tar.gz: c087c267d1084c11240bb4976a0c11bb36c2ace85cb1aa9897afaa33640d8b1d29a99cdd9aed1ba536702af793e305d1ece4058e51a22039b16e93e5496915d4
6
+ metadata.gz: dd59e98723dce31fd67a3e9e3af79ef57a0606d35a897aa73fc30664c6be1829a5e0641d3bf9c976e7ed9dc1171caab072e7f9bbad63a4fd482e503d16fc2b17
7
+ data.tar.gz: b42c26037f100b8984c4fb9c074ce0bce6d15bde8d11a7419c6a4b95c9f6af1cc49e73bbb486ca98ca54b4393739b4ef26f54d889b790d3f6b8b55d83cb1615c
data/README.md CHANGED
@@ -56,6 +56,7 @@ Specific options:
56
56
  -f, --framework=FRAMEWORK Test framework to use
57
57
  -o, --output-directory=PATH Output directory (default: .)
58
58
  -c, --config-file=PATH Configuration file (default: config)
59
+ --test-run-id=ID Export data from a test run
59
60
  --scenario-ids=IDS Filter scenarios by ids
60
61
  --scenario-tags=TAGS Filter scenarios by tags
61
62
  --tests-only Export only the tests (default: false)
@@ -63,6 +64,7 @@ Specific options:
63
64
  --split-scenarios Export each scenario in a single file (default: false)
64
65
  --leafless-export Use only last level action word (default: false)
65
66
  -s, --site=SITE Site to fetch from (default: https://hiptest.net)
67
+ -p, --push=FILE.TAP Push a results file to the server
66
68
  -v, --verbose Run verbosely (default: false)
67
69
  -H, --languages-help Show languages and framework options
68
70
  -F, --filters-help Show help about scenario filtering
@@ -13,6 +13,11 @@ module Hiptest
13
13
  def initialize(args)
14
14
  @options = OptionsParser.parse(args)
15
15
 
16
+ unless @options.push.nil? || @options.push.empty?
17
+ post_results
18
+ return
19
+ end
20
+
16
21
  xml = fetch_xml_file
17
22
  return if xml.nil?
18
23
 
@@ -106,6 +111,8 @@ module Hiptest
106
111
  end
107
112
 
108
113
  def export
114
+ return if @project.nil?
115
+
109
116
  @language_config = LanguageConfigParser.new(@options)
110
117
  Hiptest::Nodes::ParentAdder.add(@project)
111
118
  Hiptest::Nodes::ParameterTypeAdder.add(@project)
@@ -117,5 +124,18 @@ module Hiptest
117
124
 
118
125
  export_actionwords unless @options.tests_only
119
126
  end
127
+
128
+ def post_results
129
+ status_message = "Posting #{@options.push} to #{@options.site}"
130
+ show_status_message(status_message)
131
+
132
+ begin
133
+ push_results(@options)
134
+ show_status_message(status_message, :success)
135
+ rescue Exception => err
136
+ show_status_message(status_message, :failure)
137
+ trace_exception(err) if @options.verbose
138
+ end
139
+ end
120
140
  end
121
141
  end
@@ -233,6 +233,9 @@ module Hiptest
233
233
  end
234
234
 
235
235
  class Actionword < Item
236
+ def must_be_implemented?
237
+ @children[:body].empty? || @children[:body].map {|step| step.class}.compact.include?(Hiptest::Nodes::Step)
238
+ end
236
239
  end
237
240
 
238
241
  class Scenario < Item
@@ -245,6 +248,10 @@ module Hiptest
245
248
 
246
249
  @folder_uid = folder_uid
247
250
  end
251
+
252
+ def set_uid(uid)
253
+ @children[:uid] = uid
254
+ end
248
255
  end
249
256
 
250
257
  class Test < Node
@@ -279,12 +286,32 @@ module Hiptest
279
286
  :arguments => arguments
280
287
  }
281
288
  end
289
+
290
+ def set_uid(uid)
291
+ @children[:uid] = uid
292
+ end
282
293
  end
283
294
 
284
295
  class Actionwords < Node
296
+ attr_reader :to_implement, :no_implement
285
297
  def initialize(actionwords = [])
286
298
  super()
287
299
  @children = {:actionwords => actionwords}
300
+ mark_actionwords_for_implementation
301
+ end
302
+
303
+ private
304
+ def mark_actionwords_for_implementation
305
+ @to_implement = []
306
+ @no_implement = []
307
+
308
+ @children[:actionwords].each do |aw|
309
+ if aw.must_be_implemented?
310
+ @to_implement << aw
311
+ else
312
+ @no_implement << aw
313
+ end
314
+ end
288
315
  end
289
316
  end
290
317
 
@@ -75,6 +75,7 @@ class OptionsParser
75
75
  Option.new('f', 'framework=FRAMEWORK', '', String, "Test framework to use", :framework),
76
76
  Option.new('o', 'output-directory=PATH', '.', String, "Output directory", :output_directory),
77
77
  Option.new('c', 'config-file=PATH', 'config', String, "Configuration file", :config),
78
+ Option.new(nil, 'test-run-id=ID', '', String, "Export data from a test run", :test_run_id),
78
79
  Option.new(nil, 'scenario-ids=IDS', '', String, "Filter scenarios by ids", :filter_ids),
79
80
  Option.new(nil, 'scenario-tags=TAGS', '', String, "Filter scenarios by tags", :filter_tags),
80
81
  Option.new(nil, 'tests-only', false, nil, "Export only the tests", :tests_only),
@@ -82,6 +83,7 @@ class OptionsParser
82
83
  Option.new(nil, 'split-scenarios', false, nil, "Export each scenario in a single file", :split_scenarios),
83
84
  Option.new(nil, 'leafless-export', false, nil, "Use only last level action word", :leafless_export),
84
85
  Option.new('s', 'site=SITE', 'https://hiptest.net', String, "Site to fetch from", :site),
86
+ Option.new('p', 'push=FILE.TAP', '', String, "Push a results file to the server", :push),
85
87
  Option.new('v', 'verbose', false, nil, "Run verbosely", :verbose)
86
88
  ]
87
89
  end
@@ -1,6 +1,7 @@
1
1
  require 'open-uri'
2
2
  require 'openssl'
3
3
  require 'colorize'
4
+ require 'net/http/post/multipart'
4
5
 
5
6
  def hiptest_publisher_path
6
7
  Gem.loaded_specs['hiptest-publisher'].full_gem_path
@@ -17,7 +18,12 @@ def make_filter(options)
17
18
  end
18
19
 
19
20
  def fetch_project_export(options)
20
- url = "#{options.site}/publication/#{options.token}/#{options.leafless_export ? 'leafless_tests' : 'project'}?future=1#{make_filter(options)}"
21
+ url = "#{options.site}/publication/#{options.token}"
22
+ if options.test_run_id.nil? || options.test_run_id.empty?
23
+ url = "#{url}/#{options.leafless_export ? 'leafless_tests' : 'project'}?future=1#{make_filter(options)}"
24
+ else
25
+ url = "#{url}/test_run/#{options.test_run_id}"
26
+ end
21
27
 
22
28
  puts "URL: #{url}".white if options.verbose
23
29
  open(url, :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE)
@@ -44,4 +50,22 @@ def show_status_message(message, status=nil)
44
50
  end
45
51
 
46
52
  output.print "[#{status_icon}] #{message}\r#{line_end}"
53
+ end
54
+
55
+ def make_push_url(options)
56
+ "#{options.site}/import_test_results/#{options.token}/tap"
57
+ end
58
+
59
+ def push_results(options)
60
+ # Code from: https://github.com/nicksieger/multipart-posthttps://github.com/nicksieger/multipart-post
61
+ url = URI.parse(make_push_url(options))
62
+ use_ssl = make_push_url(options).start_with?('https://')
63
+
64
+ File.open(options.push) do |results|
65
+ req = Net::HTTP::Post::Multipart.new(url.path, "file" => UploadIO.new(results, "text", "results.tap"))
66
+
67
+ response = Net::HTTP.start(url.host, url.port, :use_ssl => use_ssl) do |http|
68
+ http.request(req)
69
+ end
70
+ end
47
71
  end
@@ -180,21 +180,39 @@ module Hiptest
180
180
 
181
181
  def build_actionword(actionword)
182
182
  Hiptest::Nodes::Actionword.new(
183
- css_first_content(actionword, 'name'),
183
+ css_first_content(actionword, '> name'),
184
184
  build_tags(actionword),
185
185
  build_parameters(actionword),
186
186
  build_steps(actionword))
187
187
  end
188
+ alias :build_actionwordSnapshot :build_actionword
188
189
 
189
190
  def build_scenario(scenario)
190
191
  Hiptest::Nodes::Scenario.new(
191
- css_first_content(scenario, 'name'),
192
- css_first_content(scenario, 'description'),
192
+ css_first_content(scenario, '> name'),
193
+ css_first_content(scenario, '> description'),
193
194
  build_tags(scenario),
194
195
  build_parameters(scenario),
195
196
  build_steps(scenario),
196
- css_first_content(scenario, 'folderUid'),
197
- build_node(css_first(scenario, 'datatable'), Hiptest::Nodes::Datatable))
197
+ css_first_content(scenario, '> folderUid'),
198
+ build_node(css_first(scenario, '> datatable'), Hiptest::Nodes::Datatable))
199
+ end
200
+
201
+ def build_scenarioSnapshot(scs)
202
+ scenario = build_scenario(scs)
203
+ datasets = scenario.find_sub_nodes(Hiptest::Nodes::Dataset)
204
+
205
+ if datasets.empty?
206
+ scenario.set_uid(css_first_content(scs, 'testSnapshot > uid'))
207
+ else
208
+ scs.css('testSnapshot').each do |testSnapshot|
209
+ uid = css_first_content(testSnapshot, '> uid')
210
+ index = css_first_content(testSnapshot, '> index').to_i
211
+
212
+ datasets[index].set_uid(uid) unless index >= datasets.length
213
+ end
214
+ end
215
+ scenario
198
216
  end
199
217
 
200
218
  def build_datatable(datatable)
@@ -207,12 +225,20 @@ module Hiptest
207
225
  build_node_list(dataset.css('> arguments argument')))
208
226
  end
209
227
 
210
- def build_actionwords(actionwords)
211
- build_node_list(actionwords.css('> actionword'), Hiptest::Nodes::Actionwords)
228
+ def build_actionwords(actionwords, actionwords_query = '> actionword')
229
+ build_node_list(actionwords.css(actionwords_query), Hiptest::Nodes::Actionwords)
230
+ end
231
+
232
+ def build_actionwordSnapshots(actionword_snapshots)
233
+ build_actionwords(actionword_snapshots, '> actionwordSnapshot')
212
234
  end
213
235
 
214
- def build_scenarios(scenarios)
215
- build_node_list(scenarios.css('> scenario'), Hiptest::Nodes::Scenarios)
236
+ def build_scenarios(scenarios, scenarios_query = '> scenario')
237
+ build_node_list(scenarios.css(scenarios_query), Hiptest::Nodes::Scenarios)
238
+ end
239
+
240
+ def build_scenarioSnapshots(scenario_snapshots)
241
+ build_scenarios(scenario_snapshots, '> scenarioSnapshot')
216
242
  end
217
243
 
218
244
  def build_tests(tests)
@@ -234,24 +260,40 @@ module Hiptest
234
260
  css_first_content(folder, 'parentUid'),
235
261
  css_first_content(folder, 'name'))
236
262
  end
263
+ alias :build_folderSnapshot :build_folder
237
264
 
238
- def build_testPlan(test_plan)
265
+ def build_testPlan(test_plan, folders_query = '> folder')
239
266
  tp = Hiptest::Nodes::TestPlan.new(
240
- build_node_list(test_plan.css('> folder')))
267
+ build_node_list(test_plan.css(folders_query)))
241
268
 
242
269
  tp.organize_folders
243
270
  return tp
244
271
  end
245
272
 
273
+ def build_folderSnapshots(folder_snapshots)
274
+ build_testPlan(folder_snapshots, '> folderSnapshot')
275
+ end
276
+
246
277
  def build_project
247
278
  project = css_first(@xml, 'project')
279
+ test_run = css_first(project, '> testRuns > testRun')
280
+
281
+ if test_run.nil?
282
+ test_plan_node = css_first(project, '> testPlan')
283
+ scenarios_node = css_first(project, '> scenarios')
284
+ actionwords_node = css_first(project, '> actionwords')
285
+ else
286
+ test_plan_node = css_first(test_run, '> folderSnapshots')
287
+ scenarios_node = css_first(test_run, '> scenarioSnapshots')
288
+ actionwords_node = css_first(test_run, '> actionwordSnapshots')
289
+ end
248
290
 
249
291
  @project = Hiptest::Nodes::Project.new(
250
292
  css_first_content(project, '> name'),
251
293
  css_first_content(project, '> description'),
252
- build_node(css_first(project, '> testPlan'), Hiptest::Nodes::TestPlan),
253
- build_node(css_first(project, '> scenarios'), Hiptest::Nodes::Scenarios),
254
- build_node(css_first(project, '> actionwords'), Hiptest::Nodes::Actionwords),
294
+ build_node(test_plan_node, Hiptest::Nodes::TestPlan),
295
+ build_node(scenarios_node, Hiptest::Nodes::Scenarios),
296
+ build_node(actionwords_node, Hiptest::Nodes::Actionwords),
255
297
  build_node(css_first(project, '> tests'), Hiptest::Nodes::Tests))
256
298
 
257
299
  @project.assign_scenarios_to_folders
@@ -3,5 +3,5 @@
3
3
  {{else}}{{#comment '//'}}{{{ rendered_children.description }}}
4
4
  {{#if has_tags?}}Tags: {{{ join rendered_children.tags ' '}}}{{/if}}
5
5
  {{/comment}}
6
- public void test{{{ camelize rendered_children.name }}}() {{#curly}}{{> body}}
6
+ public void test{{{ camelize rendered_children.name }}}{{#if rendered_children.uid}}Uid{{{ normalize rendered_children.uid}}}{{/if}}() {{#curly}}{{> body}}
7
7
  {{/curly}}{{/if}}
@@ -1,3 +1,3 @@
1
- public void test{{{ camelize scenario_name}}}{{{ camelize rendered_children.name}}}() {
1
+ public void test{{{ camelize scenario_name}}}{{{ camelize rendered_children.name}}}{{#if rendered_children.uid}}Uid{{{ normalize rendered_children.uid}}}{{/if}}() {
2
2
  {{{ camelize_lower scenario_name }}}({{{ join rendered_children.arguments ', '}}});
3
3
  }
@@ -4,5 +4,5 @@
4
4
  {{#if has_tags?}}Tags: {{{ join rendered_children.tags ' '}}}{{/if}}
5
5
  {{/comment}}
6
6
  @Test
7
- public void {{{ camelize_lower rendered_children.name }}}() {{#curly}}{{> body}}
7
+ public void {{{ camelize_lower rendered_children.name }}}{{#if rendered_children.uid}}Uid{{{ normalize rendered_children.uid}}}{{/if}}() {{#curly}}{{> body}}
8
8
  {{/curly}}{{/if}}
@@ -1,4 +1,4 @@
1
1
  @Test
2
- public void {{{ camelize_lower scenario_name}}}{{{ camelize rendered_children.name}}}() {
2
+ public void {{{ camelize_lower scenario_name}}}{{{ camelize rendered_children.name}}}{{#if rendered_children.uid}}Uid{{{ normalize rendered_children.uid}}}{{/if}}() {
3
3
  {{{ camelize_lower scenario_name }}}({{{ join rendered_children.arguments ', '}}});
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {{#if has_datasets?}}{{> item_as_def}}
2
2
  {{{ rendered_children.datatable }}}
3
- {{else}}def test_{{{ normalize rendered_children.name }}}({{> parameters}}):
3
+ {{else}}def test_{{{ normalize rendered_children.name }}}{{#if rendered_children.uid}}_uid{{{ normalize rendered_children.uid}}}{{/if}}({{> parameters}}):
4
4
  {{> body}}{{/if}}
@@ -1,2 +1,2 @@
1
- def test_{{{ normalize scenario_name}}}_{{{ normalize_lower rendered_children.name}}}(self):
1
+ def test_{{{ normalize scenario_name}}}_{{{ normalize_lower rendered_children.name}}}{{#if rendered_children.uid}}_uid{{{ normalize rendered_children.uid}}}{{/if}}(self):
2
2
  self.{{{ underscore scenario_name }}}({{{ join rendered_children.arguments ', ' }}})
@@ -1,4 +1,4 @@
1
- {{{ underscore rendered_children.name }}}{{#indent}}
1
+ {{{ underscore rendered_children.name }}}{{#if rendered_children.uid}}_uid{{{ normalize rendered_children.uid}}}{{/if}}{{#indent}}
2
2
  {{#if has_parameters?}}[Arguments]{{{ tab }}}{{{ join rendered_children.parameters "\t"}}}
3
3
  {{/if}}{{#each rendered_children.body}}{{{ this }}}
4
4
  {{/each}}{{/indent}}
@@ -1 +1 @@
1
- {{{ rendered_children.name}}}{{{ tab }}}{{{ join rendered_children.arguments '\t'}}}
1
+ {{{ rendered_children.name}}}{{#if rendered_children.uid}} (uid:{{{rendered_children.uid}}}){{/if}}{{{ tab }}}{{{ join rendered_children.arguments '\t'}}}
@@ -1,5 +1,5 @@
1
1
  {{#if has_datasets?}}context "{{{ remove_quotes rendered_children.name }}}" do{{#indent}}
2
2
  {{> item_as_def}}
3
- {{{ rendered_children.datatable }}}{{/indent}}{{else}}it "{{{ remove_quotes rendered_children.name }}}" do
3
+ {{{ rendered_children.datatable }}}{{/indent}}{{else}}it "{{{ remove_quotes rendered_children.name }}}{{#if rendered_children.uid}} (uid:{{{rendered_children.uid}}}){{/if}}" do
4
4
  {{> body}}{{/if}}
5
5
  end
@@ -1,3 +1,3 @@
1
- it "{{{remove_quotes rendered_children.name}}}" do
1
+ it "{{{remove_quotes rendered_children.name}}}{{#if rendered_children.uid}} (uid:{{{rendered_children.uid}}}){{/if}}" do
2
2
  {{{ underscore scenario_name }}}({{{ join rendered_children.arguments ', ' }}})
3
3
  end
@@ -1,4 +1,4 @@
1
1
  {{#if has_datasets?}}{{> item_as_def}}
2
- {{{ rendered_children.datatable }}}{{else}}def test_{{{ normalize rendered_children.name }}}
2
+ {{{ rendered_children.datatable }}}{{else}}def test_{{{ normalize rendered_children.name }}}{{#if rendered_children.uid}}_uid{{{ normalize rendered_children.uid}}}{{/if}}
3
3
  {{> body}}
4
4
  end{{/if}}
@@ -1,3 +1,3 @@
1
- def test_{{{ normalize scenario_name}}}_{{{ normalize_lower rendered_children.name}}}
1
+ def test_{{{ normalize scenario_name}}}_{{{ normalize_lower rendered_children.name}}}{{#if rendered_children.uid}}_uid{{{ normalize rendered_children.uid}}}{{/if}}
2
2
  {{{ underscore scenario_name }}}({{{ join rendered_children.arguments ', ' }}})
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiptest-publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiptest R&D
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-26 00:00:00.000000000 Z
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -110,6 +110,20 @@ dependencies:
110
110
  - - "~>"
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0.6'
113
+ - !ruby/object:Gem::Dependency
114
+ name: multipart-post
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :runtime
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
113
127
  - !ruby/object:Gem::Dependency
114
128
  name: rspec
115
129
  requirement: !ruby/object:Gem::Requirement
@@ -397,7 +411,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
397
411
  version: '0'
398
412
  requirements: []
399
413
  rubyforge_project:
400
- rubygems_version: 2.2.2
414
+ rubygems_version: 2.4.3
401
415
  signing_key:
402
416
  specification_version: 4
403
417
  summary: Export your tests from Hiptest into executable tests.