Class: KrakenMobile::Reporter

Inherits:
Object
  • Object
show all
Defined in:
lib/kraken-mobile/helpers/reporter.rb

Constant Summary collapse

PASSED =
'passed'
FAILED =
'failed',
SKIPPED = 'skipped',
PENDING = 'pending',
NOT_DEFINED = 'undefined',
AMBIGUOUS = 'ambiguous'

Instance Method Summary collapse

Constructor Details

#initialize(execution_id, options) ⇒ Reporter

Returns a new instance of Reporter.



15
16
17
18
# File 'lib/kraken-mobile/helpers/reporter.rb', line 15

def initialize(execution_id, options)
  @execution_id = execution_id
  @options = options
end

Instance Method Details

#branches(features_report) ⇒ Object

0: create 1: commit 2: merge



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/kraken-mobile/helpers/reporter.rb', line 238

def branches features_report
  branches = {}
  features_report.keys.each do |key|
    report = features_report[key]
    branches[report["hash"]] = {} if !branches[report["hash"]]
    branches[report["hash"]]["steps"]= [] if !branches[report["hash"]]["steps"]
    devices = report["devices"]
    devices.keys.each do |device_key|
      branches[report["hash"]]["steps"] << { type: 0, name: device_key }
      feature_steps = devices[device_key][0]["steps"] if devices[device_key].count > 0 && devices[device_key][0]["steps"]
      feature_steps.each do |step|
        hash_step = { type: 1, name: device_key}
        hash_step[:image] = step["after"][0]["embeddings"][0] if step["after"].count > 0 && step["after"][0]["embeddings"] && step["after"][0]["embeddings"].count > 0
        branches[report["hash"]]["steps"] << hash_step
      end
    end
  end
  branches
end

#failed_features(features) ⇒ Object



278
279
280
# File 'lib/kraken-mobile/helpers/reporter.rb', line 278

def failed_features features
  features.select{ |feature| failed_scenarios(feature) == feature["elements"].count }
end

#failed_scenarios(feature) ⇒ Object



307
308
309
310
311
312
313
# File 'lib/kraken-mobile/helpers/reporter.rb', line 307

def failed_scenarios feature
  scenarios = feature["elements"]
  scenarios.select{ |scenario|
    steps = scenario["steps"]
    steps.any?{ |step| step["result"] && step["result"]["status"] != PASSED }
  }
end


112
113
114
115
116
117
118
# File 'lib/kraken-mobile/helpers/reporter.rb', line 112

def feature_by_nodes_and_links features_report
  features = []
  features_report.values.each do |feature|
    features << nodes_and_links(feature["devices"], feature["name"]) if feature["devices"]
  end
  features
end

#feature_duration(feature) ⇒ Object



282
283
284
285
286
287
288
289
# File 'lib/kraken-mobile/helpers/reporter.rb', line 282

def feature_duration feature
  scenarios = feature["elements"]
  how_long = 0
  scenarios.each do |scenario|
    how_long += scenario_duration(scenario)
  end
  how_long
end

#feature_failed_scenarios_percentage(feature) ⇒ Object



351
352
353
# File 'lib/kraken-mobile/helpers/reporter.rb', line 351

def feature_failed_scenarios_percentage feature
  (failed_scenarios(feature).count.to_f/feature["elements"].count.to_f).round(2) * 100.00
end

#feature_id(feature) ⇒ Object



270
271
272
# File 'lib/kraken-mobile/helpers/reporter.rb', line 270

def feature_id feature
  Digest::SHA256.hexdigest("#{feature["id"].strip}#{feature["uri"].strip}")
end

#feature_passed?(feature) ⇒ Boolean

Returns:

  • (Boolean)


371
372
373
# File 'lib/kraken-mobile/helpers/reporter.rb', line 371

def feature_passed? feature
  passed_scenarios(feature).count == feature["elements"].count
end

#feature_passed_scenarios_percentage(feature) ⇒ Object



347
348
349
# File 'lib/kraken-mobile/helpers/reporter.rb', line 347

def feature_passed_scenarios_percentage feature
  (passed_scenarios(feature).count.to_f/feature["elements"].count.to_f).round(2) * 100.00
end

#fetures_from_report_by_devices(report_by_devices) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/kraken-mobile/helpers/reporter.rb', line 80

