How do I extract the inner element in Selenium?



  • I am new to Selenium and C#, which we are using right now. I am also new to using the Page Object model, to make our codes readable. Though I am having troubles using the FindsBy, so my original code was this:

    public static string WarningLabel(IWebDriver driver, string element, string elementtype)
    {
        return driver.FindElement(By.CssSelector(".col-md-12")).FindElement(By.TagName("li")).Text;
    }
    

    Now, to display the value from that element I did this:

    public void userValidate()
    {  
       var warn = GetMethods.WarningLabel(driver, "li", "Xpath");
       Console.WriteLine(warn);
    }
    

    Now, I tried the xpath using the FindsBy

    [FindsBy(How = How.Xpath, Using = "//div[1]/div[2]/div/div/div/div/ul/li")]
    public IWebElement warnLabel { get; set; }
    

    now I am trying to display it on console, it would give me the value 0. How do I display the correct value using the xpath? That xpath was working when I used it in the WarningLabel method.



  • "//div[1]/div[2]/div/div/div/div/ul/li"
    

    That XPath looks like it might be prone to breaking. It's strongly dependent on other elements up the tree so any peripheral changes that affect any of those other elements being referenced will change the absolute location of the specific warning label you want. I would first suggest using CSS selector instead of an XPath if you're able. But if not, I would look into XPath functions with the goal of trying to target the specific element you want, while touching as few others along the way as possible. You want to strike a balance between it being both concise and reliable.

    Using your original snippet which you said worked as you expected:

    driver.FindElement(By.CssSelector(".col-md-12")).FindElement(By.TagName("li")).Text;
    

    This solution is definitely on the right track, although it is probably not necessary to chain two different locators.

    As a CSS selector, this can become .col-md-12 li. What this says is that we want to target a li element that is some child node of an element with the class attribute col-md-12, which is achieved by the space in between the two elements being referenced. Which would look like driver.FindElement(By.CssSelector(".col-md-12 li").Text;

    As an XPath, this can become //div[contains(@class, 'col-md-12')]//li. // means that the element that comes after it can exist anywhere that is a child of the element that was declared before it. Having // at the beginning says that it can start looking anywhere in the DOM.

    Using your FindsBy solution it could look like:

    [FindsBy(How = How.CssSelector, Using = ".col-md-12 li")]
    public IWebElement warnLabel { get; set; }
    

    or

    [FindsBy(How = How.Xpath, Using = "//div[contains(@class, 'col-md-12')]//li")]
    public IWebElement warnLabel { get; set; }
    


Suggested Topics