Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
aaa0fba820
commit
bef328bb8c
34 changed files with 189 additions and 84 deletions
|
@ -55,12 +55,12 @@ export default {
|
|||
return generateAgentRegistrationCommand(this.agentToken, this.kasAddress);
|
||||
},
|
||||
basicInstallPath() {
|
||||
return helpPagePath('user/clusters/agent/index', {
|
||||
return helpPagePath('user/clusters/agent/install/index', {
|
||||
anchor: 'install-the-agent-into-the-cluster',
|
||||
});
|
||||
},
|
||||
advancedInstallPath() {
|
||||
return helpPagePath('user/clusters/agent/index', { anchor: 'advanced-installation' });
|
||||
return helpPagePath('user/clusters/agent/install/index', { anchor: 'advanced-installation' });
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -213,6 +213,7 @@ export default {
|
|||
<div
|
||||
v-if="hasRotateError"
|
||||
class="gl-text-red-500 gl-display-flex gl-align-items-center gl-font-weight-normal gl-mb-3"
|
||||
data-testid="rotate-error"
|
||||
>
|
||||
<gl-icon name="warning" class="gl-mr-2" />
|
||||
<span>{{ $options.translations.instanceIdRegenerateError }}</span>
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
- name: "REST API Runner will not contain 'paused'"
|
||||
- name: "REST API Runner will not contain `paused`"
|
||||
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
|
||||
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
|
||||
body: | # Do not modify this line, instead modify the lines below.
|
||||
Runner REST API will not return "paused" as a status in GitLab 15.0.
|
||||
Runner REST API will not return `paused` as a status in GitLab 15.0.
|
||||
|
||||
REST API: Paused runners' status will only relate to runner contact status, such as:
|
||||
"online", "offline", "not_connected". Status "paused" will not appear when the runner is
|
||||
Paused runners' status will only relate to runner contact status, such as:
|
||||
`online`, `offline`, or `not_connected`. Status `paused` will not appear when the runner is
|
||||
not active.
|
||||
|
||||
When checking if a runner is "paused", API users are advised to check the boolean attribute
|
||||
"active" to be `false` instead.
|
||||
When checking if a runner is `paused`, API users are advised to check the boolean attribute
|
||||
`active` to be `false` instead.
|
||||
stage: Verify
|
||||
tiers: [Core, Premium, Ultimate]
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344648
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html
|
||||
announcement_date: "2021-11-22"
|
||||
|
|
|
@ -450,6 +450,78 @@ The conventional Secure [analyzer](https://gitlab.com/gitlab-org/security-produc
|
|||
|
||||
If the scanner report is small, less than 35 lines, then feel free to [inline the report](https://gitlab.com/gitlab-org/security-products/analyzers/sobelow/-/blob/8bd2428a/convert/convert_test.go#L13-77) rather than use a `testdata` directory.
|
||||
|
||||
#### Test Diffs
|
||||
|
||||
The [go-cmp]<https://github.com/google/go-cmp> package should be used when comparing large structs in tests. It makes it possible to output a specific diff where the two structs differ, rather than seeing the whole of both structs printed out in the test logs. Here is a small example:
|
||||
|
||||
```golang
|
||||
package main
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
type Foo struct {
|
||||
Desc Bar
|
||||
Point Baz
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
A string
|
||||
B string
|
||||
}
|
||||
|
||||
type Baz struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
|
||||
func TestHelloWorld(t *testing.T) {
|
||||
want := Foo{
|
||||
Desc: Bar{A: "a", B: "b"},
|
||||
Point: Baz{X: 1, Y: 2},
|
||||
}
|
||||
|
||||
got := Foo{
|
||||
Desc: Bar{A: "a", B: "b"},
|
||||
Point: Baz{X: 2, Y: 2},
|
||||
}
|
||||
|
||||
t.Log("reflect comparison:")
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Wrong result. want:\n%v\nGot:\n%v", want, got)
|
||||
}
|
||||
|
||||
t.Log("cmp comparison:")
|
||||
if diff := cmp.Diff(want, got); diff != "" {
|
||||
t.Errorf("Wrong result. (-want +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The output demonstrates why `go-cmp` is far superior when comparing large structs. Even though you could spot the difference with this small difference, it quickly gets unwieldy as the data grows.
|
||||
|
||||
```plaintext
|
||||
main_test.go:36: reflect comparison:
|
||||
main_test.go:38: Wrong result. want:
|
||||
{{a b} {1 2}}
|
||||
Got:
|
||||
{{a b} {2 2}}
|
||||
main_test.go:41: cmp comparison:
|
||||
main_test.go:43: Wrong result. (-want +got):
|
||||
main.Foo{
|
||||
Desc: {A: "a", B: "b"},
|
||||
Point: main.Baz{
|
||||
- X: 1,
|
||||
+ X: 2,
|
||||
Y: 2,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[Return to Development documentation](../index.md).
|
||||
|
|
|
@ -94,18 +94,18 @@ Note that we are not deprecating the Kerberos SPNEGO integration, only the old p
|
|||
|
||||
Announced: 2021-09-22
|
||||
|
||||
### REST API Runner will not contain 'paused'
|
||||
### REST API Runner will not contain `paused`
|
||||
|
||||
Runner REST API will not return "paused" as a status in GitLab 15.0.
|
||||
Runner REST API will not return `paused` as a status in GitLab 15.0.
|
||||
|
||||
REST API: Paused runners' status will only relate to runner contact status, such as:
|
||||
"online", "offline", "not_connected". Status "paused" will not appear when the runner is
|
||||
Paused runners' status will only relate to runner contact status, such as:
|
||||
`online`, `offline`, or `not_connected`. Status `paused` will not appear when the runner is
|
||||
not active.
|
||||
|
||||
When checking if a runner is "paused", API users are advised to check the boolean attribute
|
||||
"active" to be `false` instead.
|
||||
When checking if a runner is `paused`, API users are advised to check the boolean attribute
|
||||
`active` to be `false` instead.
|
||||
|
||||
Announced:
|
||||
Announced: 2021-11-22
|
||||
|
||||
### `AuthenticationType` for `[runners.cache.s3]` must be explicitly assigned
|
||||
|
||||
|
|
|
@ -1175,6 +1175,19 @@ For more information, see [Offline environments](../offline_deployments/index.md
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Error waiting for API Security 'http://127.0.0.1:5000' to become available
|
||||
|
||||
A bug exists in versions of the API Fuzzing analyzer prior to v1.6.196 that can cause a background process to fail under certain conditions. The solution is to update to a newer version of the DAST API analyzer.
|
||||
|
||||
The version information can be found in the job details for the `apifuzzer_fuzz` job.
|
||||
|
||||
If the issue is occuring with versions v1.6.196 or greater, please contact Support and provide the following information:
|
||||
|
||||
1. Reference this troubleshooting section and ask for the issue to be escalated to the Dynamic Analysis Team.
|
||||
1. The full console output of the job.
|
||||
1. The `gl-api-security-scanner.log` file available as a job artifact. In the right-hand panel of the job details page, select the **Browse** button.
|
||||
1. The `apifuzzer_fuzz` job definition from your `.gitlab-ci.yml` file.
|
||||
|
||||
### Error, the OpenAPI document is not valid. Errors were found during validation of the document using the published OpenAPI schema
|
||||
|
||||
At the start of an API Fuzzing job the OpenAPI Specification is validated against the [published schema](https://github.com/OAI/OpenAPI-Specification/tree/master/schemas). This error is shown when the provided OpenAPI Specification has validation errors. Errors can be introduced when creating an OpenAPI Specification manually, and also when the schema is generated.
|
||||
|
|
|
@ -1132,6 +1132,19 @@ For more information, see [Offline environments](../offline_deployments/index.md
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Error waiting for API Security 'http://127.0.0.1:5000' to become available
|
||||
|
||||
A bug exists in versions of the DAST API analyzer prior to v1.6.196 that can cause a background process to fail under certain conditions. The solution is to update to a newer version of the DAST API analyzer.
|
||||
|
||||
The version information can be found in the job details for the `dast_api` job.
|
||||
|
||||
If the issue is occuring with versions v1.6.196 or greater, please contact Support and provide the following information:
|
||||
|
||||
1. Reference this troubleshooting section and ask for the issue to be escalated to the Dynamic Analysis Team.
|
||||
1. The full console output of the job.
|
||||
1. The `gl-api-security-scanner.log` file available as a job artifact. In the right-hand panel of the job details page, select the **Browse** button.
|
||||
1. The `dast_api` job definition from your `.gitlab-ci.yml` file.
|
||||
|
||||
### Failed to start scanner session (version header not found)
|
||||
|
||||
The DAST API engine outputs an error message when it cannot establish a connection with the scanner application component. The error message is shown in the job output window of the `dast_api` job. A common cause of this issue is changing the `DAST_API_API` variable from its default.
|
||||
|
|
|
@ -201,8 +201,7 @@ To prevent a merge request introducing a security vulnerability in a project, en
|
|||
Vulnerability-Check rule. While this rule is enabled, an additional merge request approval is
|
||||
required when the latest security report in a merge request:
|
||||
|
||||
- Contains vulnerabilities that are not present in the target branch. Note that approval is still
|
||||
required for dismissed vulnerabilities.
|
||||
- Contains vulnerabilities with states (for example, `previously detected`, `dismissed`) matching the rule's vulnerability states. Only `newly detected` will be considered if the target branch differs from the project default branch.
|
||||
- Contains vulnerabilities with severity levels (for example, `high`, `critical`, or `unknown`)
|
||||
matching the rule's severity levels.
|
||||
- Contains a vulnerability count higher than the rule allows.
|
||||
|
@ -210,7 +209,7 @@ required when the latest security report in a merge request:
|
|||
|
||||
An approval is optional when the security report:
|
||||
|
||||
- Contains no new vulnerabilities when compared to the target branch.
|
||||
- Contains only vulnerabilities with states (for example, `newly detected`, `resolved`) **NOT** matching the rule's vulnerability states.
|
||||
- Contains only vulnerabilities with severity levels (for example, `low`, `medium`) **NOT** matching
|
||||
the rule's severity levels.
|
||||
- Contains a vulnerability count equal to or less than what the rule allows.
|
||||
|
|
|
@ -26,12 +26,12 @@ describe('Alert Handler', () => {
|
|||
});
|
||||
|
||||
it('should render the alert', () => {
|
||||
expect(findFirstAlert()).toExist();
|
||||
expect(findFirstAlert()).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should dismiss the alert on click', () => {
|
||||
findFirstDismissButton().click();
|
||||
expect(findFirstAlert()).not.toExist();
|
||||
expect(findFirstAlert()).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -58,12 +58,12 @@ describe('Alert Handler', () => {
|
|||
});
|
||||
|
||||
it('should render the banner', () => {
|
||||
expect(findFirstBanner()).toExist();
|
||||
expect(findFirstBanner()).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should dismiss the banner on click', () => {
|
||||
findFirstDismissButton().click();
|
||||
expect(findFirstBanner()).not.toExist();
|
||||
expect(findFirstBanner()).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -79,12 +79,12 @@ describe('Alert Handler', () => {
|
|||
});
|
||||
|
||||
it('should render the banner', () => {
|
||||
expect(findFirstAlert()).toExist();
|
||||
expect(findFirstAlert()).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should dismiss the banner on click', () => {
|
||||
findFirstDismissButtonByClass().click();
|
||||
expect(findFirstAlert()).not.toExist();
|
||||
expect(findFirstAlert()).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -72,7 +72,7 @@ describe('ConfirmModal', () => {
|
|||
|
||||
it('starts with only JsHooks', () => {
|
||||
expect(findJsHooks()).toHaveLength(buttons.length);
|
||||
expect(findModal()).not.toExist();
|
||||
expect(findModal()).toBe(null);
|
||||
});
|
||||
|
||||
describe('when button clicked', () => {
|
||||
|
@ -87,7 +87,7 @@ describe('ConfirmModal', () => {
|
|||
|
||||
describe('GlModal', () => {
|
||||
it('is rendered', () => {
|
||||
expect(findModal()).toExist();
|
||||
expect(findModal()).not.toBe(null);
|
||||
expect(modalIsHidden()).toBe(false);
|
||||
});
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ describe('DeleteLabelModal', () => {
|
|||
|
||||
it('starts with only js-containers', () => {
|
||||
expect(findJsHooks()).toHaveLength(buttons.length);
|
||||
expect(findModal()).not.toExist();
|
||||
expect(findModal()).toBe(null);
|
||||
});
|
||||
|
||||
describe('when first button clicked', () => {
|
||||
|
@ -54,7 +54,7 @@ describe('DeleteLabelModal', () => {
|
|||
});
|
||||
|
||||
it('renders GlModal', () => {
|
||||
expect(findModal()).toExist();
|
||||
expect(findModal()).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -50,20 +50,20 @@ describe('Deploy keys key', () => {
|
|||
it('shows pencil button for editing', () => {
|
||||
createComponent({ deployKey });
|
||||
|
||||
expect(wrapper.find('.btn [data-testid="pencil-icon"]')).toExist();
|
||||
expect(wrapper.find('.btn [data-testid="pencil-icon"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('shows disable button when the project is not deletable', () => {
|
||||
createComponent({ deployKey });
|
||||
|
||||
expect(wrapper.find('.btn [data-testid="cancel-icon"]')).toExist();
|
||||
expect(wrapper.find('.btn [data-testid="cancel-icon"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('shows remove button when the project is deletable', () => {
|
||||
createComponent({
|
||||
deployKey: { ...deployKey, destroyed_when_orphaned: true, almost_orphaned: true },
|
||||
});
|
||||
expect(wrapper.find('.btn [data-testid="remove-icon"]')).toExist();
|
||||
expect(wrapper.find('.btn [data-testid="remove-icon"]').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -137,7 +137,7 @@ describe('Deploy keys key', () => {
|
|||
|
||||
it('shows pencil button for editing', () => {
|
||||
createComponent({ deployKey });
|
||||
expect(wrapper.find('.btn [data-testid="pencil-icon"]')).toExist();
|
||||
expect(wrapper.find('.btn [data-testid="pencil-icon"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('shows disable button when key is enabled', () => {
|
||||
|
@ -145,7 +145,7 @@ describe('Deploy keys key', () => {
|
|||
|
||||
createComponent({ deployKey });
|
||||
|
||||
expect(wrapper.find('.btn [data-testid="cancel-icon"]')).toExist();
|
||||
expect(wrapper.find('.btn [data-testid="cancel-icon"]').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,7 +37,7 @@ describe('Deploy keys panel', () => {
|
|||
mountComponent();
|
||||
const tableHeader = findTableRowHeader();
|
||||
|
||||
expect(tableHeader).toExist();
|
||||
expect(tableHeader.exists()).toBe(true);
|
||||
expect(tableHeader.text()).toContain('Deploy key');
|
||||
expect(tableHeader.text()).toContain('Project usage');
|
||||
expect(tableHeader.text()).toContain('Created');
|
||||
|
|
|
@ -87,7 +87,7 @@ describe('Design management list item component', () => {
|
|||
|
||||
describe('before image is loaded', () => {
|
||||
it('renders loading spinner', () => {
|
||||
expect(wrapper.find(GlLoadingIcon)).toExist();
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import Component from '~/feature_flags/components/configure_feature_flags_modal.vue';
|
||||
|
||||
describe('Configure Feature Flags Modal', () => {
|
||||
|
@ -20,7 +21,7 @@ describe('Configure Feature Flags Modal', () => {
|
|||
};
|
||||
|
||||
let wrapper;
|
||||
const factory = (props = {}, { mountFn = shallowMount, ...options } = {}) => {
|
||||
const factory = (props = {}, { mountFn = shallowMountExtended, ...options } = {}) => {
|
||||
wrapper = mountFn(Component, {
|
||||
provide,
|
||||
stubs: { GlSprintf },
|
||||
|
@ -140,11 +141,13 @@ describe('Configure Feature Flags Modal', () => {
|
|||
|
||||
describe('has rotate error', () => {
|
||||
afterEach(() => wrapper.destroy());
|
||||
beforeEach(factory.bind(null, { hasRotateError: false }));
|
||||
beforeEach(() => {
|
||||
factory({ hasRotateError: true });
|
||||
});
|
||||
|
||||
it('should display an error', async () => {
|
||||
expect(wrapper.find('.text-danger')).toExist();
|
||||
expect(wrapper.find('[name="warning"]')).toExist();
|
||||
expect(wrapper.findByTestId('rotate-error').exists()).toBe(true);
|
||||
expect(wrapper.find('[name="warning"]').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ describe('InviteMembersModal', () => {
|
|||
|
||||
describe('rendering the access expiration date field', () => {
|
||||
it('renders the datepicker', () => {
|
||||
expect(findDatepicker()).toExist();
|
||||
expect(findDatepicker().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { GlButton, GlModal } from '@gitlab/ui';
|
||||
import { GlModal } from '@gitlab/ui';
|
||||
import { stubComponent } from 'helpers/stub_component';
|
||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import CsvImportModal from '~/issuable/components/csv_import_modal.vue';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
|
||||
|
||||
|
@ -36,7 +37,6 @@ describe('CsvImportModal', () => {
|
|||
});
|
||||
|
||||
const findModal = () => wrapper.findComponent(GlModal);
|
||||
const findPrimaryButton = () => wrapper.findComponent(GlButton);
|
||||
const findForm = () => wrapper.find('form');
|
||||
const findFileInput = () => wrapper.findByLabelText('Upload CSV file');
|
||||
const findAuthenticityToken = () => new FormData(findForm().element).get('authenticity_token');
|
||||
|
@ -64,11 +64,11 @@ describe('CsvImportModal', () => {
|
|||
expect(findForm().exists()).toBe(true);
|
||||
expect(findForm().attributes('action')).toBe(importCsvIssuesPath);
|
||||
expect(findAuthenticityToken()).toBe('mock-csrf-token');
|
||||
expect(findFileInput()).toExist();
|
||||
expect(findFileInput().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('displays the correct primary button action text', () => {
|
||||
expect(findPrimaryButton()).toExist();
|
||||
expect(findModal().props('actionPrimary')).toEqual({ text: __('Import issues') });
|
||||
});
|
||||
|
||||
it('submits the form when the primary action is clicked', () => {
|
||||
|
|
|
@ -456,7 +456,7 @@ describe('Dashboard', () => {
|
|||
|
||||
it('shows the links section', () => {
|
||||
expect(wrapper.vm.shouldShowLinksSection).toBe(true);
|
||||
expect(wrapper.find(LinksSection)).toExist();
|
||||
expect(wrapper.findComponent(LinksSection).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { GlLink } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
import LinksSection from '~/monitoring/components/links_section.vue';
|
||||
import { createStore } from '~/monitoring/stores';
|
||||
|
||||
|
@ -26,12 +28,12 @@ describe('Links Section component', () => {
|
|||
createShallowWrapper();
|
||||
});
|
||||
|
||||
it('does not render a section if no links are present', () => {
|
||||
it('does not render a section if no links are present', async () => {
|
||||
setState();
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(findLinks()).not.toExist();
|
||||
});
|
||||
await nextTick();
|
||||
|
||||
expect(findLinks().length).toBe(0);
|
||||
});
|
||||
|
||||
it('renders a link inside a section', () => {
|
||||
|
|
|
@ -15,12 +15,12 @@ describe('Text variable component', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findInput = () => wrapper.find(GlFormInput);
|
||||
const findInput = () => wrapper.findComponent(GlFormInput);
|
||||
|
||||
it('renders a text input when all props are passed', () => {
|
||||
createShallowWrapper();
|
||||
|
||||
expect(findInput()).toExist();
|
||||
expect(findInput().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('always has a default value', () => {
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('monitoring/pages/dashboard_page', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findDashboardComponent = () => wrapper.find(Dashboard);
|
||||
const findDashboardComponent = () => wrapper.findComponent(Dashboard);
|
||||
|
||||
beforeEach(() => {
|
||||
buildRouter();
|
||||
|
@ -60,7 +60,7 @@ describe('monitoring/pages/dashboard_page', () => {
|
|||
smallEmptyState: false,
|
||||
};
|
||||
|
||||
expect(findDashboardComponent()).toExist();
|
||||
expect(findDashboardComponent().exists()).toBe(true);
|
||||
expect(allProps).toMatchObject(findDashboardComponent().props());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -58,7 +58,6 @@ describe('issue_note_body component', () => {
|
|||
it('adds autosave', () => {
|
||||
const autosaveKey = `autosave/Note/${note.noteable_type}/${note.id}`;
|
||||
|
||||
expect(vm.autosave).toExist();
|
||||
expect(vm.autosave.key).toEqual(autosaveKey);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -33,12 +33,12 @@ describe('InstallationCommands', () => {
|
|||
});
|
||||
}
|
||||
|
||||
const npmInstallation = () => wrapper.find(NpmInstallation);
|
||||
const mavenInstallation = () => wrapper.find(MavenInstallation);
|
||||
const conanInstallation = () => wrapper.find(ConanInstallation);
|
||||
const nugetInstallation = () => wrapper.find(NugetInstallation);
|
||||
const pypiInstallation = () => wrapper.find(PypiInstallation);
|
||||
const composerInstallation = () => wrapper.find(ComposerInstallation);
|
||||
const npmInstallation = () => wrapper.findComponent(NpmInstallation);
|
||||
const mavenInstallation = () => wrapper.findComponent(MavenInstallation);
|
||||
const conanInstallation = () => wrapper.findComponent(ConanInstallation);
|
||||
const nugetInstallation = () => wrapper.findComponent(NugetInstallation);
|
||||
const pypiInstallation = () => wrapper.findComponent(PypiInstallation);
|
||||
const composerInstallation = () => wrapper.findComponent(ComposerInstallation);
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
|
@ -57,7 +57,7 @@ describe('InstallationCommands', () => {
|
|||
it(`${packageEntity.packageType} instructions exist`, () => {
|
||||
createComponent({ packageEntity });
|
||||
|
||||
expect(selector()).toExist();
|
||||
expect(selector().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -38,7 +38,7 @@ describe('Dropdown select component', () => {
|
|||
it('creates a hidden input if fieldName is provided', () => {
|
||||
mountDropdown({ fieldName: 'namespace-input' });
|
||||
|
||||
expect(findNamespaceInput()).toExist();
|
||||
expect(findNamespaceInput().exists()).toBe(true);
|
||||
expect(findNamespaceInput().attributes('name')).toBe('namespace-input');
|
||||
});
|
||||
|
||||
|
@ -57,9 +57,9 @@ describe('Dropdown select component', () => {
|
|||
// wait for dropdown options to populate
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(findDropdownOption('user: Administrator')).toExist();
|
||||
expect(findDropdownOption('group: GitLab Org')).toExist();
|
||||
expect(findDropdownOption('group: Foobar')).not.toExist();
|
||||
expect(findDropdownOption('user: Administrator').exists()).toBe(true);
|
||||
expect(findDropdownOption('group: GitLab Org').exists()).toBe(true);
|
||||
expect(findDropdownOption('group: Foobar').exists()).toBe(false);
|
||||
|
||||
findDropdownOption('user: Administrator').trigger('click');
|
||||
await wrapper.vm.$nextTick();
|
||||
|
|
|
@ -35,7 +35,7 @@ describe('Pipelines Empty State', () => {
|
|||
});
|
||||
|
||||
it('should render the CI/CD templates', () => {
|
||||
expect(pipelinesCiTemplates()).toExist();
|
||||
expect(pipelinesCiTemplates().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -554,7 +554,7 @@ describe('Pipelines', () => {
|
|||
});
|
||||
|
||||
it('renders the CI/CD templates', () => {
|
||||
expect(wrapper.find(PipelinesCiTemplates)).toExist();
|
||||
expect(wrapper.findComponent(PipelinesCiTemplates).exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('when the code_quality_walkthrough experiment is active', () => {
|
||||
|
@ -568,7 +568,7 @@ describe('Pipelines', () => {
|
|||
});
|
||||
|
||||
it('renders the CI/CD templates', () => {
|
||||
expect(wrapper.find(PipelinesCiTemplates)).toExist();
|
||||
expect(wrapper.findComponent(PipelinesCiTemplates).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -597,7 +597,7 @@ describe('Pipelines', () => {
|
|||
});
|
||||
|
||||
it('renders the CI/CD templates', () => {
|
||||
expect(wrapper.find(PipelinesCiTemplates)).toExist();
|
||||
expect(wrapper.findComponent(PipelinesCiTemplates).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ describe('Author Select', () => {
|
|||
});
|
||||
|
||||
it('does not have popover text by default', () => {
|
||||
expect(wrapper.attributes('title')).not.toExist();
|
||||
expect(wrapper.attributes('title')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -134,12 +134,12 @@ describe('App component', () => {
|
|||
|
||||
it('renders main-heading with correct text', () => {
|
||||
const mainHeading = findMainHeading();
|
||||
expect(mainHeading).toExist();
|
||||
expect(mainHeading.exists()).toBe(true);
|
||||
expect(mainHeading.text()).toContain('Security Configuration');
|
||||
});
|
||||
|
||||
it('renders GlTab Component ', () => {
|
||||
expect(findTab()).toExist();
|
||||
expect(findTab().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders right amount of tabs with correct title ', () => {
|
||||
|
|
|
@ -50,7 +50,7 @@ describe('Issuable Time Tracking Report', () => {
|
|||
it('should render loading spinner', () => {
|
||||
mountComponent();
|
||||
|
||||
expect(findLoadingIcon()).toExist();
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should render error message on reject', async () => {
|
||||
|
|
|
@ -47,10 +47,12 @@ Object.assign(global, {
|
|||
setFixtures: setHTMLFixture,
|
||||
});
|
||||
|
||||
const JQUERY_MATCHERS_TO_EXCLUDE = ['toHaveLength', 'toExist'];
|
||||
|
||||
// custom-jquery-matchers was written for an old Jest version, we need to make it compatible
|
||||
Object.entries(jqueryMatchers).forEach(([matcherName, matcherFactory]) => {
|
||||
// Don't override existing Jest matcher
|
||||
if (matcherName === 'toHaveLength') {
|
||||
// Exclude these jQuery matchers
|
||||
if (JQUERY_MATCHERS_TO_EXCLUDE.includes(matcherName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ describe('MRWidgetMerged', () => {
|
|||
});
|
||||
|
||||
it('shows button to copy commit SHA to clipboard', () => {
|
||||
expect(selectors.copyMergeShaButton).toExist();
|
||||
expect(selectors.copyMergeShaButton).not.toBe(null);
|
||||
expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(
|
||||
vm.mr.mergeCommitSha,
|
||||
);
|
||||
|
@ -201,14 +201,14 @@ describe('MRWidgetMerged', () => {
|
|||
vm.mr.mergeCommitSha = null;
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(selectors.copyMergeShaButton).not.toExist();
|
||||
expect(selectors.copyMergeShaButton).toBe(null);
|
||||
expect(vm.$el.querySelector('.mr-info-list').innerText).not.toContain('with');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows merge commit SHA link', () => {
|
||||
expect(selectors.mergeCommitShaLink).toExist();
|
||||
expect(selectors.mergeCommitShaLink).not.toBe(null);
|
||||
expect(selectors.mergeCommitShaLink.text).toContain(vm.mr.shortMergeCommitSha);
|
||||
expect(selectors.mergeCommitShaLink.href).toBe(vm.mr.mergeCommitPath);
|
||||
});
|
||||
|
|
|
@ -16,6 +16,6 @@ describe('ContentViewer', () => {
|
|||
propsData: { path, fileSize: 1024, type },
|
||||
});
|
||||
|
||||
expect(wrapper.find(selector).element).toExist();
|
||||
expect(wrapper.find(selector).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ describe('MarkdownViewer', () => {
|
|||
it('renders an animation container while the markdown is loading', () => {
|
||||
createComponent();
|
||||
|
||||
expect(wrapper.find('.animation-container')).toExist();
|
||||
expect(wrapper.find('.animation-container').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders markdown preview preview renders and loads rendered markdown from server', () => {
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('~/whats_new/utils/notification', () => {
|
|||
|
||||
subject();
|
||||
|
||||
expect(findNotificationCountEl()).toExist();
|
||||
expect(findNotificationCountEl()).not.toBe(null);
|
||||
expect(notificationEl.classList).toContain('with-notifications');
|
||||
});
|
||||
|
||||
|
@ -38,11 +38,11 @@ describe('~/whats_new/utils/notification', () => {
|
|||
notificationEl.classList.add('with-notifications');
|
||||
localStorage.setItem('display-whats-new-notification', 'version-digest');
|
||||
|
||||
expect(findNotificationCountEl()).toExist();
|
||||
expect(findNotificationCountEl()).not.toBe(null);
|
||||
|
||||
subject();
|
||||
|
||||
expect(findNotificationCountEl()).not.toExist();
|
||||
expect(findNotificationCountEl()).toBe(null);
|
||||
expect(notificationEl.classList).not.toContain('with-notifications');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue