Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to perform any actions on elements which were located under flexbox

Selenium is able to findElement which were located under flex box but not able to perform any actions on those elements. Below I am providing couple of sample websites for detailed understanding,


Example#1:

Website: https://condos.ca/

HTML snippet:

<div class="styles___SearchField-sc-ntshwn-1 azZjo">
   <div class="styles___SiteSearch-sc-ntshwn-3 bvlPAF">
  <div class="styles___InputIcon-sc-ntshwn-4 eAuylQ">
     <svg viewBox="0 0 59.93 60" class="styles___Svg-sc-14upfal-0 frvNPk svg-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: 20px; height: 20px;">
        <path d="M59.23,55.73L44.33,40.81a25,25,0,1,0-3.53,3.54L55.7,59.27A2.5,2.5,0,1,0,59.23,55.73ZM5,25A20,20,0,1,1,25,45,20,20,0,0,1,5,25Z" transform="translate(-0.03)"></path>
     </svg>
  </div>
  <input aria-label="Search by address, Neighbourhood, MLS #" placeholder="Search by address, Neighbourhood, MLS #" id="search-input">
   </div>
   <div class="styles___GetLocationContainer-sc-ntshwn-5 cCBUUE">
  <button target="_blank" name="search nearby button" class="styles___AppButton-sc-5pk18n-0 jXQNUT styles___SearchNearby-sc-ntshwn-6 dYpkAS" id="">
     <svg viewBox="0 0 20 20" class="styles___Svg-sc-14upfal-0 frvNPk svg-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: 22px; height: 22px;">
        <path d="M10,17.49c-4.19-0.02-7.57-3.39-7.55-7.53c0.02-4.14,3.42-7.48,7.61-7.47c4.18,0.02,7.56,3.37,7.55,7.51C17.6,14.15,14.19,17.5,10,17.49C10,17.49,10,17.49,10,17.49z M10,3.48C6.37,3.5,3.43,6.43,3.45,10.02c0.02,3.59,2.98,6.5,6.61,6.48c3.62-0.02,6.54-2.92,6.55-6.5c0-3.6-2.95-6.52-6.59-6.52C10.01,3.48,10.01,3.48,10,3.48z"></path>
        <path d="M10,3.48c-0.28,0-0.5-0.22-0.5-0.49V0.49C9.5,0.22,9.72,0,10,0s0.5,0.22,0.5,0.49v2.49C10.5,3.26,10.28,3.48,10,3.48z"></path>
        <path d="M10,20c-0.28,0-0.5-0.22-0.5-0.49v-2.51c0-0.27,0.22-0.49,0.5-0.49s0.5,0.22,0.5,0.49v2.51C10.5,19.78,10.28,20,10,20z"></path>
        <path d="M19.54,10.48h-2.43c-0.28,0-0.5-0.22-0.5-0.49c0-0.27,0.22-0.49,0.5-0.49h2.43c0.28,0,0.5,0.22,0.5,0.49C20.04,10.26,19.82,10.48,19.54,10.48z"></path>
        <path d="M3,10.49H0.46c-0.28,0-0.5-0.22-0.5-0.49c0-0.27,0.22-0.49,0.5-0.49H3c0.28,0,0.5,0.22,0.5,0.49C3.5,10.27,3.28,10.49,3,10.49z"></path>
        <path d="M10,13.49c-1.95-0.02-3.52-1.61-3.5-3.54c0.02-1.93,1.62-3.48,3.58-3.46c1.94,0.02,3.51,1.59,3.5,3.51c-0.01,1.94-1.61,3.5-3.57,3.49C10.01,13.49,10,13.49,10,13.49z M10,7.48C8.6,7.5,7.48,8.64,7.5,10.03c0.02,1.39,1.18,2.49,2.58,2.47c1.38-0.02,2.49-1.13,2.5-2.5c0-1.39-1.14-2.52-2.55-2.52C10.02,7.48,10.01,7.48,10,7.48z"></path>
     </svg>
  </button>
   </div>
</div>

Code:

driver.get("https://condos.ca");
driver.findElement(By.xpath("//input[@id='search-input']")).sendKeys("test");

Result: Step is being executed without throwing any errors but text was not entered.


Example#2:

Website: https://demoqa.com/slider

HTML snippet:

<div id="sliderContainer" class="form-group row">
   <div class="col-9">
  <span class="range-slider__wrap">
     <input type="range" class="range-slider range-slider--primary" min="0" max="100" value="25" style="--value:25;">
     <div class="range-slider__tooltip range-slider__tooltip--auto range-slider__tooltip--bottom" style="left: calc(25% + 5px);">
        <div class="range-slider__tooltip__label">25</div>
        <div class="range-slider__tooltip__arrow"></div>
     </div>
  </span>
   </div>
   <div class="col-3"><input id="sliderValue" class="form-control" value="25"></div>
</div>

Code:

