I would like a to find a way to store the text from within a read only element.
IWebElement LName = Driver.Instance.FindElement(By.XPath(".//*[#id='inputGrid']/div[1]/div[1]/div/div[1]/table/tbody/tr[1]/td[4]"));
string LNValue = LName.GetAttribute("value");
The result of this code is that LNValue is empty.
However, LName is a cell that contains this text: "********"
If I inspect the element, I can see this:
<td class="htDimmed fill">********</td>
<td class="htDimmed">*********</td>
Since code is being written in C#, you can use built in "Text" property to fetch the innerHTML of that element and it should work in all browsers.
String LNValue= LName.Text;
Moreover make sure that XPath is correctly reaching the element as well..I hope this helps
You can use the textContent attribute to get the text. AFAIK, the td element doesnot have a value attribute.
string LNValue = LName.GetAttribute("textContent");
You could also use the innerText attribute, but that is not supported across all browsers.
Related
I just started looking into XPath but am a little confused on the following.
I'm parsing HTML (using the HTML-Agility-Pack in C# / .NET) and I'm able to call the contains function on the "class" attribute for an HTML element to only select the nodes whose class contains a specific value.
For example, the top answer on this SO: How can I match on an attribute that contains a certain string?
But I'm unable to call the contains function on the "href" attribute of the HTML "a" (hyperlink) element.
For example, it seems like a more complicate solution is needed, as per this SO accepted answer: Xpath get a if href contains part of string
And if I try to use the following XPath code, I get the ArgumentNullException: "Value cannot be null" exception.
//td/a[contains(#href, 'part-of-the-hyperlink')]
This is the relevant part of HTML I'm trying to select:
<td>
<a href="/name/part-of-the-hyperlink">
Hugh Dane
</a>
</td>
What am I missing?
Change
//td/a[contains(href, 'part-of-the-hyperlink')]
to
//td/a[contains(#href, 'part-of-the-hyperlink')]
to test the attribute, href, otherwise you're testing the href child element (which doesn't exist).
I have piece of code as below
<div class="span6" style="text-align:right;">
<span class="muted" style="padding-left:20px;">Member ID: </span>MKL123451KKM
<span class="muted" style="padding-left:20px;">Service Date: </span>05/08/2018
</div>
in above code i want to get the value "MKL123451KKM", this value is going to change often.
i have tried with below xpaths which was giving error.
XPATH :
/html/body/div/span[1][contains(text(),'Member ID:')]/../text()
/html/body/div/span[1][contains(.,'Member ID:')]/../text()
ERROR :
The result of the xpath expression :
/html/body/div/span[1][contains(text(),'Member ID:')]/../text() is: [object Text]. It should be an element.
NOTE:
i am using selenium driver for IE and c# with VS 2015 IDE
Can anybody throw light on this?
You were fairly close. It's generally not a good practice to create a locator that starts at the HTML tag or has too many levels because it's more brittle (more likely to break when the page changes). Ideally you would find the label element by text label, e.g. "Member ID", and then locate the following text node. The big benefit of this method is that it's tied to the "Member ID" label. Some of the other answers are hard-coded to a specific text node which may be good now but if the data changes, it may return the wrong value.
You can wrap this all in a function where you pass in the label and it returns the value.
public string GetValue(string labelName)
{
IWebElement e = Driver.FindElement(By.XPath($"//span[contains(.,'{labelName}')]"));
string s = (string)((IJavaScriptExecutor)Driver).ExecuteScript("return arguments[0].nextSibling.textContent;", e);
return s.Trim();
}
and you would call it like
GetValue("Member ID")
As per the HTML you have shared the text MKL123451KKM is not within any child <span> node but within the parent <div> node. To extract the text e.g. MKL123451KKM you can use the following code block :
IWebElement elem = driver.FindElement(By.XPath("//div[#class='span6']"));
string text = (string)((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0].childNodes[2].textContent;", elem);
That's because the text is within the div. You will need to get text from xpath:
//div[#class='span6']
Even though this xpath isn't very change-proof, it should work if you get text from it. The text though will be MKL123451KKM and 05/08/2018
Try this XPath
//div[#class='span6']/span/following-sibling::text()[1]
The element that I’m talking about is the following:
<tbody>
<tr
id="tableUsers_0__TR"
class="active"
name="Tr_tableUsers[0]_Selected">
<td>
<input
id="tableUsers_0__POSName"
type="hidden"
value="Indian"
name="tableUsers[0].POSName"/>
Indian
</td>
The solution that I propose is:
The first step is locate the element by XPath:
string xpath = ".//*[#id='tableUsers_0__PDVCode']/..";
Then get the text with the method:
driver.FindElement(By.XPath(xpath)).Text
Is it the best way? Or not?
Is there another better way than this way? Better than the use of XPath?
JavaScript Executor can also be used to return the element's text. The following script can be used:
document.getElementById('<your id>').innerText
or
document.getElementById('<your id>').textContent
To get this, the object of JavascriptExecutor has to be created first. Refer to the following script:
IWebDriver driver; // A driver object is created in the code somewhere
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
string valueFromId = (string)js.ExecuteScript("return document.getElementById('<your id>').innerText");
You can also verify this text by running the JavaScript command (document.ge...) in the browser's console.
You can use the selector By.Id("your id").
For some elements, it’s much more useful to use IWebElement.GetAttribute("text") than IWebElement.Text
Yes, a better way than using an XPath expression is to use By.id as:
driver.FindElement(By.Id("tableUsers_0__TR")).Text
Or use By.CssSelector:
driver.FindElement(By.CssSelector("tr#tableUsers_0__TR td")).Text
Note: It always gives the last priority to the XPath locator, because it is much slower than other locators. In your case, if the element has an id attribute then the best way is to use By.Id(). Otherwise, try to locate the element using other locators, like By.Name(), By.ClassName(), By.CssSelector(), etc. if it could be possible.
C# Selenium Webdriver
So i need to ensure that none of my pages (around 200 pages) contain a particular known string. Is there any way that i can scan a page for the existence of this string and if it does then return both the ElementID of that element and the entire string?
For example my source is like:
<a id="cancel_order_lnkCancel">Cancel Order</a>
I want to search for the word 'Cancel' on the whole page (<div id="sitewrapper">) and return both
cancel_order_lnkCancel;Cancel Order
Thanks
You can use XPath to find by text. e.g.:
var element = driver.FindElement(By.XPath(string.Format("//*[contains(text(), '{0}')]", value)));
value being the string you are searching for.
Then to get the element's markup and content:
var html = element.GetAttribute("outerHTML");
var text = element.Text;
or
var text = element.GetAttribute("innerHTML");
I haven't worked in C# binding but you can use FindElements to get a list of all elements containing the text. You can by no doubt use #Jarga's xpath. The good thing with FIndElements will be that it won't throw you an exception (atleast this is what happens in java) though you have to use try catch to handle getAttribute if you get null for value of id. And if you iterate over the list you can fetch all texts using getText method.
I have a C# string contains random HTML code.
How can I get all the links with this specific data- attribute "data-special-attr" and replace all the links' text with the attribute's value. Finally, remove the attribute.
for example:
before:
old text1
after:
<a href="http://example.com" style='class' data-foo=''>new text1</a>
I need to run this method on a string that contains multiple links with this specific attr and other html code.
Thanks
The "Right Way" aside, regexes are fun:
string sample = #"old text1";
string output = Regex.Replace(sample, #"<([^>]+) data-special-attr=""([^""]+)"">[^<]*</a>", "<$1>$2</a>");
Console.WriteLine(sample);
Console.WriteLine(output);
I'm assuming there's no attributes after the data-special-attr. When searching for matching quotes or '<' / '>' I like to use (eg) /"([^"]+)"/ rather than /"(.+)"/