@centreon/ui 26.10.8 → 26.10.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/package.json +6 -3
  2. package/public/mockServiceWorker.js +31 -8
  3. package/src/Dashboard/Dashboard.browser.test.tsx +107 -0
  4. package/src/Form/CollapsibleGroup.tsx +6 -33
  5. package/src/Form/Form.browser.test.tsx +553 -0
  6. package/src/Form/Form.stories.tsx +102 -1
  7. package/src/Form/Form.tsx +4 -3
  8. package/src/Form/Inputs/ExclusiveCheckboxGroup.browser.test.tsx +304 -0
  9. package/src/Form/Inputs/Grid.browser.test.tsx +186 -0
  10. package/src/Form/Inputs/Grid.tsx +59 -12
  11. package/src/Form/Inputs/PasswordInput.browser.test.tsx +80 -0
  12. package/src/Form/Inputs/SegmentedButtons.browser.test.tsx +197 -0
  13. package/src/Form/Inputs/SegmentedButtons.tsx +38 -29
  14. package/src/Form/Inputs/Text.tsx +13 -1
  15. package/src/Form/Inputs/index.tsx +10 -52
  16. package/src/Form/Inputs/models.ts +6 -0
  17. package/src/Form/Section/FormSection.browser.test.tsx +174 -0
  18. package/src/Form/Section/FormSection.tsx +20 -6
  19. package/src/Form/Section/navigateToSection.ts +26 -8
  20. package/src/Form/Section/useActiveSection.ts +213 -0
  21. package/src/InputField/Number/Number.browser.test.tsx +109 -0
  22. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.browser.test.tsx +250 -0
  23. package/src/InputField/Select/Autocomplete/Connected/index.test.tsx +37 -0
  24. package/src/InputField/Select/Autocomplete/Connected/index.tsx +56 -45
  25. package/src/Listing/Cell/DataCell.tsx +0 -2
  26. package/src/Listing/Listing.browser.test.tsx +476 -0
  27. package/src/Module/Module.browser.test.tsx +145 -0
  28. package/src/Pagination/Pagination.browser.test.tsx +184 -0
  29. package/src/RichTextEditor/RichTextEditor.browser.test.tsx +567 -0
  30. package/src/RichTextEditor/plugins/FloatingLinkEditorPlugin.tsx +3 -1
  31. package/src/TimePeriods/ResolutionTimePeriod.browser.test.tsx +143 -0
  32. package/src/TimePeriods/TimePeriods.browser.test.tsx +468 -0
  33. package/src/Typography/FluidTypography/FluidTypography.browser.test.tsx +54 -0
  34. package/src/api/useMutationQuery/useMutationQuery.browser.test.tsx +154 -0
  35. package/src/components/CollapsibleItem/CollapsibleItem.browser.test.tsx +120 -0
  36. package/src/components/CopyCommand/CopyCommand.browser.test.tsx +287 -0
  37. package/src/components/CrudPage/CrudPage.browser.test.tsx +659 -0
  38. package/src/components/DataTable/DataTable.browser.test.tsx +257 -0
  39. package/src/components/Form/AccessRights/AccessRights.browser.test.tsx +527 -0
  40. package/src/components/Header/PageHeader/PageHeader.stories.tsx +9 -0
  41. package/src/components/Header/PageHeader/PageHeaderMain.tsx +4 -2
  42. package/src/components/Header/PageHeader/PageHeaderTitle.tsx +61 -18
  43. package/src/components/ItemComposition/ItemComposition.browser.test.tsx +172 -0
  44. package/src/components/Layout/PageLayout.browser.test.tsx +114 -0
  45. package/src/components/Modal/ConfirmationModal/ConfirmationModal.browser.test.tsx +237 -0
  46. package/src/components/SortableEntriesList/SortableEntriesList.browser.test.tsx +981 -0
  47. package/src/components/Tabs/Tabs.browser.test.tsx +115 -0
  48. package/src/components/Tabs/Tabs.tsx +7 -1
  49. package/src/utils/useFullscreen/Fullscreen.browser.test.tsx +176 -0
  50. package/src/utils/useLocale/useLocale.browser.test.tsx +49 -0
  51. package/src/utils/useLocaleTimezoneDate/{LocaleTimezoneDate.cypress.spec.tsx → LocaleTimezoneDate.browser.test.tsx} +24 -11
  52. package/src/Dashboard/Dashboard.cypress.spec.tsx +0 -71
  53. package/src/Form/Form.cypress.spec.tsx +0 -306
  54. package/src/Form/Inputs/ExclusiveCheckboxGroup.cypress.spec.tsx +0 -236
  55. package/src/Form/Inputs/SegmentedButtons.cypress.spec.tsx +0 -101
  56. package/src/InputField/Number/Number.cypress.spec.tsx +0 -89
  57. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +0 -182
  58. package/src/Listing/Listing.cypress.spec.tsx +0 -304
  59. package/src/Module/Module.cypress.spec.tsx +0 -127
  60. package/src/Pagination/Pagination.cypress.spec.tsx +0 -140
  61. package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +0 -408
  62. package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +0 -74
  63. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +0 -488
  64. package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +0 -27
  65. package/src/api/useMutationQuery/useMutationQuery.cypress.spec.tsx +0 -93
  66. package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +0 -76
  67. package/src/components/CopyCommand/CopyCommand.cypress.spec.tsx +0 -167
  68. package/src/components/CrudPage/CrudPage.cypress.spec.tsx +0 -561
  69. package/src/components/DataTable/DataTable.cypress.spec.tsx +0 -174
  70. package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +0 -376
  71. package/src/components/ItemComposition/ItemComposition.cypress.spec.tsx +0 -112
  72. package/src/components/Layout/PageLayout.cypress.spec.tsx +0 -64
  73. package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +0 -171
  74. package/src/components/SortableEntriesList/SortableEntriesList.cypress.spec.tsx +0 -792
  75. package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -69
  76. package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +0 -130
  77. package/src/utils/useLocale/useLocale.cypress.spec.tsx +0 -40
