Manu
Manu

Reputation: 2291

How to return WebElement having particular CSS property using JavascriptExecutor?

I am working on a scenario where I need to find a WebElement based on its CSS property, like background-color.

I have created the JQuery to find the element as below and it finds the webelement correctly using firefox console.

$('.search-bar-submit').each(function() { 
   return $(this).css('background-color') == '#fdd922'; 
});

screenshot of firefox console searching for webElement

Hence, I wrote the code to find this WebElement, i.e. searchbox and then tried to click it.

driver.get("http://www.flipkart.com/");
driver.findElement(By.id("fk-top-search-box")).sendKeys("iphone");

String query ="$('.search-bar-submit').each(function() { "
            + "return $(this).css('background-color') == '#fdd922'; });";
    
WebElement searchbox = (WebElement) ((JavascriptExecutor)driver).executeScript(query);
searchbox.click();

When I run the program, it gives me Exception in thread "main" java.lang.NullPointerException on line searchbox.click();

Can anyone help me out find the searchbox using JavascriptExecutor and then click on it? Am I missing something silly here?

Any help is appreciated. Thanks in Advance.

Upvotes: 4

Views: 2536

Answers (2)

Vicky
Vicky

Reputation: 3021

WebElement searchbox = (WebElement) ((JavascriptExecutor)driver).executeScript(query);

The above code calls the function but doesn't do anything with the result, ie. it doesn't return it to the caller.

Add return in the script to return the webelement to the selenium script(webdriver)

return $('.search-bar-submit').each(function() { 
   return $(this).css('background-color') == '#fdd922'; 
});

The return type is List<WebElement>so typecast it to List if you typecast it to it will throw an ClassCastException as arraylist cannot be cast to a webelement

Code:

 List<WebElement> searchbox = (List<WebElement>) ((JavascriptExecutor)driver).executeScript(query);

    for(int i=0;i<searchbox.size();i++){                     

    searchbox.get(i).click();

}

EDIT:

The code was not working in firefox because the firefox browser returns a json object of the webelement.Selenium replaced its uses of org.json with gson.So it is not able to understand the response recieved

Screenshot taken from chrome

Chrome

Screenshot taken from firefox

Firefox

Solution

We are using Jquery get function to retrieve the DOM Elements matched by the jquery object

$('.search-bar-submit').each(function() { 
   return $(this).css('background-color') == '#fdd922';
}).get(0);

Code

    public class jquerytest
    {

        public static void main(String[] args) throws Exception {

      WebDriver driver = new FirefoxDriver();

      driver.get("https://www.flipkart.com");

      driver.findElement(By.id("fk-top-search-box")).sendKeys("iphone");

      String query ="return $('.search-bar-submit').each(function() { "
                  + "return $(this).css('background-color') == '#fdd922'; }).get(0);";


      Thread.sleep(5000);//wait till page loads replace thread.sleep by any waits

      WebElement searchbox = (WebElement) ((JavascriptExecutor)driver).executeScript(query);

      searchbox.click();


    }
}

I have tested the above code on both chrome and firefox it works perfectly

Hope this helps you.Kindly get back if you have any queries

Upvotes: 2

Fi Horan
Fi Horan

Reputation: 512

I ran the following code and it all works fine. Your jquery works as well (I love the little message they print to console in the dev view hahaha).

driver.get("http://www.flipkart.com/"); 
WebElement in = driver.findElement(By.id("fk-top-search-box"));
in.sendKeys("iphone");
WebElement thing = driver.findElement(By.className("fk-font-bold"));
thing.click();

I believe there's a problem with your executeScript and it should be as follows.

System.out.println(((JavascriptExecutor)driver).executeScript(query, driver));

Normally the format for my calling javascript is as follows, this would be to remove the windowed attribute so that a hyperlink would open in the same tab:

String Href = linkObject.getAttribute("href");//located the hyperlink for the documents
Href = Href.substring(0, Href.length()-10)+")";//I remove ",'windowed'" from the link to stop it opening in a new window and having to change the scripts focus
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return arguments[0].href = \""+Href + "\"", linkObject););

But then you're getting JSON back and WebDriver can't understand that. See the following link for more information on that. http://grokbase.com/t/gg/webdriver/12ckjcthg8/executing-javascript-that-returns-json-how-best-to-handle

Might I suggest this alternative, it gives the background-color in rgba format:

WebElement pain = driver.findElement(By.className("search-bar-submit");
pain.getCssValue("background-color");

Upvotes: 1

Related Questions