|
9 | 9 |
|
10 | 10 | 'use strict';
|
11 | 11 |
|
| 12 | +import {insertNodesAndExecuteScripts} from '../test-utils/FizzTestUtils'; |
| 13 | + |
12 | 14 | // Polyfills for test environment
|
13 | 15 | global.ReadableStream =
|
14 | 16 | require('web-streams-polyfill/ponyfill/es6').ReadableStream;
|
@@ -63,7 +65,9 @@ describe('ReactDOMFizzForm', () => {
|
63 | 65 | }
|
64 | 66 | result += Buffer.from(value).toString('utf8');
|
65 | 67 | }
|
66 |
| - container.innerHTML = result; |
| 68 | + const temp = document.createElement('div'); |
| 69 | + temp.innerHTML = result; |
| 70 | + insertNodesAndExecuteScripts(temp, container, null); |
67 | 71 | }
|
68 | 72 |
|
69 | 73 | // @gate enableFormActions
|
@@ -360,4 +364,75 @@ describe('ReactDOMFizzForm', () => {
|
360 | 364 | expect(buttonRef.current.hasAttribute('formMethod')).toBe(false);
|
361 | 365 | expect(buttonRef.current.hasAttribute('formTarget')).toBe(false);
|
362 | 366 | });
|
| 367 | + |
| 368 | + // @gate enableFormActions |
| 369 | + it('should replay a form action after hydration', async () => { |
| 370 | + let foo; |
| 371 | + function action(formData) { |
| 372 | + foo = formData.get('foo'); |
| 373 | + } |
| 374 | + function App() { |
| 375 | + return ( |
| 376 | + <form action={action}> |
| 377 | + <input type="text" name="foo" defaultValue="bar" /> |
| 378 | + </form> |
| 379 | + ); |
| 380 | + } |
| 381 | + |
| 382 | + const stream = await ReactDOMServer.renderToReadableStream(<App />); |
| 383 | + await readIntoContainer(stream); |
| 384 | + |
| 385 | + // Dispatch an event before hydration |
| 386 | + submit(container.getElementsByTagName('form')[0]); |
| 387 | + |
| 388 | + await act(async () => { |
| 389 | + ReactDOMClient.hydrateRoot(container, <App />); |
| 390 | + }); |
| 391 | + |
| 392 | + // It should've now been replayed |
| 393 | + expect(foo).toBe('bar'); |
| 394 | + }); |
| 395 | + |
| 396 | + // @gate enableFormActions |
| 397 | + it('should replay input/button formAction', async () => { |
| 398 | + let rootActionCalled = false; |
| 399 | + let savedTitle = null; |
| 400 | + let deletedTitle = null; |
| 401 | + |
| 402 | + function action(formData) { |
| 403 | + rootActionCalled = true; |
| 404 | + } |
| 405 | + |
| 406 | + function saveItem(formData) { |
| 407 | + savedTitle = formData.get('title'); |
| 408 | + } |
| 409 | + |
| 410 | + function deleteItem(formData) { |
| 411 | + deletedTitle = formData.get('title'); |
| 412 | + } |
| 413 | + |
| 414 | + function App() { |
| 415 | + return ( |
| 416 | + <form action={action}> |
| 417 | + <input type="text" name="title" defaultValue="Hello" /> |
| 418 | + <input type="submit" formAction={saveItem} value="Save" /> |
| 419 | + <button formAction={deleteItem}>Delete</button> |
| 420 | + </form> |
| 421 | + ); |
| 422 | + } |
| 423 | + |
| 424 | + const stream = await ReactDOMServer.renderToReadableStream(<App />); |
| 425 | + await readIntoContainer(stream); |
| 426 | + |
| 427 | + submit(container.getElementsByTagName('input')[1]); |
| 428 | + submit(container.getElementsByTagName('button')[0]); |
| 429 | + |
| 430 | + await act(async () => { |
| 431 | + ReactDOMClient.hydrateRoot(container, <App />); |
| 432 | + }); |
| 433 | + |
| 434 | + expect(savedTitle).toBe('Hello'); |
| 435 | + expect(deletedTitle).toBe('Hello'); |
| 436 | + expect(rootActionCalled).toBe(false); |
| 437 | + }); |
363 | 438 | });
|
0 commit comments