@salesforcedevs/dx-components 0.17.0 → 0.18.3
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/lwc.config.json +1 -0
- package/package.json +3 -3
- package/src/assets/svg/sidebar-loading.svg +34 -0
- package/src/modules/dx/header/__tests__/mockProps.ts +7 -1
- package/src/modules/dx/headerSearch/__tests__/headerSearch.test.ts +24 -39
- package/src/modules/dx/headerSearch/__tests__/mockProps.ts +2 -7
- package/src/modules/dx/headerSearch/headerSearch.ts +13 -19
- package/src/modules/dx/lazy/lazy.ts +0 -7
- package/src/modules/dx/sidebar/__tests__/mockSearchChangeEmptyEvent.ts +6 -0
- package/src/modules/dx/sidebar/__tests__/mockSearchChangeEvent.ts +527 -0
- package/src/modules/dx/sidebar/__tests__/sidebar.test.ts +210 -247
- package/src/modules/dx/sidebar/sidebar.css +68 -34
- package/src/modules/dx/sidebar/sidebar.html +58 -34
- package/src/modules/dx/sidebar/sidebar.stories.ts +50 -4
- package/src/modules/dx/sidebar/sidebar.ts +141 -73
- package/src/modules/dx/sidebarOld/__tests__/mockProps.ts +178 -0
- package/src/modules/dx/sidebarOld/__tests__/sidebarOld.test.ts +574 -0
- package/src/modules/dx/sidebarOld/sidebarOld.css +160 -0
- package/src/modules/dx/sidebarOld/sidebarOld.html +70 -0
- package/src/modules/dx/sidebarOld/sidebarOld.stories.ts +139 -0
- package/src/modules/dx/sidebarOld/sidebarOld.ts +187 -0
- package/src/modules/dx/sidebarSearch/__tests__/mockPreloadedState.ts +1678 -0
- package/src/modules/dx/sidebarSearch/__tests__/sidebarSearch.test.ts +113 -0
- package/src/modules/dx/sidebarSearch/sidebarSearch.css +3 -0
- package/src/modules/dx/sidebarSearch/sidebarSearch.html +26 -0
- package/src/modules/dx/sidebarSearch/sidebarSearch.ts +427 -0
- package/src/modules/dx/sidebarSearchResult/__tests__/sidebarSearchResult.test.ts +55 -0
- package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.css +36 -0
- package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.html +14 -0
- package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.ts +56 -0
- package/src/modules/dx/treeTile/__tests__/treeTile.test.ts +27 -38
- package/src/modules/dx/treeTile/treeTile.css +3 -19
- package/src/modules/dx/treeTile/treeTile.html +4 -1
- package/src/modules/dx/treeTile/treeTile.ts +2 -2
- package/src/modules/helpers/sidebar/sidebar.css +21 -0
- package/src/modules/utils/coveo/coveo.ts +69 -0
- package/src/modules/utils/highlight/__tests__/highlight.test.ts +108 -0
- package/src/modules/utils/highlight/__tests__/mockProps.ts +45 -0
- package/src/modules/utils/highlight/highlight.ts +2 -1
- package/src/modules/utils/jest/jest.ts +35 -0
- package/src/modules/utils/recentSearches/__tests__/recentSearches.test.ts +79 -0
- package/src/modules/utils/recentSearches/recentSearches.ts +57 -0
- package/src/modules/utils/tests/tests.ts +18 -11
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
import Button from "dx/button";
|
|
2
|
+
import Input from "dx/input";
|
|
3
|
+
import { track } from "dx/instrumentation";
|
|
4
|
+
import SidebarOld from "dx/sidebarOld";
|
|
5
|
+
import Tree from "dx/tree";
|
|
6
|
+
import { TreeNode } from "typings/custom";
|
|
7
|
+
import { createMediaMock } from "utils/jest";
|
|
8
|
+
import { createRenderComponent } from "utils/tests";
|
|
9
|
+
import { SAMPLE_TREES } from "./mockProps";
|
|
10
|
+
|
|
11
|
+
jest.mock("dx/instrumentation");
|
|
12
|
+
|
|
13
|
+
const TAG = "dx-sidebar-old";
|
|
14
|
+
const renderComponent = createRenderComponent(TAG, SidebarOld);
|
|
15
|
+
|
|
16
|
+
const COLLAPSED_CLASS = "collapsed";
|
|
17
|
+
const EXPECTED_QUERY = "(max-width: 768px)";
|
|
18
|
+
const GTM_EVENT_NAME = "custEv_leftNavLinkClick";
|
|
19
|
+
const TOGGLE_BUTTON_LABEL = "Toggle Sidebar";
|
|
20
|
+
|
|
21
|
+
describe(TAG, () => {
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
jest.clearAllMocks();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("desktop", () => {
|
|
27
|
+
describe("component render", () => {
|
|
28
|
+
it("should render as expanded with all the elements that sidebar includes", () => {
|
|
29
|
+
const expectedTitle = "Super cool title";
|
|
30
|
+
const component = renderComponent({
|
|
31
|
+
header: expectedTitle,
|
|
32
|
+
trees: SAMPLE_TREES
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(component.trees).toEqual(SAMPLE_TREES);
|
|
36
|
+
|
|
37
|
+
const container: HTMLElement =
|
|
38
|
+
component.shadowRoot.querySelector(".container");
|
|
39
|
+
expect(container).not.toBeNull();
|
|
40
|
+
expect(container.classList).not.toContain(COLLAPSED_CLASS);
|
|
41
|
+
|
|
42
|
+
const headerTitle: HTMLElement =
|
|
43
|
+
component.shadowRoot.querySelector(".header h2");
|
|
44
|
+
expect(headerTitle).not.toBeNull();
|
|
45
|
+
expect(headerTitle.textContent).toBe(expectedTitle);
|
|
46
|
+
|
|
47
|
+
const collapseButton: Button =
|
|
48
|
+
component.shadowRoot.querySelector("dx-button");
|
|
49
|
+
expect(collapseButton).not.toBeNull();
|
|
50
|
+
expect(collapseButton.iconSymbol).toBe("close_panel");
|
|
51
|
+
|
|
52
|
+
const searchBox: Input =
|
|
53
|
+
component.shadowRoot.querySelector("dx-input");
|
|
54
|
+
expect(searchBox).not.toBeNull();
|
|
55
|
+
expect(searchBox.value).toBe("");
|
|
56
|
+
|
|
57
|
+
const trees: Array<Tree> =
|
|
58
|
+
component.shadowRoot.querySelectorAll("dx-tree");
|
|
59
|
+
expect(trees).toHaveLength(SAMPLE_TREES.length);
|
|
60
|
+
trees.forEach((tree, index) =>
|
|
61
|
+
expect(tree.treeRoot).toHaveProperty(
|
|
62
|
+
"name",
|
|
63
|
+
SAMPLE_TREES[index].name
|
|
64
|
+
)
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Mobile specific elements should not render
|
|
68
|
+
const headerTitleDesktop = component.shadowRoot.querySelector(
|
|
69
|
+
".header span.header-title"
|
|
70
|
+
);
|
|
71
|
+
expect(headerTitleDesktop).toBeNull();
|
|
72
|
+
|
|
73
|
+
const toggleButtonDesktop = component.shadowRoot.querySelector(
|
|
74
|
+
".header .header-toggle-icon"
|
|
75
|
+
);
|
|
76
|
+
expect(toggleButtonDesktop).toBeNull();
|
|
77
|
+
|
|
78
|
+
expect(window.matchMedia).toBeCalledTimes(1);
|
|
79
|
+
expect(window.matchMedia).toBeCalledWith(EXPECTED_QUERY);
|
|
80
|
+
|
|
81
|
+
return expect(component).toBeAccessible();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("should accept a json string as trees", () => {
|
|
85
|
+
const expectedTitle = "Other super cool title";
|
|
86
|
+
const component = renderComponent({
|
|
87
|
+
header: expectedTitle,
|
|
88
|
+
trees: JSON.stringify(SAMPLE_TREES)
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(component.trees).toEqual(SAMPLE_TREES);
|
|
92
|
+
|
|
93
|
+
const container: HTMLElement =
|
|
94
|
+
component.shadowRoot.querySelector(".container");
|
|
95
|
+
expect(container).not.toBeNull();
|
|
96
|
+
expect(container.classList).not.toContain(COLLAPSED_CLASS);
|
|
97
|
+
|
|
98
|
+
const headerTitle: HTMLElement =
|
|
99
|
+
component.shadowRoot.querySelector(".header h2");
|
|
100
|
+
expect(headerTitle).not.toBeNull();
|
|
101
|
+
expect(headerTitle.textContent).toBe(expectedTitle);
|
|
102
|
+
|
|
103
|
+
const collapseButton: Button =
|
|
104
|
+
component.shadowRoot.querySelector("dx-button");
|
|
105
|
+
expect(collapseButton).not.toBeNull();
|
|
106
|
+
expect(collapseButton.iconSymbol).toBe("close_panel");
|
|
107
|
+
|
|
108
|
+
const searchBox: Input =
|
|
109
|
+
component.shadowRoot.querySelector("dx-input");
|
|
110
|
+
expect(searchBox).not.toBeNull();
|
|
111
|
+
expect(searchBox.value).toBe("");
|
|
112
|
+
|
|
113
|
+
const trees: Array<Tree> =
|
|
114
|
+
component.shadowRoot.querySelectorAll("dx-tree");
|
|
115
|
+
expect(trees).toHaveLength(SAMPLE_TREES.length);
|
|
116
|
+
trees.forEach((tree, index) =>
|
|
117
|
+
expect(tree.treeRoot).toHaveProperty(
|
|
118
|
+
"name",
|
|
119
|
+
SAMPLE_TREES[index].name
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return expect(component).toBeAccessible();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("should accept a value", () => {
|
|
127
|
+
const testValue = "introduction";
|
|
128
|
+
|
|
129
|
+
const component = renderComponent({
|
|
130
|
+
header: "Non visible title",
|
|
131
|
+
trees: SAMPLE_TREES,
|
|
132
|
+
value: testValue
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const trees: Array<Tree> =
|
|
136
|
+
component.shadowRoot.querySelectorAll("dx-tree");
|
|
137
|
+
|
|
138
|
+
expect(trees).toHaveLength(SAMPLE_TREES.length);
|
|
139
|
+
trees.forEach((tree) => expect(tree.value).toBe(testValue));
|
|
140
|
+
|
|
141
|
+
return expect(component).toBeAccessible();
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe("component interactions", () => {
|
|
146
|
+
it("should expand/collapse sidebar when toggle button is clicked", () => {
|
|
147
|
+
const component = renderComponent({
|
|
148
|
+
header: "Cool Title",
|
|
149
|
+
trees: SAMPLE_TREES
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const container: HTMLElement =
|
|
153
|
+
component.shadowRoot.querySelector(".container");
|
|
154
|
+
const toggleButton: HTMLElement =
|
|
155
|
+
component.shadowRoot.querySelector("dx-button");
|
|
156
|
+
toggleButton.click();
|
|
157
|
+
|
|
158
|
+
expect(track).toBeCalledTimes(1);
|
|
159
|
+
expect(track).toBeCalledWith(toggleButton, GTM_EVENT_NAME, {
|
|
160
|
+
sideNavAction: "collapse",
|
|
161
|
+
clickText: TOGGLE_BUTTON_LABEL
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
return Promise.resolve()
|
|
165
|
+
.then(() => {
|
|
166
|
+
expect(container.classList).toContain(COLLAPSED_CLASS);
|
|
167
|
+
|
|
168
|
+
const headerTitle: HTMLElement =
|
|
169
|
+
component.shadowRoot.querySelector(".header h2");
|
|
170
|
+
expect(headerTitle).toBeNull();
|
|
171
|
+
|
|
172
|
+
const expandButton: Button =
|
|
173
|
+
component.shadowRoot.querySelector("dx-button");
|
|
174
|
+
expect(expandButton).not.toBeNull();
|
|
175
|
+
|
|
176
|
+
const searchBox: Input =
|
|
177
|
+
component.shadowRoot.querySelector("dx-input");
|
|
178
|
+
expect(searchBox).toBeNull();
|
|
179
|
+
|
|
180
|
+
const trees: Tree =
|
|
181
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
182
|
+
expect(trees).toBeNull();
|
|
183
|
+
|
|
184
|
+
toggleButton.click();
|
|
185
|
+
|
|
186
|
+
expect(track).toBeCalledTimes(2);
|
|
187
|
+
expect(track).toHaveBeenLastCalledWith(
|
|
188
|
+
toggleButton,
|
|
189
|
+
GTM_EVENT_NAME,
|
|
190
|
+
{
|
|
191
|
+
sideNavAction: "expand",
|
|
192
|
+
clickText: TOGGLE_BUTTON_LABEL
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
})
|
|
196
|
+
.then(() => {
|
|
197
|
+
expect(container.classList).not.toContain(
|
|
198
|
+
COLLAPSED_CLASS
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const headerTitle: HTMLElement =
|
|
202
|
+
component.shadowRoot.querySelector(".header h2");
|
|
203
|
+
expect(headerTitle).not.toBeNull();
|
|
204
|
+
|
|
205
|
+
const searchBox: Input =
|
|
206
|
+
component.shadowRoot.querySelector("dx-input");
|
|
207
|
+
expect(searchBox).not.toBeNull();
|
|
208
|
+
|
|
209
|
+
const trees: Tree =
|
|
210
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
211
|
+
expect(trees).not.toBeNull();
|
|
212
|
+
|
|
213
|
+
return expect(component).toBeAccessible();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("should make hover effect on toggle button hover", () => {
|
|
218
|
+
const component = renderComponent({
|
|
219
|
+
header: "Cool Title",
|
|
220
|
+
trees: SAMPLE_TREES
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const container: HTMLElement =
|
|
224
|
+
component.shadowRoot.querySelector(".container");
|
|
225
|
+
const toggleButton: Button =
|
|
226
|
+
component.shadowRoot.querySelector("dx-button");
|
|
227
|
+
|
|
228
|
+
expect(container.classList).not.toContain(
|
|
229
|
+
"container-border-active"
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
toggleButton.dispatchEvent(new MouseEvent("mouseenter"));
|
|
233
|
+
|
|
234
|
+
return Promise.resolve()
|
|
235
|
+
.then(() => {
|
|
236
|
+
expect(container.classList).toContain(
|
|
237
|
+
"container-border-active"
|
|
238
|
+
);
|
|
239
|
+
toggleButton.dispatchEvent(
|
|
240
|
+
new MouseEvent("mouseleave")
|
|
241
|
+
);
|
|
242
|
+
})
|
|
243
|
+
.then(() => {
|
|
244
|
+
expect(container.classList).not.toContain(
|
|
245
|
+
"container-border-active"
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe("mobile", () => {
|
|
253
|
+
const oldMatchMedia = window.matchMedia;
|
|
254
|
+
|
|
255
|
+
beforeAll(() => {
|
|
256
|
+
window.matchMedia = createMediaMock(true);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
afterAll(() => {
|
|
260
|
+
window.matchMedia = oldMatchMedia;
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
describe("render", () => {
|
|
264
|
+
it("should render as collapsed", () => {
|
|
265
|
+
const expectedTitle = SAMPLE_TREES[0].label;
|
|
266
|
+
const component = renderComponent({
|
|
267
|
+
trees: SAMPLE_TREES
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const headerTitle: HTMLElement =
|
|
271
|
+
component.shadowRoot.querySelector(
|
|
272
|
+
".header span.header-title"
|
|
273
|
+
);
|
|
274
|
+
expect(headerTitle).not.toBeNull();
|
|
275
|
+
expect(headerTitle.textContent).toBe(expectedTitle);
|
|
276
|
+
|
|
277
|
+
const headerIcon = component.shadowRoot.querySelector(
|
|
278
|
+
".header .header-toggle-icon dx-icon"
|
|
279
|
+
);
|
|
280
|
+
expect(headerIcon).not.toBeNull();
|
|
281
|
+
|
|
282
|
+
const searchBox: Input =
|
|
283
|
+
component.shadowRoot.querySelector("dx-input");
|
|
284
|
+
expect(searchBox).toBeNull();
|
|
285
|
+
|
|
286
|
+
const trees: Tree =
|
|
287
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
288
|
+
expect(trees).toBeNull();
|
|
289
|
+
|
|
290
|
+
// Desktop specific elements should not render
|
|
291
|
+
const headerTitleDesktop = component.shadowRoot.querySelector(
|
|
292
|
+
".header h2.header-title"
|
|
293
|
+
);
|
|
294
|
+
expect(headerTitleDesktop).toBeNull();
|
|
295
|
+
|
|
296
|
+
const toggleButtonDesktop = component.shadowRoot.querySelector(
|
|
297
|
+
"dx-button.header-toggle-button"
|
|
298
|
+
);
|
|
299
|
+
expect(toggleButtonDesktop).toBeNull();
|
|
300
|
+
|
|
301
|
+
expect(window.matchMedia).toBeCalledTimes(1);
|
|
302
|
+
expect(window.matchMedia).toBeCalledWith(EXPECTED_QUERY);
|
|
303
|
+
|
|
304
|
+
return expect(component).toBeAccessible();
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("should ignore null values for trees api", () => {
|
|
308
|
+
const component = renderComponent({
|
|
309
|
+
header: "Cool Title",
|
|
310
|
+
trees: null
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const tree: Tree =
|
|
314
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
315
|
+
expect(tree).toBeNull();
|
|
316
|
+
|
|
317
|
+
const headerTitle: HTMLElement =
|
|
318
|
+
component.shadowRoot.querySelector(
|
|
319
|
+
".header span.header-title"
|
|
320
|
+
);
|
|
321
|
+
expect(headerTitle).not.toBeNull();
|
|
322
|
+
expect(headerTitle.textContent).toBe("");
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
describe("component interactions", () => {
|
|
327
|
+
it("should expand/collapse sidebar when mobile toggle is clicked", () => {
|
|
328
|
+
const expectedTitle = SAMPLE_TREES[0].label;
|
|
329
|
+
const component = renderComponent({
|
|
330
|
+
trees: SAMPLE_TREES
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
const container: HTMLElement =
|
|
334
|
+
component.shadowRoot.querySelector(".container");
|
|
335
|
+
const toggleDiv: HTMLElement =
|
|
336
|
+
component.shadowRoot.querySelector("div.header");
|
|
337
|
+
toggleDiv.click();
|
|
338
|
+
|
|
339
|
+
expect(track).toBeCalledTimes(1);
|
|
340
|
+
expect(track).toBeCalledWith(toggleDiv, GTM_EVENT_NAME, {
|
|
341
|
+
sideNavAction: "expand",
|
|
342
|
+
clickText: TOGGLE_BUTTON_LABEL
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
return Promise.resolve()
|
|
346
|
+
.then(() => {
|
|
347
|
+
expect(container.classList).not.toContain(
|
|
348
|
+
COLLAPSED_CLASS
|
|
349
|
+
);
|
|
350
|
+
const headerTitle: HTMLElement =
|
|
351
|
+
component.shadowRoot.querySelector(
|
|
352
|
+
".header span.header-title"
|
|
353
|
+
);
|
|
354
|
+
expect(headerTitle).not.toBeNull();
|
|
355
|
+
expect(headerTitle.textContent).toBe(expectedTitle);
|
|
356
|
+
|
|
357
|
+
const headerIcon = component.shadowRoot.querySelector(
|
|
358
|
+
".header .header-toggle-icon dx-icon"
|
|
359
|
+
);
|
|
360
|
+
expect(headerIcon).not.toBeNull();
|
|
361
|
+
|
|
362
|
+
const searchBox: Input =
|
|
363
|
+
component.shadowRoot.querySelector("dx-input");
|
|
364
|
+
expect(searchBox).not.toBeNull();
|
|
365
|
+
expect(searchBox.value).toBe("");
|
|
366
|
+
|
|
367
|
+
const trees: Array<Tree> =
|
|
368
|
+
component.shadowRoot.querySelectorAll("dx-tree");
|
|
369
|
+
expect(trees).toHaveLength(SAMPLE_TREES.length);
|
|
370
|
+
trees.forEach((tree, index) =>
|
|
371
|
+
expect(tree.treeRoot).toHaveProperty(
|
|
372
|
+
"name",
|
|
373
|
+
SAMPLE_TREES[index].name
|
|
374
|
+
)
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
// Desktop specific elements should not render
|
|
378
|
+
const headerTitleDesktop =
|
|
379
|
+
component.shadowRoot.querySelector(
|
|
380
|
+
".header h2.header-title"
|
|
381
|
+
);
|
|
382
|
+
expect(headerTitleDesktop).toBeNull();
|
|
383
|
+
|
|
384
|
+
const toggleButtonDesktop =
|
|
385
|
+
component.shadowRoot.querySelector(
|
|
386
|
+
"dx-button.header-toggle-button"
|
|
387
|
+
);
|
|
388
|
+
expect(toggleButtonDesktop).toBeNull();
|
|
389
|
+
|
|
390
|
+
toggleDiv.click();
|
|
391
|
+
|
|
392
|
+
expect(track).toBeCalledTimes(2);
|
|
393
|
+
expect(track).toHaveBeenLastCalledWith(
|
|
394
|
+
toggleDiv,
|
|
395
|
+
GTM_EVENT_NAME,
|
|
396
|
+
{
|
|
397
|
+
sideNavAction: "collapse",
|
|
398
|
+
clickText: TOGGLE_BUTTON_LABEL
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
})
|
|
402
|
+
.then(() => {
|
|
403
|
+
expect(container.classList).toContain(COLLAPSED_CLASS);
|
|
404
|
+
|
|
405
|
+
return expect(component).toBeAccessible();
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it("should update header with selected value label", () => {
|
|
410
|
+
const defaultTitle = SAMPLE_TREES[0].label;
|
|
411
|
+
const itemToSelect = SAMPLE_TREES[0].children![2];
|
|
412
|
+
const component = renderComponent({
|
|
413
|
+
trees: SAMPLE_TREES
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
const toggleDiv: HTMLElement =
|
|
417
|
+
component.shadowRoot.querySelector("div.header");
|
|
418
|
+
const headerTitle: HTMLElement = toggleDiv.querySelector(
|
|
419
|
+
".header span.header-title"
|
|
420
|
+
)!;
|
|
421
|
+
|
|
422
|
+
toggleDiv.click();
|
|
423
|
+
|
|
424
|
+
return Promise.resolve()
|
|
425
|
+
.then(() => {
|
|
426
|
+
expect(headerTitle).not.toBeNull();
|
|
427
|
+
expect(headerTitle.textContent).toBe(defaultTitle);
|
|
428
|
+
|
|
429
|
+
const tree: Tree =
|
|
430
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
431
|
+
tree.dispatchEvent(
|
|
432
|
+
new CustomEvent("select", {
|
|
433
|
+
detail: { name: itemToSelect.name }
|
|
434
|
+
})
|
|
435
|
+
);
|
|
436
|
+
})
|
|
437
|
+
.then(() => {
|
|
438
|
+
expect(headerTitle.textContent).toBe(
|
|
439
|
+
itemToSelect.label
|
|
440
|
+
);
|
|
441
|
+
return expect(component).toBeAccessible();
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
describe("general", () => {
|
|
448
|
+
describe("render", () => {
|
|
449
|
+
it("should accept a single tree element", () => {
|
|
450
|
+
const [expectedTree] = SAMPLE_TREES;
|
|
451
|
+
const component = renderComponent({
|
|
452
|
+
header: "Cool Title",
|
|
453
|
+
trees: expectedTree
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
const trees: Array<Tree> =
|
|
457
|
+
component.shadowRoot.querySelectorAll("dx-tree");
|
|
458
|
+
expect(trees).toHaveLength(1);
|
|
459
|
+
|
|
460
|
+
const [singleTree] = trees;
|
|
461
|
+
expect(singleTree.treeRoot).toHaveProperty(
|
|
462
|
+
"name",
|
|
463
|
+
expectedTree.name
|
|
464
|
+
);
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
describe("component interactions", () => {
|
|
469
|
+
it("should handle onselect event fired from dx-tree", () => {
|
|
470
|
+
const mockSelect = jest.fn();
|
|
471
|
+
const expectedName = "test_name";
|
|
472
|
+
|
|
473
|
+
const component = renderComponent({
|
|
474
|
+
header: "Cool Title",
|
|
475
|
+
trees: SAMPLE_TREES
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
component.addEventListener("select", mockSelect);
|
|
479
|
+
|
|
480
|
+
const tree: Tree =
|
|
481
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
482
|
+
expect(tree).not.toBeNull();
|
|
483
|
+
expect(tree.value).toBeUndefined();
|
|
484
|
+
|
|
485
|
+
tree.dispatchEvent(
|
|
486
|
+
new CustomEvent("select", {
|
|
487
|
+
detail: { name: expectedName },
|
|
488
|
+
composed: true,
|
|
489
|
+
bubbles: true
|
|
490
|
+
})
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
return Promise.resolve().then(() => {
|
|
494
|
+
expect(tree.value).toBe(expectedName);
|
|
495
|
+
expect(mockSelect).toBeCalledTimes(1);
|
|
496
|
+
const { detail, composed, bubbles } =
|
|
497
|
+
mockSelect.mock.calls[0][0];
|
|
498
|
+
expect(detail).toEqual({
|
|
499
|
+
name: expectedName
|
|
500
|
+
});
|
|
501
|
+
expect(composed).toBe(true);
|
|
502
|
+
expect(bubbles).toBe(true);
|
|
503
|
+
|
|
504
|
+
return expect(component).toBeAccessible();
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
describe("search", () => {
|
|
510
|
+
beforeAll(() => {
|
|
511
|
+
jest.useFakeTimers();
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it("should filter trees element label based on the search text value", () => {
|
|
515
|
+
const testSearchText = " token ";
|
|
516
|
+
const component = renderComponent({
|
|
517
|
+
header: "Cool Title",
|
|
518
|
+
trees: SAMPLE_TREES
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
const searchBox: Input =
|
|
522
|
+
component.shadowRoot.querySelector("dx-input");
|
|
523
|
+
searchBox.dispatchEvent(
|
|
524
|
+
new CustomEvent("change", {
|
|
525
|
+
detail: testSearchText
|
|
526
|
+
})
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
jest.runAllTimers();
|
|
530
|
+
|
|
531
|
+
return Promise.resolve().then(() => {
|
|
532
|
+
expect(searchBox.value).toBe(testSearchText);
|
|
533
|
+
|
|
534
|
+
const trees: Array<Tree> =
|
|
535
|
+
component.shadowRoot.querySelectorAll("dx-tree");
|
|
536
|
+
expect(trees).toHaveLength(1);
|
|
537
|
+
const treeNode = trees[0].treeRoot as TreeNode;
|
|
538
|
+
expect(treeNode.name).toBe(SAMPLE_TREES[0].name);
|
|
539
|
+
expect(treeNode.isExpanded).toBe(true);
|
|
540
|
+
expect(treeNode.children).toHaveLength(1);
|
|
541
|
+
expect(treeNode.children![0].name).toMatch(
|
|
542
|
+
testSearchText.trim()
|
|
543
|
+
);
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it("should not display anything if search text does not match", () => {
|
|
548
|
+
const testSearchText = "this does not exist";
|
|
549
|
+
const component = renderComponent({
|
|
550
|
+
header: "Cool Title",
|
|
551
|
+
trees: SAMPLE_TREES
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
const searchBox: Input =
|
|
555
|
+
component.shadowRoot.querySelector("dx-input");
|
|
556
|
+
searchBox.dispatchEvent(
|
|
557
|
+
new CustomEvent("change", {
|
|
558
|
+
detail: testSearchText
|
|
559
|
+
})
|
|
560
|
+
);
|
|
561
|
+
|
|
562
|
+
jest.runAllTimers();
|
|
563
|
+
|
|
564
|
+
return Promise.resolve().then(() => {
|
|
565
|
+
expect(searchBox.value).toBe(testSearchText);
|
|
566
|
+
|
|
567
|
+
const tree: Tree =
|
|
568
|
+
component.shadowRoot.querySelector("dx-tree");
|
|
569
|
+
expect(tree).toBeNull();
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
});
|