Michael Howell
Michael Howell

Reputation: 163

Finding an element by partial id with Selenium in C#

I am trying to locate an element with a dynamically generated id. The last part of the string is constant ("ReportViewer_fixedTable"), so I can use that to locate the element. I have tried to use regex in XPath:

targetElement = driver.FindElement(
    By.XPath("//table[regx:match(@id, "ReportViewer_fixedTable")]"));

And locating by CssSelector:

targetElement = driver.FindElement(
    By.CssSelector("table[id$='ReportViewer_fixedTable']"));

Neither works. Any suggestions would be appreciated.

Upvotes: 15

Views: 47757

Answers (3)

Greg
Greg

Reputation: 5588

That is because the css selector needs to be modified you were almost there...

driver.FindElement(By.CssSelector("table[id*='ReportViewer_fixedTable']"))`

From https://saucelabs.com/blog/selenium-tips-css-selectors-in-selenium-demystified:

css=a[id^='id_prefix_']

A link with an id that starts with the text id_prefix_.

css=a[id$='_id_sufix']

A link with an id that ends with the text _id_sufix.

css=a[id*='id_pattern']

A link with an id that contains the text id_pattern.

You were using a suffix which I'm assuming was not the partial link text identifier you were supposed to be using (unless I saw your html, which means try showing your html next time). *= is reliable in any situation though.

Upvotes: 37

iSunilSV
iSunilSV

Reputation: 11

This solution will work irrespective of the XPath version. First, create a method somewhere in your COMMON helper class.

 public static string GetXpathStringForIdEndsWith(string endStringOfControlId)
    {
        return "//*[substring(@id, string-length(@id)- string-length(\"" + endStringOfControlId + "\") + 1 )=\"" + endStringOfControlId + "\"]";
    }

In my case, below is the control ID in different version of my product ::

v1.0 :: ContentPlaceHolderDefault_MasterPlaceholder_HomeLoggedOut_7_hylHomeLoginCreateUser

v2.0 :: ContentPlaceHolderDefault_MasterPlaceholder_HomeLoggedOut_8_hylHomeLoginCreateUser

Then, you can call the above method to find the control which has static end string.

By.XPath(Common.GetXpathStringForIdEndsWith("<End String of the Control Id>"))

For the control ID's which I mentioned for v1 & v2, I use like below :

By.XPath(Common.GetXpathStringForIdEndsWith("hylHomeLoginCreateUser"))

The overall logic is that, you can use the below XPath expression to find a control which ends with particular string:

//*[substring(@id, string-length(@id)- string-length("<EndString>") + 1 )="<EndString>"]

Upvotes: 0

Prashant Shukla
Prashant Shukla

Reputation: 1389

try using

targetElement = driver.FindElement(By.XPath("//table[contains(@id, "ReportViewer_fixedTable")]"));

Note this will check for all the elements that have id which contains (and not only ends with 'ReportViewer_fixedTable'). I will try to find a regex option that would be more accurate answer to you question.

Upvotes: 2

Related Questions