gitlab-qa 10.3.0 → 12.2.1

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.gitlab/changelog_config.yml +13 -0
  4. data/.gitlab/merge_request_templates/Release.md +13 -34
  5. data/.gitlab-ci.yml +3 -1
  6. data/.rubocop.yml +13 -2
  7. data/.rubocop_todo.yml +57 -97
  8. data/Dangerfile +1 -5
  9. data/Gemfile.lock +47 -39
  10. data/README.md +1 -2
  11. data/docs/release_process.md +1 -1
  12. data/docs/running_against_remote_grid.md +42 -3
  13. data/docs/what_tests_can_be_run.md +5 -2
  14. data/gitlab-qa.gemspec +5 -3
  15. data/lib/gitlab/qa/component/base.rb +9 -9
  16. data/lib/gitlab/qa/component/gitaly.rb +7 -5
  17. data/lib/gitlab/qa/component/gitaly_cluster.rb +15 -9
  18. data/lib/gitlab/qa/component/gitlab.rb +48 -21
  19. data/lib/gitlab/qa/component/mail_hog.rb +1 -0
  20. data/lib/gitlab/qa/component/praefect.rb +41 -31
  21. data/lib/gitlab/qa/component/selenoid.rb +14 -7
  22. data/lib/gitlab/qa/component/specs.rb +11 -5
  23. data/lib/gitlab/qa/component/staging.rb +4 -4
  24. data/lib/gitlab/qa/component/telegraf.rb +2 -1
  25. data/lib/gitlab/qa/docker/engine.rb +6 -3
  26. data/lib/gitlab/qa/docker/volumes.rb +1 -1
  27. data/lib/gitlab/qa/release.rb +4 -4
  28. data/lib/gitlab/qa/runner.rb +10 -3
  29. data/lib/gitlab/qa/runtime/env.rb +47 -62
  30. data/lib/gitlab/qa/runtime/logger.rb +1 -1
  31. data/lib/gitlab/qa/runtime/omnibus_configuration.rb +1 -0
  32. data/lib/gitlab/qa/runtime/omnibus_configurations/decomposition_single_db.rb +1 -2
  33. data/lib/gitlab/qa/runtime/omnibus_configurations/object_storage_gcs.rb +2 -1
  34. data/lib/gitlab/qa/runtime/scenario.rb +1 -5
  35. data/lib/gitlab/qa/scenario/actable.rb +4 -4
  36. data/lib/gitlab/qa/scenario/test/instance/airgapped.rb +2 -4
  37. data/lib/gitlab/qa/scenario/test/instance/deployment_base.rb +2 -1
  38. data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +0 -2
  39. data/lib/gitlab/qa/scenario/test/integration/group_saml.rb +1 -1
  40. data/lib/gitlab/qa/scenario/test/integration/ldap.rb +5 -6
  41. data/lib/gitlab/qa/scenario/test/integration/mtls.rb +20 -6
  42. data/lib/gitlab/qa/scenario/test/integration/oauth.rb +13 -4
  43. data/lib/gitlab/qa/scenario/test/integration/praefect.rb +16 -10
  44. data/lib/gitlab/qa/scenario/test/integration/registry_with_cdn.rb +5 -2
  45. data/lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb +1 -1
  46. data/lib/gitlab/qa/scenario/test/omnibus/upgrade.rb +1 -3
  47. data/lib/gitlab/qa/scenario/test/sanity/version.rb +1 -1
  48. data/lib/gitlab/qa/support/config_scripts.rb +1 -1
  49. data/lib/gitlab/qa/support/gitlab_version_info.rb +30 -10
  50. data/lib/gitlab/qa/support/shell_command.rb +1 -0
  51. data/lib/gitlab/qa/test_logger.rb +2 -2
  52. data/lib/gitlab/qa/version.rb +1 -1
  53. data/lib/gitlab/qa.rb +0 -1
  54. data/support/data/admin_access_token_seed.rb +5 -1
  55. data/support/data/license_usage_seed.rb +3 -1
  56. metadata +16 -45
  57. data/bin/slack +0 -14
  58. data/exe/gitlab-qa-report +0 -10
  59. data/lib/gitlab/qa/report/base_test_results.rb +0 -39
  60. data/lib/gitlab/qa/report/find_set_dri.rb +0 -43
  61. data/lib/gitlab/qa/report/generate_test_session.rb +0 -275
  62. data/lib/gitlab/qa/report/gitlab_issue_client.rb +0 -190
  63. data/lib/gitlab/qa/report/gitlab_issue_dry_client.rb +0 -28
  64. data/lib/gitlab/qa/report/j_unit_test_results.rb +0 -27
  65. data/lib/gitlab/qa/report/json_test_results.rb +0 -29
  66. data/lib/gitlab/qa/report/prepare_stage_reports.rb +0 -86
  67. data/lib/gitlab/qa/report/relate_failure_issue.rb +0 -374
  68. data/lib/gitlab/qa/report/report_as_issue.rb +0 -176
  69. data/lib/gitlab/qa/report/report_results.rb +0 -64
  70. data/lib/gitlab/qa/report/results_in_issues.rb +0 -126
  71. data/lib/gitlab/qa/report/results_in_testcases.rb +0 -111
  72. data/lib/gitlab/qa/report/results_reporter_shared.rb +0 -70
  73. data/lib/gitlab/qa/report/summary_table.rb +0 -43
  74. data/lib/gitlab/qa/report/test_result.rb +0 -184
  75. data/lib/gitlab/qa/report/update_screenshot_path.rb +0 -63
  76. data/lib/gitlab/qa/reporter.rb +0 -131
  77. data/lib/gitlab/qa/runtime/omnibus_configurations/packages.rb +0 -17
  78. data/lib/gitlab/qa/runtime/token_finder.rb +0 -44
  79. data/lib/gitlab/qa/slack/post_to_slack.rb +0 -30
  80. data/lib/gitlab/qa/system_logs/finders/json_log_finder.rb +0 -65
  81. data/lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb +0 -21
  82. data/lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb +0 -21
  83. data/lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb +0 -21
  84. data/lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb +0 -21
  85. data/lib/gitlab/qa/system_logs/log_types/log.rb +0 -38
  86. data/lib/gitlab/qa/system_logs/log_types/rails/api_log.rb +0 -34
  87. data/lib/gitlab/qa/system_logs/log_types/rails/application_log.rb +0 -27
  88. data/lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb +0 -23
  89. data/lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb +0 -30
  90. data/lib/gitlab/qa/system_logs/shared_fields.rb +0 -29
  91. data/lib/gitlab/qa/system_logs/system_logs_formatter.rb +0 -65
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Gitlab
4
- module QA
5
- module Report
6
- # Uses the API to create or update GitLab test result issues with the results of tests from RSpec report files.
7
- class ResultsInIssues < ReportAsIssue
8
- include ResultsReporterShared
9
-
10
- def initialize(**kwargs)
11
- super
12
- @issue_type = 'issue'
13
- end
14
-
15
- def get_related_issue(testcase, test)
16
- issue = find_linked_results_issue_by_iid(testcase, test)
17
- is_new = false
18
-
19
- if issue
20
- issue = update_issue_title(issue, test) if issue_title_needs_updating?(issue, test)
21
- else
22
- puts "No valid issue link found"
23
- issue = find_or_create_results_issue(test)
24
- is_new = true
25
- end
26
-
27
- [issue, is_new]
28
- end
29
-
30
- def update_issue(issue, test)
31
- new_labels = issue_labels(issue)
32
- new_labels |= ['Testcase Linked']
33
-
34
- labels_updated = update_labels(issue, test, new_labels)
35
- note_posted = note_status(issue, test)
36
-
37
- if labels_updated || note_posted
38
- puts "Issue updated: #{issue.web_url}"
39
- else
40
- puts "Test passed, no results issue update needed."
41
- end
42
- end
43
-
44
- private
45
-
46
- def find_linked_results_issue_by_iid(testcase, test)
47
- iid = issue_iid_from_testcase(testcase)
48
-
49
- return unless iid
50
-
51
- find_issue_by_iid(iid)
52
- end
53
-
54
- def find_or_create_results_issue(test)
55
- find_issue(test) || create_issue(test)
56
- end
57
-
58
- def issue_iid_from_testcase(testcase)
59
- results = testcase.description.partition(TEST_CASE_RESULTS_SECTION_TEMPLATE).last if testcase.description.include?(TEST_CASE_RESULTS_SECTION_TEMPLATE)
60
-
61
- return puts "No issue link found" unless results
62
-
63
- issue_iid = results.split('/').last
64
-
65
- issue_iid&.to_i
66
- end
67
-
68
- def note_status(issue, test)
69
- return false if test.skipped
70
- return false if test.failures.empty?
71
-
72
- note = note_content(test)
73
-
74
- gitlab.find_issue_discussions(iid: issue.iid).each do |discussion|
75
- return gitlab.add_note_to_issue_discussion_as_thread(iid: issue.iid, discussion_id: discussion.id, body: failure_summary) if new_note_matches_discussion?(note, discussion)
76
- end
77
-
78
- gitlab.create_issue_note(iid: issue.iid, note: note)
79
-
80
- true
81
- end
82
-
83
- def note_content(test)
84
- errors = test.failures.each_with_object([]) do |failure, text|
85
- text << <<~TEXT
86
- Error:
87
- ```
88
- #{failure['message']}
89
- ```
90
-
91
- Stacktrace:
92
- ```
93
- #{failure['stacktrace']}
94
- ```
95
- TEXT
96
- end.join("\n\n")
97
-
98
- "#{failure_summary}\n\n#{errors}"
99
- end
100
-
101
- def failure_summary
102
- summary = [":x: ~\"#{pipeline}::failed\""]
103
- summary << "in job `#{Runtime::Env.ci_job_name}` in #{Runtime::Env.ci_job_url}"
104
- summary.join(' ')
105
- end
106
-
107
- def new_note_matches_discussion?(note, discussion)
108
- note_error = error_and_stack_trace(note)
109
- discussion_error = error_and_stack_trace(discussion.notes.first['body'])
110
-
111
- return false if note_error.empty? || discussion_error.empty?
112
-
113
- note_error == discussion_error
114
- end
115
-
116
- def error_and_stack_trace(text)
117
- text.strip[/Error:(.*)/m, 1].to_s
118
- end
119
-
120
- def updated_description(issue, test)
121
- new_issue_description(test)
122
- end
123
- end
124
- end
125
- end
126
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'erb'
4
-
5
- module Gitlab
6
- module QA
7
- module Report
8
- # Uses the API to create or update GitLab test cases with the results of tests from RSpec report files.
9
- class ResultsInTestCases < ReportAsIssue
10
- attr_reader :issue_type, :gitlab
11
-
12
- include ResultsReporterShared
13
-
14
- def initialize(**kwargs)
15
- super
16
- @issue_type = 'test_case'
17
- end
18
-
19
- def find_or_create_testcase(test)
20
- find_testcase(test) || create_issue(test)
21
- end
22
-
23
- def add_issue_link_to_testcase(testcase, issue, test)
24
- results_section = testcase.description.include?(TEST_CASE_RESULTS_SECTION_TEMPLATE) ? '' : TEST_CASE_RESULTS_SECTION_TEMPLATE
25
-
26
- gitlab.edit_issue(iid: testcase.iid, options: { description: (testcase.description + results_section + "\n\n#{issue.web_url}") })
27
- # We are using test.testcase for the url here instead of testcase.web_url since it has the updated test case path
28
- puts "Added results issue #{issue.web_url} link to test case #{test.testcase}"
29
- end
30
-
31
- def update_testcase(testcase, test)
32
- puts "Test case labels updated." if update_labels(testcase, test)
33
- puts "Test case quarantine section updated." if update_quarantine_link(testcase, test)
34
- end
35
-
36
- private
37
-
38
- def find_testcase(test)
39
- testcase = find_testcase_by_iid(test)
40
-
41
- if testcase
42
- testcase = update_issue_title(testcase, test) if issue_title_needs_updating?(testcase, test)
43
- else
44
- testcase = find_issue(test)
45
- end
46
-
47
- testcase
48
- end
49
-
50
- def find_testcase_by_iid(test)
51
- iid = testcase_iid_from_url(test.testcase)
52
-
53
- return unless iid
54
-
55
- find_issue_by_iid(iid)
56
- end
57
-
58
- def testcase_iid_from_url(url)
59
- return warn(%(\nPlease update #{url} to test case url")) if url&.include?('/-/issues/')
60
-
61
- url && url.split('/').last.to_i
62
- end
63
-
64
- def new_issue_description(test)
65
- quarantine_section = test.quarantine? && test.quarantine_issue ? "\n\n### Quarantine issue\n\n#{test.quarantine_issue}" : ''
66
-
67
- "#{super}#{quarantine_section}\n\n#{execution_graph_section(test)}"
68
- end
69
-
70
- def execution_graph_section(test)
71
- formatted_title = ERB::Util.url_encode(test.name)
72
-
73
- <<~MKDOWN.strip
74
- ### Executions
75
-
76
- All Environments:
77
- <img src="https://dashboards.quality.gitlab.net/render/d-solo/cW0UMgv7k/spec-health?orgId=1&var-run_type=All&var-name=#{formatted_title}&panelId=4&width=1000&height=500" />
78
- MKDOWN
79
- end
80
-
81
- def updated_description(testcase, test)
82
- historical_results_section = testcase.description.match(/### DO NOT EDIT BELOW THIS LINE[\s\S]+/)
83
-
84
- "#{new_issue_description(test)}\n\n#{historical_results_section}"
85
- end
86
-
87
- def issue_title_needs_updating?(testcase, test)
88
- super || !testcase.description.include?(execution_graph_section(test)) && !%w[canary production preprod release].include?(pipeline)
89
- end
90
-
91
- def quarantine_link_needs_updating?(testcase, test)
92
- if test.quarantine? && test.quarantine_issue
93
- return false if testcase.description.include?(test.quarantine_issue)
94
- else
95
- return false unless testcase.description.include?('Quarantine issue')
96
- end
97
-
98
- true
99
- end
100
-
101
- def update_quarantine_link(testcase, test)
102
- return unless quarantine_link_needs_updating?(testcase, test)
103
-
104
- new_description = updated_description(testcase, test)
105
-
106
- gitlab.edit_issue(iid: testcase.iid, options: { description: new_description })
107
- end
108
- end
109
- end
110
- end
111
- end
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/enumerable'
4
-
5
- module Gitlab
6
- module QA
7
- module Report
8
- module ResultsReporterShared
9
- TEST_CASE_RESULTS_SECTION_TEMPLATE = "\n\n### DO NOT EDIT BELOW THIS LINE\n\nActive and historical test results:"
10
-
11
- def find_issue(test)
12
- issues = search_for_issues(test)
13
-
14
- warn(%(Too many #{issue_type}s found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
15
- puts "Found existing #{issue_type}: #{issues.first.web_url}" unless issues.empty?
16
-
17
- issues.first
18
- end
19
-
20
- def find_issue_by_iid(iid)
21
- issues = gitlab.find_issues(iid: iid) do |issue|
22
- issue.state == 'opened' && issue.issue_type == issue_type
23
- end
24
-
25
- warn(%(#{issue_type} iid "#{iid}" not valid)) if issues.empty?
26
-
27
- issues.first
28
- end
29
-
30
- def issue_title_needs_updating?(issue, test)
31
- issue.title.strip != title_from_test(test) && !%w[canary production preprod release].include?(pipeline)
32
- end
33
-
34
- def new_issue_labels(test)
35
- %w[Quality status::automated]
36
- end
37
-
38
- def search_term(test)
39
- %("#{partial_file_path(test.file)}" "#{search_safe(test.name)}")
40
- end
41
-
42
- def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
43
- labels = super
44
- labels |= new_issue_labels(test).to_set
45
- labels.delete_if { |label| label.start_with?("#{pipeline}::") }
46
- labels << (test.failures.empty? ? "#{pipeline}::passed" : "#{pipeline}::failed")
47
- end
48
-
49
- def update_issue_title(issue, test)
50
- old_title = issue.title.strip
51
- new_title = title_from_test(test)
52
-
53
- warn(%(#{issue_type} title needs to be updated from '#{old_title}' to '#{new_title}'))
54
-
55
- new_description = updated_description(issue, test)
56
-
57
- gitlab.edit_issue(iid: issue.iid, options: { title: new_title, description: new_description })
58
- end
59
-
60
- private
61
-
62
- def search_for_issues(test)
63
- gitlab.find_issues(options: { search: search_term(test) }) do |issue|
64
- issue.state == 'opened' && issue.issue_type == issue_type && issue.title.strip == title_from_test(test)
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'nokogiri'
4
- require 'table_print'
5
-
6
- module Gitlab
7
- module QA
8
- module Report
9
- class SummaryTable
10
- def self.create(input_files:)
11
- "```\n#{TablePrint::Printer.table_print(collect_results(input_files))}```\n"
12
- end
13
-
14
- # rubocop:disable Metrics/AbcSize
15
- def self.collect_results(input_files)
16
- stage_wise_results = []
17
-
18
- Dir.glob(input_files).each do |report_file|
19
- stage_hash = {}
20
- stage_hash["Dev Stage"] = File.basename(report_file, ".*").capitalize
21
-
22
- report_stats = Nokogiri::XML(File.open(report_file)).children[0].attributes
23
-
24
- stage_hash["Total"] = report_stats["tests"].value
25
- stage_hash["Failures"] = report_stats["failures"].value
26
- stage_hash["Errors"] = report_stats["errors"].value
27
- stage_hash["Skipped"] = report_stats["skipped"].value
28
- stage_hash["Result"] = result_emoji(report_stats)
29
-
30
- stage_wise_results << stage_hash
31
- end
32
-
33
- stage_wise_results
34
- end
35
- # rubocop:enable Metrics/AbcSize
36
-
37
- def self.result_emoji(report_stats)
38
- report_stats["failures"].value.to_i.positive? || report_stats["errors"].value.to_i.positive? ? "❌" : "✅"
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,184 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/object/blank'
4
-
5
- module Gitlab
6
- module QA
7
- module Report
8
- class TestResult
9
- def self.from_json(report)
10
- JsonTestResult.new(report)
11
- end
12
-
13
- def self.from_junit(report)
14
- JUnitTestResult.new(report)
15
- end
16
-
17
- attr_accessor :report, :failures
18
-
19
- def initialize(report)
20
- self.report = report
21
- self.failures = failures_from_exceptions
22
- end
23
-
24
- def stage
25
- @stage ||= file[%r{(?:api|browser_ui)/(?:(?:\d+_)?(\w+))}, 1]
26
- end
27
-
28
- def name
29
- raise NotImplementedError
30
- end
31
-
32
- def file
33
- raise NotImplementedError
34
- end
35
-
36
- def skipped
37
- raise NotImplementedError
38
- end
39
-
40
- private
41
-
42
- def failures_from_exceptions
43
- raise NotImplementedError
44
- end
45
-
46
- class JsonTestResult < TestResult
47
- def name
48
- report['full_description']
49
- end
50
-
51
- def file
52
- report['file_path']
53
- end
54
-
55
- def status
56
- report['status']
57
- end
58
-
59
- def ci_job_url
60
- report['ci_job_url']
61
- end
62
-
63
- def skipped
64
- status == 'pending'
65
- end
66
-
67
- def testcase
68
- report['testcase']
69
- end
70
-
71
- def testcase=(new_testcase)
72
- report['testcase'] = new_testcase
73
- end
74
-
75
- def failure_issue
76
- report['failure_issue']
77
- end
78
-
79
- def failure_issue=(new_failure_issue)
80
- report['failure_issue'] = new_failure_issue
81
- end
82
-
83
- def quarantine?
84
- # The value for 'quarantine' could be nil, a hash, a string,
85
- # or true (if the test just has the :quarantine tag)
86
- # But any non-nil or false value should means the test is in quarantine
87
- report['quarantine'].present?
88
- end
89
-
90
- def quarantine_type
91
- report['quarantine']['type'] if quarantine?
92
- end
93
-
94
- def quarantine_issue
95
- report['quarantine']['issue'] if quarantine?
96
- end
97
-
98
- def screenshot?
99
- report['screenshot'].present?
100
- end
101
-
102
- def failure_screenshot
103
- report['screenshot']['image'] if screenshot?
104
- end
105
-
106
- def product_group?
107
- report['product_group'].present?
108
- end
109
-
110
- def product_group
111
- report['product_group'] if product_group?
112
- end
113
-
114
- private
115
-
116
- # rubocop:disable Metrics/AbcSize
117
- def failures_from_exceptions
118
- return [] unless report.key?('exceptions')
119
-
120
- report['exceptions'].map do |exception|
121
- spec_file_first_index = exception['backtrace'].rindex do |line|
122
- line.include?(File.basename(report['file_path']))
123
- end
124
-
125
- exception['message'].gsub!(/(private_token=)[\w-]+/, '********')
126
- Array(exception['message_lines']).each { |line| line.gsub!(/(private_token=)([\w-]+)/, '********') }
127
-
128
- {
129
- 'message' => "#{exception['class']}: #{exception['message']}",
130
- 'message_lines' => exception['message_lines'],
131
- 'stacktrace' => "#{format_message_lines(exception['message_lines'])}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}",
132
- 'correlation_id' => exception['correlation_id']
133
- }
134
- end
135
- end
136
-
137
- def format_message_lines(message_lines)
138
- message_lines.is_a?(Array) ? message_lines.join("\n") : message_lines
139
- end
140
- # rubocop:enable Metrics/AbcSize
141
- end
142
-
143
- class JUnitTestResult < TestResult
144
- def name
145
- report['name']
146
- end
147
-
148
- def file
149
- report['file']
150
- end
151
-
152
- def skipped
153
- report.search('skipped').any?
154
- end
155
-
156
- attr_accessor :testcase # Ignore it for now
157
-
158
- private
159
-
160
- # rubocop:disable Metrics/AbcSize
161
- def failures_from_exceptions
162
- failures = report.search('failure')
163
- return [] if failures.empty?
164
-
165
- failures.map do |exception|
166
- trace = exception.content.split("\n").map(&:strip)
167
- spec_file_first_index = trace.rindex do |line|
168
- line.include?(File.basename(report['file']))
169
- end
170
-
171
- exception['message'].gsub!(/(private_token=)[\w-]+/, '********')
172
-
173
- {
174
- 'message' => "#{exception['type']}: #{exception['message']}",
175
- 'stacktrace' => trace.slice(0..spec_file_first_index).join("\n")
176
- }
177
- end
178
- end
179
- # rubocop:enable Metrics/AbcSize
180
- end
181
- end
182
- end
183
- end
184
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'nokogiri'
4
- require 'json'
5
- require 'active_support/core_ext/object/blank'
6
-
7
- module Gitlab
8
- module QA
9
- module Report
10
- class UpdateScreenshotPath
11
- def initialize(files:)
12
- @files = files
13
- end
14
-
15
- REGEX = %r{(?<gitlab_qa_run>gitlab-qa-run-.*?(?=\/))\/(?<gitlab_ce_ee_qa>gitlab-(ee|ce)-qa-.*?(?=\/))}
16
- CONTAINER_PATH = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp').freeze
17
-
18
- def invoke!
19
- Dir.glob(@files).each do |rspec_report_file|
20
- match_data = rspec_report_file.match(REGEX)
21
- artifact_path = "#{match_data[:gitlab_qa_run]}/#{match_data[:gitlab_ce_ee_qa]}"
22
-
23
- xml_report = rewrite_each_xml_screenshot_path(rspec_report_file, artifact_path)
24
-
25
- File.write(rspec_report_file, xml_report)
26
-
27
- puts "Saved #{rspec_report_file}"
28
-
29
- json_rspec_report_file = rspec_report_file.gsub('.xml', '.json')
30
- json_report = rewrite_each_json_screenshot_path(json_rspec_report_file, artifact_path)
31
-
32
- File.write(json_rspec_report_file, json_report)
33
-
34
- puts "Saved #{json_rspec_report_file}"
35
- end
36
- end
37
-
38
- private
39
-
40
- def rewrite_each_xml_screenshot_path(rspec_report_file, artifact_path)
41
- report = Nokogiri::XML(File.open(rspec_report_file))
42
-
43
- report.xpath('//system-out').each do |system_out|
44
- system_out.content = system_out.content.gsub(CONTAINER_PATH, artifact_path)
45
- end
46
-
47
- report.to_s
48
- end
49
-
50
- def rewrite_each_json_screenshot_path(json_rspec_report_file, artifact_path)
51
- report = JSON.parse(File.read(json_rspec_report_file))
52
- examples = report['examples']
53
-
54
- examples.each do |example|
55
- example['screenshot']['image'] = example['screenshot']['image'].gsub(CONTAINER_PATH, artifact_path) if example['screenshot'].present?
56
- end
57
-
58
- JSON.pretty_generate(report)
59
- end
60
- end
61
- end
62
- end
63
- end