aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
authorJeremy Davis <jeremy.davis@sonarsource.com>2023-08-07 17:34:23 +0200
committersonartech <sonartech@sonarsource.com>2023-08-14 20:02:57 +0000
commit3f570b118fa9a68469a34bb98f25367050f21025 (patch)
treee4cba8c1d56a44f4a08705bd37f77d36d40cd355 /server/sonar-web/src/main/js/apps
parent08ef818d25713fcbd1e5c87f30521324b8f9e74c (diff)
downloadsonarqube-3f570b118fa9a68469a34bb98f25367050f21025.tar.gz
sonarqube-3f570b118fa9a68469a34bb98f25367050f21025.zip
SONAR-20086 Migrate new code period setup page
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx120
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx28
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx94
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx12
8 files changed, 140 insertions, 127 deletions
diff --git a/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx b/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
index 51c69701112..664bc914ae6 100644
--- a/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
@@ -21,25 +21,17 @@ import classNames from 'classnames';
import { LargeCenteredLayout } from 'design-system';
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
-import { FormattedMessage } from 'react-intl';
import { getAlmSettings } from '../../../api/alm-settings';
import withAppStateContext from '../../../app/components/app-state/withAppStateContext';
import withAvailableFeatures, {
WithAvailableFeaturesProps,
} from '../../../app/components/available-features/withAvailableFeatures';
import A11ySkipTarget from '../../../components/a11y/A11ySkipTarget';
-import DocLink from '../../../components/common/DocLink';
-import { ButtonLink, SubmitButton } from '../../../components/controls/buttons';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
-import NewCodeDefinitionSelector from '../../../components/new-code-definition/NewCodeDefinitionSelector';
-import DeferredSpinner from '../../../components/ui/DeferredSpinner';
-import { addGlobalSuccessMessage } from '../../../helpers/globalMessages';
import { translate } from '../../../helpers/l10n';
-import { getProjectUrl } from '../../../helpers/urls';
import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings';
import { AppState } from '../../../types/appstate';
import { Feature } from '../../../types/features';
-import { NewCodeDefinitiondWithCompliance } from '../../../types/new-code-definition';
import AlmBindingDefinitionForm from '../../settings/components/almIntegration/AlmBindingDefinitionForm';
import AzureProjectCreate from './Azure/AzureProjectCreate';
import BitbucketCloudProjectCreate from './BitbucketCloud/BitbucketCloudProjectCreate';
@@ -47,7 +39,7 @@ import BitbucketProjectCreate from './BitbucketServer/BitbucketProjectCreate';
import CreateProjectModeSelection from './CreateProjectModeSelection';
import GitHubProjectCreate from './Github/GitHubProjectCreate';
import GitlabProjectCreate from './Gitlab/GitlabProjectCreate';
-import CreateProjectPageHeader from './components/CreateProjectPageHeader';
+import NewCodeDefinitionSelection from './components/NewCodeDefinitionSelection';
import ManualProjectCreate from './manual/ManualProjectCreate';
import './style.css';
import { CreateProjectApiCallback, CreateProjectModes } from './types';
@@ -65,10 +57,7 @@ interface State {
githubSettings: AlmSettingsInstance[];
gitlabSettings: AlmSettingsInstance[];
loading: boolean;
- isProjectSetupDone: boolean;
creatingAlmDefinition?: AlmKeys;
- selectedNcd: NewCodeDefinitiondWithCompliance | null;
- submitting: boolean;
}
const PROJECT_MODE_FOR_ALM_KEY = {
@@ -90,13 +79,12 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
githubSettings: [],
gitlabSettings: [],
loading: true,
- isProjectSetupDone: false,
- selectedNcd: null,
- submitting: false,
};
componentDidMount() {
this.mounted = true;
+
+ this.cleanQueryParameters();
this.fetchAlmBindings();
}
@@ -104,6 +92,18 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
this.mounted = false;
}
+ cleanQueryParameters() {
+ const { location, router } = this.props;
+
+ if (location.query?.setncd === 'true' && this.createProjectFnRef === null) {
+ // Timeout is required to force the refresh of the URL
+ setTimeout(() => {
+ location.query.setncd = undefined;
+ router.replace(location);
+ }, 0);
+ }
+ }
+
fetchAlmBindings = () => {
this.setState({ loading: true });
return getAlmSettings()
@@ -138,22 +138,12 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
this.setState({ creatingAlmDefinition: alm });
};
- handleProjectCreation = async () => {
- const { selectedNcd } = this.state;
- if (this.createProjectFnRef && selectedNcd) {
- this.setState({ submitting: true });
-
- const { project } = await this.createProjectFnRef(selectedNcd.type, selectedNcd.value);
- this.props.router.push(getProjectUrl(project.key));
-
- addGlobalSuccessMessage(translate('onboarding.create_project.success'));
- this.setState({ submitting: false });
- }
- };
-
handleProjectSetupDone = (createProject: CreateProjectApiCallback) => {
+ const { location, router } = this.props;
this.createProjectFnRef = createProject;
- this.setState({ isProjectSetupDone: true });
+
+ location.query.setncd = 'true';
+ router.push(location);
};
handleOnCancelCreation = () => {
@@ -178,16 +168,6 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
}
};
- handleNcdChanged = (ncd: NewCodeDefinitiondWithCompliance) => {
- this.setState({
- selectedNcd: ncd,
- });
- };
-
- handleGoBack = () => {
- this.setState({ isProjectSetupDone: false });
- };
-
renderProjectCreation(mode?: CreateProjectModes) {
const {
appState: { canAdmin },
@@ -292,61 +272,11 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
}
}
- renderNcdSelection() {
- const { appState } = this.props;
- const { selectedNcd, submitting } = this.state;
-
- return (
- <div id="project-ncd-selection">
- <CreateProjectPageHeader
- title={translate('onboarding.create_project.new_code_definition.title')}
- />
-
- <h1 className="sw-mb-4">{translate('onboarding.create_project.new_code_definition')}</h1>
- <p className="sw-mb-2">
- {translate('onboarding.create_project.new_code_definition.description')}
- </p>
- <p className="sw-mb-2">
- {translate('onboarding.create_project.new_code_definition.description1')}
- </p>
-
- <p className="sw-mb-2">
- <FormattedMessage
- defaultMessage={translate('onboarding.create_project.new_code_definition.description2')}
- id="onboarding.create_project.new_code_definition.description2"
- values={{
- link: (
- <DocLink to="/project-administration/defining-new-code/">
- {translate('onboarding.create_project.new_code_definition.description2.link')}
- </DocLink>
- ),
- }}
- />
- </p>
-
- <NewCodeDefinitionSelector
- canAdmin={appState.canAdmin}
- onNcdChanged={this.handleNcdChanged}
- />
-
- <div className="sw-flex sw-flex-row sw-gap-4 sw-mt-4">
- <ButtonLink onClick={this.handleGoBack}>{translate('back')}</ButtonLink>
- <SubmitButton
- onClick={this.handleProjectCreation}
- disabled={!selectedNcd?.isCompliant || submitting}
- >
- {translate('onboarding.create_project.new_code_definition.create_project')}
- <DeferredSpinner className="spacer-left" loading={submitting} />
- </SubmitButton>
- </div>
- </div>
- );
- }
-
render() {
- const { location } = this.props;
- const { creatingAlmDefinition, isProjectSetupDone } = this.state;
+ const { appState, location, router } = this.props;
+ const { creatingAlmDefinition } = this.state;
const mode: CreateProjectModes | undefined = location.query?.mode;
+ const isProjectSetupDone = location.query?.setncd === 'true';
return (
<LargeCenteredLayout className="sw-pt-8">
@@ -358,7 +288,11 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
{this.renderProjectCreation(mode)}
</div>
<div className={classNames({ 'sw-hidden': !isProjectSetupDone })}>
- {this.renderNcdSelection()}
+ <NewCodeDefinitionSelection
+ canAdmin={Boolean(appState.canAdmin)}
+ router={router}
+ createProjectFnRef={this.createProjectFnRef}
+ />
</div>
{creatingAlmDefinition && (
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
index d1cc3348d03..5a3a2a1064c 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
@@ -55,7 +55,6 @@ const ui = {
}),
projectNextButton: byRole('button', { name: 'next' }),
newCodeDefinitionHeader: byText('onboarding.create_project.new_code_definition.title'),
- newCodeDefinitionBackButton: byRole('button', { name: 'back' }),
inheritGlobalNcdRadio: byRole('radio', { name: 'new_code_definition.global_setting' }),
projectCreateButton: byRole('button', {
name: 'onboarding.create_project.new_code_definition.create_project',
@@ -70,7 +69,7 @@ const ui = {
ncdOptionDaysRadio: byRole('radio', {
name: /new_code_definition.number_days/,
}),
- ncdOptionDaysInput: byRole('textbox', {
+ ncdOptionDaysInput: byRole('spinbutton', {
name: /new_code_definition.number_days.specify_days/,
}),
ncdOptionDaysInputError: byText('new_code_definition.number_days.invalid.1.90'),
@@ -113,20 +112,12 @@ afterAll(() => {
Object.defineProperty(window, 'location', { configurable: true, value: original });
});
-it('should fill form and move to NCD selection and back', async () => {
+it('should fill form and move to NCD selection', async () => {
const user = userEvent.setup();
renderCreateProject();
await fillFormAndNext('test', user);
expect(ui.newCodeDefinitionHeader.get()).toBeInTheDocument();
-
- expect(ui.newCodeDefinitionBackButton.get()).toBeInTheDocument();
- await user.click(ui.newCodeDefinitionBackButton.get());
-
- expect(ui.manualProjectHeader.get()).toBeInTheDocument();
-
- // TODO this must work at some point
- // expect(ui.displayNameField.get()).toHaveValue('test');
});
it('should select the global NCD when it is compliant', async () => {
@@ -204,7 +195,7 @@ it.each([ui.ncdOptionRefBranchRadio, ui.ncdOptionPreviousVersionRadio])(
}
);
-it('number of days should show error message if value is not a number', async () => {
+it('number of days ignores non-numeric inputs', async () => {
jest
.mocked(getNewCodePeriod)
.mockResolvedValue({ type: NewCodeDefinitionType.NumberOfDays, value: '60' });
@@ -222,21 +213,14 @@ it('number of days should show error message if value is not a number', async ()
await user.click(ui.ncdOptionDaysRadio.get());
expect(ui.ncdOptionDaysInput.get()).toBeInTheDocument();
- expect(ui.ncdOptionDaysInput.get()).toHaveValue('60');
+ expect(ui.ncdOptionDaysInput.get()).toHaveValue(60);
expect(ui.projectCreateButton.get()).toBeEnabled();
await user.click(ui.ncdOptionDaysInput.get());
await user.keyboard('abc');
- expect(ui.ncdOptionDaysInputError.get()).toBeInTheDocument();
- expect(ui.projectCreateButton.get()).toBeDisabled();
-
- await user.clear(ui.ncdOptionDaysInput.get());
- await user.click(ui.ncdOptionDaysInput.get());
- await user.keyboard('30');
-
- expect(ui.ncdOptionDaysInputError.query()).not.toBeInTheDocument();
- expect(ui.projectCreateButton.get()).toBeEnabled();
+ // it ignores the input and preserves its value
+ expect(ui.ncdOptionDaysInput.get()).toHaveValue(60);
});
it('the project onboarding page should be displayed when the project is created', async () => {
diff --git a/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx b/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx
new file mode 100644
index 00000000000..f0678eb6757
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/create/project/components/NewCodeDefinitionSelection.tsx
@@ -0,0 +1,94 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { ButtonPrimary, DeferredSpinner, Link, Title } from 'design-system';
+import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { Router } from '../../../../components/hoc/withRouter';
+import NewCodeDefinitionSelector from '../../../../components/new-code-definition/NewCodeDefinitionSelector';
+import { useDocUrl } from '../../../../helpers/docs';
+import { addGlobalSuccessMessage } from '../../../../helpers/globalMessages';
+import { translate } from '../../../../helpers/l10n';
+import { getProjectUrl } from '../../../../helpers/urls';
+import { NewCodeDefinitiondWithCompliance } from '../../../../types/new-code-definition';
+import { CreateProjectApiCallback } from '../types';
+
+interface Props {
+ canAdmin: boolean;
+ createProjectFnRef: CreateProjectApiCallback | null;
+ router: Router;
+}
+
+export default function NewCodeDefinitionSelection(props: Props) {
+ const { canAdmin, createProjectFnRef, router } = props;
+
+ const [submitting, setSubmitting] = React.useState(false);
+ const [selectedDefinition, selectDefinition] = React.useState<NewCodeDefinitiondWithCompliance>();
+
+ const getDocUrl = useDocUrl();
+
+ const handleProjectCreation = React.useCallback(async () => {
+ if (createProjectFnRef && selectedDefinition) {
+ setSubmitting(true);
+ const { project } = await createProjectFnRef(
+ selectedDefinition.type,
+ selectedDefinition.value
+ );
+ setSubmitting(false);
+ router.push(getProjectUrl(project.key));
+
+ addGlobalSuccessMessage(translate('onboarding.create_project.success'));
+ }
+ }, [createProjectFnRef, router, selectedDefinition]);
+
+ return (
+ <div id="project-ncd-selection" className="sw-body-sm">
+ <Title className="sw-mt-8">
+ {translate('onboarding.create_project.new_code_definition.title')}
+ </Title>
+
+ <p className="sw-mb-2">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.create_project.new_code_definition.description')}
+ id="onboarding.create_project.new_code_definition.description"
+ values={{
+ link: (
+ <Link to={getDocUrl('/project-administration/defining-new-code/')}>
+ {translate('onboarding.create_project.new_code_definition.description.link')}
+ </Link>
+ ),
+ }}
+ />
+ </p>
+
+ <NewCodeDefinitionSelector canAdmin={canAdmin} onNcdChanged={selectDefinition} />
+
+ <div className="sw-mt-10 sw-mb-8">
+ <ButtonPrimary
+ onClick={handleProjectCreation}
+ disabled={!selectedDefinition?.isCompliant || submitting}
+ type="submit"
+ >
+ {translate('onboarding.create_project.new_code_definition.create_project')}
+ <DeferredSpinner className="sw-ml-2" loading={submitting} />
+ </ButtonPrimary>
+ </div>
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
index 4e9b28484af..59f65f0e004 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
@@ -17,9 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { SelectionCard } from 'design-system';
import * as React from 'react';
import { components, OptionProps } from 'react-select';
-import RadioCard from '../../../components/controls/RadioCard';
import Select from '../../../components/controls/Select';
import Tooltip from '../../../components/controls/Tooltip';
import AlertErrorIcon from '../../../components/icons/AlertErrorIcon';
@@ -94,8 +94,7 @@ export default function BaselineSettingReferenceBranch(props: BaselineSettingRef
};
return (
- <RadioCard
- noRadio
+ <SelectionCard
className={className}
disabled={disabled}
onClick={() => props.onSelect(NewCodeDefinitionType.ReferenceBranch)}
@@ -132,6 +131,6 @@ export default function BaselineSettingReferenceBranch(props: BaselineSettingRef
</>
)}
</>
- </RadioCard>
+ </SelectionCard>
);
}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
index e80de3b008c..5d14760a99b 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
@@ -179,7 +179,7 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
isBranchSupportEnabled
level="branch"
/>
- <div className="display-flex-row huge-spacer-bottom" role="radiogroup">
+ <div className="display-flex-column huge-spacer-bottom sw-gap-4" role="radiogroup">
<NewCodeDefinitionPreviousVersionOption
isDefault={false}
onSelect={this.handleSelectSetting}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
index deb5da7ea24..20756d3f5eb 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
@@ -144,7 +144,7 @@ export default function ProjectBaselineSelector(props: ProjectBaselineSelectorPr
isBranchSupportEnabled={branchesEnabled}
level="project"
/>
- <div className="display-flex-row big-spacer-bottom" role="radiogroup">
+ <div className="display-flex-column big-spacer-bottom sw-gap-4" role="radiogroup">
<NewCodeDefinitionPreviousVersionOption
disabled={!overrideGeneralSetting}
onSelect={props.onSelectSetting}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
index 6a425ddc54c..8a432064a92 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
@@ -312,7 +312,7 @@ function getPageObjects() {
name: /new_code_definition.previous_version.description/,
}),
numberDaysRadio: byRole('radio', { name: /new_code_definition.number_days.description/ }),
- numberDaysInput: byRole('textbox'),
+ numberDaysInput: byRole('spinbutton'),
referenceBranchRadio: byRole('radio', { name: /baseline.reference_branch.description/ }),
chooseBranchSelect: byRole('combobox', { name: 'baseline.reference_branch.choose' }),
specificAnalysisRadio: byRole('radio', { name: /baseline.specific_analysis.description/ }),
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
index e541c4e645f..caed26144de 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
@@ -42,7 +42,7 @@ const ui = {
prevVersionRadio: byRole('radio', { name: /new_code_definition.previous_version/ }),
daysNumberRadio: byRole('radio', { name: /new_code_definition.number_days/ }),
daysNumberErrorMessage: byText('new_code_definition.number_days.invalid', { exact: false }),
- daysInput: byRole('textbox'),
+ daysInput: byRole('spinbutton') /* spinbutton is the default role for a number input */,
saveButton: byRole('button', { name: 'save' }),
cancelButton: byRole('button', { name: 'cancel' }),
};
@@ -59,14 +59,16 @@ it('renders and behaves as expected', async () => {
await user.click(ui.daysNumberRadio.get());
expect(ui.daysNumberRadio.get()).toBeChecked();
- // Save should be disabled for zero or NaN
- expect(ui.daysInput.get()).toHaveValue('30');
+ // Save should be disabled for zero
+ expect(ui.daysInput.get()).toHaveValue(30);
await user.clear(ui.daysInput.get());
await user.type(ui.daysInput.get(), '0');
expect(await ui.saveButton.find()).toBeDisabled();
+
+ // Save should not appear at all for NaN
await user.clear(ui.daysInput.get());
await user.type(ui.daysInput.get(), 'asdas');
- expect(ui.saveButton.get()).toBeDisabled();
+ expect(ui.saveButton.query()).toBeDisabled();
// Save enabled for valid days number
await user.clear(ui.daysInput.get());
@@ -98,7 +100,7 @@ it('renders and behaves properly when the current value is not compliant', async
expect(await ui.newCodeTitle.find()).toBeInTheDocument();
expect(ui.daysNumberRadio.get()).toBeChecked();
- expect(ui.daysInput.get()).toHaveValue('91');
+ expect(ui.daysInput.get()).toHaveValue(91);
// Should warn about non compliant value
expect(screen.getByText('baseline.number_days.compliance_warning.title')).toBeInTheDocument();