]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21692 Fix RTL act warnings from GlobalMessage, Account, ComponentMeasures,...
authorIsmail Cherri <ismail.cherri@sonarsource.com>
Wed, 21 Feb 2024 12:40:49 +0000 (13:40 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 21 Feb 2024 20:02:34 +0000 (20:02 +0000)
server/sonar-web/src/main/js/app/components/__tests__/GlobalMessagesContainer-it.tsx
server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx
server/sonar-web/src/main/js/apps/account/notifications/ProjectModal.tsx
server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx
server/sonar-web/src/main/js/apps/projectDeletion/__tests__/ProjectDeletionApp-it.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectManagementApp-it.tsx
server/sonar-web/src/main/js/apps/sessions/components/__tests__/Login-it.tsx
server/sonar-web/src/main/js/apps/users/__tests__/UsersApp-it.tsx

index 42946654ec4483d6e382f8bbbf6820810f1dd233..f44312ef828db58551868463488f2aece4385d33 100644 (file)
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import { screen } from '@testing-library/react';
+import { act, screen, waitFor } from '@testing-library/react';
 import React from 'react';
 import { addGlobalErrorMessage, addGlobalSuccessMessage } from '../../../helpers/globalMessages';
 import { renderApp } from '../../../helpers/testReactTestingUtils';
@@ -32,22 +32,28 @@ it('should display messages', async () => {
   // we render anything, the GlobalMessageContainer is rendered independently from routing
   renderApp('sonarqube', <NullComponent />);
 
-  addGlobalErrorMessage('This is an error');
-  addGlobalSuccessMessage('This was a triumph!');
-
+  await waitFor(() => {
+    addGlobalErrorMessage('This is an error');
+    addGlobalSuccessMessage('This was a triumph!');
+  });
   expect(await screen.findByRole('alert')).toHaveTextContent('This is an error');
   expect(screen.getByRole('status')).toHaveTextContent('This was a triumph!');
 
   // No duplicate message
-  addGlobalErrorMessage('This is an error');
+  await waitFor(() => {
+    addGlobalErrorMessage('This is an error');
+  });
   expect(screen.getByRole('alert')).toHaveTextContent(/^This is an error$/);
-  addGlobalSuccessMessage('This was a triumph!');
+  await waitFor(() => {
+    addGlobalSuccessMessage('This was a triumph!');
+  });
   expect(await screen.findByRole('status')).toHaveTextContent(
     /^This was a triumph!This was a triumph!$/,
   );
 
-  jest.runAllTimers();
-
+  act(() => {
+    jest.runAllTimers();
+  });
   expect(screen.queryByRole('alert')).not.toBeInTheDocument();
   expect(screen.queryByRole('status')).not.toBeInTheDocument();
 
index f39901cffa27cd607c53312d3091e49e53d4b2e2..4fefa37feb8fdc2b8495bf823465a74eeefc325c 100644 (file)
@@ -172,11 +172,11 @@ it('should handle a currentUser not logged in', () => {
   locationMock.mockRestore();
 });
 
-it('should render the top menu', () => {
+it('should render the top menu', async () => {
   const name = 'Tyler Durden';
   renderAccountApp(mockLoggedInUser({ name }));
 
-  expect(screen.getByText(name)).toBeInTheDocument();
+  expect(await screen.findByText(name)).toBeInTheDocument();
 
   const topMenuNavigationItems = [
     'my_account.profile',
@@ -190,7 +190,7 @@ it('should render the top menu', () => {
 });
 
 describe('profile page', () => {
-  it('should display all the information', () => {
+  it('should display all the information', async () => {
     const loggedInUser = mockLoggedInUser({
       email: 'email@company.com',
       groups: ['group1'],
@@ -198,10 +198,10 @@ describe('profile page', () => {
     });
     renderAccountApp(loggedInUser);
 
+    expect(await screen.findByText('group1')).toBeInTheDocument();
+    expect(screen.getByText('account1')).toBeInTheDocument();
     expect(screen.getAllByText(loggedInUser.login)).toHaveLength(2);
     expect(screen.getAllByText(loggedInUser.email!)).toHaveLength(2);
-    expect(screen.getByText('group1')).toBeInTheDocument();
-    expect(screen.getByText('account1')).toBeInTheDocument();
   });
 
   it('should handle missing info', () => {
@@ -392,7 +392,7 @@ describe('security page', () => {
     ).not.toBeInTheDocument();
   });
 
-  it("should not suggest creating a Project token if the user doesn't have at least one scannable Projects", () => {
+  it("should not suggest creating a Project token if the user doesn't have at least one scannable Projects", async () => {
     jest.mocked(getScannableProjects).mockResolvedValueOnce({
       projects: [],
     });
@@ -401,7 +401,9 @@ describe('security page', () => {
       securityPagePath,
     );
 
-    selectEvent.openMenu(screen.getByRole('combobox', { name: 'users.tokens.type' }));
+    await waitFor(() => {
+      selectEvent.openMenu(screen.getByRole('combobox', { name: 'users.tokens.type' }));
+    });
     expect(screen.queryByText(`users.tokens.${TokenType.Project}`)).not.toBeInTheDocument();
   });
 
@@ -429,9 +431,11 @@ describe('security page', () => {
       securityPagePath,
     );
 
-    await selectEvent.select(screen.getByRole('combobox', { name: 'users.tokens.type' }), [
-      `users.tokens.${TokenType.Project}`,
-    ]);
+    await waitFor(async () => {
+      await selectEvent.select(screen.getByRole('combobox', { name: 'users.tokens.type' }), [
+        `users.tokens.${TokenType.Project}`,
+      ]);
+    });
 
     expect(screen.getByText('Project Name 1')).toBeInTheDocument();
   });
index d72646ceed16820b8abb57dcaa9621cf400ef340..f027d36fcb7c28bfd5589906bae969cd0959a363 100644 (file)
@@ -172,7 +172,8 @@ export default class ProjectModal extends React.PureComponent<Props, State> {
     });
   };
 
-  handleSubmit = () => {
+  handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
+    event.preventDefault();
     const { selectedProject } = this.state;
 
     if (selectedProject) {
index fbde4591636f09c65e3f14b2e1f7cc8fbc10554e..60f218395b9fcf233065b91d2d559287230c3528 100644 (file)
@@ -310,7 +310,7 @@ describe('navigation', () => {
 
     await user.click(ui.maintainabilityDomainBtn.get());
     await user.click(ui.measureBtn('Code Smells 8').get());
-    await ui.changeViewToList();
+    await waitFor(() => ui.changeViewToList());
 
     expect(
       within(await ui.measuresRow('out.tsx').find()).getByRole('cell', { name: '1' }),
@@ -330,7 +330,7 @@ describe('navigation', () => {
 
     await user.click(ui.maintainabilityDomainBtn.get());
     await user.click(ui.measureBtn('Maintainability Rating metric.has_rating_X.E').get());
-    await ui.changeViewToTreeMap();
+    await waitFor(() => ui.changeViewToTreeMap());
 
     expect(await ui.treeMapCell(/folderA/).find()).toBeInTheDocument();
     expect(ui.treeMapCell(/test1\.js/).get()).toBeInTheDocument();
index 79bf52114651219c0e6ce3c98de685ec02556154..bd0dcd9a79577e5bb70c01f916314946cfcc40ad 100644 (file)
@@ -52,9 +52,9 @@ it('should be able to delete project', async () => {
 
   expect(byText('deletion.page').get()).toBeInTheDocument();
   expect(byText('project_deletion.page.description').get()).toBeInTheDocument();
-  user.click(byRole('button', { name: 'delete' }).get());
+  await user.click(byRole('button', { name: 'delete' }).get());
   expect(await byRole('dialog', { name: 'qualifier.delete.TRK' }).find()).toBeInTheDocument();
-  user.click(
+  await user.click(
     byRole('dialog', { name: 'qualifier.delete.TRK' }).byRole('button', { name: 'delete' }).get(),
   );
 
@@ -79,10 +79,10 @@ it('should be able to delete Portfolio', async () => {
   expect(byText('deletion.page').get()).toBeInTheDocument();
   expect(byText('portfolio_deletion.page.description').get()).toBeInTheDocument();
 
-  user.click(byRole('button', { name: 'delete' }).get());
+  await user.click(byRole('button', { name: 'delete' }).get());
 
   expect(await byRole('dialog', { name: 'qualifier.delete.VW' }).find()).toBeInTheDocument();
-  user.click(
+  await user.click(
     byRole('dialog', { name: 'qualifier.delete.VW' }).byRole('button', { name: 'delete' }).get(),
   );
 
@@ -107,9 +107,9 @@ it('should be able to delete Application', async () => {
   expect(byText('deletion.page').get()).toBeInTheDocument();
   expect(byText('application_deletion.page.description').get()).toBeInTheDocument();
 
-  user.click(byRole('button', { name: 'delete' }).get());
+  await user.click(byRole('button', { name: 'delete' }).get());
   expect(await byRole('dialog', { name: 'qualifier.delete.APP' }).find()).toBeInTheDocument();
-  user.click(
+  await user.click(
     byRole('dialog', { name: 'qualifier.delete.APP' }).byRole('button', { name: 'delete' }).get(),
   );
 
index d4cb21c7b72df2cb83e8d4561856b00554267aa9..871dc151f8389ed6eaf3758d1fa0ade080c1f437 100644 (file)
@@ -183,7 +183,9 @@ it('should filter projects', async () => {
   const user = userEvent.setup();
   renderProjectManagementApp();
   await waitFor(() => expect(ui.row.getAll()).toHaveLength(5));
-  await selectEvent.select(ui.visibilityFilter.get(), 'visibility.public');
+  await waitFor(() => {
+    selectEvent.select(ui.visibilityFilter.get(), 'visibility.public');
+  });
   await waitFor(() => expect(ui.row.getAll()).toHaveLength(4));
   await user.click(ui.analysisDateFilter.get());
   await user.click(await screen.findByRole('gridcell', { name: '5' }));
@@ -191,11 +193,15 @@ it('should filter projects', async () => {
   await user.click(ui.provisionedFilter.get());
   expect(ui.row.getAll()).toHaveLength(2);
   expect(ui.row.getAll()[1]).toHaveTextContent('Project 4');
-  await selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.VW');
-  expect(ui.provisionedFilter.query()).not.toBeInTheDocument();
+  await waitFor(() => {
+    selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.VW');
+  });
+  await waitFor(() => expect(ui.provisionedFilter.query()).not.toBeInTheDocument());
   expect(ui.row.getAll()).toHaveLength(2);
   await waitFor(() => expect(ui.row.getAll()[1]).toHaveTextContent('Portfolio 1'));
-  await selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.APP');
+  await waitFor(() => {
+    selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.APP');
+  });
   expect(ui.provisionedFilter.query()).not.toBeInTheDocument();
   expect(ui.row.getAll()).toHaveLength(2);
   await waitFor(() => expect(ui.row.getAll()[1]).toHaveTextContent('Application 1'));
@@ -207,12 +213,16 @@ it('should search by text', async () => {
   await waitFor(() => expect(ui.row.getAll()).toHaveLength(5));
   await user.type(ui.searchFilter.get(), 'provision');
   expect(ui.row.getAll()).toHaveLength(2);
-  await selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.VW');
+  await waitFor(() => {
+    selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.VW');
+  });
   await waitFor(() => expect(ui.row.getAll()).toHaveLength(4));
   expect(ui.searchFilter.get()).toHaveValue('');
   await user.type(ui.searchFilter.get(), 'Portfolio 2');
   expect(ui.row.getAll()).toHaveLength(2);
-  await selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.APP');
+  await waitFor(() => {
+    selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.APP');
+  });
   await waitFor(() => expect(ui.row.getAll()).toHaveLength(4));
   expect(ui.searchFilter.get()).toHaveValue('');
   await user.type(ui.searchFilter.get(), 'Application 3');
@@ -396,7 +406,9 @@ it('should load more and change the filter without caching old pages', async ()
   expect(projectRows[1]).toHaveTextContent('Project 0');
   expect(projectRows[60]).toHaveTextContent('Project 59');
 
-  await selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.VW');
+  await waitFor(() => {
+    selectEvent.select(ui.qualifierFilter.get(), 'qualifiers.VW');
+  });
   await waitFor(() => expect(projectRows[1]).not.toBeInTheDocument());
   const portfolioRows = ui.row.getAll();
   expect(portfolioRows).toHaveLength(51);
index 02d3bd88483495e8d60ed847be5e784fa167ed58..2e92bfb77f3060cebe1bf7cbb9228fb4ace6f845 100644 (file)
@@ -101,9 +101,11 @@ it('should behave correctly', async () => {
   // Incorrect login.
   await user.type(loginField, 'janedoe');
   await user.type(passwordField, 'invalid');
-  // Don't use userEvent.click() here. This allows us to more easily see the loading state changes.
-  submitButton.click();
-  await waitFor(() => expect(submitButton).toBeDisabled()); // Loading.
+  await waitFor(() => {
+    // Don't use userEvent.click() here. This allows us to more easily see the loading state changes.
+    submitButton.click();
+    expect(submitButton).toBeDisabled(); // Loading
+  });
   await waitFor(() => {
     expect(addGlobalErrorMessage).toHaveBeenCalledWith('login.authentication_failed');
   });
index 9bddc2e7728f5e8dd2bde70f0e6fac00ae172f15..c257fd290a8584bbd94ac79363d9f5060e962f45 100644 (file)
@@ -722,13 +722,17 @@ it('accessibility', async () => {
   // user creation dialog should be accessible
   await user.click(await ui.createUserButton.find());
   expect(await ui.dialogCreateUser.find()).toBeInTheDocument();
-  await expect(ui.dialogCreateUser.get()).toHaveNoA11yViolations();
+  await waitFor(async () => {
+    await expect(ui.dialogCreateUser.get()).toHaveNoA11yViolations();
+  });
   await user.click(ui.cancelButton.get());
 
   // users group membership dialog should be accessible
-  user.click(await ui.aliceUpdateGroupButton.find());
+  await user.click(await ui.aliceUpdateGroupButton.find());
   expect(await ui.dialogGroups.find()).toBeInTheDocument();
-  await expect(await ui.dialogGroups.find()).toHaveNoA11yViolations();
+  await waitFor(async () => {
+    await expect(await ui.dialogGroups.find()).toHaveNoA11yViolations();
+  });
   await user.click(ui.doneButton.get());
 
   // user update dialog should be accessible
@@ -748,7 +752,9 @@ it('accessibility', async () => {
   );
 
   expect(await ui.dialogTokens.find()).toBeInTheDocument();
-  await expect(await ui.dialogTokens.find()).toHaveNoA11yViolations();
+  await waitFor(async () => {
+    await expect(await ui.dialogTokens.find()).toHaveNoA11yViolations();
+  });
   await user.click(ui.closeButton.get());
 
   // user password dialog should be accessible