@@ -312,6 +312,114 @@ describe('InputEditor', function() {
312312
313313 } ) ;
314314
315+
316+ describe ( 'undo/redo' , function ( ) {
317+
318+ it ( 'should support undo after typing' , async function ( ) {
319+
320+ // given
321+ const onChange = sinon . spy ( ) ;
322+ const initialValue = '{"foo": "bar"}' ;
323+
324+ const { container, getByRole } = renderWithProps ( {
325+ value : initialValue ,
326+ onChange
327+ } ) ;
328+
329+ // when - type some text
330+ await user . click ( getByRole ( 'textbox' ) ) ;
331+ await user . keyboard ( '{ArrowLeft}{ArrowLeft}"baz": 42, ' ) ;
332+
333+ // then - text was added
334+ await waitFor ( ( ) => {
335+ expect ( container . textContent ) . to . include ( '"baz": 42' ) ;
336+ } ) ;
337+
338+ // when - undo
339+ await user . keyboard ( '{Control>}z{/Control}' ) ;
340+
341+ // then - text was removed
342+ await waitFor ( ( ) => {
343+ expect ( container . textContent ) . not . to . include ( '"baz": 42' ) ;
344+ expect ( container . textContent ) . to . include ( '"foo": "bar"' ) ;
345+ } ) ;
346+ } ) ;
347+
348+
349+ it ( 'should support redo after undo' , async function ( ) {
350+
351+ // given
352+ const onChange = sinon . spy ( ) ;
353+ const initialValue = '{"foo": "bar"}' ;
354+
355+ const { container, getByRole } = renderWithProps ( {
356+ value : initialValue ,
357+ onChange
358+ } ) ;
359+
360+ // when - type some text
361+ await user . click ( getByRole ( 'textbox' ) ) ;
362+ await user . keyboard ( '{ArrowLeft}{ArrowLeft}"baz": 42, ' ) ;
363+
364+ await waitFor ( ( ) => {
365+ expect ( container . textContent ) . to . include ( '"baz": 42' ) ;
366+ } ) ;
367+
368+ // when - undo
369+ await user . keyboard ( '{Control>}z{/Control}' ) ;
370+
371+ await waitFor ( ( ) => {
372+ expect ( container . textContent ) . not . to . include ( '"baz": 42' ) ;
373+ } ) ;
374+
375+ // when - redo
376+ await user . keyboard ( '{Control>}y{/Control}' ) ;
377+
378+ // then - text was restored
379+ await waitFor ( ( ) => {
380+ expect ( container . textContent ) . to . include ( '"baz": 42' ) ;
381+ } ) ;
382+ } ) ;
383+
384+
385+ it ( 'should support undo after clearing content' , async function ( ) {
386+
387+ // given
388+ const onChange = sinon . spy ( ) ;
389+ const initialValue = '{"foo": "bar", "baz": 1337}' ;
390+
391+ const { container, getByRole, rerender } = renderWithProps ( {
392+ value : initialValue ,
393+ onChange
394+ } ) ;
395+
396+ // when - clear content by setting value to empty object
397+ rerender (
398+ < InputEditor
399+ value = { '{}' }
400+ onChange = { onChange }
401+ />
402+ ) ;
403+
404+ // then - content was cleared
405+ await waitFor ( ( ) => {
406+ expect ( container . textContent ) . not . to . include ( '"foo": "bar"' ) ;
407+ expect ( container . textContent ) . not . to . include ( '"baz": 1337' ) ;
408+ } ) ;
409+
410+ // when - focus editor and undo
411+ await user . click ( getByRole ( 'textbox' ) ) ;
412+ await user . keyboard ( '{Control>}z{/Control}' ) ;
413+
414+ // then - content was restored
415+ await waitFor ( ( ) => {
416+ expect ( container . textContent ) . to . include ( '"foo": "bar"' ) ;
417+ expect ( container . textContent ) . to . include ( '"baz": 1337' ) ;
418+ } ) ;
419+ } ) ;
420+
421+ } ) ;
422+
315423} ) ;
316424
317425function renderWithProps ( props = { } ) {
0 commit comments