-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Block editor: create automatic change higher order reducer #48312
Conversation
selectionStart === state.selectionStart && | ||
selectionEnd === state.selectionEnd | ||
) { | ||
return state; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also noticed that we were continuously creating a new object here. I'm curious if this improves performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would if there are selectors using the parent key as memoization key.
Size Change: +464 B (0%) Total Size: 1.33 MB
ℹ️ View Unchanged
|
|
||
if ( | ||
nextState.blocks === state.blocks && | ||
nextState.selection === state.selection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the question is: Is there potentially an action that updates either selection or blocks but shouldn't update "automaticChangeStatus"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far every time we had this issue it's because of some other non content state
Flaky tests detected in 43b0f74. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4244683455
|
// Wait until the automatic change is marked as "final", which is done | ||
// with an idle callback, see __unstableMarkAutomaticChange. | ||
await page.evaluate( () => new Promise( window.requestIdleCallback ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not something we want to put in e2e tests, since it's implementation details and not what end users could interact with. It can potentially also be an issue for end users if they press the ArrowUp
key fast enough, right? Ideally, we should fix it in the code so that it can be deterministic. If that's not possible at the time then we should think along the line with retrying and waiting for the results, something like this:
await expect( async () => {
await page.keyboard.press( 'ArrowUp' );
expect(
await page.evaluate( () =>
window.wp.data.select( 'core/block-editor' ).getSelectedBlock()
)
).toMatchObject( { name: 'core/list' } );
} ).toPass();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not really an issue for a user: if selection changes too quickly, it's just that it will still be possible to undo the automatic change. We have a few of these lines throughout the e2e test where we have to wait for selection. We also have undo levels for rich text after 1 second of inactivity. How would we write an e2e test for something like that? Let's look at these all together separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'd rather improve test stability for trunk right now.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow up with a PR to fix this then.
We have a few of these lines throughout the e2e test where we have to wait for selection.
And this is the anti-pattern that I'm recommending against.
We also have undo levels for rich text after 1 second of inactivity. How would we write an e2e test for something like that?
Some of these can be mocked to reduce the time we have to wait. If that's hard-coded then we can always fallback to the pattern I mentioned above: wait for feedback that's accessible to the end users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid mocking entirely in e2e tests if possible otherwise it's not e2e testing anymore. If the user has to wait, let's make the test wait as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. But sometimes it's inevitable, like caching and nonce tests, or just isolating for more stable tests. Waiting is okay, we just need to wait for user-visible behaviors instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @ellatrix, friendly reminder that this exists ❤️ . Feel free to request my reviews in the PR and we can discuss alternatives there more!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure what you're asking here. I added the best solution to my knowledge in this PR. What does the code above do? It just keeps pressing up until the test passes? To me that doesn't feel like an e2e test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What to do is up to you, just don't rely on implementation details like requestIdleCallback
. This could potentially be very flaky when React changes how it schedule async work for instance. Why doesn't it feel like e2e to you? Retrying and waiting on user-visible interactions sounds exactly like how end users would use the app to me. If retrying is not suitable here, try waiting on user-visible actions (like caret position) before pressing the button.
What?
Creates an automatic change higher order reducer so we can reset
automaticChangeStatus
if blocks or selection changes.Why?
The current implementation is very fragile: if you add an action to the store, it will automatically reset the
automaticChangeStatus
when dispatched.How?
Higher order reducer
Testing Instructions
Testing Instructions for Keyboard
Screenshots or screencast