How to get the value of an attribute using XPath - selenium

I have been testing using Selenium WebDriver and I have been looking for an XPath code to get the value of the attribute of an HTML element as part of my regression testing. But I couldn't find a good answer.
Here is my sample html element:
<div class="firstdiv" alt="testdiv"></div>
I want to get the value of the "alt" attribute using the XPath. I have an XPath to get to the div element using the class attribute which is:
//div[#class="firstdiv"]
Now, I am looking for an XPath code to get the value of the "alt" attribute. The assumption is that I don't know what is the value of the "alt" attribute.

You can use the getAttribute() method.
driver.findElement(By.xpath("//div[#class='firstdiv']")).getAttribute("alt");

Using C#, .Net 4.5, and Selenium 2.45
Use findElements to capture firstdiv elements into a collection.
var firstDivCollection = driver.findElements(By.XPath("//div[#class='firstdiv']"));
Then iterate over the collection.
foreach (var div in firstDivCollection) {
div.GetAttribute("alt");
}

Just use executeScript and do XPath or querySelector/getAttribute in browser. Other solutions are wrong, because it takes forever to call getAttribute for each element from Selenium if you have more than a few.
var hrefsPromise = driver.executeScript(`
var elements = document.querySelectorAll('div.firstdiv');
elements = Array.prototype.slice.call(elements);
return elements.map(function (element) {
return element.getAttribute('alt');
});
`);

Selenium Xpath can only return elements.
You should pass javascript function that executes xpaths and returns strings to selenium.
I'm not sure why they made it this way. Xpath should support returning strings.

Related

Find elements in webpage using Selenium in Jmeter

I want to do testing using selenium webdriver in Jmeter. And i was using By.linkText to find an element, and assert whether the element exists or not.
var elements = WDS.browser.findElements(pkg.By.linkText("Tools"));
eval(elements.length != 0);
But it seems if replace 'Tools' with any other string like 'asfasdsa' it will return True, and my test is passing. It seems By.linkText doesnt work in JMeter. Is there any other alternate way to find an element in webpage other than By.id??
Also, is this a good way to verify whether an element is present?
Selenium works just fine, I'm not sure what you're trying to do with eval(elements.length != 0); function call, it will return false but fail to see where and how you're using this value
If you want to fail the WebDriver Sampler when the number of returned elements is 0 you need to do this a little bit differently, in particular conditionally call WDS.sampleResult.setSuccessful() function
Suggested code change:
WDS.sampleResult.sampleStart()
WDS.browser.get('http://example.com')
var elements = WDS.browser.findElements(org.openqa.selenium.By.linkText('More information...'))
if (elements.length == 0) {
WDS.sampleResult.setSuccessful(false)
WDS.sampleResult.setResponseMessage('Failed to find any element matching the criteria')
}
WDS.sampleResult.sampleEnd()
The above code will pass as long as you don't change More information... to something else.
See The WebDriver Sampler: Your Top 10 Questions Answered for more WebDriver Sampler tops and tricks
You can use xpath:
Using text():
var elements = WDS.browser.findElements(pkg.By.xpath("//*[text()='Tools']"));
eval(elements.length != 0);
Using contains():
var elements = WDS.browser.findElements(pkg.By.xpath("//*[contains(., 'Tools')]"));
eval(elements.length != 0);

How can i get the value from div class in TestNG selenium?

I am using TestNG and selenium for testing web app.
<div class="infoMessage">The request has been successfully submitted.</div>
In the my TestNG class file, like any other HTML elments for div element also
I have
#FindBy(xpath="//*[#id='wrapper']/table/tbody/tr[1]/td/div")
WebElement resultdiv;
Now that I got the webelement in resultdiv, how can i read the content "The request has been successfully submitted" ?
Just at a quick glance, it seem like you can try use className instead xpath:
#FindBy(className="infoMessage")
WebElement resultdiv;
Use .getText(); to achieve:
String text = resultdiv.getText();
Hi #bnath002 You can use Contains text Xpath, below is the code. this code always work for text.
WebElement element = driver.findElement(By.xpath("//div[contains(text(),'The request has been successfully submitted.')]"));
String innerText= element.getText();
System.out.println("Your inner text is: "+innerText);
I'm a little unfamiliar with #FindBy, but i'm assuming you could use getText() as normal. But if everything went as planned and the xpath located your element successfully, you should be able to retrieve the text with the following :)
WebElement element = driver.findElement(By.xpath("//*[#id='wrapper']/table/tbody/tr[1]/td/div"));
String innerText= element.getText();
System.out.println("Your inner text is: "+innerText);

