2

I was not able to get satisfactory answer after searching on google. So could you please guide me on this? I have a div containing li,a,labels below it. I am able to find the div using CssSelector by its class name. Now inside this div I want to get a label with its text and then click on it. The label is as belo:

<label>Sign Out</label>

How to do that ?

I have a working solution using XPath and iterating over all labels inside div, but I am unable to get it using CssSelector.

My Solution:

IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
IWebElement logoutLabel = menu.FindElement(By.XPath("//label[text()='Sign Out']"));

or by using foreach:

var coll = menu.FindElements(By.TagName("label"));
foreach (var label in coll)
{
  if(label.Text.Trim() =="Sign Out")
  {
      Log("Sign out was found.");
      label.Click();
      break;
  }
}

I tried with CssSelector:

IWebElement logoutLabel = menu.FindElement(By.CssSelector(":contains('Sign Out')"));
IWebElement logoutLabel = menu.FindElement(By.CssSelector("label:contains('Sign Out')"));
IWebElement logoutLabel = menu.FindElement(By.CssSelector("label['Sign Out']"));

But these are not working.

rahoolm
  • 733
  • 2
  • 12
  • 22

2 Answers2

12

There is a very good reason why your CSS selector wouldn't work, specifically the contains bit is where it falls over. Why?

It isn't part of the CSS selector specification, and therefore would never work.

The contains that we all know and love is actually coming from Sizzle, the CSS selector engine behind jQuery.

If you want text-based searching, you will either have to use XPath, or get a collection of those elements (using any locator you see fit) and then filter them down in code (like you have done in your foreach loop). There isn't a native CSS-style way to do "text based searching".

In terms of your current code, you will probably also fall over because XPath requires a little "poking" to tell it to search only the child elements of your current "element".

IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
IWebElement logoutLabel = menu.FindElement(By.XPath("//label[text()='Sign Out']"));

Should be:

IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
IWebElement logoutLabel = menu.FindElement(By.XPath(".//label[text()='Sign Out']"));

(Note the "." in the XPath)

Also, your foreach loop should have worked, therefore you will have to put a breakpoint in there and check exactly what is being returned by menu.FindElements(By.TagName("label"));.

Arran
  • 24,648
  • 6
  • 68
  • 78
  • 1
    Thanks a lot! This is a very good answer and you explained in detail. By adding break point analyzing further I was able to understand in detail. I think my method of iterating using foreach is more suitable for my needs. Thanks Arran! regards, rahoolm – rahoolm Dec 20 '13 at 19:10
  • This opened up my eyes on finding things for my company. I knew the jQuery worked for the IDE, but when writing the C# code I was getting issues. Being able to located via XPath allows me to select the things I can physically see with names on them. Now if it moves on the page, the script won't break! Thanks! – IamBatman Jan 05 '17 at 23:40
2

You are using :contains(), which is a jQuery selector, not a CSS selector. Apparently there is no way to achieve such thing using only CSS.

More info CSS selector based on element text?

Community
  • 1
  • 1
pepo
  • 669
  • 4
  • 7