@@ -0,0 +1,172 @@
1
+ import { rs } from '@rstest/core';
2
+ import { render } from '@test-setup/render';
3
+ import { screen } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+
6
+ import { ItemComposition } from '.';
7
+ import type { Props } from './ItemComposition';
8
+
9
+ interface InitializeProps extends Partial<Props> {
10
+ deleteButtonHidden?: boolean;
11
+ }
12
+
13
+ interface Callbacks {
14
+ addItem: ReturnType<typeof rs.fn>;
15
+ deleteItem: ReturnType<typeof rs.fn>;
16
+ }
17
+
18
+ const initialize = ({
19
+ deleteButtonHidden,
20
+ ...props
21
+ }: InitializeProps): Callbacks => {
22
+ const addItem = rs.fn();
23
+ const deleteItem = rs.fn();
24
+
25
+ render(
26
+ <ItemComposition {...props} labelAdd="Add" onAddItem={addItem}>
27
+ <ItemComposition.Item
28
+ deleteButtonHidden={deleteButtonHidden}
29
+ labelDelete="Delete"
30
+ onDeleteItem={deleteItem}
31
+ >
32
+ <div>Item 1</div>
33
+ </ItemComposition.Item>
34
+ <ItemComposition.Item
35
+ deleteButtonHidden={deleteButtonHidden}
36
+ labelDelete="Delete"
37
+ onDeleteItem={deleteItem}
38
+ >
39
+ <div>Item 2</div>
40
+ </ItemComposition.Item>
41
+ </ItemComposition>
42
+ );
43
+
44
+ return {
45
+ addItem,
46
+ deleteItem
47
+ };
48
+ };
49
+
50
+ // Both items are visible, Item 1 before Item 2.
51
+ const expectItemsInOrder = (): void => {
52
+ const item1 = screen.getByText('Item 1');
53
+ const item2 = screen.getByText('Item 2');
54
+
55
+ expect(item1).toBeVisible();
56
+ expect(item2).toBeVisible();
57
+ expect(
58
+ item1.compareDocumentPosition(item2) & Node.DOCUMENT_POSITION_FOLLOWING
59
+ ).toBeTruthy();
60
+ };
61
+
62
+ const expectAddButtonWithIcon = (): void => {
63
+ const addButton = screen.getByTestId('Add');
64
+
65
+ expect(addButton).toBeVisible();
66
+ expect(addButton).toHaveTextContent('Add');
67
+ expect(addButton.querySelector('[data-testid="AddIcon"]')).toBeVisible();
68
+ };
69
+
70
+ describe('ItemComposition', () => {
71
+ beforeEach(() => {
72
+ expect.hasAssertions();
73
+ });
74
+
75
+ it('displays the component', () => {
76
+ initialize({});
77
+
78
+ expect(screen.getByText('Item 1')).toBeVisible();
79
+ expect(screen.getByText('Item 2')).toBeVisible();
80
+ expect(screen.getAllByTestId('Delete')).toHaveLength(2);
81
+ expect(screen.getByTestId('Add')).toBeEnabled();
82
+
83
+ expectItemsInOrder();
84
+ expectAddButtonWithIcon();
85
+ screen.getAllByTestId('Delete').forEach((deleteButton) => {
86
+ expect(deleteButton).toBeVisible();
87
+ });
88
+ expect(document.querySelector('[data-linked]')).not.toBeInTheDocument();
89
+ });
90
+
91
+ it('displays the component with a secondary label', () => {
92
+ initialize({ secondaryLabel: 'Secondary label' });
93
+
94
+ expect(screen.getByText('Secondary label')).toBeVisible();
95
+
96
+ // The secondary label is on the right of the add button.
97
+ expectItemsInOrder();
98
+ expectAddButtonWithIcon();
99
+ expect(
100
+ screen.getByText('Secondary label').getBoundingClientRect().left
101
+ ).toBeGreaterThan(screen.getByTestId('Add').getBoundingClientRect().right);
102
+ });
103
+
104
+ it('displays add button as hidden when the prop is set to true', () => {
105
+ initialize({ addbuttonDisabled: true });
106
+
107
+ expect(screen.getByTestId('Add')).toBeDisabled();
108
+
109
+ expectItemsInOrder();
110
+ expect(screen.getByTestId('Add')).toBeVisible();
111
+ });
112
+
113
+ it('does not display the add button when the prop is set to true', () => {
114
+ initialize({ addButtonHidden: true });
115
+
116
+ expect(screen.queryByTestId('Add')).not.toBeInTheDocument();
117
+
118
+ expectItemsInOrder();
119
+ screen.getAllByTestId('Delete').forEach((deleteButton) => {
120
+ expect(deleteButton).toBeVisible();
121
+ });
122
+ });
123
+
124
+ it('does not display the delete button when the prop is set to true', () => {
125
+ initialize({ deleteButtonHidden: true });
126
+
127
+ // The delete buttons are kept in the page with `display: none`: none of
128
+ // them is displayed.
129
+ const deleteButtons = screen.queryAllByTestId('Delete');
130
+
131
+ expect(deleteButtons).toHaveLength(2);
132
+ deleteButtons.forEach((deleteButton) => {
133
+ expect(deleteButton).not.toBeVisible();
134
+ });
135
+
136
+ expectItemsInOrder();
137
+ expectAddButtonWithIcon();
138
+ });
139
+
140
+ it('calls the add function when the button is clicked', async () => {
141
+ const { addItem } = initialize({});
142
+
143
+ await userEvent.click(screen.getByTestId('Add'));
144
+
145
+ expect(addItem).toHaveBeenCalledTimes(1);
146
+ });
147
+
148
+ it('calls the delete function when the button is clicked', async () => {
149
+ const { deleteItem } = initialize({});
150
+
151
+ await userEvent.click(screen.getAllByTestId('Delete')[1]);
152
+
153
+ expect(deleteItem).toHaveBeenCalledTimes(1);
154
+ });
155
+
156
+ it('displays items as linked when the prop is set to true', () => {
157
+ initialize({ displayItemsAsLinked: true });
158
+
159
+ expect(document.querySelector('[data-linked]')).toBeVisible();
160
+
161
+ // The link icon is on the left of the items.
162
+ expectItemsInOrder();
163
+ expect(screen.getByTestId('LinkIcon')).toBeVisible();
164
+ expect(
165
+ (
166
+ document.querySelector('[data-linked]') as HTMLElement
167
+ ).getBoundingClientRect().right
168
+ ).toBeLessThanOrEqual(
169
+ screen.getByText('Item 1').getBoundingClientRect().left
170
+ );
171
+ });
172
+ });
@@ -0,0 +1,114 @@
1
+ import { rs } from '@rstest/core';
2
+ import { render } from '@test-setup/render';
3
+ import { screen, within } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { T } from 'ramda';
6
+
7
+ import { PageHeader } from '..';
8
+ import { PageLayout } from '.';
9
+ import { AreaIndicator } from './AreaIndicator';
10
+
11
+ const initialize = (): void => {
12
+ render(
13
+ <PageLayout>
14
+ <PageLayout.Header>
15
+ <PageHeader>
16
+ <PageHeader.Menu>
17
+ <PageLayout.QuickAccess
18
+ create={rs.fn()}
19
+ elements={[
20
+ {
21
+ id: 1,
22
+ name: 'Entity'
23
+ }
24
+ ]}
25
+ goBack={rs.fn()}
26
+ isActive={T}
27
+ labels={{
28
+ create: 'Create',
29
+ goBack: 'Go back'
30
+ }}
31
+ navigateToElement={rs.fn()}
32
+ />
33
+ </PageHeader.Menu>
34
+ <PageHeader.Main>
35
+ <PageHeader.Title description="Description" title="Title" />
36
+ </PageHeader.Main>
37
+ <PageHeader.Actions>Actions</PageHeader.Actions>
38
+ </PageHeader>
39
+ </PageLayout.Header>
40
+ <PageLayout.Body>
41
+ <PageLayout.Actions>
42
+ <AreaIndicator name="Body actions" />
43
+ </PageLayout.Actions>
44
+ <h1>Content</h1>
45
+ </PageLayout.Body>
46
+ </PageLayout>
47
+ );
48
+ };
49
+
50
+ describe('Page layout', () => {
51
+ beforeEach(() => {
52
+ expect.hasAssertions();
53
+ initialize();
54
+ });
55
+
56
+ it('displays the page layout', async () => {
57
+ // The header (quick access button, title, description, actions) above
58
+ // the body (actions area, then content), and the quick access menu closed.
59
+ const header = document.querySelector('#header') as HTMLElement;
60
+ const body = document.querySelector('#page-body') as HTMLElement;
61
+
62
+ const title = await within(header).findByRole('heading', {
63
+ name: 'page header title'
64
+ });
65
+
66
+ expect(title).toBeVisible();
67
+ expect(title).toHaveTextContent(/^Title$/);
68
+ expect(within(header).getByText('Description')).toBeVisible();
69
+ expect(within(header).getByText('Actions')).toBeVisible();
70
+ expect(within(header).getByTestId('quickaccess')).toBeVisible();
71
+ expect(within(header).getByTestId('quickaccess')).toHaveAttribute(
72
+ 'data-is-active',
73
+ 'false'
74
+ );
75
+
76
+ const bodyActions = within(body).getByText('Body actions');
77
+ const content = within(body).getByRole('heading', { name: 'Content' });
78
+
79
+ expect(bodyActions).toBeVisible();
80
+ expect(content).toBeVisible();
81
+ expect(header.getBoundingClientRect().bottom).toBeLessThanOrEqual(
82
+ body.getBoundingClientRect().top
83
+ );
84
+ expect(bodyActions.getBoundingClientRect().bottom).toBeLessThanOrEqual(
85
+ content.getBoundingClientRect().top
86
+ );
87
+ expect(screen.queryByText('Entity')).not.toBeInTheDocument();
88
+ });
89
+
90
+ it('opens the quick access poppin when the corresponding logo is displayed', async () => {
91
+ await userEvent.click(await screen.findByTestId('quickaccess'));
92
+
93
+ expect(await screen.findByText('Entity')).toBeVisible();
94
+ expect(await screen.findByText('Create')).toBeVisible();
95
+ expect(await screen.findByText('Go back')).toBeVisible();
96
+
97
+ // The button shown as open, the active element selected, and "Go back"
98
+ // before "Create".
99
+ expect(screen.getByTestId('quickaccess')).toHaveAttribute(
100
+ 'data-is-active',
101
+ 'true'
102
+ );
103
+ expect(screen.getByRole('menuitem', { name: 'Entity' })).toHaveClass(
104
+ 'Mui-selected'
105
+ );
106
+ expect(
107
+ screen.getByRole('button', { name: 'Go back' }).getBoundingClientRect()
108
+ .right
109
+ ).toBeLessThanOrEqual(
110
+ screen.getByRole('button', { name: 'Create' }).getBoundingClientRect()
111
+ .left
112
+ );
113
+ });
114
+ });
@@ -0,0 +1,237 @@
1
+ import { Button } from '@mui/material';
2
+
3
+ import { rs } from '@rstest/core';
4
+ import { render } from '@test-setup/render';
5
+ import { screen, waitFor } from '@testing-library/react';
6
+ import userEvent from '@testing-library/user-event';
7
+ import { atom, createStore, Provider, useSetAtom } from 'jotai';
8
+
9
+ import {
10
+ ConfirmationModal,
11
+ type ConfirmationModalProps
12
+ } from './ConfirmationModal';
13
+
14
+ const testAtom = atom<string | null>(null);
15
+
16
+ const buttonLabel = 'Click to open modal';
17
+
18
+ const TestComponent = (args: ConfirmationModalProps<string>): JSX.Element => {
19
+ const setAtom = useSetAtom(testAtom);
20
+
21
+ return (
22
+ <>
23
+ <Button onClick={() => setAtom('John')}>{buttonLabel}</Button>
24
+ <ConfirmationModal<string> {...args} />
25
+ </>
26
+ );
27
+ };
28
+
29
+ const staticLabels = {
30
+ cancel: 'Cancel',
31
+ confirm: 'Confirm',
32
+ description: 'Description',
33
+ title: 'Title'
34
+ };
35
+
36
+ const dynamicLabels = {
37
+ cancel: 'Cancel',
38
+ confirm: 'Confirm',
39
+ description: (data: string | null): string => `Description ${data}`,
40
+ title: (data: string | null): string => `Hello ${data}`
41
+ };
42
+
43
+ type InitializeProps = Pick<
44
+ ConfirmationModalProps<string>,
45
+ 'labels' | 'disabled' | 'hasCloseButton' | 'isDanger'
46
+ >;
47
+
48
+ interface InitializeResult {
49
+ cancel: ReturnType<typeof rs.fn>;
50
+ confirm: ReturnType<typeof rs.fn>;
51
+ }
52
+
53
+ const initialize = (props: InitializeProps): InitializeResult => {
54
+ const store = createStore();
55
+
56
+ const cancel = rs.fn();
57
+ const confirm = rs.fn();
58
+
59
+ render(
60
+ <Provider store={store}>
61
+ <TestComponent
62
+ {...props}
63
+ atom={testAtom}
64
+ onCancel={cancel}
65
+ onConfirm={confirm}
66
+ />
67
+ </Provider>
68
+ );
69
+
70
+ return {
71
+ cancel,
72
+ confirm
73
+ };
74
+ };
75
+
76
+ const openModal = async (): Promise<void> => {
77
+ await userEvent.click(screen.getByText(buttonLabel));
78
+ };
79
+
80
+ // The open modal: the title, the description, then the Cancel and Confirm
81
+ // buttons, in that order.
82
+ const expectModalContent = async ({
83
+ description,
84
+ title
85
+ }: {
86
+ description: string;
87
+ title: string;
88
+ }): Promise<void> => {
89
+ const dialog = await screen.findByRole('dialog');
90
+
91
+ expect(screen.getByTestId('modal-header')).toHaveTextContent(
92
+ new RegExp(`^${title}$`)
93
+ );
94
+ expect(dialog).toHaveTextContent(description);
95
+ expect(screen.getByTestId('cancel')).toBeVisible();
96
+ expect(screen.getByTestId('cancel')).toHaveTextContent(/^Cancel$/);
97
+ expect(screen.getByTestId('confirm')).toBeVisible();
98
+ expect(screen.getByTestId('confirm')).toHaveTextContent(/^Confirm$/);
99
+ expect(
100
+ screen
101
+ .getByTestId('cancel')
102
+ .compareDocumentPosition(screen.getByTestId('confirm'))
103
+ ).toBe(Node.DOCUMENT_POSITION_FOLLOWING);
104
+ };
105
+
106
+ const expectModalClosed = async (): Promise<void> => {
107
+ await waitFor(() => {
108
+ expect(screen.queryByText('Title')).not.toBeInTheDocument();
109
+ });
110
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
111
+ expect(screen.getByText(buttonLabel)).toBeVisible();
112
+ };
113
+
114
+ describe('Confirmation modal', () => {
115
+ beforeEach(() => {
116
+ expect.hasAssertions();
117
+ });
118
+
119
+ it('displays the modal with static labels', async () => {
120
+ initialize({ labels: staticLabels });
121
+
122
+ await openModal();
123
+
124
+ expect(await screen.findByText('Title')).toBeVisible();
125
+ expect(screen.getByText('Description')).toBeVisible();
126
+ expect(screen.getByLabelText('close')).toBeVisible();
127
+
128
+ await expectModalContent({ description: 'Description', title: 'Title' });
129
+ expect(screen.getByTestId('confirm')).toBeEnabled();
130
+ expect(screen.getByTestId('confirm')).toHaveAttribute(
131
+ 'data-is-danger',
132
+ 'false'
133
+ );
134
+ });
135
+
136
+ it('displays the modal with dynamic labels', async () => {
137
+ initialize({ labels: dynamicLabels });
138
+
139
+ await openModal();
140
+
141
+ expect(await screen.findByText('Hello John')).toBeVisible();
142
+ expect(screen.getByText('Description John')).toBeVisible();
143
+
144
+ await expectModalContent({
145
+ description: 'Description John',
146
+ title: 'Hello John'
147
+ });
148
+ expect(screen.getByLabelText('close')).toBeVisible();
149
+ });
150
+
151
+ it('displays the confirm button as disabled when a prop is set', async () => {
152
+ initialize({ disabled: true, labels: staticLabels });
153
+
154
+ await openModal();
155
+
156
+ expect(await screen.findByText('Confirm')).toBeVisible();
157
+ expect(screen.getByTestId('confirm')).toBeDisabled();
158
+
159
+ await expectModalContent({ description: 'Description', title: 'Title' });
160
+ expect(screen.getByTestId('cancel')).toBeEnabled();
161
+ });
162
+
163
+ it('displays the confirm button as danger when a prop is set', async () => {
164
+ initialize({ isDanger: true, labels: staticLabels });
165
+
166
+ await openModal();
167
+
168
+ expect(await screen.findByText('Confirm')).toBeVisible();
169
+ expect(screen.getByTestId('confirm')).toHaveAttribute(
170
+ 'data-is-danger',
171
+ 'true'
172
+ );
173
+
174
+ await expectModalContent({ description: 'Description', title: 'Title' });
175
+
176
+ // A red Confirm button: its background is the theme's error colour.
177
+ const errorColorProbe = document.createElement('div');
178
+ errorColorProbe.style.backgroundColor = 'var(--color-error-main)';
179
+ document.body.appendChild(errorColorProbe);
180
+ const errorColor = getComputedStyle(errorColorProbe).backgroundColor;
181
+ errorColorProbe.remove();
182
+
183
+ expect(errorColor).not.toBe('rgba(0, 0, 0, 0)');
184
+ expect(
185
+ getComputedStyle(screen.getByTestId('confirm')).backgroundColor
186
+ ).toBe(errorColor);
187
+ });
188
+
189
+ it('displays the modal without the close button when a prop is set', async () => {
190
+ initialize({ hasCloseButton: false, labels: staticLabels });
191
+
192
+ await openModal();
193
+
194
+ await expectModalContent({ description: 'Description', title: 'Title' });
195
+ expect(screen.queryByLabelText('close')).not.toBeInTheDocument();
196
+ });
197
+
198
+ it('closes the modal when the close button is clicked', async () => {
199
+ initialize({ labels: staticLabels });
200
+
201
+ await openModal();
202
+
203
+ expect(await screen.findByText('Title')).toBeVisible();
204
+
205
+ await userEvent.click(screen.getByLabelText('close'));
206
+
207
+ await expectModalClosed();
208
+ });
209
+
210
+ it('closes the modal when the cancel button is clicked', async () => {
211
+ const { cancel } = initialize({ labels: staticLabels });
212
+
213
+ await openModal();
214
+
215
+ expect(await screen.findByText('Title')).toBeVisible();
216
+
217
+ await userEvent.click(screen.getByText('Cancel'));
218
+
219
+ expect(cancel).toHaveBeenCalledWith('John');
220
+
221
+ await expectModalClosed();
222
+ });
223
+
224
+ it('closes the modal when the confirm button is clicked', async () => {
225
+ const { confirm } = initialize({ labels: staticLabels });
226
+
227
+ await openModal();
228
+
229
+ expect(await screen.findByText('Title')).toBeVisible();
230
+
231
+ await userEvent.click(screen.getByText('Confirm'));
232
+
233
+ expect(confirm).toHaveBeenCalledWith('John');
234
+
235
+ await expectModalClosed();
236
+ });
237
+ });