gitlab_quality-test_tooling 2.10.0 → 2.15.3

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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +22 -5
  4. data/exe/{feature-readiness-check → feature-readiness-checklist} +2 -2
  5. data/exe/feature-readiness-evaluation +62 -0
  6. data/lib/gitlab_quality/test_tooling/feature_readiness/analyzed_items/analyzed_epic.rb +94 -0
  7. data/lib/gitlab_quality/test_tooling/feature_readiness/analyzed_items/analyzed_issue.rb +92 -0
  8. data/lib/gitlab_quality/test_tooling/feature_readiness/analyzed_items/analyzed_merge_request.rb +139 -0
  9. data/lib/gitlab_quality/test_tooling/feature_readiness/concerns/work_item_concern.rb +26 -12
  10. data/lib/gitlab_quality/test_tooling/feature_readiness/evaluation.rb +82 -0
  11. data/lib/gitlab_quality/test_tooling/feature_readiness/operational_readiness_check.rb +4 -4
  12. data/lib/gitlab_quality/test_tooling/gitlab_client/issues_client.rb +7 -1
  13. data/lib/gitlab_quality/test_tooling/gitlab_client/issues_dry_client.rb +1 -1
  14. data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_client.rb +21 -0
  15. data/lib/gitlab_quality/test_tooling/gitlab_client/merge_requests_dry_client.rb +0 -10
  16. data/lib/gitlab_quality/test_tooling/gitlab_client/work_items_client.rb +71 -34
  17. data/lib/gitlab_quality/test_tooling/report/concerns/results_reporter.rb +1 -1
  18. data/lib/gitlab_quality/test_tooling/report/concerns/utils.rb +3 -3
  19. data/lib/gitlab_quality/test_tooling/report/feature_readiness/report_on_epic.rb +174 -0
  20. data/lib/gitlab_quality/test_tooling/report/generate_test_session.rb +1 -1
  21. data/lib/gitlab_quality/test_tooling/report/relate_failure_issue.rb +21 -7
  22. data/lib/gitlab_quality/test_tooling/runtime/env.rb +1 -1
  23. data/lib/gitlab_quality/test_tooling/test_meta/processor/add_to_blocking_processor.rb +1 -1
  24. data/lib/gitlab_quality/test_tooling/test_meta/processor/add_to_quarantine_processor.rb +1 -1
  25. data/lib/gitlab_quality/test_tooling/test_result/base_test_result.rb +13 -4
  26. data/lib/gitlab_quality/test_tooling/version.rb +1 -1
  27. metadata +21 -8
@@ -72,6 +72,12 @@ module GitlabQuality
72
72
  end
73
73
  end
74
74
 
75
+ def related_merge_requests(iid:)
76
+ handle_gitlab_client_exceptions do
77
+ client.related_merge_requests(project, iid).auto_paginate
78
+ end
79
+ end
80
+
75
81
  def find_issue_discussions(iid:)
76
82
  handle_gitlab_client_exceptions do
77
83
  client.issue_discussions(project, iid, order_by: 'created_at', sort: 'asc').auto_paginate
@@ -169,7 +175,7 @@ module GitlabQuality
169
175
  def find_commit_parent(project, sha)
170
176
  handle_gitlab_client_exceptions do
171
177
  # In a merged results commit, the first parent is the one from
172
- # the main branch, and the second parent is from the branch
178
+ # the default branch, and the second parent is from the branch
173
179
  # itself (more likely to have caused the issue)
174
180
  client.commit(project, sha).parent_ids.last
175
181
  end
@@ -4,7 +4,7 @@ module GitlabQuality
4
4
  module TestTooling
5
5
  module GitlabClient
6
6
  class IssuesDryClient < IssuesClient
7
- def create_issue(title:, description:, labels:, issue_type: 'issue', confidential: false)
7
+ def create_issue(title:, description:, labels:, issue_type: 'issue', _assignee_id: nil, _due_date: nil, confidential: false)
8
8
  attrs = { description: description, labels: labels, confidential: confidential }
9
9
 
10
10
  puts "The following #{issue_type} would have been created:"
