@centreon/ui 26.12.0 → 26.12.2
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.
- package/package.json +6 -3
- package/public/mockServiceWorker.js +31 -8
- package/src/Dashboard/Dashboard.browser.test.tsx +107 -0
- package/src/Form/Form.browser.test.tsx +445 -0
- package/src/Form/Inputs/ExclusiveCheckboxGroup.browser.test.tsx +304 -0
- package/src/Form/Inputs/SegmentedButtons.browser.test.tsx +113 -0
- package/src/InputField/Number/Number.browser.test.tsx +109 -0
- package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.browser.test.tsx +250 -0
- package/src/Listing/Listing.browser.test.tsx +476 -0
- package/src/Module/Module.browser.test.tsx +145 -0
- package/src/Pagination/Pagination.browser.test.tsx +184 -0
- package/src/Panel/Section/index.test.tsx +1 -1
- package/src/RichTextEditor/RichTextEditor.browser.test.tsx +567 -0
- package/src/RichTextEditor/plugins/FloatingLinkEditorPlugin.tsx +3 -1
- package/src/TimePeriods/ResolutionTimePeriod.browser.test.tsx +143 -0
- package/src/TimePeriods/TimePeriods.browser.test.tsx +468 -0
- package/src/Typography/FluidTypography/FluidTypography.browser.test.tsx +54 -0
- package/src/api/useMutationQuery/useMutationQuery.browser.test.tsx +154 -0
- package/src/components/CollapsibleItem/CollapsibleItem.browser.test.tsx +120 -0
- package/src/components/CopyCommand/CopyCommand.browser.test.tsx +287 -0
- package/src/components/CrudPage/CrudPage.browser.test.tsx +659 -0
- package/src/components/DataTable/DataTable.browser.test.tsx +257 -0
- package/src/components/Form/AccessRights/AccessRights.browser.test.tsx +527 -0
- package/src/components/ItemComposition/ItemComposition.browser.test.tsx +172 -0
- package/src/components/Layout/PageLayout.browser.test.tsx +114 -0
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.browser.test.tsx +237 -0
- package/src/components/SortableEntriesList/SortableEntriesList.browser.test.tsx +981 -0
- package/src/components/Tabs/Tabs.browser.test.tsx +115 -0
- package/src/utils/useFullscreen/Fullscreen.browser.test.tsx +176 -0
- package/src/utils/useLocale/useLocale.browser.test.tsx +49 -0
- package/src/utils/useLocaleTimezoneDate/{LocaleTimezoneDate.cypress.spec.tsx → LocaleTimezoneDate.browser.test.tsx} +24 -11
- package/src/Dashboard/Dashboard.cypress.spec.tsx +0 -71
- package/src/Form/Form.cypress.spec.tsx +0 -306
- package/src/Form/Inputs/ExclusiveCheckboxGroup.cypress.spec.tsx +0 -236
- package/src/Form/Inputs/SegmentedButtons.cypress.spec.tsx +0 -101
- package/src/InputField/Number/Number.cypress.spec.tsx +0 -89
- package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +0 -182
- package/src/Listing/Listing.cypress.spec.tsx +0 -349
- package/src/Module/Module.cypress.spec.tsx +0 -127
- package/src/Pagination/Pagination.cypress.spec.tsx +0 -140
- package/src/RichTextEditor/RichTextEditor.cypress.spec.tsx +0 -408
- package/src/TimePeriods/ResolutionTimePeriod.cypress.spec.tsx +0 -74
- package/src/TimePeriods/TimePeriods.cypress.spec.tsx +0 -488
- package/src/Typography/FluidTypography/FluidTypography.cypress.spec.tsx +0 -27
- package/src/api/useMutationQuery/useMutationQuery.cypress.spec.tsx +0 -93
- package/src/components/CollapsibleItem/CollapsibleItem.cypress.spec.tsx +0 -76
- package/src/components/CopyCommand/CopyCommand.cypress.spec.tsx +0 -167
- package/src/components/CrudPage/CrudPage.cypress.spec.tsx +0 -561
- package/src/components/DataTable/DataTable.cypress.spec.tsx +0 -174
- package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +0 -376
- package/src/components/ItemComposition/ItemComposition.cypress.spec.tsx +0 -112
- package/src/components/Layout/PageLayout.cypress.spec.tsx +0 -64
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.cypress.spec.tsx +0 -171
- package/src/components/SortableEntriesList/SortableEntriesList.cypress.spec.tsx +0 -792
- package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -69
- package/src/utils/useFullscreen/Fullscreen.cypress.spec.tsx +0 -130
- package/src/utils/useLocale/useLocale.cypress.spec.tsx +0 -40
|
@@ -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
|
+
});
|