2

I'm writing some Selenium tests in Java and will later need to find elements by DOM attributes that are not visible in the html. The code below attempts to find the search bar in google using the "class" attribute and then the DOM attribute "checked". Only the first of these works for me, the 2nd one fails with "Unable to locate element".

I assume that I'm either doing something wrong with the xpath or that I'm not understanding the DOM attributes correctly. I tried with several other attributes in the DOM but always get the same result. I also tried using cssSeletor instead of xpath, but again with the same results.

As indicated in the code I use Chrome (with Windows 7).

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.remote.DesiredCapabilities;

public class SeleniumTest {

    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "D:\\Selenium\\Drivers\\chromedriver.exe");
        DesiredCapabilities caps = DesiredCapabilities.chrome();
        WebDriver driver = new ChromeDriver(caps);
        driver.manage().window().maximize();
        driver.get("http://www.google.com");
        WebElement elementByClass = driver.findElement(By.xpath("//input[@class='gsfi']"));
        WebElement elementByDOM = driver.findElement(By.xpath("//input[@checked='false']"));
    }
}

Edit: If I inspect the google searchbar with F12 dev tool I find the html:

<input spellcheck="false" dir="ltr" style="border: medium none; padding: 0px; margin: 0px; height: auto; width: 100%; background: transparent url(&quot;data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D&quot;) repeat scroll 0% 0%; position: absolute; z-index: 6; left: 0px; outline: medium none;" aria-autocomplete="both" role="combobox" aria-haspopup="false" class="gsfi" id="lst-ib" maxlength="2048" name="q" autocomplete="off" title="Søk" value="" aria-label="Søk" type="text">

If I inspect the DOM proprties of this element I can see the attribute "checked"=true. See image:

7
  • What is the html element that you are trying to find ? When i do the search of your second xpath - //input[@checked='false'], i don't find any element at all. Can you share the html code too? Commented Sep 25, 2015 at 8:29
  • Your code is looking correct but importabt point is your html code. Please can you share piece of html code you try? Commented Sep 25, 2015 at 8:35
  • I added html of the search box element to the question. Commented Sep 25, 2015 at 8:39
  • You posted a wrong HTML part. You have a text input, not a checkbox. Commented Sep 25, 2015 at 8:40
  • If I click on the html of that input I can under properties in chrome see the attribute ´checked: false´. Am i viewing the DOM properties incorrectly? Commented Sep 25, 2015 at 8:45

2 Answers 2

2

There are a couple problems with your approach.

XPath works literally

The XPath expression you use //input[@checked='false'] will match only input elements that have the attribute checked explicitly set to "false". It will not take into accounts those input elements where checked is not set an therefore has the default value of false.

Attributes !== properties

What you need to check if you want to know whether an input is currently checked is its checked property not the attribute. The attribute only serves to give an initial value to the property. After that, manipulating the input won't change the attribute (unless you actually write code to do it). What will change are the properties of the input. Your XPath checks attributes, and XPath cannot be used to select by properties.

There is a pseudo-class selector you can use for this: :checked.

driver.findElement(By.css("input:checked"));

You can use input:not(:checked) to find the unchecked ones.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the clarification of the difference between attributes and proprties. Your solution solves my problem:)
0

Hi After some research and initial struggle with selenium I have learnt that you can execute javascript using Selenium JavaScriptExecutor class to access any of the DOM properties of a web control. So I have designed a generic function which can search for any web control on the page provided you input the unique DOM properties of that control which you are searching on the browser. As this function is traversing through the DOM hierarchy it can actually work across multiple browsers. Have a look

` 
/// <summary>
        /// Fetch the object reference of any control on the screen
        /// Please Note : Make sure you pass unique objPropNames,objPropValues    of the control,
        /// if not then the first matched control is returned
        /// </summary>
        /// <param name="driver"></param>
        /// <param name="objPropNames"></param>
        /// <param name="objPropValues"></param>
        /// <param name="elementTagName"></param>
        /// <returns></returns>
        public static IWebElement GetWebObject(IWebDriver driver,string[] objPropNames, string[] objPropValues, string elementTagName)
        {
            IWebElement webObj = null;
            //string elementPropVlu;

            //string propName, propVlu;
            try
            {
                IList<IWebElement> lstElement = driver.FindElements(By.TagName(elementTagName));
                foreach (var item in lstElement)
                {
                    //reset the flag to true for every iteration
                    bool objectFound = true;

                    for (int i = 0; i < objPropNames.Length; i++)
                    {
                        ObjPropName = objPropNames[i];
                        ObjPropVlu = objPropValues[i];
                        //get the value of the attribute
                        //elementPropVlu = item.GetAttribute(ObjPropName.ToString());
                        var elementPropVlu = (Object)null;
                        try
                        {
                           elementPropVlu = ((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0]." + ObjPropName + "; ", item);
                        }
                        catch (InvalidOperationException ex)
                        {


                        }
                        if (elementPropVlu != null)
                        {
                            if (elementPropVlu.ToString().ToLower().Trim() != ObjPropVlu.ToString().ToLower().Trim())
                            {
                                objectFound = false;
                                break;
                            }
                        }                     

                    }
                    //if all the prop values of that object are satisfied then the match is found which 
                    //means the element we are searching for is found
                    if (objectFound)
                    {
                        webObj = item;
                        break;
                    }
                }
            }
            catch (NoSuchElementException e)
            {
                //throw;
                //log the exception
            }
            return webObj;
        }` 

Usage :

GetWebObject(DriverContext.Driver, new string[] { "checked", "className" }, new string[] { "false", "gsfi" }, "INPUT")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.