aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/jest.config.js1
-rw-r--r--server/sonar-web/package.json1
-rw-r--r--server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx213
-rw-r--r--server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppActivity-it.tsx138
-rw-r--r--server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx183
-rw-r--r--server/sonar-web/yarn.lock8
6 files changed, 332 insertions, 212 deletions
diff --git a/server/sonar-web/jest.config.js b/server/sonar-web/jest.config.js
index 567f049d18d..92fa4a39329 100644
--- a/server/sonar-web/jest.config.js
+++ b/server/sonar-web/jest.config.js
@@ -62,6 +62,7 @@ module.exports = {
outputFilepath: '/tmp/ut-ts-web-monitoring.log',
},
],
+ ['jest-slow-test-reporter', { numTests: 5, warnOnSlowerThan: 10000, color: true }],
],
testTimeout: 60000,
};
diff --git a/server/sonar-web/package.json b/server/sonar-web/package.json
index 2540b442595..071eac6d249 100644
--- a/server/sonar-web/package.json
+++ b/server/sonar-web/package.json
@@ -100,6 +100,7 @@
"jest-axe": "7.0.1",
"jest-environment-jsdom": "29.5.0",
"jest-junit": "16.0.0",
+ "jest-slow-test-reporter": "1.0.0",
"jsdom": "21.1.1",
"openapi-types": "12.1.3",
"path-browserify": "1.0.1",
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 9ea10f02b66..142d0791670 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
@@ -22,7 +22,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 { mockCurrentUser, mockLoggedInUser } from '../../../helpers/testMocks';
+import { mockLoggedInUser } from '../../../helpers/testMocks';
import { byRole } from '../../../helpers/testSelector';
import { ComponentQualifier } from '../../../types/component';
import { IssueType } from '../../../types/issues';
@@ -667,214 +667,3 @@ describe('redirects', () => {
expect(screen.getByText('/security_hotspots?assignedToMe=false')).toBeInTheDocument();
});
});
-
-describe('activity', () => {
- it('should be able to add or update comment', async () => {
- const user = userEvent.setup();
- issuesHandler.setIsAdmin(true);
- renderIssueApp();
- await act(async () => {
- await user.click(await screen.findByRole('link', { name: 'Fix that' }));
- });
-
- expect(
- screen.getByRole('tab', { name: `coding_rules.description_section.title.activity` })
- ).toBeInTheDocument();
-
- await act(async () => {
- await user.click(
- screen.getByRole('tab', { name: `coding_rules.description_section.title.activity` })
- );
- });
-
- // Add comment to the issue
- await act(async () => {
- await user.click(
- screen.getByRole('button', {
- name: `issue.activity.add_comment`,
- })
- );
- await user.click(screen.getByRole('textbox'));
- await user.keyboard('activity comment');
- await user.click(screen.getByText('hotspots.comment.submit'));
- });
- expect(screen.getByText('activity comment')).toBeInTheDocument();
-
- // Cancel editing the comment
- await act(async () => {
- await user.click(screen.getByRole('button', { name: 'issue.comment.edit' }));
- await user.click(screen.getByRole('textbox'));
- await user.keyboard(' new');
- await user.click(screen.getByRole('button', { name: 'cancel' }));
- });
- expect(screen.queryByText('activity comment new')).not.toBeInTheDocument();
-
- // Edit the comment
- await act(async () => {
- await user.click(screen.getByRole('button', { name: 'issue.comment.edit' }));
- await user.click(screen.getByRole('textbox'));
- await user.keyboard(' new');
- await user.click(screen.getByText('hotspots.comment.submit'));
- });
- expect(screen.getByText('activity comment new')).toBeInTheDocument();
-
- // Delete the comment
- await act(async () => {
- await user.click(screen.getByRole('button', { name: 'issue.comment.delete' }));
- await user.click(screen.getByRole('button', { name: 'delete' })); // Confirm button
- });
- expect(screen.queryByText('activity comment new')).not.toBeInTheDocument();
- });
-
- it('should be able to show changelog', async () => {
- const user = userEvent.setup();
- issuesHandler.setIsAdmin(true);
- renderIssueApp();
-
- await act(async () => {
- await user.click(await screen.findByRole('link', { name: 'Fix that' }));
-
- await user.click(
- screen.getByRole('tab', { name: `coding_rules.description_section.title.activity` })
- );
- });
-
- expect(screen.getByText('issue.activity.review_history.created')).toBeInTheDocument();
- expect(
- screen.getByText(
- 'issue.changelog.changed_to.issue.changelog.field.assign.darth.vader (issue.changelog.was.luke.skywalker)'
- )
- ).toBeInTheDocument();
- expect(
- screen.getByText(
- 'issue.changelog.changed_to.issue.changelog.field.status.REOPENED (issue.changelog.was.CONFIRMED)'
- )
- ).toBeInTheDocument();
- });
-});
-
-describe('guide', () => {
- it('should display guide', async () => {
- const user = userEvent.setup();
- renderIssueApp(mockCurrentUser({ isLoggedIn: true }));
-
- expect(await ui.guidePopup.find()).toBeInTheDocument();
-
- expect(await ui.guidePopup.find()).toBeInTheDocument();
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.title');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.content');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.1.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.2.title');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.2.content');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.2.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.3.title');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.3.content');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.3.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.4.title');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.4.content');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.4.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.5.title');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.5.content');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.5.5');
-
- expect(ui.guidePopup.byRole('button', { name: 'Next' }).query()).not.toBeInTheDocument();
-
- await user.click(ui.guidePopup.byRole('button', { name: 'close' }).get());
-
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-
- it('should not show guide for those who dismissed it', async () => {
- renderIssueApp(
- mockCurrentUser({ isLoggedIn: true, dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true } })
- );
-
- expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0);
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-
- it('should skip guide', async () => {
- const user = userEvent.setup();
- renderIssueApp(mockCurrentUser({ isLoggedIn: true }));
-
- expect(await ui.guidePopup.find()).toBeInTheDocument();
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.title');
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.1.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'skip' }).get());
-
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-
- it('should not show guide if issues need sync', async () => {
- renderProjectIssuesApp(
- undefined,
- { needIssueSync: true },
- mockCurrentUser({ isLoggedIn: true })
- );
-
- expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0);
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-
- it('should not show guide if user is not logged in', async () => {
- renderIssueApp(mockCurrentUser({ isLoggedIn: false }));
-
- expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0);
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-
- it('should not show guide if there are no issues', () => {
- issuesHandler.setIssueList([]);
- renderIssueApp(mockCurrentUser({ isLoggedIn: true }));
-
- expect(ui.loading.query()).not.toBeInTheDocument();
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-
- it('should show guide on issue page', async () => {
- const user = userEvent.setup();
- renderProjectIssuesApp(
- 'project/issues?issues=issue11&open=issue11&id=myproject',
- undefined,
- mockCurrentUser({ isLoggedIn: true })
- );
-
- expect(await ui.guidePopup.find()).toBeInTheDocument();
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.1.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.2.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.3.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.4.5');
-
- await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
-
- expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.5.5');
-
- expect(ui.guidePopup.byRole('button', { name: 'Next' }).query()).not.toBeInTheDocument();
-
- await user.click(ui.guidePopup.byRole('button', { name: 'close' }).get());
-
- expect(ui.guidePopup.query()).not.toBeInTheDocument();
- });
-});
diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppActivity-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppActivity-it.tsx
new file mode 100644
index 00000000000..385ae0f873e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppActivity-it.tsx
@@ -0,0 +1,138 @@
+/*
+ * 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 } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import React from 'react';
+import { branchHandler, componentsHandler, issuesHandler, renderIssueApp } 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();
+});
+
+it('should be able to add or update comment', async () => {
+ const user = userEvent.setup();
+ issuesHandler.setIsAdmin(true);
+ renderIssueApp();
+ await act(async () => {
+ await user.click(await screen.findByRole('link', { name: 'Fix that' }));
+ });
+
+ expect(
+ screen.getByRole('tab', { name: `coding_rules.description_section.title.activity` })
+ ).toBeInTheDocument();
+
+ await act(async () => {
+ await user.click(
+ screen.getByRole('tab', { name: `coding_rules.description_section.title.activity` })
+ );
+ });
+
+ // Add comment to the issue
+ await act(async () => {
+ await user.click(
+ screen.getByRole('button', {
+ name: `issue.activity.add_comment`,
+ })
+ );
+ await user.click(screen.getByRole('textbox'));
+ await user.keyboard('activity comment');
+ await user.click(screen.getByText('hotspots.comment.submit'));
+ });
+ expect(screen.getByText('activity comment')).toBeInTheDocument();
+
+ // Cancel editing the comment
+ await act(async () => {
+ await user.click(screen.getByRole('button', { name: 'issue.comment.edit' }));
+ await user.click(screen.getByRole('textbox'));
+ await user.keyboard(' new');
+ await user.click(screen.getByRole('button', { name: 'cancel' }));
+ });
+ expect(screen.queryByText('activity comment new')).not.toBeInTheDocument();
+
+ // Edit the comment
+ await act(async () => {
+ await user.click(screen.getByRole('button', { name: 'issue.comment.edit' }));
+ await user.click(screen.getByRole('textbox'));
+ await user.keyboard(' new');
+ await user.click(screen.getByText('hotspots.comment.submit'));
+ });
+ expect(screen.getByText('activity comment new')).toBeInTheDocument();
+
+ // Delete the comment
+ await act(async () => {
+ await user.click(screen.getByRole('button', { name: 'issue.comment.delete' }));
+ await user.click(screen.getByRole('button', { name: 'delete' })); // Confirm button
+ });
+ expect(screen.queryByText('activity comment new')).not.toBeInTheDocument();
+});
+
+it('should be able to show changelog', async () => {
+ const user = userEvent.setup();
+ issuesHandler.setIsAdmin(true);
+ renderIssueApp();
+
+ await act(async () => {
+ await user.click(await screen.findByRole('link', { name: 'Fix that' }));
+
+ await user.click(
+ screen.getByRole('tab', { name: `coding_rules.description_section.title.activity` })
+ );
+ });
+
+ expect(screen.getByText('issue.activity.review_history.created')).toBeInTheDocument();
+ expect(
+ screen.getByText(
+ 'issue.changelog.changed_to.issue.changelog.field.assign.darth.vader (issue.changelog.was.luke.skywalker)'
+ )
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText(
+ 'issue.changelog.changed_to.issue.changelog.field.status.REOPENED (issue.changelog.was.CONFIRMED)'
+ )
+ ).toBeInTheDocument();
+});
diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx
new file mode 100644
index 00000000000..e8460b50de3
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx
@@ -0,0 +1,183 @@
+/*
+ * 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 userEvent from '@testing-library/user-event';
+import React from 'react';
+import { mockCurrentUser } from '../../../helpers/testMocks';
+import { NoticeType } from '../../../types/users';
+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();
+});
+
+it('should display guide', async () => {
+ const user = userEvent.setup();
+ renderIssueApp(mockCurrentUser({ isLoggedIn: true }));
+
+ expect(await ui.guidePopup.find()).toBeInTheDocument();
+
+ expect(await ui.guidePopup.find()).toBeInTheDocument();
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.title');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.content');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.1.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.2.title');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.2.content');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.2.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.3.title');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.3.content');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.3.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.4.title');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.4.content');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.4.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.5.title');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.5.content');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.5.5');
+
+ expect(ui.guidePopup.byRole('button', { name: 'Next' }).query()).not.toBeInTheDocument();
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'close' }).get());
+
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
+
+it('should not show guide for those who dismissed it', async () => {
+ renderIssueApp(
+ mockCurrentUser({ isLoggedIn: true, dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true } })
+ );
+
+ expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0);
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
+
+it('should skip guide', async () => {
+ const user = userEvent.setup();
+ renderIssueApp(mockCurrentUser({ isLoggedIn: true }));
+
+ expect(await ui.guidePopup.find()).toBeInTheDocument();
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.title');
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.1.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'skip' }).get());
+
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
+
+it('should not show guide if issues need sync', async () => {
+ renderProjectIssuesApp(undefined, { needIssueSync: true }, mockCurrentUser({ isLoggedIn: true }));
+
+ expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0);
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
+
+it('should not show guide if user is not logged in', async () => {
+ renderIssueApp(mockCurrentUser({ isLoggedIn: false }));
+
+ expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0);
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
+
+it('should not show guide if there are no issues', () => {
+ issuesHandler.setIssueList([]);
+ renderIssueApp(mockCurrentUser({ isLoggedIn: true }));
+
+ expect(ui.loading.query()).not.toBeInTheDocument();
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
+
+it('should show guide on issue page', async () => {
+ const user = userEvent.setup();
+ renderProjectIssuesApp(
+ 'project/issues?issues=issue11&open=issue11&id=myproject',
+ undefined,
+ mockCurrentUser({ isLoggedIn: true })
+ );
+
+ expect(await ui.guidePopup.find()).toBeInTheDocument();
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.1.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.2.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.3.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.4.5');
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get());
+
+ expect(ui.guidePopup.get()).toHaveTextContent('guiding.step_x_of_y.5.5');
+
+ expect(ui.guidePopup.byRole('button', { name: 'Next' }).query()).not.toBeInTheDocument();
+
+ await user.click(ui.guidePopup.byRole('button', { name: 'close' }).get());
+
+ expect(ui.guidePopup.query()).not.toBeInTheDocument();
+});
diff --git a/server/sonar-web/yarn.lock b/server/sonar-web/yarn.lock
index bd24a6320eb..cde83498bee 100644
--- a/server/sonar-web/yarn.lock
+++ b/server/sonar-web/yarn.lock
@@ -4986,6 +4986,7 @@ __metadata:
jest-axe: 7.0.1
jest-environment-jsdom: 29.5.0
jest-junit: 16.0.0
+ jest-slow-test-reporter: 1.0.0
jsdom: 21.1.1
lodash: 4.17.21
lunr: 2.3.9
@@ -9632,6 +9633,13 @@ __metadata:
languageName: node
linkType: hard
+"jest-slow-test-reporter@npm:1.0.0":
+ version: 1.0.0
+ resolution: "jest-slow-test-reporter@npm:1.0.0"
+ checksum: bfbf15ca823f1a2861c33cbe3e9549638d78fa07dc5197464a1bbeb8a30c2d75e7f6f6976b16117db7decaef62cb94a6d641d2bb5823ad72bb46d2af5d49e217
+ languageName: node
+ linkType: hard
+
"jest-snapshot@npm:^29.5.0":
version: 29.5.0
resolution: "jest-snapshot@npm:29.5.0"