3

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.

7
  • That xpath looks like it might be prone to breaking. It's strongly dependent on other elements so any peripheral changes that affects any of those other divs will change the absolute location of the specific warning label you want. I would first suggest using css selectors instead of xpaths 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 so it only targets the element you want. – Julian Jun 10 '16 at 17:27
  • Just to clarify, this works using your WarningLabel method solution, but does not work when you try to target the same element using the FindsBy solution? – Julian Jun 10 '16 at 17:28
  • Yes this works using my WarningLabel method solution, the reason why I used the Xpath using FindsBy is because i don't know how to call the "li" element – Marj Jun 10 '16 at 18:41
  • You could try using a css selector in your FindsBy solution by combing the exact two you use in the method. .col-md-12 li will find a li tag name that is a child of another element that has the css class col-md-12 – Julian Jun 10 '16 at 20:24
  • 2
    Or an xpath that matches your method's solution could be made such as //div[contains(@class, 'col-md-12')]//li (substituting div for whatever the actual tag name is). – Julian Jun 10 '16 at 20:27
3
"//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; }
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.