7

I am using selenium 2 (WebDriver).

I am locating a button and clicking by the script:

driver.findElement(By.cssSelector("button:contains('Run Query')")); 

or

driver.findElement(By.cssSelector("css=.gwt-Button:contains('Run Query')")) 

whose html is like :

<button type="button" class="gwt-Button" id="ext-gen362">Run Query</ 
button> 

As the id is dynamically generated, I can't make use of the ID.

Is there any way to use cssSelector with something like contains ? Is this possible?

Vince Bowdren
  • 8,326
  • 3
  • 31
  • 56
Nick Kahn
  • 19,652
  • 91
  • 275
  • 406

6 Answers6

12

You can't do this with CSS selectors, because there is no such thing as :contains() in CSS. It was a proposal that was abandoned years ago.

If you want to select by the element text, you'll have use an XPath selector. Something like

driver.findelement(By.xpath("//button[contains(., 'Run Query']"))

or

driver.findelement(By.xpath("//[contains(concat(' ', @class, ' '), ' .gwt-Button ') and contains(., 'Run Query']"))

Ross Patterson
  • 9,527
  • 33
  • 48
  • 1
    i am trying to avoid using xpath because its slow and it fails most of the time to detect the element and its pain to use xpath. – Nick Kahn Jan 30 '13 at 03:41
  • 4
    XPath is no less reliable than any other location method. There's no rule that says you must use the same location method every time. If you're forced to use XPath in a few locators, that's a performance hit that should be acceptable. – JimEvans Jan 30 '13 at 11:16
3

Another option is using jQuery, if it's present on the page, something like:

var webElement = ((JavascriptExecutor)driver).executeScript("return jQuery('button:contains(Run Query)')");
Arran
  • 24,648
  • 6
  • 68
  • 78
0

CSS alone will not get you what you need; you cannot filter by the text. You could either use js to get the id of the element, or loop through all the buttons in your code until you find the one with the right text. If this were in python:

[btn for btn in browser.find_elements_by_css_selector('button')
 if 'Run Query' in btn.text]

You could easily generalize this and make a helper function, too.

Community
  • 1
  • 1
outofculture
  • 6,023
  • 1
  • 18
  • 20
0

I'm in the same boat, currently using XPath selectors with "contains" to find elements with specific text content. Some are <td> and some are <td><a> deep within large tables (specific columns, but row unknown in advance). It's very slow (4 to 5 seconds just to find such a table entry with Firefox 20), so I was hoping to use CSS to be faster. Often the text will be by itself (complete) and other times it will be a filename at the end of a path I'd like to ignore. Does anyone have suggestions for the fastest XPath search pattern, given that it's a known column but unknown row, and may be a <td> or <td><a> (sometimes in the same table). Would an equality comparison be much faster than contains(), for the majority of cases where the text I'm looking for is complete (not at the end of other text)? I think there's a "starts with" lookup, but is there an "ends with" lookup? I know that using an "id" would be even faster, but unfortunately this HTML doesn't have any IDs here, and they can't be added. I'm looking to find the <tr> containing this text so I can locate another element in the same row and get its text or click on a link. It doesn't hurt to locate a small subset of the rows and check their text, but I'd like to avoid doing separate searches for <td> and <td><a> if that's possible.

Phil Perry
  • 2,126
  • 14
  • 18
0

You cannot use contains but use a wild card instead.

driver.findElement(By.cssSelector("button:(*'Run Query'*)")); 
Jinesh
  • 1
-1
driver.findElement("#ext-gen362").Where(webElement => webElement.Text.Contains("Run Query"))
Papershine
  • 4,995
  • 2
  • 24
  • 48
Shubham
  • 1
  • 1
  • 1
    It's good practice on Stack Overflow to add an explanation as to why your solution should work. For more information read [How To Answer](//stackoverflow.com/help/how-to-answer). – Samuel Liew Apr 10 '18 at 00:46