How to send values to textboxes that doesn't have input ids in selenium webdriver? I am using phptravles.net for testing?

phptravels location text field
Have attached a image with Html code.
I couldn't able to write a xpath to recognise and sendkeys.
The text field has different xpath when it is focused and when it is not.
Its throwing me NoSuchElementFound exception.
driver.get("http://www.phptravels.net");
WebElement e = driver.findElement(By.xpath("//*[#id='select2-search']/input"));
e.click();
e.sendKeys(city);
You can create xpath using other attributes of that element like
//input[contains(#attribute,'attribute_value')]
Eg. For a input element with class attribute "textbox", xpath can be written like
//input[contains(#class,'textBox')]
I tried with below two points and it worked for me,
1) modified xpath with span text()
2) Instead of e.sendKeys(), tried actions.sendKeys() as the former throwing 'cannot focus' error. Credit to link
driver.get("http://www.phptravels.net");
WebElement e = driver.findElement(By.xpath("//span[text()='Search by Hotel or City Name']"));
/* e.click();
e.sendKeys("GOA");
*/
Actions actions = new Actions(driver);
actions.moveToElement(e);
actions.click();
actions.sendKeys("GOA");
actions.build().perform();

Taking all local-name of WebElement

Can I take all local-name() of WebElement?
I don't know the attributes of this webElement and I wish to find and save it.
Edit:
I have WebElement elm which it tagName is Div. I find this element by the next command:
WebElememnt elem = driver.findElements(By.xpath(//*[identifier="c")).get(1)
Now, I want to know all the attributes of this element, which I don't know when I do my query. for example: elm is the next in my DOM:
<div identifier="c" someAtr="b" someAtr2="c">
So I wish to know that I have an attributes which it name is "someAtr"="b" and "someAtr2"="c" (Again, I don't know that someAtr even exists, and for that I want all the attributes).
You can do so using the Javascript Executor and then getting the innerHtml:
String html = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", ele);
Then you can parse the String as you normally would.

Selenium Xpath Not Matching Items

I am trying to use Selenium's Xpath ability to be able to find an set of elements. I have used FirePath on FireFox to create and test the Xpath that I have come up with and that is working just fine but when I use the Xpath in my c# test with Selenium nothing is returned.
var MiElements = this._driver.FindElements(By.XPath("//div[#class='context-menu-item' and descendant::div[text()='Action Selected Jobs']]"));
and the Html looks like this:-
Can Anyone please point me right as everything that I have read the web says to me that this Xpath is correct.
Thanking you all in-advance.
Please post the actual HTML, so we can simply "drop it in" into a HTML file and try it ourselves but I noticed that there is a trailing space at the end of the class name:
<div title="Actions Selected Jobs." class="context-menu-item " .....
So force XPath to strip the trailing spaces first:
var MiElements = this._driver.FindElements(By.XPath("//div[normalize-space(#class)='context-menu-item' and descendant::div[text()='Action Selected Jobs']]"));
Perhaps you don't take into consideration the time that the elements need to load and you look for them when they aren't yet "searchable". UPDATE I skipped examples regarding this issue. See Slanec's comment.
Anyway, Selenium recommends to avoid searching by xpath whenever it is possible, because of being slower and more "fragile".
You could find your element like this:
//see the method code below
WebElement div = findDivByTitle("Action Selected Jobs");
//example of searching for one (first found) element
if (div != null) {
WebElement myElement = div.findElement(By.className("context-menu-item"));
}
......
//example of searching for all the elements
if (div != null) {
WebElement myElement = div.findElements(By.className("context-menu-item-inner"));
}
//try to wrap the code above in convenient method/s with expressive names
//and separate it from test code
......
WebElement findDivByTitle(final String divTitle) {
List<WebElement> foundDivs = this._driver.findElements(By.tagName("div"));
for (WebElement div : foundDivs) {
if (element.getAttribute("title").equals(divTitle)) {
return element;
}
}
return null;
}
This is approximate code (based on your explanation), you should adapt it better to your purposes. Again, remember to take the load time into account and to separate your utility code from the test code.
Hope it helps.