def fetures_from_report_by_devices report_by_devices
  features = {}
  report_by_devices.keys.each do |user_key|
    report = report_by_devices[user_key]
    report.each do |feature|
      features[feature["id"]] = {} if !features[feature["id"]]
      features[feature["id"]]["name"] = feature["name"] if !features[feature["id"]]["name"] && feature["name"]
      features[feature["id"]]["devices"] = {} if !features[feature["id"]]["devices"]
      if feature["elements"] && feature["elements"].count > 0
        features[feature["id"]]["devices"][user_key] = []
        if feature["elements"].first["steps"]
          failed = false
          feature["elements"].first["steps"].each do |step|
            next if failed
            failed = step["result"]["status"] != PASSED
            image = nil
            image = step["after"].first["embeddings"].first["data"] if step["after"] && step["after"].count > 0 && step["after"].first["embeddings"] && step["after"].first["embeddings"].count > 0
            features[feature["id"]]["devices"][user_key] << {
              name: "#{step['keyword']} #{step['name']}",
              duration: step["result"]["duration"],
              image: image,
              device_model: feature["device_model"],
              status: failed ? FAILED : PASSED
            }
          end
        end
      end
    end
  end
  features
end

#format_duration(nanoseconds) ⇒ Object



375
376
377
378
379
# File 'lib/kraken-mobile/helpers/reporter.rb', line 375

def format_duration(nanoseconds)
  duration_in_seconds = nanoseconds.to_f/1000000000.0
  m, s = duration_in_seconds.divmod(60)
  "#{m}m #{format('%.3f', s)}s"
end

#generate_device_report(device) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/kraken-mobile/helpers/reporter.rb', line 44

def generate_device_report device
  @apk_path = device.config["apk_path"] ? device.config["apk_path"] : @options[:apk_path]
  report_file = open("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/#{KrakenMobile::Constants::REPORT_FILE_NAME}.json")
  content = report_file.read
  @features = JSON.parse(content)
  @total_scenarios = total_scenarios @features
  @device = device
  @total_failed_scenarios_percentage = total_failed_scenarios_percentage @features
  @total_passed_scenarios_percentage = total_passed_scenarios_percentage @features
  @total_passed_features_percentage = total_passed_features_percentage @features
  @total_failed_features_percentage = total_failed_features_percentage @features
  erb_file = File.join(File.expand_path("../../../../reporter/", __FILE__), "feature_report.html.erb")
  html_file = File.join(File.expand_path("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/"), File.basename(erb_file, '.erb')) #=>"page.html"
  # Variables
  template = File.read(erb_file)
  result = ERB.new(template).result(binding)
  # write result to file
  File.open(html_file, 'w+') do |f|
    f.write result
  end
  generate_features_report @features, device
end

#generate_feature_report(feature, device) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/kraken-mobile/helpers/reporter.rb', line 222

def generate_feature_report feature, device
  Dir.mkdir("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/features_report") unless File.exists?("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/features_report")
  file_name = feature_id feature
  erb_file = File.join(File.expand_path("../../../../reporter/", __FILE__), "scenario_report.html.erb")
  html_file = File.join(File.expand_path("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/features_report"), "#{file_name}.html") #=>"page.html"
  # Variables
  @feature = feature
  template = File.read(erb_file)
  result = ERB.new(template).result(binding)
  # write result to file
  File.open(html_file, 'w+') do |f|
    f.write result
  end
end

#generate_features_report(features, device) ⇒ Object



216
217
218
219
220
# File 'lib/kraken-mobile/helpers/reporter.rb', line 216

def generate_features_report features, device
  features.each do |feature|
    generate_feature_report feature, device
  end
end

#generate_general_reportObject


Generator




23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/kraken-mobile/helpers/reporter.rb', line 23

def generate_general_report
  erb_file = File.join(File.expand_path("../../../../reporter/", __FILE__), "index.html.erb")
  html_file = File.join(File.expand_path("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/"), "index.html")
  # Variables
  report_file = open("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{KrakenMobile::Constants::REPORT_DEVICES_FILE_NAME}.json")
  content = report_file.read
  @devices = JSON.parse(content)
  devices_report = report_by_devices(@devices)
  @features_report = fetures_from_report_by_devices devices_report
  data_hash = feature_by_nodes_and_links @features_report
  file = open("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/assets/js/#{KrakenMobile::Constants::D3_DATA_FILE_NAME}.json", 'w')
  file.puts(data_hash.to_json)
  file.close
  template = File.read(erb_file)
  result = ERB.new(template).result(binding)
  # write result to file
  File.open(html_file, 'w+') do |f|
    f.write result
  end
