-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
[RNMobile] - Add waits to fix editor test flakiness #39668
Conversation
? '//android.widget.Button[@content-desc="Add block, Double tap to add a block"]' | ||
: '//XCUIElementTypeButton[@name="add-block-button"]'; |
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.
Moved to use XPath
instead of accessibilityId
because if an accessibilityId
is not found, the Appium session is immediately terminated giving no chance to wait and retry. While XPaths are not recommended locators, it is the workaround for this case for now.
Let me know if anyone knows of a better alternative!
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.
True, it's generally not recommended to use XPaths
but I wouldn't oppose using it if there's no other option. I haven't investigated other approaches, but I recall that WebDriver automatically finishes the session upon some failures, even if the call is wrapped with try-catch
😞 .
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.
Yeah, I tried wrapping it in a try-catch, hoping to bypass the error but it didn't work 😞 I also checked if it was configurable but looks like it isn't.
// For certain blocks, clicking on it will display additional options that the test should wait for before next steps | ||
if ( blockName === 'Image' ) { |
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.
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.
Media blocks like Image automatically open the media options picker. In this case, I think that waiting for the block picker should be part of the test that adds the block. Which by the way is already being done, as outlined in the following example:
gutenberg/packages/react-native-editor/__device-tests__/gutenberg-editor-image-@canary.test.js
Lines 10 to 12 in a4c8730
await editorPage.addNewBlock( blockNames.image ); | |
await editorPage.driver.sleep( 1000 ); | |
await editorPage.closePicker(); |
Although it would be great to use the waitForVisible
helper for that element (i.e. media options picker) too 😅 .
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.
Ah ok, I was actually looking to find what that was called. I'll update this to move to closePicker()
I think would make more sense there so that it covers all media blocks.
I think the implicit waits on the tests can then be removed with this change, but I'll do that in a future PR so that this PR can focus on this one test file first.
// Wait for the first block, Paragraph block, to load before looking for other blocks | ||
const paragraphBlockLocator = isAndroid() | ||
? '//android.widget.Button[@content-desc="Paragraph block"]/android.widget.TextView' | ||
: '//XCUIElementTypeButton[@name="Paragraph block"]'; |
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.
For now, I've set that it waits for the Paragraph block to load because it's the first one on the blocks list, I'm not sure how often the list changes so this has the potential to fail in the future. Another option is to wait for the search box. What do you all think?
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.
The block picker view has a testID
attribute with value add-block-button
, maybe we should rely on that, wdyt?
As an alternative, we might consider adding accessibility info, which apart from helping us query the element, would be a good improvement in terms of a11y.
testID: 'add-block-button', |
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.
Ah ok but looks like that is before the block picker view:
After some investigation, looks like we can actually create another wait helper that uses IDs! But it has to be an ID defined like this (i.e For Android, android:id/{value}
):
There is an open issue for this here. Appium doc how to use this here.
I am not sure where this is defined (looks like not on the ./index.native.js
file), if we can add an ID on a more appropriate view we could depend on that to load first before continuing the test.
I think, for now, I will leave it to wait for Paragraph block before continuing the test. Future improvements (i.e. add id and use it for the test) to be done in a separate PR. Is that ok?
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.
Oh sorry, I'm afraid I referenced the wrong test ID. The one I'm wanted to share is InserterUI-Blocks
:
testID={ `InserterUI-${ name }` } |
In any case, I think it's quite reliable to use the Paragraph block as it's a block that will be always present.
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.
Thanks @jostnes for introducing these amazing fixes which will help on reducing the test flakiness 🏅.
I added some comments, most of them reply to yours. Let me know if you'd like me to expand any of them.
packages/react-native-editor/__device-tests__/helpers/test-data.js
Outdated
Show resolved
Hide resolved
packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion-2.test.js
Outdated
Show resolved
Hide resolved
// For certain blocks, clicking on it will display additional options that the test should wait for before next steps | ||
if ( blockName === 'Image' ) { |
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.
Media blocks like Image automatically open the media options picker. In this case, I think that waiting for the block picker should be part of the test that adds the block. Which by the way is already being done, as outlined in the following example:
gutenberg/packages/react-native-editor/__device-tests__/gutenberg-editor-image-@canary.test.js
Lines 10 to 12 in a4c8730
await editorPage.addNewBlock( blockNames.image ); | |
await editorPage.driver.sleep( 1000 ); | |
await editorPage.closePicker(); |
Although it would be great to use the waitForVisible
helper for that element (i.e. media options picker) too 😅 .
? '//android.widget.Button[@content-desc="Add block, Double tap to add a block"]' | ||
: '//XCUIElementTypeButton[@name="add-block-button"]'; |
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.
True, it's generally not recommended to use XPaths
but I wouldn't oppose using it if there's no other option. I haven't investigated other approaches, but I recall that WebDriver automatically finishes the session upon some failures, even if the call is wrapped with try-catch
😞 .
// Wait for the first block, Paragraph block, to load before looking for other blocks | ||
const paragraphBlockLocator = isAndroid() | ||
? '//android.widget.Button[@content-desc="Paragraph block"]/android.widget.TextView' | ||
: '//XCUIElementTypeButton[@name="Paragraph block"]'; |
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.
The block picker view has a testID
attribute with value add-block-button
, maybe we should rely on that, wdyt?
As an alternative, we might consider adding accessibility info, which apart from helping us query the element, would be a good improvement in terms of a11y.
testID: 'add-block-button', |
Thanks for the review @fluiddot! I've made some changes based on the comments and this is now ready for a re-review. |
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?
This PR adds
waitForVisible()
to check that locators are available before continuing the test for all tests on gutenberg-editor-block-insertion-2.test.jsThis PR also moved all the test data on that test file to
test-data.js
so that it is consistent with other tests and also if there is a change in the HTML, we would now only need to change it in one place instead of multiple.Why?
The waits are added to ensure that the screen is at the correct stage before the test continues, this will help reduce flakiness.
How?
By adding
waitForVisible()
to the tests, the test will fail if the locator is not present.Testing Instructions
Ensure that the gutenberg-editor-block-insertion-2.test.js test file passes on both local runs and on CI. I've run it 10 times here, while there are failures those are other flaky tests/other reasons. That will be tackled separately in future PRs.
Screenshots or screencast
N/A