11import _ from 'lodash' ;
2- import { getProxyDriver } from '../utils' ;
2+ import { getProxyDriver , FLUTTER_LOCATORS } from '../utils' ;
33import { JWProxy } from 'appium/driver' ;
44import { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver' ;
5+ // @ts -ignore
6+ import { XCUITestDriver } from 'appium-xcuitest-driver' ;
7+ // @ts -ignore
8+ import { Mac2Driver } from 'appium-mac2-driver' ;
59import { W3C_ELEMENT_KEY } from 'appium/driver' ;
610import type { AppiumFlutterDriver } from '../driver' ;
711
@@ -15,28 +19,53 @@ export async function findElOrEls(
1519) : Promise < any > {
1620 const driver = await getProxyDriver . bind ( this ) ( strategy ) ;
1721 let elementBody ;
18- if (
19- ! ( driver instanceof JWProxy ) &&
20- ! ( this . proxydriver instanceof AndroidUiautomator2Driver )
22+ function constructFindElementPayload (
23+ strategy : string ,
24+ selector : string ,
25+ proxyDriver : XCUITestDriver | AndroidUiautomator2Driver | Mac2Driver ,
2126 ) {
22- elementBody = {
23- using : strategy ,
24- value : selector ,
25- context, //this needs be validated
26- } ;
27- } else {
28- elementBody = {
29- strategy,
30- selector : [ '-flutter descendant' , '-flutter ancestor' ] . includes (
31- strategy ,
32- )
33- ? _ . isString ( selector )
34- ? JSON . parse ( selector )
35- : selector
36- : selector ,
37- context,
38- } ;
27+ const isFlutterLocator =
28+ strategy . startsWith ( '-flutter' ) || FLUTTER_LOCATORS . includes ( strategy ) ;
29+
30+ let parsedSelector ;
31+ if ( [ '-flutter descendant' , '-flutter ancestor' ] . includes ( strategy ) ) {
32+ // Handle descendant/ancestor special case
33+ parsedSelector = _ . isString ( selector )
34+ ? JSON . parse ( selector )
35+ : selector ;
36+
37+ // For Mac2Driver and XCUITestDriver, format selector differently
38+ if (
39+ proxyDriver instanceof XCUITestDriver ||
40+ proxyDriver instanceof Mac2Driver
41+ ) {
42+ return {
43+ using : strategy ,
44+ value : JSON . stringify ( parsedSelector ) ,
45+ context,
46+ } ;
47+ }
48+ } else {
49+ parsedSelector = selector ;
50+ }
51+
52+ // If user is looking for Native IOS/Mac locator
53+ if (
54+ ! isFlutterLocator &&
55+ ( proxyDriver instanceof XCUITestDriver ||
56+ proxyDriver instanceof Mac2Driver )
57+ ) {
58+ return { using : strategy , value : parsedSelector , context } ;
59+ } else {
60+ return { strategy, selector : parsedSelector , context } ;
61+ }
3962 }
63+
64+ elementBody = constructFindElementPayload (
65+ strategy ,
66+ selector ,
67+ this . proxydriver ,
68+ ) ;
4069 if ( mult ) {
4170 const response = await driver . command ( '/elements' , 'POST' , elementBody ) ;
4271 response . forEach ( ( element : any ) => {
@@ -52,9 +81,42 @@ export async function findElOrEls(
5281
5382export async function click ( this : AppiumFlutterDriver , element : string ) {
5483 const driver = ELEMENT_CACHE . get ( element ) ;
55- return await driver . command ( `/element/${ element } /click` , 'POST' , {
56- element,
57- } ) ;
84+
85+ if ( this . proxydriver instanceof Mac2Driver ) {
86+ this . log . debug ( 'Mac2Driver detected, using non-blocking click' ) ;
87+
88+ try {
89+ // Working around Mac2Driver issues which is blocking click request when clicking on Flutter elements opens native dialog
90+ // For Flutter elements, we just verify the element is in our cache
91+ if ( ! ELEMENT_CACHE . has ( element ) ) {
92+ throw new Error ( 'Element not found in cache' ) ;
93+ }
94+
95+ // Element exists, send click command
96+ driver
97+ . command ( `/element/${ element } /click` , 'POST' , {
98+ element,
99+ } )
100+ . catch ( ( err : Error ) => {
101+ // Log error but don't block
102+ this . log . debug (
103+ `Click command sent (non-blocking). Any error: ${ err . message } ` ,
104+ ) ;
105+ } ) ;
106+
107+ // Return success since element check passed
108+ return true ;
109+ } catch ( err ) {
110+ // Element check failed - this is a legitimate error we should report
111+ this . log . error ( 'Element validation failed before click:' , err ) ;
112+ throw new Error ( `Element validation failed: ${ err . message } ` ) ;
113+ }
114+ } else {
115+ // For other drivers, proceed with normal click behavior
116+ return await driver . command ( `/element/${ element } /click` , 'POST' , {
117+ element,
118+ } ) ;
119+ }
58120}
59121
60122export async function getText ( this : AppiumFlutterDriver , elementId : string ) {
0 commit comments