From a76f6132b202735d05021368c9891a9b48d572a9 Mon Sep 17 00:00:00 2001
From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
Date: Tue, 28 Jan 2025 10:49:07 +0100
Subject: [PATCH 1/4] test: prevent warnings about unhandled side effects
Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
---
.../CustomControl/CustomControl.test.tsx | 60 +++++++++++--------
.../EntityModal/EntityModal.test.tsx | 6 +-
.../InteractAllStatusButton.test.tsx | 31 ++++++----
.../table/tests/CustomTableRow.test.tsx | 7 ++-
.../table/tests/TableExpansionRow.test.tsx | 9 ++-
5 files changed, 67 insertions(+), 46 deletions(-)
diff --git a/ui/src/components/CustomControl/CustomControl.test.tsx b/ui/src/components/CustomControl/CustomControl.test.tsx
index f4c96cb86..f1641d06a 100644
--- a/ui/src/components/CustomControl/CustomControl.test.tsx
+++ b/ui/src/components/CustomControl/CustomControl.test.tsx
@@ -1,4 +1,4 @@
-import { render, screen } from '@testing-library/react';
+import { act, render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import userEvent from '@testing-library/user-event';
import CustomControl from './CustomControl';
@@ -18,7 +18,7 @@ const mockClearErrorMsg = jest.fn();
const FIELD_NAME = 'testCustomField';
-beforeEach(() => {
+const setup = async () => {
const mockConfig = getGlobalConfigMock();
setUnifiedConfig(mockConfig);
@@ -26,40 +26,50 @@ beforeEach(() => {
virtual: true,
});
- render(
-
- );
-});
+ await act(async () => {
+ render(
+
+ );
+
+ const loading = screen.queryByText('Loading...');
+ if (loading) {
+ await waitFor(() => expect(loading).not.toHaveTextContent('Loading...'));
+ }
+ });
+};
it('should render custom component correctly', async () => {
+ await setup();
const renderedModal = await screen.findByTestId('customSelect');
expect(renderedModal).toBeInTheDocument();
});
it('should try to add validator', async () => {
+ await setup();
expect(addingCustomValidation).toHaveBeenCalled();
});
it('should correctly call handler on change', async () => {
+ await setup();
const selectElem = document.querySelector('select');
expect(selectElem).toBeInTheDocument();
const SELECTED_OPTION = 'input_one';
diff --git a/ui/src/components/EntityModal/EntityModal.test.tsx b/ui/src/components/EntityModal/EntityModal.test.tsx
index a43d8a556..1547113ff 100644
--- a/ui/src/components/EntityModal/EntityModal.test.tsx
+++ b/ui/src/components/EntityModal/EntityModal.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { render, screen, waitFor } from '@testing-library/react';
+import { act, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';
import EntityModal, { EntityModalProps } from './EntityModal';
@@ -534,7 +534,9 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
const passedState = `tests${stateCodeFromUrl}`;
- window.getMessage({ code, state: passedState, error: undefined });
+ act(() => {
+ window.getMessage({ code, state: passedState, error: undefined });
+ });
expect(screen.getByText(ERROR_STATE_MISSING_TRY_AGAIN)).toBeInTheDocument();
});
diff --git a/ui/src/components/InteractAllStatusButton.test.tsx b/ui/src/components/InteractAllStatusButton.test.tsx
index fc67c4f60..5a2e89a2b 100644
--- a/ui/src/components/InteractAllStatusButton.test.tsx
+++ b/ui/src/components/InteractAllStatusButton.test.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
+import { userEvent } from '@testing-library/user-event';
import { InputRowData, InteractAllStatusButtons } from './InteractAllStatusButton';
describe('InteractAllStatusButtons', () => {
@@ -95,15 +96,16 @@ describe('InteractAllStatusButtons', () => {
});
it('Deactivate All enabled rows correctly', async () => {
+ const user = userEvent.setup();
const disableBtn = await screen.findByText('Deactivate all');
expect(disableBtn).toBeInTheDocument();
- disableBtn.click();
+ await user.click(disableBtn);
const yesPopUpBtn = await screen.findByText('Yes');
expect(yesPopUpBtn).toBeInTheDocument();
- yesPopUpBtn.click();
+ await user.click(yesPopUpBtn);
expect(handleToggleStatusChange).toHaveBeenCalledWith(
allDataRowsMockUp.find((x) => x.name === 'aaaaa')
@@ -118,15 +120,16 @@ describe('InteractAllStatusButtons', () => {
});
it('Activate All disabled rows correctly', async () => {
+ const user = userEvent.setup();
const enableBtn = await screen.findByText('Activate all');
expect(enableBtn).toBeInTheDocument();
- enableBtn.click();
+ await user.click(enableBtn);
const yesPopUpBtn = await screen.findByText('Yes');
expect(yesPopUpBtn).toBeInTheDocument();
- yesPopUpBtn.click();
+ await user.click(yesPopUpBtn);
expect(handleToggleStatusChange).toHaveBeenCalledWith(
allDataRowsMockUp.find((x) => x.name === 'cccccc')
@@ -141,57 +144,61 @@ describe('InteractAllStatusButtons', () => {
});
it('Do not disable status if rejected', async () => {
+ const user = userEvent.setup();
const disableBtn = await screen.findByText('Deactivate all');
expect(disableBtn).toBeInTheDocument();
- disableBtn.click();
+ await user.click(disableBtn);
const noPopUpBtn = await screen.findByText('No');
expect(noPopUpBtn).toBeInTheDocument();
- noPopUpBtn.click();
+ await user.click(noPopUpBtn);
expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});
it('Do not enable status if rejected', async () => {
+ const user = userEvent.setup();
const enableBtn = await screen.findByText('Activate all');
expect(enableBtn).toBeInTheDocument();
- enableBtn.click();
+ await user.click(enableBtn);
const noPopUpBtn = await screen.findByText('No');
expect(noPopUpBtn).toBeInTheDocument();
- noPopUpBtn.click();
+ await user.click(noPopUpBtn);
expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});
it('Do not enable status if popup modal closed by X', async () => {
+ const user = userEvent.setup();
const enableBtn = await screen.findByText('Activate all');
expect(enableBtn).toBeInTheDocument();
- enableBtn.click();
+ await user.click(enableBtn);
const closeXBtn = screen.getByTestId('close');
expect(closeXBtn).toBeInTheDocument();
- closeXBtn.click();
+ await user.click(closeXBtn);
expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});
it('Do not disable status if popup modal closed by X', async () => {
+ const user = userEvent.setup();
const disableBtn = await screen.findByText('Deactivate all');
expect(disableBtn).toBeInTheDocument();
- disableBtn.click();
+ await user.click(disableBtn);
const closeXBtn = screen.getByTestId('close');
expect(closeXBtn).toBeInTheDocument();
- closeXBtn.click();
+ await user.click(closeXBtn);
expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});
diff --git a/ui/src/components/table/tests/CustomTableRow.test.tsx b/ui/src/components/table/tests/CustomTableRow.test.tsx
index 102e279f8..69ea15691 100644
--- a/ui/src/components/table/tests/CustomTableRow.test.tsx
+++ b/ui/src/components/table/tests/CustomTableRow.test.tsx
@@ -1,4 +1,5 @@
import { render, screen, within } from '@testing-library/react';
+import { userEvent } from '@testing-library/user-event';
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
@@ -52,7 +53,8 @@ it('Render action icons correctly', async () => {
});
it('Correctly call action handlers for page dialog', async () => {
- (await screen.findAllByRole('button', { name: /edit/i }))[0].click();
+ const user = userEvent.setup();
+ await user.click((await screen.findAllByRole('button', { name: /edit/i }))[0]);
expect(handleOpenPageStyleDialog).toHaveBeenCalledWith(expect.objectContaining({}), 'edit');
@@ -66,8 +68,9 @@ it('Correctly call action handlers for page dialog', async () => {
});
it('Correctly render modal for delete action click', async () => {
+ const user = userEvent.setup();
// Clicking delete renders modal
- (await screen.findAllByRole('button', { name: /delete/i }))[0].click();
+ await user.click((await screen.findAllByRole('button', { name: /delete/i }))[0]);
expect(await screen.findByRole('dialog')).toHaveTextContent('Delete Confirmation');
});
diff --git a/ui/src/components/table/tests/TableExpansionRow.test.tsx b/ui/src/components/table/tests/TableExpansionRow.test.tsx
index 0dcca8b66..0d8724ccc 100644
--- a/ui/src/components/table/tests/TableExpansionRow.test.tsx
+++ b/ui/src/components/table/tests/TableExpansionRow.test.tsx
@@ -103,12 +103,11 @@ function setup() {
}
async function expectIntervalInExpandedRow(inputRow: HTMLElement, expectedInterval: number) {
- const arrow = within(inputRow).getByRole('cell', { name: /expandable/i });
- const isExpanded = arrow.getAttribute('aria-expanded');
- if (isExpanded === 'false') {
- await userEvent.click(arrow);
+ const expandable = within(inputRow).queryByRole('cell', { name: /expand/i });
+ if (expandable && expandable.getAttribute('aria-expanded') === 'false') {
+ await userEvent.click(expandable);
+ await waitFor(() => expect(expandable.getAttribute('aria-expanded')).not.toBe('false'));
}
- await waitFor(() => expect(arrow.getAttribute('aria-expanded')).not.toBe('false'));
const loading = screen.queryByText('Loading...');
if (loading) {
await waitForElementToBeRemoved(loading);
From 604b4f42d239552b7b4a4b29478574d9cb65bdc4 Mon Sep 17 00:00:00 2001
From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
Date: Tue, 28 Jan 2025 11:33:18 +0100
Subject: [PATCH 2/4] add await for act
Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
---
ui/src/components/EntityModal/EntityModal.test.tsx | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/ui/src/components/EntityModal/EntityModal.test.tsx b/ui/src/components/EntityModal/EntityModal.test.tsx
index 1547113ff..5674ae6d4 100644
--- a/ui/src/components/EntityModal/EntityModal.test.tsx
+++ b/ui/src/components/EntityModal/EntityModal.test.tsx
@@ -491,12 +491,12 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
- window.getMessage({ code, state: stateCodeFromUrl, error: undefined });
-
- await waitFor(async () => {
- expect(requestHandler).toHaveBeenCalledTimes(1);
+ await act(async () => {
+ window.getMessage({ code, state: stateCodeFromUrl, error: undefined });
});
+ expect(requestHandler).toHaveBeenCalledTimes(1);
+
const receivedRequest: Request = requestHandler.mock.calls[0][0];
const receivedBody = await receivedRequest.text();
@@ -534,7 +534,7 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
const passedState = `tests${stateCodeFromUrl}`;
- act(() => {
+ await act(async () => {
window.getMessage({ code, state: passedState, error: undefined });
});
From 20727190ed97778f138212b15fb93b02454c65b8 Mon Sep 17 00:00:00 2001
From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
Date: Tue, 28 Jan 2025 11:33:50 +0100
Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=A4=B7=E2=80=8D=E2=99=82=EF=B8=8F=20f?=
=?UTF-8?q?r=20fr?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
---
ui/src/components/EntityModal/EntityModal.test.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ui/src/components/EntityModal/EntityModal.test.tsx b/ui/src/components/EntityModal/EntityModal.test.tsx
index 5674ae6d4..da8c45a1a 100644
--- a/ui/src/components/EntityModal/EntityModal.test.tsx
+++ b/ui/src/components/EntityModal/EntityModal.test.tsx
@@ -491,7 +491,7 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
- await act(async () => {
+ await act(() => {
window.getMessage({ code, state: stateCodeFromUrl, error: undefined });
});
@@ -534,7 +534,7 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
const passedState = `tests${stateCodeFromUrl}`;
- await act(async () => {
+ await act(() => {
window.getMessage({ code, state: passedState, error: undefined });
});
From f2b1a6bcb1da3da548cb261819fe5abba14d2e60 Mon Sep 17 00:00:00 2001
From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
Date: Tue, 28 Jan 2025 11:35:42 +0100
Subject: [PATCH 4/4] =?UTF-8?q?cap=20cap=20=F0=9F=A7=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com>
---
ui/src/components/EntityModal/EntityModal.test.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ui/src/components/EntityModal/EntityModal.test.tsx b/ui/src/components/EntityModal/EntityModal.test.tsx
index da8c45a1a..4f6b46e6b 100644
--- a/ui/src/components/EntityModal/EntityModal.test.tsx
+++ b/ui/src/components/EntityModal/EntityModal.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { act, render, screen, waitFor } from '@testing-library/react';
+import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';
import EntityModal, { EntityModalProps } from './EntityModal';
@@ -491,7 +491,7 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
- await act(() => {
+ await act(async () => {
window.getMessage({ code, state: stateCodeFromUrl, error: undefined });
});
@@ -534,7 +534,7 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
const passedState = `tests${stateCodeFromUrl}`;
- await act(() => {
+ await act(async () => {
window.getMessage({ code, state: passedState, error: undefined });
});