end

#isReadSignal(step) ⇒ Object



196
197
198
199
# File 'lib/kraken-mobile/helpers/reporter.rb', line 196

def isReadSignal step
  line = step.split(' ')[1..-1].join(' ')
  (line =~ /^I wait for a signal containing "([^\"]*)"$/ ? true : false) || (line =~ /^I wait for a signal containing "([^\"]*)" for (\d+) seconds$/ ? true : false)
end

#isWriteSignal(step) ⇒ Object



201
202
203
204
# File 'lib/kraken-mobile/helpers/reporter.rb', line 201

def isWriteSignal step
  line = step.split(' ')[1..-1].join(' ')
  line =~ /^I send a signal to user (\d+) containing "([^\"]*)"$/ ? true : false
end


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/kraken-mobile/helpers/reporter.rb', line 120

def nodes_and_links feature_report, feature_name
  last_node_id = 0
  nodes = [{ name: "", id: "empty", image: nil }]
  signal_hash = {}
  links = []
  feature_report.keys.each do |key|
    steps = feature_report[key]
    coming_from_signal = false
    last_signal = -1
    steps.each_with_index do |step, index|
      node_id = last_node_id+1
      if isReadSignal(step[:name]) && step[:status] == PASSED
        signal = signalContent(step[:name])
        already_created_signal = signal_hash[signal] ? true : false
        signal_hash[signal] = already_created_signal ? signal_hash[signal] : { id: "#{node_id}", receiver: key }
        node = { name: "Signal: #{signal}, Receiver: #{step[:device_model]}", id: signal_hash[signal][:id], image: nil, status: step[:status] }
        if already_created_signal
          entry = nodes.select{ |node| node[:id] == signal_hash[signal][:id] }.first
          entry[:name] = "Signal: #{signal}, Receiver: #{step[:device_model]}" if entry
        end
        source = (coming_from_signal ? last_signal : (index == 0 ? 0 : last_node_id))
        link = {
          source: source,
          target: signal_hash[signal][:id].to_i,
          value: 1,
          owner: key,
          owner_model: step[:device_model]
        }
        nodes << node if !already_created_signal
        links << link
        last_node_id += 1 if !already_created_signal
        last_signal = signal_hash[signal][:id].to_i
        coming_from_signal = true
      elsif isWriteSignal(step[:name]) && step[:status] == PASSED
        signal = signalContent(step[:name])
        receiver = signalReceiver(step[:name])
        already_created_signal = signal_hash[signal] ? true : false
        signal_hash[signal] = already_created_signal ? signal_hash[signal] : { id: "#{node_id}", receiver: receiver }
        node = { name: step[:name], id: signal_hash[signal][:id], image: nil, status: step[:status] }
        source = (coming_from_signal ? last_signal : (index == 0 ? 0 : last_node_id))
        link = {
          source: source,
          target: signal_hash[signal][:id].to_i,
          value: 1,
          owner: key,
          owner_model: step[:device_model]
        }
        nodes << node if !already_created_signal
        links << link
        last_node_id += 1 if !already_created_signal
        last_signal = signal_hash[signal][:id].to_i
        coming_from_signal = true
      else
        node = { name: step[:name], id: "#{node_id}", image: step[:image], status: step[:status] }
        source = (coming_from_signal ? last_signal : (index == 0 ? 0 : last_node_id))
        link = {
          source: source,
          target: node_id,
          value: 1,
          owner: key,
          owner_model: step[:device_model]
        }
        nodes << node
        links << link
        last_node_id += 1
        coming_from_signal = false
      end
    end
  end
  return {
    name: feature_name,
    nodes: nodes,
    links: links
  }
end

#passed_features(features) ⇒ Object



274
275
276
# File 'lib/kraken-mobile/helpers/reporter.rb', line 274

def passed_features features
  features.select{ |feature| passed_scenarios(feature) == feature["elements"].count }
end

#passed_scenarios(feature) ⇒ Object



299
300
301
302
303
304
305
# File 'lib/kraken-mobile/helpers/reporter.rb', line 299

def passed_scenarios feature
    scenarios = feature["elements"]
    scenarios.select{ |scenario|
      steps = scenario["steps"]
      steps.all?{ |step| step["result"] && step["result"]["status"] == PASSED }
    }
