appium / appium-xcuitest-driver

Appium iOS driver, backed by Apple XCTest
https://appium.github.io/appium-xcuitest-driver/
Apache License 2.0
752 stars 420 forks source link

InvalidArgumentException thrown with msg: The XCUITest driver only supports W3C actions execution in the native context. #2468

Closed PrasadNutalapati closed 1 month ago

PrasadNutalapati commented 2 months ago

@jlipps @saikrishna321 Gurus; Here is the same issue as #1928, but in a different way. I am running the same MobileWeb test on Android and iOS one after another. With Android, the default context is 'CHROMIUM' and it is running the entire test just fine whether I shifted to 'CHROMIUM' context or not. With iOS, even after shifting to _WEBVIEW1097.1 which is the WebView context name, I am facing the following error message org.openqa.selenium.InvalidArgumentException: The XCUITest driver only supports W3C actions execution in the native context. when the below code was ran actions.moveToElement(categoryElm).click(categoryElm).build().perform(); Basically, it is like moving to the Element 'categoryElm' and trying to click it, using the Actions class. I am not trying to do any gesture actions. I have to use this Actions class approach because other methods of click() such as WebElement.click(), JavascriptExecutor are not working for my page. What is the coding approach for this issue to be used to overcome ?

Thanks a lot. --Prasad Nutalapati

PrasadNutalapati commented 2 months ago

I want to add this: As per the suggestion in the issue#1928 I incorporated the looping in order to shift in to WEB_VIEW, and using CHROME browser, as below,

This time the script could not go past the first web element locator, and failed doing it. Basically it is TOTALLY FAILING with CHROME browser.

    /**
     * context switcher ==> https://github.com/appium/appium/issues/16481
     * In our case with iOS 17.6.1 real device, iOS webview is available by adding webviewConnectTimeout capability.    
     * 
     * @throws InterruptedException
     */
        public void changeDriverContextToWeb() throws InterruptedException {
            Thread.sleep(2000);
            if (platform.equalsIgnoreCase("Android")) {
                Set<String> allContexts = ((AndroidDriver) driver).getContextHandles();//'Set' ensures non duplicate values
                System.out.println("Android allContexts = "+allContexts);
                for (String context : allContexts) {
                    if (context.contains("WEBVIEW")) {
                        System.out.println("Android allcontexts has WEBVIEW");
                        ((AndroidDriver) driver).context(context);
                    } // if
                } // for
        System.out.println("Current Android Context="+((SupportsContextSwitching)driver).getContext());
            } else {                 //"iOS"
                Integer loopCount = 1;
                while (loopCount < 10) { // looping ONLY for 'iOS' 
                    Thread.sleep(10000); // sleep and hope the driver eventually pulls the webview context
                    Set<String> allContexts = ((IOSDriver) driver).getContextHandles();//Set ensures non duplicate values
                    System.out.println("iOS allContexts = "+loopCount+", "+allContexts);
                    for (String context : allContexts) {
                        if (context.contains("WEBVIEW")) {
                            System.out.println("iOS allcontexts has WEBVIEW");
                            ((IOSDriver) driver).context(context);
                            loopCount = 11;//exit 'while', once 'for' is done
                        } // if
                    } // for
         System.out.println("Current iOS Context="+loopCount+", "+((SupportsContextSwitching)driver).getContext());
                    loopCount++;
                } // while
            } // else
        }// method

the console output as

_driver instanceof AppiumDriver=true iOS allContexts = 1, [NATIVE_APP] Current iOS Context=1, NATIVE_APP

iOS allContexts = 2, [NATIVE_APP] Current iOS Context=2, NATIVE_APP

iOS allContexts = 3, [NATIVE_APP] Current iOS Context=3, NATIVE_APP

iOS allContexts = 4, [NATIVE_APP] Current iOS Context=4, NATIVE_APP

iOS allContexts = 5, [NATIVE_APP] Current iOS Context=5, NATIVE_APP

iOS allContexts = 6, [NATIVE_APP] Current iOS Context=6, NATIVE_APP

iOS allContexts = 7, [NATIVE_APP] Current iOS Context=7, NATIVE_APP

iOS allContexts = 8, [NATIVE_APP] Current iOS Context=8, NATIVE_APP

iOS allContexts = 9, [NATIVE_APP] Current iOS Context=9, NATIVEAPP

jlipps commented 2 months ago

I'm sorry, it's not clear from this report what you are saying the problem is? Is it that you can't find the webview on iOS even after looping?

PrasadNutalapati commented 1 month ago

@jlipps I could see WebView on iOS only after adding webviewConnectTimeout to the capabilities, which is fine. Android by default is starting with Chromium view, which is working like WebView, where as iOS is starting with Native which needs to be shifted to WebView (after only adding the webviewConnectTimeout capability). This is what I wanted to convey.

jlipps commented 1 month ago

Yes, whether or not iOS automatically looks for a webview is dependent on your capabilities. If you're using the safari browser, or setting appium:autoWebview to true, the session will start you in a webview that it finds.