@khanacademy/wonder-blocks-tooltip 2.4.1 → 2.4.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.
@@ -1,379 +0,0 @@
1
- import * as React from "react";
2
- import * as ReactDOM from "react-dom";
3
- import {render, screen} from "@testing-library/react";
4
- import {userEvent} from "@testing-library/user-event";
5
-
6
- import {View} from "@khanacademy/wonder-blocks-core";
7
-
8
- import Tooltip from "../tooltip";
9
-
10
- const mockIDENTIFIER = "mock-identifier";
11
- jest.mock("@khanacademy/wonder-blocks-core", () => {
12
- const Core = jest.requireActual("@khanacademy/wonder-blocks-core");
13
- // We want all of Core to be the regular thing except for UniqueIDProvider
14
- return {
15
- ...Core,
16
- UniqueIDProvider: (props: any) =>
17
- // NOTE(kevinb): We aren't actually access the DOM here. The logic
18
- // used by this lint rule to determine DOM access could be more
19
- // precise.
20
- // eslint-disable-next-line testing-library/no-node-access
21
- props.children({
22
- get: () => mockIDENTIFIER,
23
- }),
24
- };
25
- });
26
-
27
- describe("Tooltip", () => {
28
- beforeEach(() => {
29
- jest.clearAllMocks();
30
- jest.clearAllTimers();
31
- jest.useFakeTimers();
32
- });
33
-
34
- describe("basic operations", () => {
35
- it("should not show the tooltip to being with", async () => {
36
- // Arrange
37
- render(
38
- <View>
39
- <Tooltip title="Title" content="Content">
40
- <View>Anchor</View>
41
- </Tooltip>
42
- </View>,
43
- );
44
-
45
- // Act
46
- const tooltip = screen.queryByRole("tooltip");
47
-
48
- // Assert
49
- expect(tooltip).not.toBeInTheDocument();
50
- });
51
-
52
- it("should show the tooltip on hover", async () => {
53
- // Arrange
54
- const ue = userEvent.setup({
55
- advanceTimers: jest.advanceTimersByTime,
56
- });
57
- render(
58
- <View>
59
- <Tooltip title="Title" content="Content">
60
- <View>Anchor</View>
61
- </Tooltip>
62
- </View>,
63
- );
64
-
65
- const node = await screen.findByText("Anchor");
66
- await ue.hover(node);
67
- jest.runOnlyPendingTimers();
68
-
69
- // Act
70
- const tooltip = await screen.findByRole("tooltip");
71
-
72
- // Assert
73
- expect(tooltip).toBeInTheDocument();
74
- });
75
-
76
- it("should hide the tooltip on unhover", async () => {
77
- // Arrange
78
- const ue = userEvent.setup({
79
- advanceTimers: jest.advanceTimersByTime,
80
- });
81
- render(
82
- <View>
83
- <Tooltip title="Title" content="Content">
84
- <View>Anchor</View>
85
- </Tooltip>
86
- </View>,
87
- );
88
-
89
- const node = await screen.findByText("Anchor");
90
- await ue.hover(node);
91
- jest.runOnlyPendingTimers();
92
- await ue.unhover(node);
93
- jest.runOnlyPendingTimers();
94
-
95
- // Act
96
- const tooltip = screen.queryByRole("tooltip");
97
-
98
- // Assert
99
- expect(tooltip).not.toBeInTheDocument();
100
- });
101
-
102
- it("should work when the anchor is text", async () => {
103
- // Arrange
104
- const ue = userEvent.setup({
105
- advanceTimers: jest.advanceTimersByTime,
106
- });
107
- render(
108
- <View>
109
- <Tooltip title="Title" content="Content">
110
- Anchor
111
- </Tooltip>
112
- </View>,
113
- );
114
-
115
- const node = await screen.findByText("Anchor");
116
- await ue.hover(node);
117
- jest.runOnlyPendingTimers();
118
-
119
- // Act
120
- const tooltip = await screen.findByRole("tooltip");
121
-
122
- // Assert
123
- expect(tooltip).toBeInTheDocument();
124
- });
125
-
126
- it("should have a background color if one is set", async () => {
127
- // Arrange
128
- render(
129
- <View>
130
- <Tooltip
131
- title="Title"
132
- content="Content"
133
- backgroundColor="blue"
134
- opened={true}
135
- >
136
- Anchor
137
- </Tooltip>
138
- </View>,
139
- );
140
-
141
- // Act
142
- const tooltipContent = await screen.findByRole("tooltip");
143
- // eslint-disable-next-line testing-library/no-node-access
144
- const innerTooltipContentView = tooltipContent.firstChild;
145
- expect(innerTooltipContentView).toBeInTheDocument();
146
-
147
- // Assert
148
- expect(innerTooltipContentView).toHaveStyle(
149
- "background-color: rgb(24, 101, 242)",
150
- );
151
- });
152
- });
153
-
154
- describe("accessibility", () => {
155
- test("no id, sets identifier of TooltipBubble with UniqueIDProvider", async () => {
156
- // Arrange
157
- const ue = userEvent.setup({
158
- advanceTimers: jest.advanceTimersByTime,
159
- });
160
- render(
161
- <View>
162
- <Tooltip title="Title" content="Content">
163
- <View>Anchor</View>
164
- </Tooltip>
165
- </View>,
166
- );
167
- const node = await screen.findByText("Anchor");
168
- await ue.hover(node);
169
- jest.runOnlyPendingTimers();
170
-
171
- // Act
172
- // eslint-disable-next-line testing-library/no-node-access
173
- const result = document.querySelector("#" + mockIDENTIFIER);
174
-
175
- // Assert
176
- expect(result).toBeInTheDocument();
177
- });
178
-
179
- test("custom id, sets identifier of TooltipBubble", async () => {
180
- // Arrange
181
- const ue = userEvent.setup({
182
- advanceTimers: jest.advanceTimersByTime,
183
- });
184
- render(
185
- <View>
186
- <Tooltip id="tooltip-1" title="Title" content="Content">
187
- <View>Anchor</View>
188
- </Tooltip>
189
- </View>,
190
- );
191
- const node = await screen.findByText("Anchor");
192
- await ue.hover(node);
193
- jest.runOnlyPendingTimers();
194
-
195
- // Act
196
- // eslint-disable-next-line testing-library/no-node-access
197
- const result = document.querySelector("#tooltip-1");
198
-
199
- // Assert
200
- expect(result).toBeInTheDocument();
201
- });
202
-
203
- describe("text-only anchor", () => {
204
- test("wraps with element", async () => {
205
- // Arrange
206
- render(
207
- <View>
208
- <Tooltip content="Content">Anchor</Tooltip>
209
- </View>,
210
- );
211
-
212
- // Act
213
- const result = await screen.findByText("Anchor");
214
-
215
- // Assert
216
- expect(result).toBeInstanceOf(HTMLSpanElement);
217
- expect(result.innerHTML).toBe("Anchor");
218
- });
219
-
220
- test("id provided, does not attach aria-describedby", async () => {
221
- // Arrange
222
- render(
223
- <View>
224
- <Tooltip id="tooltip-2" content="Content">
225
- Anchor
226
- </Tooltip>
227
- </View>,
228
- );
229
- const node = await screen.findByText("Anchor");
230
-
231
- // Act
232
- const result = node.getAttribute("aria-describedby");
233
-
234
- // Assert
235
- expect(result).toBeNull();
236
- });
237
-
238
- test("no id provided, attaches aria-describedby", async () => {
239
- // Arrange
240
- render(
241
- <View>
242
- <Tooltip content="Content">Anchor</Tooltip>
243
- </View>,
244
- );
245
- const node = await screen.findByText("Anchor");
246
-
247
- // Act
248
-
249
- // Assert
250
- expect(node).toHaveAttribute(
251
- "aria-describedby",
252
- mockIDENTIFIER,
253
- );
254
- });
255
- });
256
-
257
- describe("element anchor", () => {
258
- test("does not wrap", async () => {
259
- // Arrange
260
- const anchor = (
261
- <View>
262
- <View>Anchor</View>
263
- </View>
264
- );
265
- const ref = await new Promise((resolve: any) => {
266
- render(
267
- <View>
268
- <Tooltip ref={resolve} content="Content">
269
- {anchor}
270
- </Tooltip>
271
- </View>,
272
- );
273
- });
274
-
275
- // Act
276
- // @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
277
- const result = ReactDOM.findDOMNode(ref) as any;
278
-
279
- // Assert
280
- expect(result).toBeInstanceOf(HTMLDivElement);
281
- expect(result.innerHTML).not.toBe("Anchor");
282
- // eslint-disable-next-line testing-library/no-node-access
283
- expect(result.children[0].innerHTML).toBe("Anchor");
284
- });
285
-
286
- test("id provided, does not attach aria-describedby", async () => {
287
- // Arrange
288
- const anchor = (
289
- <View>
290
- <View>Anchor</View>
291
- </View>
292
- );
293
- const ref = await new Promise((resolve: any) => {
294
- render(
295
- <View>
296
- <Tooltip
297
- id="tooltip-3"
298
- ref={resolve}
299
- content="Content"
300
- >
301
- {anchor}
302
- </Tooltip>
303
- </View>,
304
- );
305
- });
306
- // @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
307
- const node = ReactDOM.findDOMNode(ref) as any;
308
-
309
- // Act
310
- const result = node.getAttribute("aria-describedby");
311
-
312
- // Assert
313
- expect(result).toBeNull();
314
- });
315
-
316
- test("no id provided, attaches aria-describedby", async () => {
317
- // Arrange
318
- const anchor = (
319
- <View>
320
- <View>Anchor</View>
321
- </View>
322
- );
323
- const ref = await new Promise((resolve: any) => {
324
- render(
325
- <View>
326
- <Tooltip ref={resolve} content="Content">
327
- {anchor}
328
- </Tooltip>
329
- </View>,
330
- );
331
- });
332
- // @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
333
- const node = ReactDOM.findDOMNode(ref) as any;
334
-
335
- // Act
336
- const result = node.getAttribute("aria-describedby");
337
-
338
- // Assert
339
- expect(result).toBe(mockIDENTIFIER);
340
- });
341
- });
342
- });
343
-
344
- describe("Controlled", () => {
345
- test("can be opened programmatically", async () => {
346
- // Arrange
347
- render(
348
- <View>
349
- <Tooltip id="tooltip" content="Content" opened={true}>
350
- <View>Anchor</View>
351
- </Tooltip>
352
- </View>,
353
- );
354
-
355
- // Act
356
- jest.runOnlyPendingTimers();
357
-
358
- // Assert
359
- expect(await screen.findByText("Content")).toBeInTheDocument();
360
- });
361
-
362
- test("can be closed programmatically", async () => {
363
- // Arrange
364
- render(
365
- <View>
366
- <Tooltip id="tooltip" content="Content" opened={false}>
367
- <View>Anchor</View>
368
- </Tooltip>
369
- </View>,
370
- );
371
-
372
- // Act
373
- jest.runOnlyPendingTimers();
374
-
375
- // Assert
376
- expect(screen.queryByText("Content")).not.toBeInTheDocument();
377
- });
378
- });
379
- });