diff --git a/app/assets/javascripts/ci/reports/components/issue_status_icon.vue b/app/assets/javascripts/ci/reports/components/issue_status_icon.vue index 56010a5f588c20e522d056569902c52fdcfbeb18..f2346a5512e0d95faac42015438702852cf4b694 100644 --- a/app/assets/javascripts/ci/reports/components/issue_status_icon.vue +++ b/app/assets/javascripts/ci/reports/components/issue_status_icon.vue @@ -50,6 +50,6 @@ export default { }" class="report-block-list-icon" > - <gl-icon :name="iconName" :size="statusIconSize" :data-qa-selector="`status_${status}_icon`" /> + <gl-icon :name="iconName" :size="statusIconSize" /> </div> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue index 51f519f6f0c1edc90d19e6251daead1481895928..3e2f3ab4103437cd95ba235bf75cfed10e60a05b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue @@ -305,11 +305,7 @@ export default { </script> <template> - <section - class="media-section" - data-testid="widget-extension" - data-qa-selector="mr_widget_extension" - > + <section class="media-section" data-testid="widget-extension"> <state-container :status="statusIconName" :is-loading="isLoadingSummary" @@ -359,7 +355,6 @@ export default { :icon="isCollapsed ? 'chevron-lg-down' : 'chevron-lg-up'" category="tertiary" data-testid="toggle-button" - data-qa-selector="toggle_button" size="small" @click="toggleCollapsed" /> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue index 5cd9179ef7285f4e162113129b46c7af854bf166..5f0fd973e84022d93c39c3cc06d6933265c79896 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue @@ -127,7 +127,6 @@ export default { :modal-id="modalId" :level="3" data-testid="child-content" - data-qa-selector="child_content" @clickedAction="onClickedAction" /> </li> diff --git a/ee/spec/frontend/vue_merge_request_widget/extensions/license_compliance/__snapshots__/index_spec.js.snap b/ee/spec/frontend/vue_merge_request_widget/extensions/license_compliance/__snapshots__/index_spec.js.snap index 39b9c1f8fa8b091480457fd703b775fad85b7193..0a860a13f6151103fb62291e1c83480f74e53d7e 100644 --- a/ee/spec/frontend/vue_merge_request_widget/extensions/license_compliance/__snapshots__/index_spec.js.snap +++ b/ee/spec/frontend/vue_merge_request_widget/extensions/license_compliance/__snapshots__/index_spec.js.snap @@ -52,7 +52,6 @@ exports[`License Compliance extension expanded data with new licenses displays a <li> <div class="gl-pl-6 gl-w-full" - data-qa-selector="child_content" data-testid="child-content" > <div @@ -197,7 +196,6 @@ exports[`License Compliance extension expanded data with new licenses displays d <li> <div class="gl-pl-6 gl-w-full" - data-qa-selector="child_content" data-testid="child-content" > <div @@ -334,7 +332,6 @@ exports[`License Compliance extension expanded data with new licenses displays u <li> <div class="gl-pl-6 gl-w-full" - data-qa-selector="child_content" data-testid="child-content" > <div diff --git a/qa/qa/ee/page/component/license_management.rb b/qa/qa/ee/page/component/license_management.rb index e678148dfb58c877a2fdaa9623380ed236791496..19b66427ad2461503b809a5569176091ec899128 100644 --- a/qa/qa/ee/page/component/license_management.rb +++ b/qa/qa/ee/page/component/license_management.rb @@ -11,50 +11,19 @@ def self.prepended(base) super base.class_eval do - view 'app/assets/javascripts/ci/reports/components/report_item.vue' do - element 'report-item-row' - end - - view 'app/assets/javascripts/ci/reports/components/issue_status_icon.vue' do - element :icon_status, ':data-qa-selector="`status_${status}_icon`" ' # rubocop:disable QA/ElementWithPattern - end - view 'app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue' do - element :mr_widget_extension - end - - view 'app/assets/javascripts/vue_merge_request_widget/components/action_buttons.vue' do - element :mr_widget_extension_actions_button + element 'widget-extension' + element 'toggle-button' end view 'app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue' do - element :child_content + element 'child-content' end end end - def has_approved_license?(name) - within_element(:child_content, text: name) do - has_element?(:status_success_icon, wait: 1) - end - end - - def has_denied_license?(name) - within_element(:child_content, text: name) do - has_element?(:status_failed_icon, wait: 1) - end - end - - def click_manage_licenses_button - previous_page = page.current_url - - within_element(:mr_widget_extension) do - click_element(:mr_widget_extension_actions_button, text: 'Manage Licenses') - end - # TODO workaround for switched to a new window UI - wait_until(max_duration: 15, reload: false) do - page.current_url != previous_page - end + def has_license?(name) + has_element?('child-content', text: name) end end end diff --git a/qa/qa/ee/page/merge_request/show.rb b/qa/qa/ee/page/merge_request/show.rb index 7ea4480fbae7815a692f1db9fb7e2e9099ac4377..82b3ba9118c525be838834702f08135654c7e95e 100644 --- a/qa/qa/ee/page/merge_request/show.rb +++ b/qa/qa/ee/page/merge_request/show.rb @@ -80,7 +80,10 @@ def self.prepended(base) end def wait_for_license_compliance_report - has_text?('License Compliance detected', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME) + retry_until(reload: true, sleep_interval: 2, max_attempts: 30, + message: 'Finding "License Compliance" widget') do + has_text?('License Compliance detected') + end end def approvals_required_from @@ -108,8 +111,8 @@ def click_approve end def expand_license_report - within_element(:mr_widget_extension) do - click_element(:toggle_button) + within_element('widget-extension') do + click_element('toggle-button') end end diff --git a/qa/qa/specs/features/ee/browser_ui/13_secure/license_scanning_spec.rb b/qa/qa/specs/features/ee/browser_ui/13_secure/license_scanning_spec.rb index d184d59840d2c2ccaa940634f97f39eb41173081..e5787bcc0f2951ed112e2a4382226de802c61e70 100644 --- a/qa/qa/specs/features/ee/browser_ui/13_secure/license_scanning_spec.rb +++ b/qa/qa/specs/features/ee/browser_ui/13_secure/license_scanning_spec.rb @@ -5,7 +5,7 @@ module QA only: { subdomain: %i[staging staging-canary] } do describe 'License Scanning' do let!(:test_project) do - create(:project, name: 'license-scanning-project', description: 'License Scanning Project') + create(:project, :with_readme, name: 'license-scanning-project', description: 'License Scanning Project') end let!(:licenses) do @@ -23,19 +23,21 @@ module QA executor: :docker) end - before do - Resource::Repository::ProjectPush.fabricate! do |project_push| - project_push.project = test_project - project_push.files = [ + let!(:source) do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = test_project + commit.branch = 'license-management-mr' + commit.start_branch = test_project.default_branch + commit.add_files([ { - name: '.gitlab-ci.yml', + file_path: '.gitlab-ci.yml', content: File.read( File.join(EE::Runtime::Path.fixtures_path, 'secure_license_scanning_files', '.gitlab-ci.yml') ) }, { - name: 'package.json', + file_path: 'package.json', content: File.read( File.join( EE::Runtime::Path.fixtures_path, @@ -45,7 +47,7 @@ module QA ) }, { - name: 'package-lock.json', + file_path: 'package-lock.json', content: File.read( File.join( EE::Runtime::Path.fixtures_path, @@ -54,13 +56,8 @@ module QA ) ) } - ] - project_push.commit_message = 'NPM Package and Package Lock files' + ]) end - Flow::Login.sign_in_unless_signed_in - - test_project.visit! - Flow::Pipeline.wait_for_latest_pipeline(status: 'passed', wait: 600) end after do @@ -68,9 +65,29 @@ module QA end context 'when populated by a Dependency Scan' do - it 'populates licenses in the pipeline', + it 'populates licenses in the pipeline, dashboard and merge request', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/409969' do + merge_request = Resource::MergeRequest.fabricate_via_api! do |merge_request| + merge_request.source = source + merge_request.project = test_project + merge_request.source_branch = 'license-management-mr' + merge_request.target_branch = test_project.default_branch + end Flow::Login.sign_in_unless_signed_in + + merge_request.visit! + + Page::MergeRequest::Show.perform do |mr| + mr.wait_for_license_compliance_report + mr.expand_license_report + licenses.each do |license| + expect(mr).to have_license(license) + end + mr.merge_immediately! + end + + Flow::Pipeline.wait_for_latest_pipeline(status: 'passed', wait: 600) + test_project.visit! Flow::Pipeline.visit_latest_pipeline Page::Project::Pipeline::Show.perform do |pipeline| @@ -79,11 +96,6 @@ module QA expect(pipeline).to have_license(license) end end - end - - it 'populates licenses in the dashboard', - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/409967' do - Flow::Login.sign_in_unless_signed_in test_project.visit! Page::Project::Menu.perform(&:go_to_license_compliance) EE::Page::Project::Secure::LicenseCompliance.perform do |license_compliance| diff --git a/qa/qa/specs/features/ee/browser_ui/13_secure/merge_request_license_widget_spec.rb b/qa/qa/specs/features/ee/browser_ui/13_secure/merge_request_license_widget_spec.rb deleted file mode 100644 index 528d4de048574d8a02a2944705ceba751c59d8d9..0000000000000000000000000000000000000000 --- a/qa/qa/specs/features/ee/browser_ui/13_secure/merge_request_license_widget_spec.rb +++ /dev/null @@ -1,259 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Secure', :runner, product_group: :composition_analysis, quarantine: { - type: :waiting_on, - issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/397067' - } do - describe 'License merge request widget' do - describe 'when a license scanning report exists' do - let(:approved_license_name) { "MIT License" } - let(:denied_license_name) { "zlib License" } - let(:executor) { "qa-runner-#{Time.now.to_i}" } - - after do - @runner.remove_via_api! - end - - before do - Flow::Login.sign_in - - @project = create(:project, name: 'license-widget-project', description: 'License widget test') - - @runner = Resource::ProjectRunner.fabricate! do |runner| - runner.project = @project - runner.name = executor - runner.tags = ['secure_license'] - end - - Resource::Repository::Commit.fabricate_via_api! do |resource| - resource.project = @project - resource.commit_message = 'Create license file' - resource.add_directory(Pathname.new(EE::Runtime::Path.fixture('secure_license_files'))) - end - - @project.visit! - Flow::Pipeline.wait_for_latest_pipeline(status: 'passed', wait: 180) - - @merge_request = Resource::MergeRequest.fabricate_via_api! do |mr| - mr.project = @project - mr.source_branch = 'license-management-mr' - mr.target_branch = @project.default_branch - mr.file_name = 'gl-license-scanning-report.json' - mr.file_content = - <<~FILE_UPDATE - { - "version": "2.1", - "licenses": [ - { - "id": "Apache-2.0", - "name": "Apache License 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - }, - { - "id": "MIT", - "name": "MIT License", - "url": "https://opensource.org/licenses/MIT" - }, - { - "id": "Zlib", - "name": "zlib License", - "url": "https://opensource.org/licenses/Zlib" - } - ], - "dependencies": [ - { - "name": "actioncable", - "version": "6.0.3.3", - "package_manager": "bundler", - "path": "Gemfile.lock", - "licenses": ["MIT"] - }, - { - "name": "test_package", - "version": "0.1.0", - "package_manager": "bundler", - "path": "Gemfile.lock", - "licenses": ["Apache-2.0"] - }, - { - "name": "zlib", - "version": "1.2.11", - "package_manager": "bundler", - "path": "Gemfile.lock", - "licenses": ["Zlib"] - } - ] - } - FILE_UPDATE - mr.target_new_branch = false - mr.update_existing_file = true - end - - @project.visit! - Flow::Pipeline.wait_for_latest_pipeline(status: 'passed', wait: 180) - end - - it 'manage licenses from the merge request', - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348039' do - @merge_request.visit! - - Page::MergeRequest::Show.perform do |show| - # Give time for the runner to complete pipeline - show.has_pipeline_status?('passed') - - Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 5) do - show.wait_for_license_compliance_report - end - - show.click_manage_licenses_button - end - - EE::Page::Project::Secure::LicenseCompliance.perform do |license_compliance| - license_compliance.open_tab - license_compliance.approve_license(approved_license_name) - license_compliance.deny_license(denied_license_name) - end - - @merge_request.visit! - - Page::MergeRequest::Show.perform do |show| - show.wait_for_license_compliance_report - show.expand_license_report - expect(show).not_to have_approved_license approved_license_name - expect(show).not_to have_denied_license denied_license_name - end - end - end - - describe 'when a CycloneDX SBOM file exists', only: { subdomain: :staging } do - let(:approved_license_name) { "CC0-1.0" } - let(:denied_license_name) { "Apache-2.0" } - let(:executor) { "qa-runner-#{Time.now.to_i}" } - - after do - @runner.remove_via_api! - end - - before do - Flow::Login.sign_in - - @project = create(:project, name: 'license-widget-project', description: 'License widget test') - - @runner = Resource::ProjectRunner.fabricate! do |runner| - runner.project = @project - runner.name = executor - runner.tags = ['secure_sbom'] - end - - Resource::Repository::Commit.fabricate_via_api! do |resource| - resource.project = @project - resource.commit_message = 'Create sbom file' - resource.add_directory(Pathname.new(EE::Runtime::Path.fixture('secure_sbom_files'))) - end - - @project.visit! - Flow::Pipeline.wait_for_latest_pipeline(status: 'passed', wait: 180) - - @merge_request = Resource::MergeRequest.fabricate_via_api! do |mr| - mr.project = @project - mr.source_branch = 'license-management-mr' - mr.target_branch = @project.default_branch - mr.file_name = 'gl-sbom-npm-npm.cdx.json' - mr.file_content = - <<~FILE_UPDATE - { - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "serialNumber": "urn:uuid:aec33827-20ae-40d0-ae83-18ee846364d2", - "version": 1, - "metadata": { - "timestamp": "2022-02-23T08:01:37Z", - "tools": [ - { - "vendor": "GitLab", - "name": "Gemnasium", - "version": "2.34.0" - } - ], - "authors": [ - { - "name": "GitLab", - "email": "support@gitlab.com" - } - ], - "properties": [ - { - "name": "gitlab:dependency_scanning:input_file", - "value": "package-lock.json" - }, - { - "name": "gitlab:dependency_scanning:package_manager", - "value": "npm" - } - ] - }, - "components": [ - { - "name": "dragselect", - "version": "1.3.6", - "purl": "pkg:npm/dragselect@1.3.6", - "type": "library" - }, - { - "name": "@polkadot/rpc-augment", - "version": "8.4.1", - "purl": "pkg:npm/@polkadot/rpc-augment@8.4.1", - "type": "library" - }, - { - "name": "spdx-license-list", - "version": "6.6.0", - "purl": "pkg:npm/spdx-license-list@6.6.0", - "type": "library" - } - ] - } - FILE_UPDATE - mr.target_new_branch = false - mr.update_existing_file = true - end - - @project.visit! - Flow::Pipeline.wait_for_latest_pipeline(status: 'passed', wait: 180) - end - - it 'manage licenses from the merge request', - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/394713' do - @merge_request.visit! - - Page::MergeRequest::Show.perform do |show| - # Give time for the runner to complete pipeline - show.has_pipeline_status?('passed') - - Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 5) do - show.wait_for_license_compliance_report - end - - show.click_manage_licenses_button - end - - EE::Page::Project::Secure::LicenseCompliance.perform do |license_compliance| - license_compliance.open_tab - license_compliance.approve_license(approved_license_name) - license_compliance.deny_license(denied_license_name) - end - - @merge_request.visit! - - Page::MergeRequest::Show.perform do |show| - show.wait_for_license_compliance_report - show.expand_license_report - expect(show).to have_approved_license approved_license_name - expect(show).to have_denied_license denied_license_name - end - end - end - end - end -end diff --git a/spec/frontend/ci/reports/components/__snapshots__/issue_status_icon_spec.js.snap b/spec/frontend/ci/reports/components/__snapshots__/issue_status_icon_spec.js.snap index b402503bb89c736658e914b90bcd994fc3570b78..2de634a62098eadb98f9a4c0ae4a530f488df70f 100644 --- a/spec/frontend/ci/reports/components/__snapshots__/issue_status_icon_spec.js.snap +++ b/spec/frontend/ci/reports/components/__snapshots__/issue_status_icon_spec.js.snap @@ -5,7 +5,6 @@ exports[`IssueStatusIcon renders "failed" state correctly 1`] = ` class="failed report-block-list-icon" > <gl-icon-stub - data-qa-selector="status_failed_icon" name="status_failed_borderless" size="24" /> @@ -17,7 +16,6 @@ exports[`IssueStatusIcon renders "neutral" state correctly 1`] = ` class="neutral report-block-list-icon" > <gl-icon-stub - data-qa-selector="status_neutral_icon" name="dash" size="24" /> @@ -29,7 +27,6 @@ exports[`IssueStatusIcon renders "success" state correctly 1`] = ` class="report-block-list-icon success" > <gl-icon-stub - data-qa-selector="status_success_icon" name="status_success_borderless" size="24" />