@@ -1,5 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'gitlab'
4
+
5
+ module Gitlab
6
+ # Monkey patch the Gitlab client to allow passing query options
7
+ class Client
8
+ def merge_request_diffs(project, merge_request_iid, options = {})
9
+ get("/projects/#{url_encode(project)}/merge_requests/#{merge_request_iid}/diffs", query: options).auto_paginate
10
+ end
11
+ end
12
+ end
13
+
3
14
  module GitlabQuality
4
15
  module TestTooling
5
16
  module GitlabClient
@@ -10,6 +21,12 @@ module GitlabQuality
10
21
  end
11
22
  end
12
23
 
24
+ def merge_request_diffs(merge_request_iid:)
25
+ handle_gitlab_client_exceptions do
26
+ client.merge_request_diffs(project, merge_request_iid, per_page: 100)
27
+ end
28
+ end
29
+
13
30
  def create_merge_request(title:, source_branch:, target_branch:, description:, labels:, assignee_id: nil, reviewer_ids: [])
14
31
  attrs = {
15
32
  source_branch: source_branch,
@@ -33,6 +50,10 @@ module GitlabQuality
33
50
  merge_request
34
51
  end
35
52
 
53
+ def merge_request(id:, options: {})
54
+ client.merge_request(project, id, options)
55
+ end
56
+
36
57
  def find(iid: nil, options: {}, &select)
37
58
  select ||= :itself
38
59
 
@@ -4,16 +4,6 @@ module GitlabQuality
4
4
  module TestTooling
5
5
  module GitlabClient
6
6
  class MergeRequestsDryClient < MergeRequestsClient
7
- def find_merge_request_changes(merge_request_iid:)
8
- puts "Finding changes for merge_request_id #{merge_request_iid}"
9
- puts "project: #{project}"
10
- end
11
-
12
- def merge_request_changed_files(merge_request_iid:)
13
- puts "Changed files for #{merge_request_iid}"
14
- []
15
- end
16
-
17
7
  def find_note(body:, merge_request_iid:)
18
8
  puts "Find note for #{merge_request_iid} with body: #{body} for mr_iid: #{merge_request_iid}"
19
9
  end
@@ -3,15 +3,14 @@
3
3
  module GitlabQuality
4
4
  module TestTooling
5
5
  module GitlabClient
6
- # The GitLab client is used for API access: https://github.com/NARKOZ/gitlab
7
6
  class WorkItemsClient < GitlabGraphqlClient
8
- def work_item(workitem_iid: nil)
7
+ def work_item(workitem_iid:, widgets: [:notes, :linked_items, :labels, :hierarchy])
9
8
  query = <<~GQL
10
9
  query {
11
10
  namespace(fullPath: "#{group}") {
12
11
  workItem(iid: "#{workitem_iid}") {
13
12
  #{work_item_fields}
14
- #{work_item_widgets}
13
+ #{work_item_widgets(widgets)}
15
14
  }
16
15
  }
17
16
  }
@@ -19,7 +18,7 @@ module GitlabQuality
19
18
  post(query)[:workItem]
20
19
  end
21
20
 
22
- def group_work_items(labels: [], cursor: '', state: 'opened', created_after: nil, extras: [])
21
+ def group_work_items(labels: [], cursor: '', state: 'opened', created_after: nil, extras: [:work_item_fields])
23
22
  query = <<~GQL
24
23
  query {
25
24
  group(fullPath: "#{group}") {
@@ -73,6 +72,18 @@ module GitlabQuality
73
72
  post(query)
74
73
  end
75
74
 
75
+ def update_note(note_id:, body:)
76
+ query = <<~GQL
77
+ mutation UpdateNote {
78
+ updateNote(input: { body: "#{body}", id: "#{note_id}" }) {
79
+ clientMutationId
80
+ errors
81
+ }
82
+ }
83
+ GQL
84
+ post(query)
85
+ end
86
+
76
87
  def create_linked_items(work_item_id:, item_ids:, link_type:)
77
88
  query = <<~GQL
78
89
  mutation WorkItemAddLinkedItems {
@@ -160,50 +171,76 @@ module GitlabQuality
160
171
  GQL
161
172
  end
162
173
 
163
- def work_item_widgets
174
+ def work_item_widget_notes
164
175
  <<~GQL
165
- widgets(onlyTypes: [LINKED_ITEMS, NOTES, LABELS, HIERARCHY]) {
166
- ... on WorkItemWidgetNotes {
167
- discussions(filter: ONLY_COMMENTS) {
168
- nodes {
169
- notes {
170
- nodes {
171
- #{note_fields}
172
- }
176
+ ... on WorkItemWidgetNotes {
177
+ discussions(filter: ONLY_COMMENTS) {
178
+ nodes {
179
+ notes {
180
+ nodes {
181
+ #{note_fields}
173
182
  }
174
183
  }
175
- }
176
- }
177
- ... on WorkItemWidgetLinkedItems {
178
- linkedItems {
179
- nodes {
180
- linkType
181
- workItem {
182
- #{work_item_fields}
183
- }
184
184
  }
185
- }
186
185
  }
186
+ }
187
+ GQL
188
+ end
187
189
 
188
- ... on WorkItemWidgetLabels{
189
- labels{
190
- nodes{
191
- title
192
- }
190
+ def work_item_widget_linked_items
191
+ <<~GQL
192
+ ... on WorkItemWidgetLinkedItems {
193
+ linkedItems {
194
+ nodes {
195
+ linkType
196
+ workItem {
197
+ #{work_item_fields}
198
+ }
199
+ }
193
200
  }
201
+ }
202
+ GQL
203
+ end
204
+
205
+ def work_item_widget_labels
206
+ <<~GQL
207
+ ... on WorkItemWidgetLabels{
208
+ labels{
209
+ nodes{
210
+ title
211
+ }
194
212
  }
213
+ }
214
+ GQL
215
+ end
195
216
 
196
- ... on WorkItemWidgetHierarchy {
197
- children {
198
- nodes{
199
- #{work_item_fields}
200
- }
201
- }
217
+ def work_item_widget_hierarchy
218
+ <<~GQL
219
+ ... on WorkItemWidgetHierarchy {
220
+ children {
221
+ nodes{
222
+ #{work_item_fields}
223
+ }
202
224
  }
203
225
  }
204
226
  GQL
205
227
  end
206
228
 
229
+ def work_item_widgets(widgets = [])
230
+ <<~GQL
231
+ widgets(onlyTypes: [#{types_for_widgets(widgets)}]) {
232
+ #{work_item_widget_notes if widgets.include?(:notes)}
233
+ #{work_item_widget_linked_items if widgets.include?(:linked_items)}
234
+ #{work_item_widget_labels if widgets.include?(:labels)}
235
+ #{work_item_widget_hierarchy if widgets.include?(:hierarchy)}
236
+ }
237
+ GQL
238
+ end
239
+
240
+ def types_for_widgets(widgets = [])
241
+ widgets.map(&:upcase).join(', ')
242
+ end
243
+
207
244
  # https://docs.gitlab.com/api/graphql/reference/#note
208
245
  def note_fields
209
246
  <<~GQL
@@ -36,7 +36,7 @@ module GitlabQuality
36
36
  end
37
37
 
38
38
  def new_issue_labels(_test)
39
- %w[Quality status::automated]
39
+ %w[E2E status::automated]
40
40
  end
41
41
 
42
42
  def up_to_date_labels(test:, issue: nil, new_labels: Set.new)
@@ -43,9 +43,9 @@ module GitlabQuality
43
43
  # Some of those run in their own project, so CI_PROJECT_NAME is the name we need. Those are:
44
44
  # nightly, staging, canary, production, and preprod
45
45
  #
46
- # MR, master/main, and gitlab tests run in gitlab-qa, but we only want to report tests run on
47
- # master/main because the other pipelines will be monitored by the author of the MR that triggered them.
48
- # So we assume that we're reporting a master/main pipeline if the project name is 'gitlab'.
46
+ # MR, master, and gitlab tests run in gitlab-qa, but we only want to report tests run on
47
+ # master because the other pipelines will be monitored by the author of the MR that triggered them.
48
+ # So we assume that we're reporting a master pipeline if the project name is 'gitlab'.
49
49
 
50
50
  @pipeline ||= Runtime::Env.pipeline_from_project_name
51
51
  end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pp'
4
+ require 'stringio'
5
+
6
+ module GitlabQuality
7
+ module TestTooling
8
+ module Report
9
+ module FeatureReadiness
10
+ class ReportOnEpic
11
+ FEATURE_READINESS_REPORT_COMMENT_ID = '<!-- FEATURE READINESS REPORT COMMENT -->'
12
+
13
+ class << self
14
+ include GitlabQuality::TestTooling::FeatureReadiness::Concerns::WorkItemConcern
15
+
16
+ def report(analyzed_epic, work_item_client)
17
+ must_haves_report_rows = generate_report_rows(analyzed_epic, :must_haves)
18
+ should_haves_report_rows = generate_report_rows(analyzed_epic, :should_haves)
19
+
20
+ existing_note = existing_note_containing_text(FEATURE_READINESS_REPORT_COMMENT_ID, analyzed_epic[:epic_iid], work_item_client)
21
+
22
+ if existing_note
23
+ work_item_client.update_note(note_id: existing_note[:id],
24
+ body: comment({ must_haves: must_haves_report_rows, should_haves: should_haves_report_rows }, analyzed_epic).tr('"', "'"))
25
+ else
26
+ work_item_client.create_discussion(id: analyzed_epic[:epic_id],
27
+ note: comment({ must_haves: must_haves_report_rows, should_haves: should_haves_report_rows }, analyzed_epic).tr('"', "'"))
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def generate_report_rows(epic, type)
34
+ status_checks = check_statuses(epic)
35
+ create_rows(epic, type, status_checks)
36
+ end
37
+
38
+ def create_rows(epic, type, status_checks)
39
+ if type == :must_haves
40
+ [
41
+ create_documentation_row(epic, status_checks),
42
+ create_feature_flag_row(epic, status_checks),
43
+ create_unit_tests_coverage_row(status_checks)
44
+
45
+ ]
46
+ else
47
+ [
48
+ create_feature_tests_row(epic, status_checks),
49
+ create_e2e_tests_row(epic, status_checks)
50
+ ]
51
+ end
52
+ end
53
+
54
+ def create_documentation_row(epic, status_checks)
55
+ ["Documentation added?", status_icon(status_checks[:has_docs]),
56
+ prepend_text('Added in:', format_links(epic[:doc_mrs]))]
57
+ end
58
+
59
+ def create_feature_flag_row(epic, status_checks)
60
+ ["Feature Flag added?", status_icon(status_checks[:feature_flag_added]),
61
+ prepend_text('Added in:', format_links(epic[:feature_flag_mrs]))]
62
+ end
63
+
64
+ def create_feature_tests_row(epic, status_checks)
65
+ ["Feature tests added?", status_icon(status_checks[:has_feature_specs]),
66
+ format_links(epic[:feature_spec_mrs])]
67
+ end
68
+
69
+ def create_e2e_tests_row(epic, status_checks)
70
+ ["End-to-end tests added?", status_icon(status_checks[:has_e2e_specs]),
71
+ format_links(epic[:e2e_spec_mrs])]
72
+ end
73
+
74
+ def create_unit_tests_coverage_row(status_checks)
75
+ ["Unit tests coverage complete?", status_icon(status_checks[:has_complete_unit_tests]),
76
+ prepend_text('Coverage missing for:', format_links(status_checks[:missing_specs]))]
77
+ end
78
+
79
+ def prepend_text(prepend_text, text)
80
+ return "#{prepend_text} #{text}" unless text.empty?
81
+
82
+ text
83
+ end
84
+
85
+ def check_statuses(epic)
86
+ {
87
+ has_docs: epic[:doc_mrs].any?,
88
+ feature_flag_added: epic[:feature_flag_mrs].any?,
89
+ has_feature_specs: epic[:feature_spec_mrs].any?,
90
+ has_e2e_specs: epic[:e2e_spec_mrs].any?,
91
+ missing_specs: missing_spec_mrs(epic),
92
+ has_complete_unit_tests: missing_spec_mrs(epic).empty?
93
+ }
94
+ end
95
+
96
+ def comment(rows, epic)
97
+ # Generate markdown table
98
+ must_haves_table_rows = rows[:must_haves].map do |description, status, links|
99
+ "| #{description} | #{status} | #{links} |"
100
+ end.join("\n")
101
+
102
+ should_haves_table_rows = rows[:should_haves].map do |description, status, links|
103
+ "| #{description} | #{status} | #{links} |"
104
+ end.join("\n")
105
+
106
+ <<~COMMENT
107
+ #{FEATURE_READINESS_REPORT_COMMENT_ID}
108
+
109
+ # :vertical_traffic_light: Feature Readiness Evaluation Report
110
+
111
+ ### :octagonal_sign: Must haves
112
+
113
+ | Evaluation | Result | Notes |
114
+ |------------|--------|-------|
115
+ #{must_haves_table_rows}
116
+
117
+ ### :warning: Should haves
118
+
119
+ | Evaluation | Result | Notes |
120
+ |------------|--------|-------|
121
+ #{should_haves_table_rows}
122
+
123
+ #{data(epic)}
124
+
125
+ ---
126
+
127
+ _Please note that this automation is under testing. Please add any feedback on [this issue](https://gitlab.com/gitlab-org/quality/quality-engineering/team-tasks/-/issues/3587)._
128
+
129
+ COMMENT
130
+ end
131
+
132
+ def status_icon(condition)
133
+ condition ? ':white_check_mark:' : ':x:'
134
+ end
135
+
136
+ def format_links(data)
137
+ return '' if data.empty?
138
+
139
+ data.map do |item|
140
+ item.map { |key, url| "[#{key}](#{url})" }.first
141
+ end.join(", ")
142
+ end
143
+
144
+ def missing_spec_mrs(epic)
145
+ epic[:issues].flat_map do |issue|
146
+ issue[:merge_requests].flat_map do |mr|
147
+ next [] unless mr[:files_with_missing_specs]&.any?
148
+
149
+ mr[:files_with_missing_specs].map do |file|
150
+ { file => mr[:merge_request_web_url] }
151
+ end
152
+ end.compact
153
+ end
154
+ end
155
+
156
+ def data(epic)
157
+ output = StringIO.new
158
+ PP.pp(epic, output)
159
+ <<~DATA
160
+ <details><summary>Expand for data</summary>
161
+
162
+ ```ruby
163
+ #{output.string}
164
+ ```
165
+
166
+ </details>
167
+ DATA
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -33,7 +33,7 @@ module GitlabQuality
33
33
  issue = gitlab.create_issue(
34
34
  title: "#{Time.now.strftime('%Y-%m-%d')} Test session report | #{Runtime::Env.qa_run_type}",
35
35
  description: generate_description(tests),
36
- labels: ['automation:bot-authored', 'Quality', 'QA', 'triage report', pipeline_name_label],
36
+ labels: ['automation:bot-authored', 'E2E', 'triage report', pipeline_name_label],
37
37
  confidential: confidential
38
38
  )
39
39
 
@@ -23,16 +23,23 @@ module GitlabQuality
23
23
  FAILURE_STACKTRACE_REGEX = %r{(?:(?:.*Failure/Error:(?<stacktrace>.+))|(?<stacktrace>.+))}m
24
24
  ISSUE_STACKTRACE_REGEX = /### Stack trace\s*(```)#{FAILURE_STACKTRACE_REGEX}(```)\n*\n###/m
25
25
 
26
- NEW_ISSUE_LABELS = Set.new(%w[test failure::new priority::2 automation:bot-authored]).freeze
26
+ NEW_ISSUE_LABELS = Set.new(%w[test failure::new priority::2 automation:bot-authored type::maintenance]).freeze
27
27
  SCREENSHOT_IGNORED_ERRORS = ['500 Internal Server Error', 'fabricate_via_api!', 'Error Code 500'].freeze
28
-
28
+ FAILURE_ISSUE_GUIDE_URL = "https://handbook.gitlab.com/handbook/engineering/testing/guide-to-e2e-test-failure-issues/"
29
+ FAILURE_ISSUE_HANDBOOK_GUIDE = "**:rotating_light: [End-to-End Test Failure Issue Debugging Guide](#{FAILURE_ISSUE_GUIDE_URL}) :rotating_light:**\n".freeze
29
30
  # Map commits to security fork (gitlab-org/security/gitlab) for gitlab-org/gitlab since security patches exist
30
31
  # there before being released to the public repository
31
32
  DIFF_PROJECT_MAPPINGS = {
33
+ 'gitlab-org/quality/e2e-test-issues' => 'gitlab-org/security/gitlab',
32
34
  'gitlab-org/gitlab' => 'gitlab-org/security/gitlab',
33
35
  'gitlab-org/customers-gitlab-com' => 'gitlab-org/customers-gitlab-com'
34
36
  }.freeze
35
37
 
38
+ # Don't use the E2E test issues project for commit parent
39
+ COMMIT_PROJECT_MAPPINGS = {
40
+ 'gitlab-org/quality/e2e-test-issues' => 'gitlab-org/gitlab'
41
+ }.freeze
42
+
36
43
  # The project contains record of the deployments we use to determine the commit diff
37
44
  OPS_RELEASES_METADATA_PROJECT = 'gitlab-org/release/metadata'
38
45
 
@@ -179,7 +186,9 @@ module GitlabQuality
179
186
  end
180
187
 
181
188
  created_issue = super
182
- test.failure_issue ||= created_issue.web_url
189
+
190
+ # On a dry run, created_issue may not be populated
191
+ test.failure_issue ||= created_issue&.web_url
183
192
 
184
193
  created_issue
185
194
  end
@@ -300,7 +309,7 @@ module GitlabQuality
300
309
  end
301
310
 
302
311
  def new_issue_description(test)
303
- super + [
312
+ FAILURE_ISSUE_HANDBOOK_GUIDE + super + [
304
313
  "\n#{commit_diff_section}",
305
314
  "### Stack trace",
306
315
  "```\n#{test.full_stacktrace}\n```",
@@ -318,10 +327,10 @@ module GitlabQuality
318
327
  initialize_gitlab_ops_client
319
328
 
320
329
  if Runtime::Env.ci_pipeline_url.include?('ops.gitlab.net')
321
- pipeline = ops_gitlab_client.find_pipeline(project, Runtime::Env.ci_pipeline_id.to_i)
330
+ pipeline = ops_gitlab_client.find_pipeline(Runtime::Env.ci_project_path, Runtime::Env.ci_pipeline_id.to_i)
322
331
  generate_ops_gitlab_diff(pipeline)
323
332
  else
324
- pipeline = gitlab.find_pipeline(project, Runtime::Env.ci_pipeline_id.to_i)
333
+ pipeline = gitlab.find_pipeline(Runtime::Env.ci_project_path, Runtime::Env.ci_pipeline_id.to_i)
325
334
  generate_gitlab_diff(pipeline)
326
335
  end
327
336
  end
@@ -342,6 +351,8 @@ module GitlabQuality
342
351
  end
343
352
 
344
353
  def fetch_deployment_info(pipeline)
354
+ return 'No pipeline name set.' unless Runtime::Env.ci_pipeline_name
355
+
345
356
  pipeline_deploy_version = Runtime::Env.ci_pipeline_name.match(/(\d+\.\d+\.\d+)(?:-|$)/)&.captures&.first
346
357
  deployments = fetch_deployments(ops_gitlab_client, pipeline)
347
358
  found_deployment = find_matching_deployment(pipeline_deploy_version, deployments)
@@ -427,7 +438,8 @@ module GitlabQuality
427
438
 
428
439
  def generate_gitlab_diff(pipeline)
429
440
  pipeline_sha = pipeline.sha
430
- parent_sha = gitlab.find_commit_parent(project, pipeline_sha)
441
+ commit_project = COMMIT_PROJECT_MAPPINGS.fetch(project, project)
442
+ parent_sha = gitlab.find_commit_parent(commit_project, pipeline_sha)
431
443
  diff_project = if DIFF_PROJECT_MAPPINGS.key?(project)
432
444
  DIFF_PROJECT_MAPPINGS[project]
433
445
  else
@@ -542,6 +554,8 @@ module GitlabQuality
542
554
  end
543
555
 
544
556
  def screenshot_artifact_url(test)
557
+ return "" unless test.screenshot_image
558
+
545
559
  ci_job_url = test.ci_job_url
546
560
  screenshot_path = test.screenshot_image[%r{qa/.*$}]
547
561
 
@@ -46,7 +46,7 @@ module GitlabQuality
46
46
  end
47
47
 
48
48
  def default_branch
49
- env_var_value_if_defined('QA_DEFAULT_BRANCH') || 'main'
49
+ 'master'
50
50
  end
51
51
 
52
52
  def ci_api_v4_url
@@ -97,7 +97,7 @@ module GitlabQuality
97
97
 
98
98
  This MR was created based on data from reliable e2e test report: #{context.report_issue}
99
99
 
100
- /label ~"Quality" ~"QA" ~"type::maintenance"
100
+ /label ~"E2E" ~"type::maintenance"
101
101
  /label ~"devops::#{devops_stage}"
102
102
  #{context.label_from_product_group(product_group)}
103
103
 
@@ -137,7 +137,7 @@ module GitlabQuality
137
137
  - [ ] To ensure a faster turnaround, ask in the `#quality_maintainers` Slack channel for someone to review and merge the merge request, rather than assigning it directly.
138
138
 
139
139
  <!-- Base labels. -->
140
- /label ~"Quality" ~"QA" ~"type::maintenance" ~"maintenance::pipelines"
140
+ /label ~"E2E" ~"type::maintenance" ~"maintenance::pipelines"
141
141
 
142
142
  <!--
143
143
  Choose the stage that appears in the test path, e.g. ~"devops::create" for
@@ -14,7 +14,8 @@ module GitlabQuality
14
14
  "Error reference number: 502",
15
15
  "(502): `GitLab is not responding`",
16
16
  "<head><title>502 Bad Gateway</title></head>",
17
- "14:connections to all backends failing"
17
+ "14:connections to all backends failing",
18
+ "gitlab_canary=true cookie was set in browser but 'Next' badge was not shown on UI"
18
19
  ].freeze
19
20
 
20
21
  SHARED_EXAMPLES_CALLERS = %w[include_examples it_behaves_like].freeze
@@ -114,7 +115,7 @@ module GitlabQuality
114
115
  end
115
116
 
116
117
  def file_base_url
117
- @file_base_url ||= "https://gitlab.com/#{project}/-/blob/#{ref}/"
118
+ @file_base_url ||= "https://gitlab.com/#{project == 'gitlab-org/quality/e2e-test-issues' ? 'gitlab-org/gitlab' : project}/-/blob/#{ref}/"
118
119
  end
119
120
 
120
121
  def test_file_link
@@ -143,15 +144,23 @@ module GitlabQuality
143
144
  def files_client
144
145
  @files_client ||= GitlabClient::RepositoryFilesClient.new(
145
146
  token: token,
146
- project: project,
147
+ project: mapped_project,
147
148
  file_path: file,
148
- ref: ref)
149
+ ref: ref.nil? || ref.empty? ? 'master' : ref)
149
150
  end
150
151
 
151
152
  private
152
153
 
153
154
  attr_reader :token, :project, :ref
154
155
 
156
+ def mapped_project
157
+ if project == 'gitlab-org/quality/e2e-test-issues'
158
+ 'gitlab-org/gitlab'
159
+ else
160
+ project
161
+ end
162
+ end
163
+
155
164
  def screenshot
156
165
  report.fetch('screenshot', nil)
157
166
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitlabQuality
4
4
  module TestTooling
5
- VERSION = "2.10.0"
5
+ VERSION = "2.15.3"
6
6
  end
7
7
  end