Appium finding an element that need to be scrolled into view



  • I am testing a mobile application using Appium + Selenium + Java.

    I have a page who contains several elements with the following ids:

    • field_1
    • field_2
    • field_3
    • bouton_1

    When I open the page. The element "field_1" and "field_2" are visible but the other two need to be scrolled into view.

    Since I need to interact with all four of these elements, I first need to find them. Here is how I do it:

    WebDriverWait wait = new WebDriverWait(driver,10);
    wait.until(ExpectedConditions.presenceOfElementLocated((By.xpath("//*[@resource-id='"+id+"']"))));
    WebElement element = driver.findElement(By.xpath("//*[@resource-id='"+id+"']"));
    

    This way of doing things work fine for my elements "field_1" and "field_2" but doesn't for the other two and I got the following error:

    org.openqa.selenium.TimeoutException: Expected condition failed: waiting for presence of element located by: By.xpath: //*[@resource-id='field_3'] (tried for 10 second(s) with 500 milliseconds interval)
    

    However, if I manually scroll into view, the elements are found without any issues.


    Is it expected behavior that selenium can't find an element who is here but need to be scrolled into view? I never had this issue when I was testing web applications on desktops.

    How can I find those elements when the only information I have about them is their id? I'm thinking of using some "scroll method", but I wasn't able to find one that fit my needs.

    I'm aware of this one but it seems like you have to specify how much you want to scroll and I don't know that (it depends of what mobile phone you are using. So I would need to get this information dynamically).

    I'm also aware of this "scroll to text" method (another link about this here), but I don't have a text/name here. I just have an id.


    Here are the relevant information on my pom:

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.141.59</version>
    </dependency>
    
    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>7.3.0</version>
    </dependency>
    


  • For Android:

    You can scroll till you don’t find element with given resource id. This can be achieved with UiAutomator2as automation engine. You need to use automation name as UiAutomator2 in desires capabilities.

    Add in desired capability UiAutomator2 if you are using appium as automation engine.

    capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
    

    Now use below functions if you have element's resource id, and index as 0 if there is one element on page.

    public void scrollByID(String Id, int index) {
    
            try {
    
                 driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().resourceId(\""+Id+"\").instance("+index+"));")); 
    
            } catch (Exception e) {
               e.printStackTrace();
            }
        }
    

    This is dynamic approach it will scroll till element is not visible.

    For IOS:

    Best practice for performing controlled scrolling using the Appium “mobile:scroll” script command. This command is performed using the executeScript() method.

    RemoteWebElement element = (RemoteWebElement)driver.findElement(By.className("XCUIElementTypeTable"));
    String elementID = element.getId();
    HashMap<String, String> scrollObject = new HashMap<String, String>();
    scrollObject.put("element", elementID); 
    scrollObject.put("direction", "down");
    driver.executeScript("mobile:scroll", scrollObject);
    

    element: The id of the element that you want to scroll – “element” must be scrollable.

    direction: “up”, “down”, “left, “right”.

    More details about scrolling on IOS check here



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2