@player-ui/react 0.12.0 → 0.12.1-next.0

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,7 +1,14 @@
1
- import { test, expect, vitest } from "vitest";
1
+ import { test, expect, vitest, describe, beforeEach } from "vitest";
2
2
  import React, { Suspense } from "react";
3
3
  import { makeFlow } from "@player-ui/make-flow";
4
- import { render, act, configure, waitFor } from "@testing-library/react";
4
+ import {
5
+ render,
6
+ act,
7
+ configure,
8
+ waitFor,
9
+ screen,
10
+ } from "@testing-library/react";
11
+ import { userEvent } from "@testing-library/user-event";
5
12
  import {
6
13
  MetricsCorePlugin,
7
14
  RequestTimeWebPlugin,
@@ -23,116 +30,103 @@ vitest.mock("@player-ui/metrics-plugin", async () => {
23
30
 
24
31
  configure({ testIdAttribute: "id" });
25
32
 
26
- const testOptions = { legacyRoot: true };
33
+ describe.each([
34
+ { legacyRoot: true, version: 17 },
35
+ { legacyRoot: false, version: 18 },
36
+ ])("ManagedPlayer with React $version", ({ legacyRoot }) => {
37
+ beforeEach(() => {
38
+ vitest.clearAllMocks();
39
+ });
27
40
 
28
- test("requestTime should be available", async () => {
29
- const manager: FlowManager = {
30
- next: vitest
31
- .fn()
32
- .mockReturnValueOnce(
33
- Promise.resolve({
34
- value: makeFlow({
35
- id: "flow-1",
36
- type: "collection",
37
- values: [
38
- {
39
- asset: {
40
- id: "action",
41
- type: "action",
42
- value: "Next",
43
- label: "Continue",
41
+ test("requestTime should be available", async () => {
42
+ const manager: FlowManager = {
43
+ next: vitest
44
+ .fn()
45
+ .mockReturnValueOnce(
46
+ Promise.resolve({
47
+ value: makeFlow({
48
+ id: "flow-1",
49
+ type: "collection",
50
+ values: [
51
+ {
52
+ asset: {
53
+ id: "action",
54
+ type: "action",
55
+ value: "Next",
56
+ label: "Continue",
57
+ },
44
58
  },
45
- },
46
- ],
59
+ ],
60
+ }),
47
61
  }),
48
- }),
49
- )
50
- .mockReturnValueOnce(
51
- Promise.resolve({
52
- value: makeFlow({
53
- id: "flow-2",
54
- type: "collection",
55
- values: [
56
- {
57
- asset: {
58
- id: "action",
59
- type: "action",
60
- value: "Next",
61
- label: "Continue",
62
+ )
63
+ .mockReturnValueOnce(
64
+ Promise.resolve({
65
+ value: makeFlow({
66
+ id: "flow-2",
67
+ type: "collection",
68
+ values: [
69
+ {
70
+ asset: {
71
+ id: "action",
72
+ type: "action",
73
+ value: "Next",
74
+ label: "Continue",
75
+ },
62
76
  },
63
- },
64
- ],
77
+ ],
78
+ }),
65
79
  }),
66
- }),
67
- )
68
- .mockReturnValue(Promise.resolve({ done: true })),
69
- };
80
+ )
81
+ .mockReturnValue(Promise.resolve({ done: true })),
82
+ };
70
83
 
71
- const onComplete = vitest.fn();
72
- const onError = vitest.fn();
73
-
74
- const container = render(
75
- <Suspense fallback="loading">
76
- <ManagedPlayer
77
- manager={manager}
78
- plugins={[new SimpleAssetPlugin(), new MetricsCorePlugin()]}
79
- onComplete={onComplete}
80
- onError={onError}
81
- />
82
- </Suspense>,
83
- testOptions,
84
- );
85
-
86
- expect(manager.next).toBeCalledWith(undefined);
87
- const view = await container.findByTestId("flow-1");
88
- expect(view).toBeInTheDocument();
89
-
90
- await act(async () => {
91
- const nextButton = await container.findByText("Continue");
92
- nextButton.click();
93
- });
84
+ const onComplete = vitest.fn();
85
+ const onError = vitest.fn();
86
+
87
+ const container = render(
88
+ <Suspense fallback="loading">
89
+ <ManagedPlayer
90
+ manager={manager}
91
+ plugins={[new SimpleAssetPlugin(), new MetricsCorePlugin()]}
92
+ onComplete={onComplete}
93
+ onError={onError}
94
+ />
95
+ </Suspense>,
96
+ { legacyRoot },
97
+ );
98
+
99
+ expect(manager.next).toBeCalledWith(undefined);
100
+ const view = await container.findByTestId("flow-1");
101
+ expect(view).toBeInTheDocument();
94
102
 
95
- expect(manager.next).toBeCalledTimes(2);
103
+ await act(async () => {
104
+ const nextButton = await container.findByText("Continue");
105
+ nextButton.click();
106
+ });
96
107
 
97
- const view2 = await container.findByTestId("flow-2");
98
- expect(view2).toBeInTheDocument();
108
+ expect(manager.next).toBeCalledTimes(2);
99
109
 
100
- await act(async () => {
101
- const nextButton = await container.findByText("Continue");
102
- nextButton.click();
110
+ const view2 = await container.findByTestId("flow-2");
111
+ expect(view2).toBeInTheDocument();
112
+
113
+ await act(async () => {
114
+ const nextButton = await container.findByText("Continue");
115
+ nextButton.click();
116
+ });
117
+ const getRequestTime = (RequestTimeWebPlugin as any).mock.calls[0][0];
118
+ expect(getRequestTime()).toBeDefined();
119
+ expect(onComplete).toBeCalled();
103
120
  });
104
- const getRequestTime = (RequestTimeWebPlugin as any).mock.calls[0][0];
105
- expect(getRequestTime()).toBeDefined();
106
- expect(onComplete).toBeCalled();
107
- });
108
121
 
109
- test("handles dummy flows", async () => {
110
- const manager: FlowManager = {
111
- next: vitest
112
- .fn()
113
- .mockReturnValueOnce(
114
- Promise.resolve({
115
- value: makeFlow({
116
- id: "flow-1",
117
- type: "collection",
118
- values: [
119
- {
120
- asset: {
121
- id: "action",
122
- type: "action",
123
- value: "Next",
124
- label: "Continue",
125
- },
126
- },
127
- ],
128
- }),
129
- }),
130
- )
131
- .mockReturnValueOnce(
132
- Promise.resolve({
133
- value: {
134
- ...makeFlow({
135
- id: "flow-2",
122
+ test("handles dummy flows", async () => {
123
+ const manager: FlowManager = {
124
+ next: vitest
125
+ .fn()
126
+ .mockReturnValueOnce(
127
+ Promise.resolve({
128
+ value: makeFlow({
129
+ id: "flow-1",
136
130
  type: "collection",
137
131
  values: [
138
132
  {
@@ -145,298 +139,309 @@ test("handles dummy flows", async () => {
145
139
  },
146
140
  ],
147
141
  }),
148
- data: { foo: "bar" },
149
- },
150
- }),
151
- )
152
- .mockReturnValue(Promise.resolve({ done: true })),
153
- };
142
+ }),
143
+ )
144
+ .mockReturnValueOnce(
145
+ Promise.resolve({
146
+ value: {
147
+ ...makeFlow({
148
+ id: "flow-2",
149
+ type: "collection",
150
+ values: [
151
+ {
152
+ asset: {
153
+ id: "action",
154
+ type: "action",
155
+ value: "Next",
156
+ label: "Continue",
157
+ },
158
+ },
159
+ ],
160
+ }),
161
+ data: { foo: "bar" },
162
+ },
163
+ }),
164
+ )
165
+ .mockReturnValue(Promise.resolve({ done: true })),
166
+ };
154
167
 
155
- const onComplete = vitest.fn();
156
- const onError = vitest.fn();
157
-
158
- const screen = render(
159
- <Suspense fallback="loading">
160
- <ManagedPlayer
161
- manager={manager}
162
- plugins={[new SimpleAssetPlugin()]}
163
- onComplete={onComplete}
164
- onError={onError}
165
- />
166
- </Suspense>,
167
- testOptions,
168
- );
169
-
170
- expect(manager.next).toBeCalledWith(undefined);
171
- const view = await screen.findByTestId("flow-1");
172
- expect(view).toBeInTheDocument();
173
-
174
- await act(async () => {
175
- const nextButton = await screen.findByText("Continue");
176
- nextButton.click();
177
- });
168
+ const onComplete = vitest.fn();
169
+ const onError = vitest.fn();
170
+
171
+ const screen = render(
172
+ <Suspense fallback="loading">
173
+ <ManagedPlayer
174
+ manager={manager}
175
+ plugins={[new SimpleAssetPlugin()]}
176
+ onComplete={onComplete}
177
+ onError={onError}
178
+ />
179
+ </Suspense>,
180
+ { legacyRoot },
181
+ );
182
+
183
+ expect(manager.next).toBeCalledWith(undefined);
184
+ const view = await screen.findByTestId("flow-1");
185
+ expect(view).toBeInTheDocument();
186
+
187
+ await act(async () => {
188
+ const nextButton = await screen.findByText("Continue");
189
+ nextButton.click();
190
+ });
178
191
 
179
- expect(manager.next).toBeCalledTimes(2);
192
+ expect(manager.next).toBeCalledTimes(2);
180
193
 
181
- const view2 = await screen.findByTestId("flow-2");
182
- expect(view2).toBeInTheDocument();
194
+ const view2 = await screen.findByTestId("flow-2");
195
+ expect(view2).toBeInTheDocument();
183
196
 
184
- await act(async () => {
185
- const nextButton = await screen.findByText("Continue");
186
- nextButton.click();
197
+ await act(async () => {
198
+ const nextButton = await screen.findByText("Continue");
199
+ nextButton.click();
200
+ });
201
+ expect(onComplete).toBeCalledWith(
202
+ expect.objectContaining({
203
+ status: "completed",
204
+ data: { foo: "bar" },
205
+ }),
206
+ );
187
207
  });
188
- expect(onComplete).toBeCalledWith(
189
- expect.objectContaining({
190
- status: "completed",
191
- data: { foo: "bar" },
192
- }),
193
- );
194
- });
195
208
 
196
- test("handles FlowManager error", async () => {
197
- const manager: FlowManager = {
198
- next: vitest
199
- .fn()
200
- .mockReturnValueOnce(
201
- Promise.resolve({
202
- value: makeFlow({
203
- id: "flow-1",
204
- type: "collection",
205
- values: [
206
- {
207
- asset: {
208
- id: "action",
209
- type: "action",
210
- value: "Next",
211
- label: "Continue",
209
+ test("handles FlowManager error", async () => {
210
+ const user = userEvent.setup();
211
+ const manager: FlowManager = {
212
+ next: vitest
213
+ .fn()
214
+ .mockReturnValueOnce(
215
+ Promise.resolve({
216
+ value: makeFlow({
217
+ id: "flow-1",
218
+ type: "collection",
219
+ values: [
220
+ {
221
+ asset: {
222
+ id: "action",
223
+ type: "action",
224
+ value: "Next",
225
+ label: "Continue",
226
+ },
212
227
  },
213
- },
214
- ],
228
+ ],
229
+ }),
215
230
  }),
216
- }),
217
- )
218
- .mockImplementationOnce(() => {
219
- throw new Error();
220
- })
221
- .mockImplementationOnce(() => {
222
- throw new Error();
223
- })
224
- .mockReturnValue(Promise.resolve({ done: true })),
225
- };
231
+ )
232
+ .mockImplementationOnce(() => {
233
+ throw new Error();
234
+ })
235
+ .mockImplementationOnce(() => {
236
+ throw new Error();
237
+ })
238
+ .mockReturnValue(Promise.resolve({ done: true })),
239
+ };
240
+
241
+ const onComplete = vitest.fn();
242
+ const onError = vitest.fn();
243
+ /**
244
+ *
245
+ */
246
+ const MyFallback = (props: FallbackProps) => (
247
+ <div>
248
+ <button type="button" onClick={props?.retry}>
249
+ Retry
250
+ </button>
251
+ <button type="button" onClick={props?.reset}>
252
+ Reset
253
+ </button>
254
+ </div>
255
+ );
226
256
 
227
- const onComplete = vitest.fn();
228
- const onError = vitest.fn();
229
- /**
230
- *
231
- */
232
- const MyFallback = (props: FallbackProps) => (
233
- <div>
234
- <button type="button" onClick={props?.retry}>
235
- Retry
236
- </button>
237
- <button type="button" onClick={props?.reset}>
238
- Reset
239
- </button>
240
- </div>
241
- );
242
-
243
- const screen = render(
244
- <Suspense fallback="loading">
245
- <ManagedPlayer
246
- manager={manager}
247
- plugins={[new SimpleAssetPlugin()]}
248
- fallbackComponent={MyFallback}
249
- onComplete={onComplete}
250
- onError={onError}
251
- />
252
- </Suspense>,
253
- testOptions,
254
- );
255
-
256
- expect(manager.next).toBeCalledWith(undefined);
257
- const view = await screen.findByTestId("flow-1");
258
- expect(view).toBeInTheDocument();
259
-
260
- await act(async () => {
261
- const nextButton = await screen.findByText("Continue");
262
- nextButton.click();
263
- });
257
+ const screen = render(
258
+ <Suspense fallback="loading">
259
+ <ManagedPlayer
260
+ manager={manager}
261
+ plugins={[new SimpleAssetPlugin()]}
262
+ fallbackComponent={MyFallback}
263
+ onComplete={onComplete}
264
+ onError={onError}
265
+ />
266
+ </Suspense>,
267
+ { legacyRoot },
268
+ );
264
269
 
265
- expect(manager.next).toBeCalledTimes(2);
270
+ expect(manager.next).toBeCalledWith(undefined);
271
+ const view = await screen.findByTestId("flow-1");
272
+ expect(view).toBeInTheDocument();
266
273
 
267
- await act(async () => {
268
- const nextButton = await screen.findByText("Retry");
269
- nextButton.click();
270
- });
274
+ let nextButton = await screen.findByText("Continue");
275
+ await user.click(nextButton);
271
276
 
272
- expect(manager.next).toBeCalledTimes(3);
277
+ expect(manager.next).toBeCalledTimes(2);
273
278
 
274
- await act(async () => {
275
- const nextButton = await screen.findByText("Reset");
276
- nextButton.click();
277
- });
279
+ nextButton = await screen.findByText("Retry");
280
+ await user.click(nextButton);
278
281
 
279
- expect(manager.next).toBeCalledTimes(4);
280
- expect(onError).toBeCalledTimes(2);
281
- expect(onComplete).toBeCalled();
282
- });
282
+ expect(manager.next).toBeCalledTimes(3);
283
283
 
284
- test("handles flow error", async () => {
285
- const manager: FlowManager = {
286
- next: vitest
287
- .fn()
288
- .mockReturnValueOnce(
289
- Promise.resolve({
290
- value: makeFlow({
291
- id: "flow-1",
292
- type: "collection",
293
- values: [
294
- {
295
- asset: {
296
- id: "action",
297
- type: "action",
298
- value: "Next",
299
- label: "Continue",
284
+ nextButton = await screen.findByText("Reset");
285
+ await user.click(nextButton);
286
+
287
+ expect(manager.next).toBeCalledTimes(4);
288
+ expect(onError).toBeCalledTimes(2);
289
+ expect(onComplete).toBeCalled();
290
+ });
291
+
292
+ test("handles flow error", async () => {
293
+ const manager: FlowManager = {
294
+ next: vitest
295
+ .fn()
296
+ .mockReturnValueOnce(
297
+ Promise.resolve({
298
+ value: makeFlow({
299
+ id: "flow-1",
300
+ type: "collection",
301
+ values: [
302
+ {
303
+ asset: {
304
+ id: "action",
305
+ type: "action",
306
+ value: "Next",
307
+ label: "Continue",
308
+ },
300
309
  },
301
- },
302
- ],
310
+ ],
311
+ }),
303
312
  }),
304
- }),
305
- )
306
- .mockReturnValueOnce(
307
- Promise.resolve({
308
- value: makeFlow({
309
- id: "flow-2",
310
- type: "action",
311
- exp: "err(",
312
- label: "Error",
313
+ )
314
+ .mockReturnValueOnce(
315
+ Promise.resolve({
316
+ value: makeFlow({
317
+ id: "flow-2",
318
+ type: "action",
319
+ exp: "err(",
320
+ label: "Error",
321
+ }),
313
322
  }),
314
- }),
315
- )
316
- .mockReturnValueOnce(
317
- Promise.resolve({
318
- value: makeFlow({
319
- id: "flow-2",
320
- type: "action",
321
- exp: "err(",
322
- label: "Error",
323
+ )
324
+ .mockReturnValueOnce(
325
+ Promise.resolve({
326
+ value: makeFlow({
327
+ id: "flow-2",
328
+ type: "action",
329
+ exp: "err(",
330
+ label: "Error",
331
+ }),
323
332
  }),
324
- }),
325
- )
326
- .mockReturnValue(Promise.resolve({ done: true })),
327
- };
328
- const onComplete = vitest.fn();
329
- const onError = vitest.fn();
330
-
331
- /**
332
- *
333
- */
334
- const MyFallback = (props: FallbackProps) => (
335
- <div>
336
- <button type="button" onClick={props?.retry}>
337
- Retry
338
- </button>
339
- <button type="button" onClick={props?.reset}>
340
- Reset
341
- </button>
342
- </div>
343
- );
344
-
345
- const screen = render(
346
- <Suspense fallback="loading">
347
- <ManagedPlayer
348
- manager={manager}
349
- plugins={[new SimpleAssetPlugin()]}
350
- fallbackComponent={MyFallback}
351
- onComplete={onComplete}
352
- onError={onError}
353
- />
354
- </Suspense>,
355
- testOptions,
356
- );
357
-
358
- expect(manager.next).toBeCalledWith(undefined);
359
- const view = await screen.findByTestId("flow-1");
360
- expect(view).toBeInTheDocument();
361
-
362
- await act(async () => {
363
- const nextButton = await screen.findByText("Continue");
364
- nextButton.click();
365
- });
333
+ )
334
+ .mockReturnValue(Promise.resolve({ done: true })),
335
+ };
336
+ const onComplete = vitest.fn();
337
+ const onError = vitest.fn();
338
+
339
+ /**
340
+ *
341
+ */
342
+ const MyFallback = (props: FallbackProps) => (
343
+ <div>
344
+ <button type="button" onClick={props?.retry}>
345
+ Retry
346
+ </button>
347
+ <button type="button" onClick={props?.reset}>
348
+ Reset
349
+ </button>
350
+ </div>
351
+ );
366
352
 
367
- await waitFor(() => expect(manager.next).toBeCalledTimes(2));
353
+ const screen = render(
354
+ <Suspense fallback="loading">
355
+ <ManagedPlayer
356
+ manager={manager}
357
+ plugins={[new SimpleAssetPlugin()]}
358
+ fallbackComponent={MyFallback}
359
+ onComplete={onComplete}
360
+ onError={onError}
361
+ />
362
+ </Suspense>,
363
+ { legacyRoot },
364
+ );
368
365
 
369
- const view2 = await screen.findByTestId("flow-2");
370
- expect(view2).toBeInTheDocument();
366
+ expect(manager.next).toBeCalledWith(undefined);
367
+ const view = await screen.findByTestId("flow-1");
368
+ expect(view).toBeInTheDocument();
371
369
 
372
- await act(async () => {
373
- view2.click();
374
- });
370
+ await act(async () => {
371
+ const nextButton = await screen.findByText("Continue");
372
+ nextButton.click();
373
+ });
375
374
 
376
- const retryButton = await screen.findByText("Retry");
377
- expect(retryButton).toBeInTheDocument();
375
+ await waitFor(() => expect(manager.next).toBeCalledTimes(2));
378
376
 
379
- await act(async () => {
380
- retryButton.click();
381
- });
377
+ const view2 = await screen.findByTestId("flow-2");
378
+ expect(view2).toBeInTheDocument();
382
379
 
383
- expect(manager.next).toBeCalledTimes(3);
380
+ await act(async () => {
381
+ view2.click();
382
+ });
384
383
 
385
- const view3 = await screen.findByTestId("flow-2");
386
- expect(view3).toBeInTheDocument();
384
+ const retryButton = await screen.findByText("Retry");
385
+ expect(retryButton).toBeInTheDocument();
387
386
 
388
- await act(async () => {
389
- view3.click();
390
- });
387
+ await act(async () => {
388
+ retryButton.click();
389
+ });
391
390
 
392
- const resetButton = await screen.findByText("Retry");
393
- expect(resetButton).toBeInTheDocument();
391
+ expect(manager.next).toBeCalledTimes(3);
394
392
 
395
- await act(async () => {
396
- resetButton.click();
397
- });
393
+ const view3 = await screen.findByTestId("flow-2");
394
+ expect(view3).toBeInTheDocument();
398
395
 
399
- expect(manager.next).toBeCalledTimes(4);
400
- expect(onError).toBeCalledTimes(2);
396
+ await act(async () => {
397
+ view3.click();
398
+ });
401
399
 
402
- expect(onComplete).toBeCalled();
403
- });
400
+ const resetButton = await screen.findByText("Retry");
401
+ expect(resetButton).toBeInTheDocument();
402
+
403
+ await act(async () => {
404
+ resetButton.click();
405
+ });
406
+
407
+ expect(manager.next).toBeCalledTimes(4);
408
+ expect(onError).toBeCalledTimes(2);
409
+
410
+ expect(onComplete).toBeCalled();
411
+ });
404
412
 
405
- test("handles terminating with data", async () => {
406
- vitest.useRealTimers();
407
- const manager: FlowManager = {
408
- next: vitest.fn().mockReturnValueOnce(
409
- Promise.resolve({
410
- value: {
411
- ...makeFlow({
412
- id: "flow-1",
413
- type: "collection",
414
- values: [
415
- {
416
- asset: {
417
- id: "action",
418
- type: "action",
419
- value: "Next",
420
- label: "Continue",
413
+ test("handles terminating with data", async () => {
414
+ const manager: FlowManager = {
415
+ next: vitest.fn().mockReturnValueOnce(
416
+ Promise.resolve({
417
+ value: {
418
+ ...makeFlow({
419
+ id: "flow-1",
420
+ type: "collection",
421
+ values: [
422
+ {
423
+ asset: {
424
+ id: "action",
425
+ type: "action",
426
+ value: "Next",
427
+ label: "Continue",
428
+ },
421
429
  },
422
- },
423
- ],
424
- }),
425
- data: {
426
- returns: { id: "123" },
430
+ ],
431
+ }),
432
+ data: {
433
+ returns: { id: "123" },
434
+ },
427
435
  },
428
- },
429
- }),
430
- ),
431
- terminate: vitest.fn(),
432
- };
436
+ }),
437
+ ),
438
+ terminate: vitest.fn(),
439
+ };
433
440
 
434
- const onComplete = vitest.fn();
435
- const onError = vitest.fn();
441
+ const onComplete = vitest.fn();
442
+ const onError = vitest.fn();
436
443
 
437
- let renderResult;
438
- act(() => {
439
- renderResult = render(
444
+ const result = render(
440
445
  <Suspense fallback="loading">
441
446
  <ManagedPlayer
442
447
  manager={manager}
@@ -445,10 +450,152 @@ test("handles terminating with data", async () => {
445
450
  onError={onError}
446
451
  />
447
452
  </Suspense>,
453
+ { legacyRoot },
448
454
  );
455
+
456
+ await screen.findByTestId("flow-1");
457
+ result.unmount();
458
+ expect(manager.terminate).toBeCalledWith({ returns: { id: "123" } });
449
459
  });
450
460
 
451
- await renderResult.findByTestId("flow-1");
452
- (renderResult as any).unmount();
453
- expect(manager.terminate).toBeCalledWith({ returns: { id: "123" } });
461
+ test("handles new manager", async () => {
462
+ const user = userEvent.setup();
463
+
464
+ const makeManager = (num: number): FlowManager => {
465
+ return {
466
+ terminate: vitest.fn(),
467
+ next: vitest
468
+ .fn()
469
+ .mockReturnValueOnce(
470
+ Promise.resolve({
471
+ value: makeFlow({
472
+ id: `flow-1-${num}`,
473
+ type: "collection",
474
+ values: [
475
+ {
476
+ asset: {
477
+ id: "action",
478
+ type: "action",
479
+ value: "Next",
480
+ label: "Continue",
481
+ },
482
+ },
483
+ ],
484
+ }),
485
+ }),
486
+ )
487
+ .mockReturnValueOnce(
488
+ Promise.resolve({
489
+ value: {
490
+ ...makeFlow({
491
+ id: `flow-2-${num}`,
492
+ type: "collection",
493
+ values: [
494
+ {
495
+ asset: {
496
+ id: "action",
497
+ type: "action",
498
+ value: "Next",
499
+ label: "Continue",
500
+ },
501
+ },
502
+ ],
503
+ }),
504
+ data: { foo: "bar" },
505
+ },
506
+ }),
507
+ )
508
+ .mockReturnValue(Promise.resolve({ done: true })),
509
+ };
510
+ };
511
+
512
+ let manager = makeManager(1);
513
+ const previousManager = {
514
+ current: manager,
515
+ };
516
+
517
+ const onComplete = vitest.fn();
518
+ const onError = vitest.fn();
519
+
520
+ const Wrapper = () => {
521
+ const [count, setCount] = React.useState(1);
522
+
523
+ return (
524
+ <div>
525
+ <button
526
+ id="newManager"
527
+ type="button"
528
+ onClick={() =>
529
+ setCount((c) => {
530
+ const newVal = c + 1;
531
+ previousManager.current = manager;
532
+ manager = makeManager(newVal);
533
+ return newVal;
534
+ })
535
+ }
536
+ >
537
+ New Manager {count}
538
+ </button>
539
+ <ManagedPlayer
540
+ manager={manager}
541
+ plugins={[new SimpleAssetPlugin()]}
542
+ onComplete={onComplete}
543
+ onError={onError}
544
+ />
545
+ </div>
546
+ );
547
+ };
548
+
549
+ const screen = render(
550
+ <Suspense fallback="loading">
551
+ <Wrapper />
552
+ </Suspense>,
553
+ { legacyRoot },
554
+ );
555
+
556
+ expect(manager.next).toBeCalledWith(undefined);
557
+ const view = await screen.findByTestId("flow-1-1");
558
+ expect(view).toBeInTheDocument();
559
+
560
+ let newManagerBtn = await screen.findByTestId("newManager");
561
+ await user.click(newManagerBtn);
562
+
563
+ expect(previousManager.current.terminate).toBeCalledWith({});
564
+ expect(previousManager.current.next).toBeCalledTimes(1);
565
+ expect(manager.next).toBeCalledTimes(1);
566
+ await screen.findByTestId("flow-1-2");
567
+
568
+ newManagerBtn = await screen.findByTestId("newManager");
569
+ await user.click(newManagerBtn);
570
+
571
+ const prevMan = previousManager.current;
572
+ expect(prevMan.terminate).toBeCalledWith({});
573
+ expect(prevMan.next).toBeCalledTimes(1);
574
+ expect(manager.next).toBeCalledTimes(1);
575
+ await screen.findByTestId("flow-1-3");
576
+
577
+ let nextButton = await screen.findByText("Continue");
578
+ await user.click(nextButton);
579
+
580
+ expect(prevMan).toEqual(previousManager.current);
581
+ expect(previousManager.current.next).toBeCalledTimes(1);
582
+ expect(manager.next).toBeCalledTimes(2);
583
+
584
+ const view2 = await screen.findByTestId("flow-2-3");
585
+ expect(view2).toBeInTheDocument();
586
+
587
+ nextButton = await screen.findByText("Continue");
588
+ await user.click(nextButton);
589
+
590
+ expect(prevMan).toEqual(previousManager.current);
591
+ expect(previousManager.current.next).toBeCalledTimes(1);
592
+ expect(manager.next).toBeCalledTimes(3);
593
+
594
+ expect(onComplete).toBeCalledWith(
595
+ expect.objectContaining({
596
+ status: "completed",
597
+ data: { foo: "bar" },
598
+ }),
599
+ );
600
+ });
454
601
  });