]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20649 Fix flaky test bulk issue change
authorstanislavh <stanislav.honcharov@sonarsource.com>
Thu, 5 Oct 2023 11:48:36 +0000 (13:48 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 6 Oct 2023 20:02:52 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx

diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx
new file mode 100644 (file)
index 0000000..8ac1afb
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * 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 { act, screen, within } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+import { TabKeys } from '../../../components/rules/RuleTabViewer';
+import { byRole } from '../../../helpers/testSelector';
+import {
+  branchHandler,
+  componentsHandler,
+  issuesHandler,
+  renderIssueApp,
+  renderProjectIssuesApp,
+  ui,
+} from '../test-utils';
+
+jest.mock('../sidebar/Sidebar', () => {
+  const fakeSidebar = () => {
+    return <div data-guiding-id="issue-5" />;
+  };
+  return {
+    __esModule: true,
+    default: fakeSidebar,
+    Sidebar: fakeSidebar,
+  };
+});
+
+jest.mock('../../../components/common/ScreenPositionHelper', () => ({
+  __esModule: true,
+  default: class ScreenPositionHelper extends React.Component<{
+    children: (args: { top: number }) => React.ReactNode;
+  }> {
+    render() {
+      // eslint-disable-next-line testing-library/no-node-access
+      return this.props.children({ top: 10 });
+    }
+  },
+}));
+
+beforeEach(() => {
+  issuesHandler.reset();
+  componentsHandler.reset();
+  branchHandler.reset();
+  window.scrollTo = jest.fn();
+  window.HTMLElement.prototype.scrollTo = jest.fn();
+});
+
+describe('issue app', () => {
+  it('should navigate to Why is this an issue tab', async () => {
+    renderProjectIssuesApp('project/issues?issues=issue2&open=issue2&id=myproject&why=1');
+
+    expect(
+      await screen.findByRole('tab', {
+        name: `coding_rules.description_section.title.root_cause`,
+      }),
+    ).toHaveAttribute('aria-current', 'true');
+  });
+
+  it('should interact with flows and locations', async () => {
+    const user = userEvent.setup();
+    renderProjectIssuesApp('project/issues?issues=issue11&open=issue11&id=myproject');
+
+    expect(await screen.findByLabelText('list_of_issues')).toBeInTheDocument();
+
+    const dataFlowButton = await screen.findByRole('button', {
+      name: 'issue.flow.x_steps.2 Backtracking 1',
+    });
+    const exectionFlowButton = screen.getByRole('button', {
+      name: 'issue.flow.x_steps.3 issue.full_execution_flow',
+    });
+
+    let dataLocation1Button = screen.getByRole('link', { name: '1 Data location 1' });
+    let dataLocation2Button = screen.getByRole('link', { name: '2 Data location 2' });
+
+    expect(dataFlowButton).toBeInTheDocument();
+    expect(dataLocation1Button).toBeInTheDocument();
+    expect(dataLocation2Button).toBeInTheDocument();
+
+    await user.click(dataFlowButton);
+    // Colapsing flow
+    expect(dataLocation1Button).not.toBeInTheDocument();
+    expect(dataLocation2Button).not.toBeInTheDocument();
+
+    await user.click(exectionFlowButton);
+    expect(screen.getByRole('link', { name: '1 Execution location 1' })).toBeInTheDocument();
+    expect(screen.getByRole('link', { name: '2 Execution location 2' })).toBeInTheDocument();
+    expect(screen.getByRole('link', { name: '3 Execution location 3' })).toBeInTheDocument();
+
+    // Keyboard interaction
+    await user.click(dataFlowButton);
+    dataLocation1Button = screen.getByRole('link', { name: '1 Data location 1' });
+    dataLocation2Button = screen.getByRole('link', { name: '2 Data location 2' });
+
+    // Location navigation
+    await user.keyboard('{Alt>}{ArrowDown}{/Alt}');
+
+    expect(dataLocation1Button).toHaveAttribute('aria-current', 'true');
+    await user.keyboard('{Alt>}{ArrowDown}{/Alt}');
+    expect(dataLocation1Button).toHaveAttribute('aria-current', 'false');
+    expect(dataLocation2Button).toHaveAttribute('aria-current', 'true');
+    await user.keyboard('{Alt>}{ArrowDown}{/Alt}');
+    expect(dataLocation1Button).toHaveAttribute('aria-current', 'false');
+    expect(dataLocation2Button).toHaveAttribute('aria-current', 'false');
+    await user.keyboard('{Alt>}{ArrowUp}{/Alt}');
+    expect(dataLocation1Button).toHaveAttribute('aria-current', 'false');
+
+    expect(dataLocation2Button).toHaveAttribute('aria-current', 'true');
+
+    // Flow navigation
+    await user.keyboard('{Alt>}{ArrowRight}{/Alt}');
+    expect(screen.getByRole('link', { name: '1 Execution location 1' })).toHaveAttribute(
+      'aria-current',
+      'true',
+    );
+    await user.keyboard('{Alt>}{ArrowLeft}{/Alt}');
+    expect(screen.getByRole('link', { name: '1 Data location 1' })).toHaveAttribute(
+      'aria-current',
+      'true',
+    );
+  });
+
+  it('should show education principles', async () => {
+    const user = userEvent.setup();
+    renderProjectIssuesApp('project/issues?issues=issue2&open=issue2&id=myproject');
+    await user.click(
+      await screen.findByRole('tab', { name: `coding_rules.description_section.title.more_info` }),
+    );
+    expect(screen.getByRole('heading', { name: 'Defense-In-Depth', level: 3 })).toBeInTheDocument();
+  });
+
+  it('should be able to perform action on issues', async () => {
+    const user = userEvent.setup();
+    issuesHandler.setIsAdmin(true);
+    renderIssueApp();
+
+    // Get a specific issue list item
+    const listItem = within(await screen.findByRole('region', { name: 'Fix that' }));
+
+    // Change issue status
+    expect(listItem.getByText('issue.status.OPEN')).toBeInTheDocument();
+
+    await act(async () => {
+      await user.click(listItem.getByText('issue.status.OPEN'));
+    });
+    expect(listItem.getByText('issue.transition.confirm')).toBeInTheDocument();
+    expect(listItem.getByText('issue.transition.resolve')).toBeInTheDocument();
+
+    await act(async () => {
+      await user.click(listItem.getByText('issue.transition.confirm'));
+    });
+    expect(
+      listItem.getByLabelText('issue.transition.status_x_click_to_change.issue.status.CONFIRMED'),
+    ).toBeInTheDocument();
+
+    // As won't fix
+    await act(async () => {
+      await user.click(listItem.getByText('issue.status.CONFIRMED'));
+      await user.click(listItem.getByText('issue.transition.wontfix'));
+    });
+    // Comment should open and close
+    expect(listItem.getByRole('button', { name: 'issue.comment.formlink' })).toBeInTheDocument();
+    await act(async () => {
+      await user.keyboard('test');
+      await user.click(listItem.getByRole('button', { name: 'issue.comment.formlink' }));
+    });
+    expect(
+      listItem.queryByRole('button', { name: 'issue.comment.submit' }),
+    ).not.toBeInTheDocument();
+
+    // Assign issue to a different user
+    await act(async () => {
+      await user.click(
+        listItem.getByRole('combobox', { name: 'issue.assign.unassigned_click_to_assign' }),
+      );
+      await user.click(screen.getByLabelText('search.search_for_users'));
+      await user.keyboard('luke');
+    });
+    expect(screen.getByText('Skywalker')).toBeInTheDocument();
+
+    await act(async () => {
+      await user.click(screen.getByText('Skywalker'));
+    });
+    await listItem.findByRole('combobox', {
+      name: 'issue.assign.assigned_to_x_click_to_change.luke',
+    });
+    expect(
+      listItem.getByRole('combobox', {
+        name: 'issue.assign.assigned_to_x_click_to_change.luke',
+      }),
+    ).toBeInTheDocument();
+
+    // Change tags
+    expect(listItem.getByText('issue.no_tag')).toBeInTheDocument();
+    await act(async () => {
+      await user.click(listItem.getByText('issue.no_tag'));
+    });
+    expect(listItem.getByRole('searchbox', { name: 'search.search_for_tags' })).toBeInTheDocument();
+    expect(listItem.getByText('android')).toBeInTheDocument();
+    expect(listItem.getByText('accessibility')).toBeInTheDocument();
+
+    await act(async () => {
+      await user.click(listItem.getByText('accessibility'));
+      await user.click(listItem.getByText('android'));
+    });
+
+    await user.keyboard('{Escape}');
+    await expect(
+      byRole('button', { name: 'accessibility android +' }).byText('accessibility').get(),
+    ).toHaveATooltipWithContent('accessibility, android');
+
+    await act(async () => {
+      await user.click(listItem.getByRole('button', { name: 'accessibility android +' }));
+    });
+
+    // Unselect
+    await act(async () => {
+      await user.click(screen.getByRole('checkbox', { name: 'accessibility' }));
+    });
+
+    await user.keyboard('{Escape}');
+    await expect(
+      byRole('button', { name: 'android +' }).byText('android').get(),
+    ).toHaveATooltipWithContent('android');
+
+    await act(async () => {
+      await user.click(listItem.getByRole('button', { name: 'android +' }));
+    });
+
+    await act(async () => {
+      await user.click(screen.getByRole('searchbox', { name: 'search.search_for_tags' }));
+      await user.keyboard('addNewTag');
+    });
+    expect(
+      screen.getByRole('checkbox', { name: 'issue.create_tag: addnewtag' }),
+    ).toBeInTheDocument();
+  });
+
+  it('should not allow performing actions when user does not have permission', async () => {
+    const user = userEvent.setup();
+    renderIssueApp();
+
+    await act(async () => {
+      await user.click(await ui.issueItem4.find());
+    });
+
+    expect(
+      screen.queryByRole('button', {
+        name: `issue.assign.unassigned_click_to_assign`,
+      }),
+    ).not.toBeInTheDocument();
+    expect(
+      screen.queryByRole('button', {
+        name: `issue.type.type_x_click_to_change.issue.type.CODE_SMELL`,
+      }),
+    ).not.toBeInTheDocument();
+
+    expect(
+      screen.queryByRole('button', {
+        name: `issue.transition.status_x_click_to_change.issue.status.OPEN`,
+      }),
+    ).not.toBeInTheDocument();
+    expect(
+      screen.queryByRole('button', {
+        name: `issue.severity.severity_x_click_to_change.severity.MAJOR`,
+      }),
+    ).not.toBeInTheDocument();
+  });
+
+  it('should open the actions popup using keyboard shortcut', async () => {
+    const user = userEvent.setup();
+    issuesHandler.setIsAdmin(true);
+    renderIssueApp();
+
+    // Select an issue with an advanced rule
+    await act(async () => {
+      await user.click(await ui.issueItemAction5.find());
+
+      // Open status popup on key press 'f'
+      await user.keyboard('f');
+    });
+    expect(screen.getByText('issue.transition.confirm')).toBeInTheDocument();
+    expect(screen.getByText('issue.transition.resolve')).toBeInTheDocument();
+
+    // Open comment popup on key press 'c'
+    await act(async () => {
+      await user.keyboard('c');
+    });
+    expect(screen.getByText('issue.comment.formlink')).toBeInTheDocument();
+    await act(async () => {
+      await user.keyboard('{Escape}');
+    });
+
+    // Open tags popup on key press 't'
+    await act(async () => {
+      await user.keyboard('t');
+    });
+    expect(screen.getByRole('searchbox', { name: 'search.search_for_tags' })).toBeInTheDocument();
+    expect(screen.getByText('android')).toBeInTheDocument();
+    expect(screen.getByText('accessibility')).toBeInTheDocument();
+
+    // Close tags popup
+    await act(async () => {
+      await user.click(screen.getByText('issue.no_tag'));
+
+      // Open assign popup on key press 'a'
+      await user.keyboard('a');
+    });
+    expect(screen.getByRole('searchbox', { name: 'search.search_for_tags' })).toBeInTheDocument();
+  });
+
+  it('should not open the actions popup using keyboard shortcut when keyboard shortcut flag is disabled', async () => {
+    localStorage.setItem('sonarqube.preferences.keyboard_shortcuts_enabled', 'false');
+    const user = userEvent.setup();
+    issuesHandler.setIsAdmin(true);
+    renderIssueApp();
+
+    // Select an issue with an advanced rule
+    await act(async () => {
+      await user.click(await ui.issueItem5.find());
+    });
+
+    // open status popup on key press 'f'
+    await user.keyboard('f');
+    expect(screen.queryByText('issue.transition.confirm')).not.toBeInTheDocument();
+    expect(screen.queryByText('issue.transition.resolve')).not.toBeInTheDocument();
+
+    // open comment popup on key press 'c'
+    await user.keyboard('c');
+    expect(screen.queryByText('issue.comment.submit')).not.toBeInTheDocument();
+    localStorage.setItem('sonarqube.preferences.keyboard_shortcuts_enabled', 'true');
+  });
+
+  it('should show code tabs when any secondary location is selected', async () => {
+    const user = userEvent.setup();
+    renderIssueApp();
+
+    await act(async () => {
+      await user.click(await ui.issueItemAction4.find());
+    });
+    expect(screen.getByRole('link', { name: 'location 1' })).toBeInTheDocument();
+    expect(screen.getByRole('link', { name: 'location 2' })).toBeInTheDocument();
+
+    // Select the "why is this an issue" tab
+    await act(async () => {
+      await user.click(
+        screen.getByRole('tab', { name: 'coding_rules.description_section.title.root_cause' }),
+      );
+    });
+    expect(
+      screen.queryByRole('tab', {
+        name: `issue.tabs.${TabKeys.Code}`,
+      }),
+    ).toHaveAttribute('aria-current', 'false');
+
+    await act(async () => {
+      await user.click(screen.getByRole('link', { name: 'location 1' }));
+    });
+    expect(
+      screen.queryByRole('tab', {
+        name: `issue.tabs.${TabKeys.Code}`,
+      }),
+    ).toHaveAttribute('aria-current', 'true');
+
+    // Select the same selected hotspot location should also navigate back to code page
+    await act(async () => {
+      await user.click(
+        screen.getByRole('tab', { name: 'coding_rules.description_section.title.root_cause' }),
+      );
+    });
+    expect(
+      screen.queryByRole('tab', {
+        name: `issue.tabs.${TabKeys.Code}`,
+      }),
+    ).toHaveAttribute('aria-current', 'false');
+
+    await act(async () => {
+      await user.click(screen.getByRole('link', { name: 'location 1' }));
+    });
+    expect(
+      screen.queryByRole('tab', {
+        name: `issue.tabs.${TabKeys.Code}`,
+      }),
+    ).toHaveAttribute('aria-current', 'true');
+  });
+
+  it('should show issue tags if applicable', async () => {
+    const user = userEvent.setup();
+    issuesHandler.setIsAdmin(true);
+    renderIssueApp();
+
+    // Select an issue with an advanced rule
+    await act(async () => {
+      await user.click(await ui.issueItemAction7.find());
+    });
+
+    await expect(
+      screen.getByText('issue.quick_fix_available_with_sonarlint_no_link'),
+    ).toHaveATooltipWithContent('issue.quick_fix_available_with_sonarlint');
+  });
+});
index 2a109065e40481b2d5ea436bda02b669a4b9cf6e..1f08341020f7c3109b0df75a23be45fb0f31443c 100644 (file)
@@ -21,9 +21,7 @@
 import { act, screen, within } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import React from 'react';
-import { TabKeys } from '../../../components/rules/RuleTabViewer';
 import { mockLoggedInUser } from '../../../helpers/testMocks';
-import { byRole } from '../../../helpers/testSelector';
 import { ComponentQualifier } from '../../../types/component';
 import { IssueType } from '../../../types/issues';
 import { NoticeType } from '../../../types/users';
@@ -47,18 +45,6 @@ jest.mock('../sidebar/Sidebar', () => {
   };
 });
 