driver.get("https://demoqa.com/slider");
JavascriptExecutor executor = (JavascriptExecutor) driver;
WebElement slider = driver.findElement(By.xpath("//input[@type='range']"));
System.out.println("Cuurent value: " + slider.getAttribute("value"));
executor.executeScript("arguments[0].setAttribute('value', ' 30 ')", slider);

Result: Printed attribute value but didn't set the new value.


Few SO questions and blogs are suggesting to use Selenium flex api to automate these these type of applications but I can see a pre-requiste to install flex plugin for eclipse and I cannot find that. Also, these post are little old (5 years old).

  • How to handle these elements?
  • Is there any new way to do this?

References:

  • Is selenium automation tool supports flex applications?
  • https://www.linkedin.com/pulse/automating-flex-application-selenium-webdriver-himanshu-tewari/
like image 984
Nandan A Avatar asked Dec 23 '21 09:12

Nandan A


People also ask

Why is flexbox not working?

Activation Troubleshooting If you're having trouble activating your Flex streaming TV Box, the most common solution is to restart it by reconnecting your USB-C power cord and HDMI cable to both the Flex streaming TV Box and TV.

How do you place elements in Flex?

Justify ContentFlex Start positions element at the start of the page. Flex End sets the element to the end of the page. Space Around arranges the items evenly but with spaces between them. The spaces will be equal among all the elements inside a flex-box container, but not outside them.

When using flexbox method what properties and values are used to display flex items in a column?

The flex-basis property The initial value of this property is auto — in this case the browser looks to see if the items have a size. In the example above, all of the items have a width of 100 pixels and so this is used as the flex-basis . If the items don't have a size then the content's size is used as the flex-basis.


1 Answers

Solution to Example 1

If you load the website, you will observe that the text above the search editbox initially looks like:

enter image description here

After sometime, the same element's text gets changed to: enter image description here

Only after this happens, try performing the sendkeys operation. Note that you don't have to perform the sendkeys operation on the element with id = 'search-input'. You first need to click on that element and then another element(cssSelector -> div[role='combobox'] [placeholder='Search by address, Neighbourhood, MLS #']) becomes visible on which you have to perform the sendkeys operation.

Please refer the code below for the same(tested on chrome, edge and firefox).

package usecase;

import java.time.Duration;
import java.util.regex.Pattern;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import io.github.bonigarcia.wdm.WebDriverManager;

public class Flexcase {
    public static WebDriver driver;
    private static final int maxtime = 20;

    /**
     * Creating a custom findElement method that uses Explicit wait and waits for an
     * element to be clickable
     */
    public static WebElement findElement(By by) {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(maxtime));
        return wait.until(ExpectedConditions.elementToBeClickable(by));
    }

    /**
     * Waits for an element to contain a text matched by the given pattern(regex)
     */
    public static Boolean doesElementContainTextPattern(By by, String pattern) {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(maxtime));
        return wait.until(ExpectedConditions.textMatches(by, Pattern.compile(pattern)));
    }

    public static void main(String[] args) throws InterruptedException {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://condos.ca/");
        // Waiting for the text to achieve a specific pattern - Search followed by 1+
        // occurrences of either digits or commas followed by 0+ occurrences of any
        // character that is not a newline character followed by the word Listings
        if (doesElementContainTextPattern(By.className("dPFjpJ"), "Search [\\d,]+.*Listings")) {
            findElement(By.id("search-input")).click();
            findElement(By.cssSelector("div[role='combobox'] [placeholder='Search by address, Neighbourhood, MLS #']"))
                    .sendKeys("Test");
        }

        Thread.sleep(10000); // Pls let me see what's happening on the screen
        driver.quit();
    }
}

Demo: enter image description here

Solution for Example 2

Instead of using javascriptexecutor, I have used the Actions class to build a composite action made up by following actions:

  • move the mouse to leftmost position of the slider by finding the slider width in pixels
  • move the mouse to the desired position on the slider proportiante to the percentage value passed

Code:(sliding accuracy can be improved)

package usecase;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

import io.github.bonigarcia.wdm.WebDriverManager;

public class Slider {

    public static WebDriver driver;

    public static void moveSliderToPosition(By by, int percentage) throws InterruptedException {
        WebElement slider = driver.findElement(by);
        Actions builder = new Actions(driver);
        builder.moveToElement(slider, (int) (-slider.getRect().width / 2), 0) // move to the leftmost position of the
                                                                                // element
                .moveByOffset((int) (percentage * slider.getRect().width / 100), 0) // move the cursor by an offset
                                                                                    // proportionate to the value passed
                .click().build().perform();
        Thread.sleep(3000); // let me see what has happened on the screen
    }

    public static void main(String[] args) throws InterruptedException {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://demoqa.com/slider");
        By slider = By.cssSelector("input.range-slider");
        moveSliderToPosition(slider, 47);
        moveSliderToPosition(slider, 83);
        moveSliderToPosition(slider, 35);
        driver.quit();
    }
}

Demo: enter image description here

like image 189
Gurmanjot Singh Avatar answered Nov 02 '22 18:11

Gurmanjot Singh