While investigating on #5468 I've noticed inconsistencies in the way Undo and Redo work, depending if using the mouse or the keyboard. Seems to me this feature is a bit fragile and prone to errors and probably worth some investigation.
I've tried to reduce the inconsistencies I've noticed to a few cases, hopefully easy to reproduce;
1
Undo / Redo using only the mouse:
Now click Undo multiple times through all the history steps and carefully observe what happens:
Now click Redo multiple times:
2
Undo / Redo using only the keyboard:
Now click Undo multiple times:
Now click Redo:

3
Using Cmd/Ctrl+z and Cmd/Ctrl+Shift+z:
Instead of clicking Undo and Redo, using the keyboard shortcuts generally produces the same inconsistencies except for:

Sorry I can't help further, I don't have the knowledge to understand how Undo/Redo exactly works. If I had to guess, I'd suspect history steps are saved differently when using the mouse or the keyboard. Not sure this can be fully fixed, given how the UI works. However, it would be nice to investigate on some of these cases, especially the ones that are potentially very confusing for users.
For reference: tested on current master 8434cc93d04d70543f26994f8b75cac51aac995b a few days after release 2.4.0.
I encountered a similar issue when working on improvements for e2e tests in #8301:
It happens only in the headless mode when running e2e tests. Sometimes it creates two undo levels for the first paragraph. When you modify test and add snapshots after each undo action you might see the following:
exports[`undo Should undo to expected level intervals 5`] = ` “<!-- wp:paragraph --> <p>This</p> <!-- /wp:paragraph -->” `; exports[`undo Should undo to expected level intervals 6`] = ` “<!-- wp:paragraph --> <p>Thi</p> <!-- /wp:paragraph -->” `;This isn't expected behavior. It uncovers some edge case happening inside the logic which creates undo levels.
Test which might allow to reproduce it: https://github.com/WordPress/gutenberg/blob/master/test/e2e/specs/undo.test.js
You can run it as follows:
PUPPETEER_HEADLESS=false npm run test-e2e test/e2e/specs/undo.test.js
Forgive me not being more specific, but let me just add, that Ctrl-Z, Ctrl-Y rarely gives me the expected results. Using Gutenberg 3.4 - on production site, woop woop! ;)
@iseulde is it possible that this thing forces editor to create another undo level even when new block wasn't created or blur didn't happen?
In the e2e tes (test/e2e/specs/undo.test.js) it happens the following from time to time:
test, sometime undo level is create after I type tes and another one when I hit enter and new block gets created.When test fails, this is always the reason.
I think we should remove the change event handler and replace it with our own logic so we have complete control over it. So that means: deregistering built in shortcuts and reregister them to use our own formatting methods, then create history records for any formatting change and any clicks in the editor (click = typing interruption), and maybe some other things like the ENTER key etc. Planning to have a look at this.
Should be fixed after #10650. Please reopen if this is not the case. :)
I see the behavior has improved a lot with regards to RichText, thanks! However, following the steps above, the post title is not restored. Depending on the flow, seems the title is not included in the undo/redo history also in other cases.
GIF:

Also, I understand the switch from the default (empty) block to a paragraph is included in the history, but maybe that could be potentially confusing for users.
Yes, I think only blocks are included in the history reducers. Could you make a new issue for this? It seems unrelated to this one.
Yes, I think only blocks are included in the history reducers
Edits (including title) are included.
Could you make a new issue for this? It seems unrelated to this one.
This issue has been created: #12075.