-jest.mock('../../../components/common/ScreenPositionHelper', () => ({
-  __esModule: true,
-  default: class ScreenPositionHelper extends React.Component<{
-    children: (args: { top: number }) => React.ReactNode;
-  }> {
-    render() {
-      // eslint-disable-next-line testing-library/no-node-access
-      return this.props.children({ top: 10 });
-    }
-  },
-}));
-
 beforeEach(() => {
   issuesHandler.reset();
   componentsHandler.reset();
@@ -259,6 +245,7 @@ describe('issues app', () => {
 
     // Improve this to include all the bulk change fonctionality
     it('should be able to bulk change', async () => {
+      jest.useRealTimers();
       const user = userEvent.setup();
       const currentUser = mockLoggedInUser({
         dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true },
@@ -306,360 +293,6 @@ describe('issues app', () => {
   });
 });
 
-describe('issues item', () => {
-  it('should navigate to Why is this an issue tab', async () => {
-    renderProjectIssuesApp('project/issues?issues=issue2&open=issue2&id=myproject&why=1');
-
-    expect(
-      await screen.findByRole('tab', {
-        name: `coding_rules.description_section.title.root_cause`,
-      }),
-    ).toHaveAttribute('aria-current', 'true');
-  });
-
-  it('should interact with flows and locations', async () => {
-    const user = userEvent.setup();
-    renderProjectIssuesApp('project/issues?issues=issue11&open=issue11&id=myproject');
-
-    expect(await screen.findByLabelText('list_of_issues')).toBeInTheDocument();
-
-    const dataFlowButton = await screen.findByRole('button', {
-      name: 'issue.flow.x_steps.2 Backtracking 1',
-    });
-    const exectionFlowButton = screen.getByRole('button', {
-      name: 'issue.flow.x_steps.3 issue.full_execution_flow',
-    });
-
-    let dataLocation1Button = screen.getByRole('link', { name: '1 Data location 1' });
-    let dataLocation2Button = screen.getByRole('link', { name: '2 Data location 2' });
-
-    expect(dataFlowButton).toBeInTheDocument();
-    expect(dataLocation1Button).toBeInTheDocument();
-    expect(dataLocation2Button).toBeInTheDocument();
-
-    await user.click(dataFlowButton);
-    // Colapsing flow
-    expect(dataLocation1Button).not.toBeInTheDocument();
-    expect(dataLocation2Button).not.toBeInTheDocument();
-
-    await user.click(exectionFlowButton);
-    expect(screen.getByRole('link', { name: '1 Execution location 1' })).toBeInTheDocument();
-    expect(screen.getByRole('link', { name: '2 Execution location 2' })).toBeInTheDocument();
-    expect(screen.getByRole('link', { name: '3 Execution location 3' })).toBeInTheDocument();
-
-    // Keyboard interaction
-    await user.click(dataFlowButton);
-    dataLocation1Button = screen.getByRole('link', { name: '1 Data location 1' });
-    dataLocation2Button = screen.getByRole('link', { name: '2 Data location 2' });
-
-    // Location navigation
-    await user.keyboard('{Alt>}{ArrowDown}{/Alt}');
-
-    expect(dataLocation1Button).toHaveAttribute('aria-current', 'true');
-    await user.keyboard('{Alt>}{ArrowDown}{/Alt}');
-    expect(dataLocation1Button).toHaveAttribute('aria-current', 'false');
-    expect(dataLocation2Button).toHaveAttribute('aria-current', 'true');
-    await user.keyboard('{Alt>}{ArrowDown}{/Alt}');
-    expect(dataLocation1Button).toHaveAttribute('aria-current', 'false');
-    expect(dataLocation2Button).toHaveAttribute('aria-current', 'false');
-    await user.keyboard('{Alt>}{ArrowUp}{/Alt}');
-    expect(dataLocation1Button).toHaveAttribute('aria-current', 'false');
-
-    expect(dataLocation2Button).toHaveAttribute('aria-current', 'true');
-
-    // Flow navigation
-    await user.keyboard('{Alt>}{ArrowRight}{/Alt}');
-    expect(screen.getByRole('link', { name: '1 Execution location 1' })).toHaveAttribute(
-      'aria-current',
-      'true',
-    );
-    await user.keyboard('{Alt>}{ArrowLeft}{/Alt}');
-    expect(screen.getByRole('link', { name: '1 Data location 1' })).toHaveAttribute(
-      'aria-current',
-      'true',
-    );
-  });
-
-  it('should show education principles', async () => {
-    const user = userEvent.setup();
-    renderProjectIssuesApp('project/issues?issues=issue2&open=issue2&id=myproject');
-    await user.click(
-      await screen.findByRole('tab', { name: `coding_rules.description_section.title.more_info` }),
-    );
-    expect(screen.getByRole('heading', { name: 'Defense-In-Depth', level: 3 })).toBeInTheDocument();
-  });
-
-  it('should be able to perform action on issues', async () => {
-    const user = userEvent.setup();
-    issuesHandler.setIsAdmin(true);
-    renderIssueApp();
-
-    // Get a specific issue list item
-    const listItem = within(await screen.findByRole('region', { name: 'Fix that' }));
-
-    // Change issue status
-    expect(listItem.getByText('issue.status.OPEN')).toBeInTheDocument();
-
-    await act(async () => {
-      await user.click(listItem.getByText('issue.status.OPEN'));
-    });
-    expect(listItem.getByText('issue.transition.confirm')).toBeInTheDocument();
-    expect(listItem.getByText('issue.transition.resolve')).toBeInTheDocument();
-
-    await act(async () => {
-      await user.click(listItem.getByText('issue.transition.confirm'));
-    });
-    expect(
-      listItem.getByLabelText('issue.transition.status_x_click_to_change.issue.status.CONFIRMED'),
-    ).toBeInTheDocument();
-
-    // As won't fix
-    await act(async () => {
-      await user.click(listItem.getByText('issue.status.CONFIRMED'));
-      await user.click(listItem.getByText('issue.transition.wontfix'));
-    });
-    // Comment should open and close
-    expect(listItem.getByRole('button', { name: 'issue.comment.formlink' })).toBeInTheDocument();
-    await act(async () => {
-      await user.keyboard('test');
-      await user.click(listItem.getByRole('button', { name: 'issue.comment.formlink' }));
-    });
-    expect(
-      listItem.queryByRole('button', { name: 'issue.comment.submit' }),
-    ).not.toBeInTheDocument();
-
-    // Assign issue to a different user
-    await act(async () => {
-      await user.click(
-        listItem.getByRole('combobox', { name: 'issue.assign.unassigned_click_to_assign' }),
-      );
-      await user.click(screen.getByLabelText('search.search_for_users'));
-      await user.keyboard('luke');
-    });
-    expect(screen.getByText('Skywalker')).toBeInTheDocument();
-
-    await act(async () => {
-      await user.click(screen.getByText('Skywalker'));
-    });
-    await listItem.findByRole('combobox', {
-      name: 'issue.assign.assigned_to_x_click_to_change.luke',
-    });
-    expect(
-      listItem.getByRole('combobox', {
-        name: 'issue.assign.assigned_to_x_click_to_change.luke',
-      }),
-    ).toBeInTheDocument();
-
-    // Change tags
-    expect(listItem.getByText('issue.no_tag')).toBeInTheDocument();
-    await act(async () => {
-      await user.click(listItem.getByText('issue.no_tag'));
-    });
-    expect(listItem.getByRole('searchbox', { name: 'search.search_for_tags' })).toBeInTheDocument();
-    expect(listItem.getByText('android')).toBeInTheDocument();
-    expect(listItem.getByText('accessibility')).toBeInTheDocument();
-
-    await act(async () => {
-      await user.click(listItem.getByText('accessibility'));
-      await user.click(listItem.getByText('android'));
-    });
-
-    await user.keyboard('{Escape}');
-    await expect(
-      byRole('button', { name: 'accessibility android +' }).byText('accessibility').get(),
-    ).toHaveATooltipWithContent('accessibility, android');
-
-    await act(async () => {
-      await user.click(listItem.getByRole('button', { name: 'accessibility android +' }));
-    });
-
-    // Unselect
-    await act(async () => {
-      await user.click(screen.getByRole('checkbox', { name: 'accessibility' }));
-    });
-
-    await user.keyboard('{Escape}');
-    await expect(
-      byRole('button', { name: 'android +' }).byText('android').get(),
-    ).toHaveATooltipWithContent('android');
-
-    await act(async () => {
-      await user.click(listItem.getByRole('button', { name: 'android +' }));
-    });
-
-    await act(async () => {
-      await user.click(screen.getByRole('searchbox', { name: 'search.search_for_tags' }));
-      await user.keyboard('addNewTag');
-    });
-    expect(
-      screen.getByRole('checkbox', { name: 'issue.create_tag: addnewtag' }),
-    ).toBeInTheDocument();
-  });
-
-  it('should not allow performing actions when user does not have permission', async () => {
-    const user = userEvent.setup();
-    renderIssueApp();
-
-    await act(async () => {
-      await user.click(await ui.issueItem4.find());
-    });
-
-    expect(
-      screen.queryByRole('button', {
-        name: `issue.assign.unassigned_click_to_assign`,
-      }),
-    ).not.toBeInTheDocument();
-    expect(
-      screen.queryByRole('button', {
-        name: `issue.type.type_x_click_to_change.issue.type.CODE_SMELL`,
-      }),
-    ).not.toBeInTheDocument();
-
-    expect(
-      screen.queryByRole('button', {
-        name: `issue.transition.status_x_click_to_change.issue.status.OPEN`,
-      }),
-    ).not.toBeInTheDocument();
-    expect(
-      screen.queryByRole('button', {
-        name: `issue.severity.severity_x_click_to_change.severity.MAJOR`,
-      }),
-    ).not.toBeInTheDocument();
-  });
-
-  it('should open the actions popup using keyboard shortcut', async () => {
-    const user = userEvent.setup();
-    issuesHandler.setIsAdmin(true);
-    renderIssueApp();
-
-    // Select an issue with an advanced rule
-    await act(async () => {
-      await user.click(await ui.issueItemAction5.find());
-
-      // Open status popup on key press 'f'
-      await user.keyboard('f');
-    });
-    expect(screen.getByText('issue.transition.confirm')).toBeInTheDocument();
-    expect(screen.getByText('issue.transition.resolve')).toBeInTheDocument();
-
-    // Open comment popup on key press 'c'
-    await act(async () => {
-      await user.keyboard('c');
-    });
-    expect(screen.getByText('issue.comment.formlink')).toBeInTheDocument();
-    await act(async () => {
-      await user.keyboard('{Escape}');
-    });
-
-    // Open tags popup on key press 't'
-    await act(async () => {
-      await user.keyboard('t');
-    });
-    expect(screen.getByRole('searchbox', { name: 'search.search_for_tags' })).toBeInTheDocument();
-    expect(screen.getByText('android')).toBeInTheDocument();
-    expect(screen.getByText('accessibility')).toBeInTheDocument();
-
-    // Close tags popup
-    await act(async () => {
-      await user.click(screen.getByText('issue.no_tag'));
-
-      // Open assign popup on key press 'a'
-      await user.keyboard('a');
-    });
-    expect(screen.getByRole('searchbox', { name: 'search.search_for_tags' })).toBeInTheDocument();
-  });
-
-  it('should not open the actions popup using keyboard shortcut when keyboard shortcut flag is disabled', async () => {
-    localStorage.setItem('sonarqube.preferences.keyboard_shortcuts_enabled', 'false');
-    const user = userEvent.setup();
-    issuesHandler.setIsAdmin(true);
-    renderIssueApp();
-
-    // Select an issue with an advanced rule
-    await act(async () => {
-      await user.click(await ui.issueItem5.find());
-    });
-
-    // open status popup on key press 'f'
-    await user.keyboard('f');
-    expect(screen.queryByText('issue.transition.confirm')).not.toBeInTheDocument();
-    expect(screen.queryByText('issue.transition.resolve')).not.toBeInTheDocument();
-
-    // open comment popup on key press 'c'
-    await user.keyboard('c');
-    expect(screen.queryByText('issue.comment.submit')).not.toBeInTheDocument();
-    localStorage.setItem('sonarqube.preferences.keyboard_shortcuts_enabled', 'true');
-  });
-
-  it('should show code tabs when any secondary location is selected', async () => {
-    const user = userEvent.setup();
-    renderIssueApp();
-
-    await act(async () => {
-      await user.click(await ui.issueItemAction4.find());
-    });
-    expect(screen.getByRole('link', { name: 'location 1' })).toBeInTheDocument();
-    expect(screen.getByRole('link', { name: 'location 2' })).toBeInTheDocument();
-
-    // Select the "why is this an issue" tab
-    await act(async () => {
-      await user.click(
-        screen.getByRole('tab', { name: 'coding_rules.description_section.title.root_cause' }),
-      );
-    });
-    expect(
-      screen.queryByRole('tab', {
-        name: `issue.tabs.${TabKeys.Code}`,
-      }),
-    ).toHaveAttribute('aria-current', 'false');
-
-    await act(async () => {
-      await user.click(screen.getByRole('link', { name: 'location 1' }));
-    });
-    expect(
-      screen.queryByRole('tab', {
-        name: `issue.tabs.${TabKeys.Code}`,
-      }),
-    ).toHaveAttribute('aria-current', 'true');
-
-    // Select the same selected hotspot location should also navigate back to code page
-    await act(async () => {
-      await user.click(
-        screen.getByRole('tab', { name: 'coding_rules.description_section.title.root_cause' }),
-      );
-    });
-    expect(
-      screen.queryByRole('tab', {
-        name: `issue.tabs.${TabKeys.Code}`,
-      }),
-    ).toHaveAttribute('aria-current', 'false');
-
-    await act(async () => {
-      await user.click(screen.getByRole('link', { name: 'location 1' }));
-    });
-    expect(
-      screen.queryByRole('tab', {
-        name: `issue.tabs.${TabKeys.Code}`,
-      }),
-    ).toHaveAttribute('aria-current', 'true');
-  });
-
-  it('should show issue tags if applicable', async () => {
-    const user = userEvent.setup();
-    issuesHandler.setIsAdmin(true);
-    renderIssueApp();
-
-    // Select an issue with an advanced rule
-    await act(async () => {
-      await user.click(await ui.issueItemAction7.find());
-    });
-
-    await expect(
-      screen.getByText('issue.quick_fix_available_with_sonarlint_no_link'),
-    ).toHaveATooltipWithContent('issue.quick_fix_available_with_sonarlint');
-  });
-});
-
 describe('redirects', () => {
   it('should work for hotspots', () => {
     renderProjectIssuesApp(`project/issues?types=${IssueType.SecurityHotspot}`);