end

#report_by_devices(devices) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/kraken-mobile/helpers/reporter.rb', line 67

def report_by_devices devices
  devices_report = {}
  devices.each do |device|
    next if !File.exists?("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device['id']}/#{KrakenMobile::Constants::REPORT_FILE_NAME}.json")
    report_file = open("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device['id']}/#{KrakenMobile::Constants::REPORT_FILE_NAME}.json")
    content = report_file.read
    devices_report[device['user']] = JSON.parse(content)
    devices_report[device['user']].each do |d| d["device_model"] = device["model"] if !d["device_model"] end
    devices_report[device['user']].each do |d| d["device_id"] = device["id"] if !d["device_id"] end
  end
  devices_report
end

#scenario_duration(scenario) ⇒ Object



291
292
293
294
295
296
297
# File 'lib/kraken-mobile/helpers/reporter.rb', line 291

def scenario_duration scenario
  how_long = 0
  scenario["steps"].each do |step|
    how_long += step["result"]["duration"] if step["result"] && step["result"]["duration"]
  end
  how_long
end

#signalContent(step) ⇒ Object



206
207
208
209
# File 'lib/kraken-mobile/helpers/reporter.rb', line 206

def signalContent step
  line = step.split(' ')[1..-1].join(' ')
  line.scan(/"([^\"]*)"/).first.first if line.scan(/"([^\"]*)"/).first
end

#signalReceiver(step) ⇒ Object



211
212
213
214
# File 'lib/kraken-mobile/helpers/reporter.rb', line 211

def signalReceiver step
  line = step.split(' ')[1..-1].join(' ')
  line.scan(/(\d+)/).first.first if line.scan(/(\d+)/).first
end

#total_failed_features(features) ⇒ Object



339
340
341
342
343
344
345
# File 'lib/kraken-mobile/helpers/reporter.rb', line 339

def total_failed_features features
  how_many = 0
  features.each do |feature|
    how_many += 1 if !feature_passed?(feature)
  end
  how_many
end

#total_failed_features_percentage(features) ⇒ Object



367
368
369
# File 'lib/kraken-mobile/helpers/reporter.rb', line 367

def total_failed_features_percentage features
  (total_failed_features(features).to_f/features.count.to_f).round(2) * 100.00
end

#total_failed_scenarios(features) ⇒ Object



323
324
325
326
327
328
329
# File 'lib/kraken-mobile/helpers/reporter.rb', line 323

def total_failed_scenarios features
  how_many = 0
  features.each do |feature|
    how_many += failed_scenarios(feature).count
  end
  how_many
end

#total_failed_scenarios_percentage(features) ⇒ Object



363
364
365
# File 'lib/kraken-mobile/helpers/reporter.rb', line 363

def total_failed_scenarios_percentage features
  (total_failed_scenarios(features).to_f/total_scenarios(features).to_f).round(2) * 100.00
end

#total_passed_features(features) ⇒ Object



331
332
333
334
335
336
337
# File 'lib/kraken-mobile/helpers/reporter.rb', line 331

def total_passed_features features
  how_many = 0
  features.each do |feature|
    how_many += 1 if feature_passed?(feature)
  end
  how_many
end

#total_passed_features_percentage(features) ⇒ Object



359
360
361
# File 'lib/kraken-mobile/helpers/reporter.rb', line 359

def total_passed_features_percentage features
  (total_passed_features(features).to_f/features.count.to_f).round(2) * 100.00
end

#total_passed_scenarios(features) ⇒ Object



315
316
317
318
319
320
321
# File 'lib/kraken-mobile/helpers/reporter.rb', line 315

def total_passed_scenarios features
  how_many = 0
  features.each do |feature|
    how_many += passed_scenarios(feature).count
  end
  how_many
end

#total_passed_scenarios_percentage(features) ⇒ Object



355
356
357
# File 'lib/kraken-mobile/helpers/reporter.rb', line 355

def total_passed_scenarios_percentage features
  (total_passed_scenarios(features).to_f/total_scenarios(features).to_f).round(2) * 100.00
end

#total_scenarios(features) ⇒ Object


Helpers




261
262
263
264
265
266
267
268
# File 'lib/kraken-mobile/helpers/reporter.rb', line 261

def total_scenarios features
  how_many = 0
  features.each do |feature|
    scenarios = feature["elements"]
    how_many += scenarios.count if scenarios
  end
  how_many
end