Finding an element by partial id with Selenium in C# - 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.

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.

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.

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>"]

Related

How do I get a Title of the link in AngleSharp item object?

Here is a link:
<a title = "mylink" href="mysite">content</a>
In AngleSharp object I can easily get content with this code:
string innerContent = item.TextContent;
But I need to get a title of the link and also a href. How do I do that?
Note that AngleSharp uses the standard DOM as defined by the W3C - thus you can just search for, e.g., "how to get href from anchor element in DOM" to retrieve an answer. For completeness, the example search query leads to (first hit on Google) Get local href value from anchor (a) tag, which answers your question.
Just translated to C# that means
var anchor = item as IHtmlAnchorElement; // Assumption: You have obtained it "only" as an IHtmlElement
string title = item.Title;
string href = item.Href;
Remark: There is a difference between .GetAttribute("href") and .Href. The former is always available (even on non-IHtmlAnchorElement) and gives you the real value. The latter is a special computed version available on some elements (e.g., IHtmlAnchorElement) and will get you a normalized version, already considering the base URL of the current document.
TL;DR: .Href will give you an absolute URL while .GetAttribute("href") may give you a relative URL.
HTH!

Selenium find element via Data-Qa attribute

I have building my Selenium framework. All the elements need to be found by Data-QA. I am unsure on how to do this. I have done the pervious using Ids that was simple enough. I cannot find data qa in the find element by
Would anyone be able to point me in the right direction.
It looks like you are attempting to find elements with a particular value for a specific attribute. I don't know C#, but with Python the following should work (I like to use a CSS selector):
all_login_inputs = find_elements_by_css_selector("input[data-qa='input_login_operator']")
this will return a list of elements that have a tag "input" with the "data-qa" attribute set to the value "input_login_operator"
It looks like there are extra single quotes in the HTML, inside the double quotes:
data-qa="'input_login_operator'"
I would remove the single quotes from the DOM, or escape them in the CSS selector.

Find second div with same class

Trying to find second div with same class on a page. I only retrieve the first one when fetching the data and cannot figure out how to get the second or third etc..
HtmlAgilityPack.HtmlDocument data = web.Load(URL);
var res = data.DocumentNode.SelectSingleNode("//div[#class='col-sm-5']");
Also I'm using two slash signs in the start, I don't know why but it worked. I've seen numerous of different solutions ("/", "./" "//" ".//"). Could someone explain the difference please?
Thanks in advance,
xolo
Try this command:
var res = data.DocumentNode.SelectNodes("//div[#class='col-sm-5']");
This is the difference between single and double slash:
/
start selection from the document node
allows you to create 'absolute' path expressions
e.g. ā€œ/html/body/pā€ matches all the paragraph elements
//
start selection matching anywhere in the docume
allows you to create 'relative' path expressions
e.g. ā€œ//pā€ matches all the paragraph elements

Combining Regex with Selenium in C#

I have a Automation Suite, currently testing against Wordpress (a test site to practice against). I am attempting to verify when a user edit's an existing Page they are taken to the correct screen. Previously the following code snippet was working fine, however now the ID mentioned below is no longer present (it was an image).
public static bool IsInEditMode()
{
return Driver.Instance.FindElement(By.Id("icon-edit-pages")) != null;
}
Assert.AreEqual(NewPostPage.IsInEditMode(), "You are not in edit mode");
The HTML I am targeting is...
<h2>
Edit Page
Add New
</h2>
I would like to extract the value of the h2 tag 'Edit Page'. Currently I am also getting the value of the anchor 'Add New', which I need to ignore.
using a CssSelector with "h2:first-child" returns both values.
I think I need to use a regular expression, if anyone has any suggestions to help that would be great.
I attempted doing something similar in JSFiddle but require the C# equivalent
var myString = document.getElementsByTagName('h2')[0].innerHTML;
var newString = myString.replace(/<([^>]+?)([^>]*?)>(.*?)<\/\1>/ig, "");
console.log(newString);
You can also get the parent element's text and remove the child element's text from it:
var parent = Driver.FindElement(By.TagName("h2"));
var child = parent.FindElement(By.TagName("a"));
var text = parent.Text.Replace(child.Text, "").Trim();
You can use StringAssert to verify if the string to check contains the expected string. I think is better because you not need to use regex
Example:
StringAssert.Contains(message, expectedmessage);

Adding string variable to xpath c# selenium

I have probably spent a good 8 hours trying to figure this out but am constantly failing. I have searched an age for a solution
I am trying to find an selenium element by partial id match using xpath (c# selenium libraries). The following works perfectly fine. The partial text is sel_1-rowse1
IWebElement elem = wait5.Until(x => x.FindElement(By.XPath("//a[contains(#id,'sel_1-rowsel')]")));
However when I want to use a variable named partial this does not work
string partial = "sel_1-rowse1";
IWebElement search = wait.Until(x => x.FindElement(By.XPath(String.Format("//a[contains(#id,'{0}')]", partial))));
or
IWebElement search = wait.Until(x => x.FindElement(By.XPath(String.Format("//a[contains(#id,{0})]", partial))));
I have tried single quotes double quotes and escape chars. But cant figure this out. I cant even provide the error as its picking up a valid id. Brain is severely depleted on this one.
Just an observation, the first example element id ends with lower case 'L' (so l) while the second one with number 1. Might be just a copy paste error but worth asking...
partial is a reserved keyword in C#.
Refactor partial to something else (not reserved by C#) and you should be golden.

Categories