@@ -391,6 +391,29 @@ class Appium extends Webdriver {
391391 return `${ protocol } ://${ hostname } :${ port } ${ normalizedPath } /session/${ this . browser . sessionId } `
392392 }
393393
394+ /**
395+ * Helper method to safely call isDisplayed() on mobile elements.
396+ * Handles the case where webdriverio tries to use execute/sync which isn't supported in Appium.
397+ * @private
398+ */
399+ async _isDisplayedSafe ( element ) {
400+ if ( this . isWeb ) {
401+ // For web contexts, use the normal isDisplayed
402+ return element . isDisplayed ( )
403+ }
404+
405+ try {
406+ return await element . isDisplayed ( )
407+ } catch ( err ) {
408+ // If isDisplayed fails due to execute/sync not being supported in native mobile contexts,
409+ // fall back to assuming the element is displayed (since we found it)
410+ if ( err . message && err . message . includes ( 'Method is not implemented' ) ) {
411+ return true
412+ }
413+ throw err
414+ }
415+ }
416+
394417 /**
395418 * Execute code only on iOS
396419 *
@@ -619,6 +642,7 @@ class Appium extends Webdriver {
619642 */
620643 async resetApp ( ) {
621644 onlyForApps . call ( this )
645+ this . isWeb = false // Reset to native context after app reset
622646 return this . axios ( {
623647 method : 'post' ,
624648 url : `${ this . _buildAppiumEndpoint ( ) } /appium/app/reset` ,
@@ -1134,7 +1158,7 @@ class Appium extends Webdriver {
11341158 ] ,
11351159 } ,
11361160 ] )
1137- await this . browser . pause ( 1000 )
1161+ await this . browser . pause ( 2000 )
11381162 }
11391163
11401164 /**
@@ -1296,28 +1320,26 @@ class Appium extends Webdriver {
12961320 let currentSource
12971321 return browser
12981322 . waitUntil (
1299- ( ) => {
1323+ async ( ) => {
13001324 if ( err ) {
13011325 return new Error ( `Scroll to the end and element ${ searchableLocator } was not found` )
13021326 }
1303- return browser
1304- . $$ ( parseLocator . call ( this , searchableLocator ) )
1305- . then ( els => els . length && els [ 0 ] . isDisplayed ( ) )
1306- . then ( res => {
1307- if ( res ) {
1308- return true
1309- }
1310- return this [ direction ] ( scrollLocator , offset , speed )
1311- . getSource ( )
1312- . then ( source => {
1313- if ( source === currentSource ) {
1314- err = true
1315- } else {
1316- currentSource = source
1317- return false
1318- }
1319- } )
1320- } )
1327+ const els = await browser . $$ ( parseLocator . call ( this , searchableLocator ) )
1328+ if ( els . length ) {
1329+ const displayed = await this . _isDisplayedSafe ( els [ 0 ] )
1330+ if ( displayed ) {
1331+ return true
1332+ }
1333+ }
1334+
1335+ await this [ direction ] ( scrollLocator , offset , speed )
1336+ const source = await this . browser . getPageSource ( )
1337+ if ( source === currentSource ) {
1338+ err = true
1339+ } else {
1340+ currentSource = source
1341+ return false
1342+ }
13211343 } ,
13221344 timeout * 1000 ,
13231345 errorMsg ,
@@ -1523,7 +1545,28 @@ class Appium extends Webdriver {
15231545 */
15241546 async dontSeeElement ( locator ) {
15251547 if ( this . isWeb ) return super . dontSeeElement ( locator )
1526- return super . dontSeeElement ( parseLocator . call ( this , locator ) )
1548+
1549+ // For mobile native apps, use safe isDisplayed wrapper
1550+ const parsedLocator = parseLocator . call ( this , locator )
1551+ const res = await this . _locate ( parsedLocator , false )
1552+ const { truth } = require ( '../assert/truth' )
1553+ const Locator = require ( '../locator' )
1554+
1555+ if ( ! res || res . length === 0 ) {
1556+ return truth ( `elements of ${ new Locator ( parsedLocator ) } ` , 'to be seen' ) . negate ( false )
1557+ }
1558+
1559+ const selected = [ ]
1560+ for ( const el of res ) {
1561+ const displayed = await this . _isDisplayedSafe ( el )
1562+ if ( displayed ) selected . push ( true )
1563+ }
1564+
1565+ try {
1566+ return truth ( `elements of ${ new Locator ( parsedLocator ) } ` , 'to be seen' ) . negate ( selected )
1567+ } catch ( err ) {
1568+ throw err
1569+ }
15271570 }
15281571
15291572 /**
@@ -1577,7 +1620,18 @@ class Appium extends Webdriver {
15771620 */
15781621 async grabNumberOfVisibleElements ( locator ) {
15791622 if ( this . isWeb ) return super . grabNumberOfVisibleElements ( locator )
1580- return super . grabNumberOfVisibleElements ( parseLocator . call ( this , locator ) )
1623+
1624+ // For mobile native apps, use safe isDisplayed wrapper
1625+ const parsedLocator = parseLocator . call ( this , locator )
1626+ const res = await this . _locate ( parsedLocator )
1627+
1628+ const selected = [ ]
1629+ for ( const el of res ) {
1630+ const displayed = await this . _isDisplayedSafe ( el )
1631+ if ( displayed ) selected . push ( true )
1632+ }
1633+
1634+ return selected . length
15811635 }
15821636
15831637 /**
@@ -1656,7 +1710,30 @@ class Appium extends Webdriver {
16561710 */
16571711 async seeElement ( locator ) {
16581712 if ( this . isWeb ) return super . seeElement ( locator )
1659- return super . seeElement ( parseLocator . call ( this , locator ) )
1713+
1714+ // For mobile native apps, use safe isDisplayed wrapper
1715+ const parsedLocator = parseLocator . call ( this , locator )
1716+ const res = await this . _locate ( parsedLocator , true )
1717+ const ElementNotFound = require ( './errors/ElementNotFound' )
1718+ const { truth } = require ( '../assert/truth' )
1719+ const { dontSeeElementError } = require ( './errors/ElementAssertion' )
1720+ const Locator = require ( '../locator' )
1721+
1722+ if ( ! res || res . length === 0 ) {
1723+ throw new ElementNotFound ( parsedLocator )
1724+ }
1725+
1726+ const selected = [ ]
1727+ for ( const el of res ) {
1728+ const displayed = await this . _isDisplayedSafe ( el )
1729+ if ( displayed ) selected . push ( true )
1730+ }
1731+
1732+ try {
1733+ return truth ( `elements of ${ new Locator ( parsedLocator ) } ` , 'to be seen' ) . assert ( selected )
1734+ } catch ( e ) {
1735+ dontSeeElementError ( parsedLocator )
1736+ }
16601737 }
16611738
16621739 /**
@@ -1703,7 +1780,30 @@ class Appium extends Webdriver {
17031780 */
17041781 async waitForVisible ( locator , sec = null ) {
17051782 if ( this . isWeb ) return super . waitForVisible ( locator , sec )
1706- return super . waitForVisible ( parseLocator . call ( this , locator ) , sec )
1783+
1784+ // For mobile native apps, use safe isDisplayed wrapper
1785+ const parsedLocator = parseLocator . call ( this , locator )
1786+ const aSec = sec || this . options . waitForTimeoutInSeconds
1787+ const Locator = require ( '../locator' )
1788+
1789+ return this . browser . waitUntil (
1790+ async ( ) => {
1791+ const res = await this . _res ( parsedLocator )
1792+ if ( ! res || res . length === 0 ) return false
1793+
1794+ const selected = [ ]
1795+ for ( const el of res ) {
1796+ const displayed = await this . _isDisplayedSafe ( el )
1797+ if ( displayed ) selected . push ( true )
1798+ }
1799+
1800+ return selected . length > 0
1801+ } ,
1802+ {
1803+ timeout : aSec * 1000 ,
1804+ timeoutMsg : `element (${ new Locator ( parsedLocator ) } ) still not visible after ${ aSec } sec` ,
1805+ } ,
1806+ )
17071807 }
17081808
17091809 /**
@@ -1712,7 +1812,27 @@ class Appium extends Webdriver {
17121812 */
17131813 async waitForInvisible ( locator , sec = null ) {
17141814 if ( this . isWeb ) return super . waitForInvisible ( locator , sec )
1715- return super . waitForInvisible ( parseLocator . call ( this , locator ) , sec )
1815+
1816+ // For mobile native apps, use safe isDisplayed wrapper
1817+ const parsedLocator = parseLocator . call ( this , locator )
1818+ const aSec = sec || this . options . waitForTimeoutInSeconds
1819+ const Locator = require ( '../locator' )
1820+
1821+ return this . browser . waitUntil (
1822+ async ( ) => {
1823+ const res = await this . _res ( parsedLocator )
1824+ if ( ! res || res . length === 0 ) return true
1825+
1826+ const selected = [ ]
1827+ for ( const el of res ) {
1828+ const displayed = await this . _isDisplayedSafe ( el )
1829+ if ( displayed ) selected . push ( true )
1830+ }
1831+
1832+ return selected . length === 0
1833+ } ,
1834+ { timeout : aSec * 1000 , timeoutMsg : `element (${ new Locator ( parsedLocator ) } ) still visible after ${ aSec } sec` } ,
1835+ )
17161836 }
17171837
17181838 /**
0 commit comments