Cannot get input by its value using XPath - java

I have multiple HTML <input> elements like this:
<input type="text" class="information">
<input type="text" class="information">
<input type="text" class="information">
After entering different texts (e.g. “hello” "hi" "hey") in these input elements and save it I am able to print out their value using element.getAttribute("value"), which gives “hello” "hi" "hey".
However, when I try to grab this input element using XPath
//input[#class='information' and #value='hello']
//input[#class='information' and #value='hi']
//input[#class='information' and #value='hey']
it does not work (can not identify element with the expression). Any idea why this happens or how to get the input element using XPath in this case? Thanks in advance!

Maybe not the best way to do it but
try finding it by Xpath as follows:
xpath=(//input[#type='text'])[2]
the [2] being the boxes number (1/2/3). Once you've found the box you can access its value.
IWebElement box2 = FindElement(By.XPath('//input[#type='text'])[2]'));
box2.getAttribute();
A better way to do this might be trying to select the " :nth-child(n) " of the div. Perhaps google up on that

As nullpointer wrote, you should first get the list of elements using //input[#class='information'] and then have a closer look at each element using getAttribute("value").
You won't be able to find the values via XPath bc they have been entered after loading the page. In order to find the value attributes with XPath, they would have had to be loaded with the page, like in <input type="text" value="hello">, which it isn't in your case.

Related

Selenium - WebDriver - Java: Why am I getting empty strings from my elements?

I have a webpage where some elements get set on page load. I then need to read some of these elements using Selenium. The problem is that when I read them, all I get is an empty string.
This is a partial image of my website:
I'm trying to obtain the Number field.
Here is what the DOM looks like for this element:
<input style="; ; " class="form-control disabled " id="sys_readonly.u_po_coordination.number" value="POI1356285" ng-non-bindable="" readonly="readonly" aria-label="Number">
Here is my JAVA code to get that value:
String num = driver.findElement(By.id("sys_readonly.u_po_coordination.number")).getText();
I've tried using XPath as well. I've also tried getting other elements as well.
The result is ALWAYS the same: a blank string...
What am I missing? The elements exist because I can set various elements, but reading ones that should be set are always blank.
Any help would be greatly appreciated.
Thanks!
driver.findElement(By.id("sys_readonly.u_po_coordination.number")).getAttribute("value");
Found this website which was pretty useful:
https://www.lambdatest.com/blog/how-to-get-text-of-an-element-in-selenium/
Instead of getText() can you try getValue()?

Finding the label of an input field in Selenium Webdriver

I have a form where each text box has a title. I already have the WebElement of the text boxes, and I want to reference their title (the title that has "for=id" pointing to them).
I've tried their getText which only returns the text in the input box, tried getCssValue("label") which doesn't return with anything. I've tried finding all the labels but that doesn't help as I'd still have to sift through all of them, and find the 8 different labels that need to have the *.
<label for="customer_firstname">First name <sup>*</sup></label>
<input onkeyup="$('#firstname').val(this.value);" type="text" class="is_required validate form-control" data-validate="isName" id="customer_firstname" name="customer_firstname" value="">
I want to get back a string of the label text so I can check (with .contains())if it contains the "*"at the end. Preferably with as little Xpath as possible.
to indicate label tag using input tag, you can use this xpath :
//input[#id='customer_firstname']/preceding-sibling::label
if you just want input field then you should use id which I think is unique in your case, though you will have to verify this in DOM.
id = customer_firstname
For referencing with <label **for**>
you can use this code :
String custLabelAttribute = driver.findElement(By.xpath("//input[#id='customer_firstname']/preceding-sibling::label")).getAttribute("for")
this should print : customer_firstname
if both Input and label tags are belongs from same parent then you can take first unique xpath of parents and then adding // you can reach up to the label tag and get text. you should reach up to label tag by find unique xpath and use .gettext() then u will get innertext of label tag.

Xpath changing after each run

Could someone help, please.
I need to grasp a number that's generated after each run. As this number changes after each run, I need to grasp it and write it to excel sheet. I'm using Xpath for this field but not sure how to make this field more generic so that it only catches the number that is generated last.
The Xpath I tried is shown below and the syntax that is changing is div[2] to div[3] :-
driver.findElement(By.xpath("/html/body/div/div[3]/div/div/div[3]/div/section/section/article/div[2]/div/div/div/div[2]/div[2]/div[1]/div/div[2]/p")).getText();
driver.findElement(By.xpath("/html/body/div/div[3]/div/div/div[3]/div/section/section/article/div[2]/div/div/div/div[2]/div[3]/div[1]/div/div[2]/p")).getText();
My HTML SOURCE code is :
<div class="card-details row"> <div class="pane base4"> <div class="card"> <div class="card-name"> <div class="card-number"> <h4>Card number</h4> <p>633597015500042861</p> </div> <a class="submit-btn uniform-button button-smaller button-orange" href="/my-account/replacement-card?cardId=1ce25b86-27e6-4ce8-8ef3-6576f9a0ae84"> </div>
Thanks and Regards,
Az.
Please try to use below xpath to retrieve the card number.
String cardNum = driver.findElement(By.xpath(".//div[#class='card-number']/p")).getText();
You are accessing the randomly generated card number from the <div class="card-number"> tag.
Hope this helps.
//h4[contains(text(),'Card number')]/following-sibling::p
or
div[h4[contains(text(),'Card number')]]/p
if occurrence of same xpath more than once in your code and you want to select the last one following is the way:
xpath[count(sameXpath)]
this will give you the last occurence of the xpath
Please do it like below:
// as per your given xpath
String FirstXpath = "/html/body/div/div[3]/div/div/div[3]/div/section/section/article/div[2]/div/div/div/div[2]/div[";
String SecondXpath = "]/div[1]/div/div[2]/p";
// make sure here i value is as per your application
for(int i=2;i<4;i++){
driver.findElement(By.xpath(FirstXpath + i + SecondXpath)).getText();
}
Just make sure value of i as per your div value change.
Update
As per html provided driver.findElement(By.xpath("//*[#class='card-number']/h4/p")).getText();.

Dynamic filter code in Selenium using java

I have an Ui where there is a dynamic filter present.
I need to check the functionality of the filter by entering any input value,but here the issue is the result is not constant from where i can search.
This is the HTML body of the filter:
<label>
Filter:
<input class="" type="search" placeholder="" aria-controls="revtable"/>
</label>
</div>
And also i need to verify that the filter is working properly.
You can possibly grab a collection of elements and do a quick check to see if the element exist. Notice if you have element loading issue then some other mechanism needs to be used to confirm element load.
//Make sure the selector is written precisely.
List<WebElement> elements = driver.findElements(By.cssSelector("[aria-controls='revtable']"));
if (elements.size()>0){
//we know element present
//I am grabbing first item on the list
elements.get(0).sendKeys("Test");
}else{
//element does not exist
}

Xpath for checkbox element by locating it's following label element by value

I have been working for quite a while on this and still haven't found an answer specific to my problem in stackoverflow or from experimenting with the Xpath myself. I am quite inexperienced so I alpogise if this is a simple problem but I would really appreciate any help.
I am working with Selenium to test a web app that uses Wicket. I need the Xpath to the checkbox that correlates to the respective label. This is because I need to be able to enter the value shown on the label and for it to find the relevant checkbox based on the label text such as "001", as the checkbox ids do not match the values.
Mockup below shows the checkboxes and their corresponding labels;
The corresponding HTML is show below;
<span wicket:id="excludeDepotCheckBox" id="excludeDepotCheckBox5">
<input name="adminPreferenceSection:excludeDepotCheckBox" type="checkbox" value="0" id="excludeDepotCheckBox5-adminPreferenceSection:excludeDepotCheckBox_0">
<label for="excludeDepotCheckBox5-adminPreferenceSection:excludeDepotCheckBox_0">001</label>
<br>
<input name="adminPreferenceSection:excludeDepotCheckBox" type="checkbox" value="1" id="excludeDepotCheckBox5-adminPreferenceSection:excludeDepotCheckBox_1">
<label for="excludeDepotCheckBox5-adminPreferenceSection:excludeDepotCheckBox_1">009</label>
<br>
</span>
Another problem I also face is that the Xpath must include the fact that it is inside the span shown in the html as there are 3 other groups of checkboxes on the page with the same values so it must be specific for each span for example:
id="excludeDepotCheckBox5"
I have tried the following Xpaths to no avail;
//span[#id='excludeDepotCheckBox5' and contains(., '009')]"
"//*[#id='excludeDepotCheckBox5' and ./label/text()='009']/preceding-sibling::*[#name='adminPreferenceSection:excludeDepotCheckBox']
//*[#id='excludeDepotCheckBox5' and ./label/text()='009']/preceding-sibling::input[1]"
Again I aplogise if it is a simple syntax/understanding problem but I would really appreciate any help.
Since "preceding-sibling" is so error-prone (it will break as soon as the HTML structure changes a little bit), here's a more stable variant (wrapped for legibility):
//span[#id = 'excludeDepotCheckBox5']//input[
#id = //span[#id = 'excludeDepotCheckBox5']//label[normalize-space() = '001']/#for
]
You can use the below xpaths:
1- For checking the checkbox related to label '001':
//span[#id='excludeDepotCheckBox5']/label[.='001']/preceding-sibling::input[1]
2- For checking the checkbox related to label '009':
//span[#id='excludeDepotCheckBox5']/label[.='009']/preceding-sibling::input[1]
NOTE: It will check for the 'input' element which is the first preceeding sibling of label element with exact innerHTML/text as '001' or '009' under a span element with id='excludeDepotCheckBox5'.
//*[#id='excludeDepotCheckBox5']/label[contains(text(),'001')]//preceding-sibling::input[1]

Categories

Resources