-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Add waitForVisible() to all blocks #41126
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
Changes from all commits
7bf096d
85bfebf
db54e18
4432298
08435cb
65f3c62
1a00cd1
a5ba829
9dc1b8f
dd7aa72
0b2c965
46798af
36adacd
86a5d30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -310,7 +310,8 @@ const longPressMiddleOfElement = async ( driver, element ) => { | |
| const x = location.x + size.width / 2; | ||
| const y = location.y + size.height / 2; | ||
| action.press( { x, y } ); | ||
| action.wait( 2000 ); | ||
| // Setting to wait a bit longer because this is failing more frequently on the CI | ||
| action.wait( 5000 ); | ||
| action.release(); | ||
| await action.perform(); | ||
| }; | ||
|
|
@@ -419,24 +420,28 @@ const toggleHtmlMode = async ( driver, toggleOn ) => { | |
|
|
||
| const showHtmlButtonXpath = | ||
| '/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[9]'; | ||
| const showHtmlButton = await driver.elementByXPath( | ||
| showHtmlButtonXpath | ||
|
|
||
| await clickIfClickable( driver, showHtmlButtonXpath ); | ||
| } else if ( toggleOn ) { | ||
| await clickIfClickable( | ||
| driver, | ||
| '//XCUIElementTypeButton[@name="..."]' | ||
| ); | ||
| await clickIfClickable( | ||
| driver, | ||
| '//XCUIElementTypeButton[@name="Switch to HTML"]' | ||
| ); | ||
| await showHtmlButton.click(); | ||
| } else { | ||
| const menuButton = await driver.elementByAccessibilityId( '...' ); | ||
| await menuButton.click(); | ||
| let toggleHtmlButton; | ||
| if ( toggleOn ) { | ||
| toggleHtmlButton = await driver.elementByAccessibilityId( | ||
| 'Switch to HTML' | ||
| ); | ||
| } else { | ||
| toggleHtmlButton = await driver.elementByAccessibilityId( | ||
| 'Switch To Visual' | ||
| ); | ||
| } | ||
| await toggleHtmlButton.click(); | ||
| // This is to wait for the clipboard paste notification to disappear, currently it overlaps with the menu button | ||
| await driver.sleep( 3000 ); | ||
| await clickIfClickable( | ||
| driver, | ||
| '//XCUIElementTypeButton[@name="..."]' | ||
| ); | ||
| await clickIfClickable( | ||
| driver, | ||
| '//XCUIElementTypeButton[@name="Switch To Visual"]' | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
|
|
@@ -492,7 +497,7 @@ const waitForVisible = async ( | |
| } | ||
|
|
||
| const element = await driver.elementsByXPath( elementLocator ); | ||
| if ( element.length !== 1 ) { | ||
| if ( element.length === 0 ) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Certain blocks don't return exactly one element (e.g. Column and Unsupported blocks), so updating the condition to as long as it's not 0.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be interesting adding a parameter to the function to configure whether the function returns the first element or the elements array. It could be useful for those cases where we need to pick one of the elements, like for example in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I agree, since this always returns the first element, for cases like above, we have to make the call first before making a separate call to get the list of elements. I'll make that enhancement in a separate PR, as might take a while to test to make sure it covers all use cases. |
||
| // if locator is not visible, try again | ||
| return waitForVisible( | ||
| driver, | ||
|
|
@@ -530,6 +535,39 @@ const isElementVisible = async ( | |
| return true; | ||
| }; | ||
|
|
||
| const clickIfClickable = async ( | ||
| driver, | ||
| elementLocator, | ||
| maxIteration = 25, | ||
| iteration = 0 | ||
| ) => { | ||
| const element = await waitForVisible( | ||
| driver, | ||
| elementLocator, | ||
| maxIteration, | ||
| iteration | ||
| ); | ||
|
|
||
| try { | ||
| return await element.click(); | ||
| } catch ( error ) { | ||
| if ( iteration >= maxIteration ) { | ||
| // eslint-disable-next-line no-console | ||
| console.error( | ||
| `"${ elementLocator }" still not clickable after "${ iteration }" retries` | ||
| ); | ||
| return ''; | ||
| } | ||
|
|
||
| return clickIfClickable( | ||
| driver, | ||
| elementLocator, | ||
| maxIteration, | ||
| iteration + 1 | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| // Only for Android | ||
| const waitIfAndroid = async () => { | ||
| if ( isAndroid() ) { | ||
|
|
@@ -540,6 +578,7 @@ const waitIfAndroid = async () => { | |
| module.exports = { | ||
| backspace, | ||
| clickBeginningOfElement, | ||
| clickIfClickable, | ||
| clickMiddleOfElement, | ||
| doubleTap, | ||
| isAndroid, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.