I have the below code that I am attempting to extract a specific attribute from(data-id).
I am new to using selenium and have been pained by this for over a day now.
To add context to this I will give you a little background into what I am trying to achieve.
I have a webpage that has a auction, the auction has an ID, all items in the auction have unique ID's but all link to the original Auction ID.
I am attempting to extract the "data-id" attribute of an element however I have yet to find out how.
Here is a snippet of the code I am attempting to get the id from.
<div class="dropdown open">
<a class="dropdown-toggle form-control" href="#" data-toggle="dropdown">
<ul class="dropdown-menu dropdown-menu-form" role="menu">
<li id="liAuction4c42556772376a443736343d">
<label class="checkbox">
<input id="chkAuction4c42556772376a443736343d" class="auction" type="checkbox" data-caption="09-10-2015 10:30:00" data-id="4c42556772376a443736343d" checked="checked"/>
09-10-2015 10:30:00
</label>
</li>
</ul>
</div>
I have been on many forums and searched the whole of google and not found a solution that has worked for me yet otherwise I would not be posting the question and look like a complete Rookie.
I have attempted to use .getAttribute however I have had some issues with that and the code has never compiled, I guess I have not done something correctly.
String dataID = selenium.findElement(By.xpath("//*[starts-with(#id, 'liAuction')]")).getAttribute("data-id");
When I attempted the above the "findElement" part is underlined red and I have the following message,
"The method findElement(By) is undefined for the type Selenium".
If I change the parentisis around to look like this;
String dataID = selenium.findElement(By.xpath("//*[starts-with(#id, 'liAuction')]").getAttribute("data-id"));
"findElement" is no longer underlined, however now the ".getAttribute" part is underlined red and I have the following message, "The method getAttribute(String) is undefined for the type By"
I would really appreciate some assistance with this as I am about to throw my laptop out of the window, and I don't really want to lose all of my files.
Thanks in advance
Tony
You can use the getAttribute method.
First find the input element, then extract the data-id:
WebElement inputElement = selenium.findElement(By.id("chkAuction4c42556772376a443736343d"));
String data-id = inputElement.getAttribute("data-id");
Use below xpath:-
//input[#id='chkAuction4c42556772376a443736343d']/#data-id
Then use:-
String dataID = selenium.findElement(By.xpath("//input[#id='chkAuction4c42556772376a443736343d']/#data-id")).gettext();
Full Code:-
static WebDriver driver=null;
public static void main(String[] args) {
driver = new FirefoxDriver();
driver.get("URL");
String dataID = driver.findElement(By.xpath("//input[#id='chkAuction4c42556772376a443736343d']/#data-id")).gettext();
System.out.println(dataID);
}
Hope it will help you :)
Thank you for your hekp with this guys, was not expecting to get the answer quite so quickly.
I needed to use the following line to retrieve the "data-id" attribute of an element.
String dataID = selenium.getValue("//input[#id='chkAuction4c42556772376a443736343d']/#data-id");
This ended up being alot easier that initially thought, I would like to thank #Shubham Jain for help with this his suggestion pointed me to where I needed to be.
I hope this helps others in the future
Hi I suggest you to use the following code. It will work absolutely fine.
WebElement element = selenium.findElement(By.xpath("//input[#class='auction']"));
String dataId= element..getAttribute("data-id");
Detail
I'm identifing the object using following xpath //input[#class='auction'] and save it to an WebElement variable.
then By using getAttribute() im getting the string from data-id
Related
I am trying to access an input field with a dynamically changing ID, and using other ways to find the element doesn't seem to work either.
This is the input field:
<input data-v-44dd203d="" type="search" placeholder="Search users" class="form-control form-control-md" inputmode="search" id="__BVID__27">
This is my current code in Java:
driver.get("website");
driver.findElement(By.xpath("//input[#type='search']")).sendKeys("name");
I am not getting any error, but when i am running the code, the website opens but nothing happens to the field. Seems i cannot access it, if it makes sense.
I had similar issue once and adding a click to the element first and then send keys worked for me.
<div class="jss7113 jss7118"><div></div><div class="jss7114">Invalid username or password</div><button class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-textPrimary" tabindex="0" type="button"><span class="MuiButton-label"><i icon="close-circle-outline" title="" class="mdi mdi-close-circle-outline" aria-hidden="true"></i></span><span class="MuiTouchRipple-root"></span></button></div>
This is what wrote
//System.out.println(driver.findElement(By.cssSelector("*.jss5107")).getText()); //Get the error message from the Invalid credentials
//System.out.println(driver.findElement(By.cssSelector("div[class = 'jss7114']")).getText().equals("Invalid username or password"));
//System.out.println(driver.findElement(By.xpath("//div[#class = 'jss7114']")).getText().equals("Invalid username or password"));
It seems like the class name you're trying to find doesn't exist:
//System.out.println(driver.findElement(By.cssSelector("*.jss5107")).getText());
this type of gibberish names for elements usually indicates random attribute values being generated and making your automation relying on those values is a no go because we want our automation to be as solid and low maintenance as possible.
Instead, try to find a better way to locate the element you're looking for.
I could've tried to give you a better locator but it seems like you pasted a part of the HTML code which I can't read it properly (for example there's a div tag that immediately gets closed right after):
<div class="jss7113 jss7118"><div></div>
Please provide a better snippet of this part of the HTML in order for us to help with your question.
If you want to validate the message, you can locate the element by the text within it:
driver.findElement(By.xpath("//div[contains(text(),'Invalid username or password')]
Here is what I'm trying to do:
I have some links on a webpage with this pattern:
/html/body/div[4]/div/div/section/div[2]/div[3]/div/div1/div1/div/div[2]/a
/html/body/div[4]/div/div/section/div[2]/div[3]/div/div1/div[2]/div/div[2]/a
/html/body/div[4]/div/div/section/div[2]/div[3]/div/div1/div[3]/div/div[2]/a
/html/body/div[4]/div/div/section/div[2]/div[3]/div/div1/div[4]/div/div[2]/a
However, I also have other links within the same web page that have a similar path but not exactly following the same pattern:
/html/body/div[4]/div/div/section/div[2]/div[3]/div/div[3]/div/div1/div1/div/div[2]/a
How can I get just the links which follow the first pattern displayed and ignore the other ones?
Ps: I'm using Selenium Webdriver and Java and this is the update question with the html for the links
<div class="col-sm-6 half-tile">
<div class="outside-caro">
<div class="grey-overlay">
<div class="inside-caro" style="background-image:url(' https://resources/images/metabolism.jpg'")>
</div>
</div>
<div class="tile-content">
<h4 class="module title-long-card">Healthy Weight Loss</h4>
<p class="module line-clamp">This online eLearning programme is designed to help you make smart decisions when it comes to dieting and to be aware of the pitfalls.</p>
<a class="more-button" href="/application/res-courses/overview?id=23">Learn More<i style="font-size: 10px;padding-left: 5px; "class="fa fa-chevron-right" aria-hidden="true"></i></a>
</div>
</div>
</div>
Thanks very much.
I'm not quite following what you're really hoping for from your description, but I can make some guesses.
The quick answer is, just always give the full path.
But there are ways to make things a little easier to code. There are a couple ways you can create a pointer on the page and to only look for things beyond that point. The most straightforward is using simple string concatenation:
String pointer = "/html/body/div[4]/div/div/section/div[2]/div[3]/div/div[1]";
WebElement tag1 = driver.findElement(By.xpath(pointer + "/div[1]/div/div[2]/a"));
WebElement tag2 = driver.findElement(By.xpath(pointer + "/div[2]/div/div[2]/a"));
The other is to declare that pointer as a WebElement, and then use it as a base for all future findElements:
WebElement pointer = driver.findElement(By.xpath("/html/body/div[4]/div/div/section/div[2]/div[3]/div/div[1]"));
WebElement tag1 = pointer.findElement(By.xpath("./div[1]/div/div[2]/a"));
WebElement tag2 = pointer.findElement(By.xpath("./div[2]/div/div[2]/a"));
Note the dot at the beginning of the xpath to say "Use this node as your starting point".
Now, what I think you're really trying to accomplish to to make a list of all the anchors, not just pick them one by one. As in "get all the link that match one pattern but not a different but similar pattern". For that, you could just do a variation of either of the two above methods. For instance:
WebElement pointer = driver.findElement(By.xpath("/html/body/div[4]/div/div/section/div[2]/div[3]/div/div[1]"));
List<WebElement> tags = pointer.findElement(By.xpath("./div/div/div[2]/a"));
This will pull in all the links that match the pattern into a List. There are a couple things to take note:
The first element is just div, not div[1] and div[2]. since that seems to be the only thing changing in the pattern.
Most likely, the language you will use to script this is 0-indexed. So div[1] is tags.get(0).
I have a solution to problem and i hope it will help you.
You just have to identify a single parent for all 4 links that you mentioned above. And i feel you can use this locator as parent node /html/body/div[4]/div/div/section/div[2]/div[3]/div/div[1]/div[1].
Please find my code..
System.setProperty("webdriver.chrome.driver","Drivers/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.abodeqa.com/2015/08/26/finding-child-elements-in-webdriver-using-findelements/");
Thread.sleep(3000);
WebElement parent = driver.findElement(By.xpath("//section[#class='secondary clearfix']"));
List<WebElement>childernNodes = parent.findElements(By.xpath("./aside//a"));
System.out.println("Total: "+childernNodes.size());
for(WebElement value: childernNodes){
System.out.println(value.getAttribute("href"));
}
WebElement pointer = driver.findElement(By.xpath("/html/body/div[4]/div/div/section/div[2]/div[3]/div/div[1]"));
// Generic path to simulate the change in the xpath for the elements of the following pattern:
// WebElement tag1 = pointer.findElement(By.xpath("./div[1]/div/div[2]/a"));
// WebElement tag2 = pointer.findElement(By.xpath("./div[2]/div/div[2]/a"));
List<WebElement> linksList = pointer.findElements(By.xpath("./div/div/div[2]/a"));
for (WebElement link : linksList) {
System.out.println(link.getAttribute("href"));
}
I have html code:
<div class="formCaptionContainer fill-width" data-dyn-bind="sizing: { width: $dyn.layout.Size.available }">
<h1 class="formCaption" data-dyn-bind="text: $data.Caption, click: $data.GoGridView">Expense report for Aditi Mehta - GS1-000282, testing2</h1>
<h2 class="formCaption-context" data-dyn-bind="text: $data.ParentTitleFields">Aditi Mehta : GS1-000282</h2>
</div>
I want to get the value Expense report for Aditi Mehta - GS1-000282, testing2 from /h1 tag
Any one know how to do it?
I've tried :
By.xpath(".//div[#class='formCaption']/h1";
Above showing no element found
By.className("formCaption");
Above showing blank data
By.xpath(".//*[#class='formCaption']/h1");
Above showing no element found
This code work for me very well
String textprint=driver.findElement(By.xpath("//h2[#class='formCaption-context']")).getText();
System.out.println(textprint);
Hope It will solve your problem
Try this one
String msg= driver.findElement(By.xpath(//div[contains(#class='formCaptionContainer')]/h1 ).getText();
Can you try the below Xpath.
String msg=driver.findElement(By.xpath("//div[#class='formCaptionContainer fill-width']/h1[#class='formCaption-context']")).getText();
As per the HTML you have shared, the node attributes looks dynamic to me. So we have to induce WebDriverWait as follows :
new WebDriverWait(driver, 10).until(ExpectedConditions.textToBePresentInElementLocated(By.xpath("//h1[#class='formCaption']"), "Aditi Mehta - GS1-"));
System.out.println(driver.findElement(By.xpath("//h1[#class='formCaption']")).getAttribute("innerHTML"));
You need to consider your locator strategy, the following provide good preferences for general case approach.
location by ID globally unique elements
locate by name for page unique elements
locate by css as catch all case
You should also take a look at the PageObject pattern.
It appears the page is using a JS library to display the contents through late binding/resolution. Your test needs allow for this and wait until the page elements you are interested in are fully rendered. Find out from the developers what the element looks like before it is resolved and afterwards. Late resolution is one considerations in determining your locator strategy. The strategy should include fluent waiting and default time-outs for elements to appear.
This is not a problem of fixing a single locator.
Thanks all for your help. It is working fine now. I use the below code
By headingExpenseText = By.xpath("//*[#class='formCaption'][contains(text(),'Expense report for')]");
public String getTitleEx()
{
return driver.findElement(headingExpenseText).getAttribute("innerHTML");
}
This worked for me:
String titleElem = driver.findElement(By.xpath("//*[#class='formCaptionContainer fill-width']/h1")).getAttribute("innerHTML");
assertEquals("Worked", titleElem);
What do you need exactly, Data displayed on web page or textValue used in HTML code?
If your locator is correct , then instead of getText(), you can try getAttibute("innerHTML") like below,
By.xpath("//*[#class='formCaption'][contains(text(),'Aditi Mehta')]").getAttribute("innerHTML");
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();.