diff options
Diffstat (limited to 'server/sonar-web')
12 files changed, 61 insertions, 43 deletions
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx index 3c7f9ec94d6..745e6a1d02f 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx @@ -125,6 +125,7 @@ export default class Workers extends React.PureComponent<{}, State> { {!loading && canSetWorkerCount && ( <Tooltip overlay={translate('background_tasks.change_number_of_workers')}> <EditButton + aria-label={translate('background_tasks.change_number_of_workers')} className="js-edit button-small spacer-left" onClick={this.handleChangeClick} title={translate('edit')} diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap index 4829f3a5f53..6cefea0b1b2 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap @@ -18,6 +18,7 @@ exports[`opens form 1`] = ` overlay="background_tasks.change_number_of_workers" > <EditButton + aria-label="background_tasks.change_number_of_workers" className="js-edit button-small spacer-left" onClick={[Function]} title="edit" @@ -44,6 +45,7 @@ exports[`opens form 2`] = ` overlay="background_tasks.change_number_of_workers" > <EditButton + aria-label="background_tasks.change_number_of_workers" className="js-edit button-small spacer-left" onClick={[Function]} title="edit" @@ -89,6 +91,7 @@ exports[`renders 2`] = ` overlay="background_tasks.change_number_of_workers" > <EditButton + aria-label="background_tasks.change_number_of_workers" className="js-edit button-small spacer-left" onClick={[Function]} title="edit" @@ -126,6 +129,7 @@ exports[`renders 3`] = ` overlay="background_tasks.change_number_of_workers" > <EditButton + aria-label="background_tasks.change_number_of_workers" className="js-edit button-small spacer-left" onClick={[Function]} title="edit" @@ -189,6 +193,7 @@ exports[`updates worker count 1`] = ` overlay="background_tasks.change_number_of_workers" > <EditButton + aria-label="background_tasks.change_number_of_workers" className="js-edit button-small spacer-left" onClick={[Function]} title="edit" @@ -230,6 +235,7 @@ exports[`updates worker count 2`] = ` overlay="background_tasks.change_number_of_workers" > <EditButton + aria-label="background_tasks.change_number_of_workers" className="js-edit button-small spacer-left" onClick={[Function]} title="edit" diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx index b64b65adf42..95f89618efb 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx @@ -41,7 +41,6 @@ import { removeSideBarClass, removeWhitePageClass, } from '../../../helpers/pages'; -import { scrollToElement } from '../../../helpers/scrolling'; import { SecurityStandard } from '../../../types/security'; import { Dict, Paging, RawQuery, Rule, RuleActivation } from '../../../types/types'; import { CurrentUser, isLoggedIn } from '../../../types/users'; @@ -385,15 +384,15 @@ export class App extends React.PureComponent<Props, State> { open: undefined, }, }); - this.scrollToSelectedRule(false); + this.scrollToSelectedRule(); }; - scrollToSelectedRule = (smooth = false) => { + scrollToSelectedRule = () => { const selected = this.getSelectedRuleKey(this.props); if (selected) { const element = document.querySelector(`[data-rule="${selected}"]`); if (element) { - scrollToElement(element, { topOffset: 150, bottomOffset: 100, smooth }); + element.scrollIntoView({ behavior: 'auto', block: 'center' }); } } }; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx index 7778955775c..c82b35c2b86 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx @@ -121,7 +121,7 @@ it('should show import project feature when PAT is already set', async () => { expect(screen.getByText('BitbucketCloud Repo 2')).toBeInTheDocument(); projectItem = screen.getByRole('row', { - name: 'bitbucketcloud_repo_1 project opens_in_new_window onboarding.create_project.bitbucketcloud.link onboarding.create_project.repository_imported', + name: 'qualifier.TRK BitbucketCloud Repo 1 project opens_in_new_window onboarding.create_project.bitbucketcloud.link onboarding.create_project.repository_imported', }); expect( within(projectItem).getByText('onboarding.create_project.repository_imported') @@ -136,7 +136,7 @@ it('should show import project feature when PAT is already set', async () => { ); projectItem = screen.getByRole('row', { - name: 'bitbucketcloud_repo_2 project opens_in_new_window onboarding.create_project.bitbucketcloud.link onboarding.create_project.set_up', + name: 'BitbucketCloud Repo 2 project opens_in_new_window onboarding.create_project.bitbucketcloud.link onboarding.create_project.set_up', }); const importProjectButton = within(projectItem).getByRole('button', { name: 'onboarding.create_project.set_up', diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx index f2a3a26fcdf..88644cb4e44 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx @@ -66,10 +66,11 @@ it('should ask for PAT when it is not set yet and show the import project featur expect(screen.getByText('onboarding.create_project.enter_pat')).toBeInTheDocument(); expect(screen.getByText('onboarding.create_project.pat_help.title')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'save' })).toBeInTheDocument(); - - await user.click(ui.personalAccessTokenInput.get()); - await user.keyboard('secret'); - await user.click(screen.getByRole('button', { name: 'save' })); + await act(async () => { + await user.click(ui.personalAccessTokenInput.get()); + await user.keyboard('secret'); + await user.click(screen.getByRole('button', { name: 'save' })); + }); expect(screen.getByText('Gitlab project 1')).toBeInTheDocument(); expect(screen.getByText('Gitlab project 2')).toBeInTheDocument(); @@ -90,7 +91,7 @@ it('should show import project feature when PAT is already set', async () => { expect(screen.getByText('Gitlab project 2')).toBeInTheDocument(); projectItem = screen.getByRole('row', { - name: 'Gitlab_project_1 company/best-projects opens_in_new_window onboarding.create_project.gitlab.link onboarding.create_project.repository_imported', + name: 'qualifier.TRK Gitlab project 1 Company / Best Projects opens_in_new_window onboarding.create_project.gitlab.link onboarding.create_project.repository_imported', }); expect( within(projectItem).getByText('onboarding.create_project.repository_imported') @@ -102,13 +103,15 @@ it('should show import project feature when PAT is already set', async () => { ); projectItem = screen.getByRole('row', { - name: 'Gitlab_project_2 company/best-projects opens_in_new_window onboarding.create_project.gitlab.link onboarding.create_project.set_up', + name: 'Gitlab project 2 Company / Best Projects opens_in_new_window onboarding.create_project.gitlab.link onboarding.create_project.set_up', }); const importProjectButton = within(projectItem).getByRole('button', { name: 'onboarding.create_project.set_up', }); - await user.click(importProjectButton); + await act(async () => { + await user.click(importProjectButton); + }); expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument(); }); diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx index 8a5f32ce976..acb64a13432 100644 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx @@ -90,9 +90,7 @@ it('should be able to bulk change', async () => { expect(screen.getByRole('button', { name: 'issues.bulk_change_X_issues.1' })).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'issues.bulk_change_X_issues.1' })); - await user.click( - screen.getByRole('textbox', { name: 'issue.comment.formlink issue_bulk_change.comment.help' }) - ); + await user.click(screen.getByRole('textbox', { name: 'issue.comment.formlink' })); await user.keyboard('New Comment'); expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled(); @@ -567,8 +565,8 @@ it('should show code tabs when any secondary location is selected', async () => renderIssueApp(); await user.click(await screen.findByRole('region', { name: 'Fix this' })); - expect(screen.getByRole('button', { name: 'location 1' })).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'location 2' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '1 location 1' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: '2 location 2' })).toBeInTheDocument(); // Select the "why is this an issue" tab await user.click( @@ -619,7 +617,7 @@ it('should show issue tags if applicable', async () => { expect( screen.getByRole('heading', { - name: 'Issue with tags issue.quick_fix_available_with_sonarlint opens_in_new_window SonarLint rules.status.DEPRECATED.help opens_in_new_window see_x.rules', + name: 'Issue with tags sonar-lint-icon issue.resolution.badge.DEPRECATED', }) ).toBeInTheDocument(); }); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGate-it.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGate-it.tsx index 76a1faf300a..58d83b0da6d 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGate-it.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGate-it.tsx @@ -53,9 +53,10 @@ it('should list all quality gates', async () => { name: `${handler.getDefaultQualityGate().name} default`, }) ).toBeInTheDocument(); + expect( - await screen.findByRole('menuitem', { - name: `${handler.getBuiltInQualityGate().name} quality_gates.built_in.help`, + screen.getByRole('menuitem', { + name: `${handler.getBuiltInQualityGate().name} quality_gates.built_in`, }) ).toBeInTheDocument(); }); diff --git a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx index 891b9259e70..1558d997ad4 100644 --- a/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx +++ b/server/sonar-web/src/main/js/components/activity-graph/GraphsLegendCustom.tsx @@ -50,7 +50,12 @@ export default function GraphsLegendCustom(props: GraphsLegendCustomProps) { key={serie.name} overlay={translate('project_activity.graphs.custom.metric_no_history')} > - <li className="spacer-left spacer-right">{legendItem}</li> + <li + className="spacer-left spacer-right" + aria-label={translate('project_activity.graphs.custom.metric_no_history')} + > + {legendItem} + </li> </Tooltip> ); } diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx index 4570f8d105e..f0c013aca29 100644 --- a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx +++ b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx @@ -398,13 +398,14 @@ export class TooltipInner extends React.Component<TooltipProps, State> { renderOverlay() { const isVisible = this.isVisible(); - const { classNameSpace = 'tooltip' } = this.props; + const { classNameSpace = 'tooltip', accessible = true } = this.props; return ( <div className={classNames(`${classNameSpace}-inner`, { hidden: !isVisible })} id={this.id} - aria-hidden={!isVisible} + role="tooltip" + aria-hidden={!accessible || !isVisible} > {this.props.overlay} </div> @@ -427,7 +428,6 @@ export class TooltipInner extends React.Component<TooltipProps, State> { // See https://sarahmhigley.com/writing/tooltips-in-wcag-21/ // See https://css-tricks.com/accessible-svgs/ 'aria-describedby': accessible ? this.id : undefined, - 'aria-labelledby': accessible ? this.id : undefined, })} {!isVisible && this.renderOverlay()} {isVisible && ( diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap index 52a4190126a..1af0c540140 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap @@ -16,7 +16,6 @@ exports[`should render 1`] = ` <Fragment> <div aria-describedby="tooltip-1" - aria-labelledby="tooltip-1" id="tooltip" onBlur={[Function]} onFocus={[Function]} @@ -28,6 +27,7 @@ exports[`should render 1`] = ` aria-hidden={true} className="tooltip-inner hidden" id="tooltip-1" + role="tooltip" > <span id="overlay" @@ -40,7 +40,6 @@ exports[`should render 2`] = ` <Fragment> <div aria-describedby="tooltip-1" - aria-labelledby="tooltip-1" id="tooltip" onBlur={[Function]} onFocus={[Function]} diff --git a/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx b/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx index 96a00bf418d..06319880b8f 100644 --- a/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx +++ b/server/sonar-web/src/main/js/components/facet/FacetHeader.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { Button } from '../../components/controls/buttons'; +import { Button, ButtonLink } from '../../components/controls/buttons'; import HelpTooltip from '../../components/controls/HelpTooltip'; import OpenCloseIcon from '../../components/icons/OpenCloseIcon'; import DeferredSpinner from '../../components/ui/DeferredSpinner'; @@ -72,17 +72,20 @@ export default class FacetHeader extends React.PureComponent<Props> { const { disabled, values, disabledHelper, name, open, children, fetching } = this.props; const showClearButton = values != null && values.length > 0 && this.props.onClear != null; const header = disabled ? ( - <Tooltip overlay={disabledHelper}> - <span>{name}</span> + <Tooltip overlay={disabledHelper} accessible={false}> + <ButtonLink + className="disabled" + aria-disabled={true} + aria-label={`${name}, ${disabledHelper}`} + > + {name} + </ButtonLink> </Tooltip> ) : ( name ); return ( - <div - aria-disabled={disabled} - className="search-navigator-facet-header-wrapper display-flex-center" - > + <div className="search-navigator-facet-header-wrapper display-flex-center"> {this.props.onClick ? ( <span className="search-navigator-facet-header display-flex-center"> <button diff --git a/server/sonar-web/src/main/js/components/ui/PageShortcutsTooltip.tsx b/server/sonar-web/src/main/js/components/ui/PageShortcutsTooltip.tsx index 03e30b940d8..6dfdf6809b2 100644 --- a/server/sonar-web/src/main/js/components/ui/PageShortcutsTooltip.tsx +++ b/server/sonar-web/src/main/js/components/ui/PageShortcutsTooltip.tsx @@ -34,6 +34,7 @@ export default function PageShortcutsTooltip(props: PageShortcutsTooltipProps) { const { className, leftAndRightLabel, leftLabel, upAndDownLabel, metaModifierLabel } = props; return ( <Tooltip + accessible={false} overlay={ <div className="small nowrap"> <div> @@ -72,7 +73,7 @@ export default function PageShortcutsTooltip(props: PageShortcutsTooltipProps) { </div> } > - <div + <aside aria-label={` ${translate('shortcuts.on_page.intro')} ${ @@ -97,15 +98,17 @@ export default function PageShortcutsTooltip(props: PageShortcutsTooltipProps) { 'page-shortcuts-tooltip note text-center display-inline-block' )} > - <div> - <span className="shortcut-button shortcut-button-tiny">↑</span> - </div> - <div> - <span className="shortcut-button shortcut-button-tiny">←</span> - <span className="shortcut-button shortcut-button-tiny">↓</span> - <span className="shortcut-button shortcut-button-tiny">→</span> + <div aria-hidden={true}> + <div> + <span className="shortcut-button shortcut-button-tiny">↑</span> + </div> + <div> + <span className="shortcut-button shortcut-button-tiny">←</span> + <span className="shortcut-button shortcut-button-tiny">↓</span> + <span className="shortcut-button shortcut-button-tiny">→</span> + </div> </div> - </div> + </aside> </Tooltip> ); } |