How to get the xpath for the span button - selenium

I am new to selenium IDE and trying to get the target in the right order.
I have tried many combination to get the right element when there is span for the button. I need to get the xpath for the "Read More" button.Can someone please advise how the target in the IDE should be.
Here is the code:
<div class="is_centered l_bottom_pad">
<a class="btn_teal_outline has_arrow" href="https://test.com/jobs/view.php?id=8">
<span>Read More</span>
</a>
</div>

In some browsers (I think it was mainly MSIE) it is necessary to address the <a> element, not its child <span> in order to click a button or link. So you should adress:
//a[span[text()='Read More']]
Or you go directly for LinkText ("Read More") instead of XPath!

Targeting for span button is very simple. Just see what is unique attribute in that element.
I feel the button text itself is unique.Try this one
xpath=.//span[text()='Read More']

Related

Selenium (Python): Strategy for locating item with inconsistent Xpath

writing a Python selenium script to auto-populate many forms. On one particular form, I have to add the entry, then click the "Add Another" button in order add the next entry. I successfully located the "Add Another" button via find.element(By.XPATH, xx), which works on the first two iterations with an xpath that looks like this:
//*[#id="7d977bf8-9863-5be0-ab89-c90cff57953d"]/div[3]/div[2]/div[2]/div/div[1]/div/div[2]/button[1]
But it is unable to locate the button on the third pass through. I found that the xpath changed ever so slighty: The index of the second /div in the path changed from "2" to "6":
//*[#id="7d977bf8-9863-5be0-ab89-c90cff57953d"]/div[3]/div[6]/div[2]/div/div[1]/div/div[2]/button[1]
My immediate reaction was to code for a NoSuchElementException and if the original is not found, search for the second. But given the observed behavior, I'm not sure I can be certain it's just those two Xpaths. I may need to "Add Another" 40 or 50 times, I could end up with a block of code that tries 10 or 20 xpaths (I am not a web developer, so I have no idea why this change of path is happening, or when it may happen again on the same Form).
So I'm trying to come up with another method to locate this button. Here is the HTML:
<button class="grid-button" data-bind="click: function() { imagetrend.formComposer.controlHandlers.grid.addAnotherButtonClickHandler($context) }, css: { 'disabled' : imagetrend.FormComposer.isReadOnly($context) }, disableEvent: { 'click': imagetrend.FormComposer.isReadOnly.bind(null, $context) }"> <i class="fa fa-lg fa-plus"></i> Add Another </button>
I don't see any unique element in there that I can search by given what I know about Selenium: Tag, ID, CSS_Selector...I tried locating by the "fa fa-lg fa-plus" class, but that isn't found (I think I've deduced that's for the large plug sign in the button).
So is there some sort of bulletproof way I can find this element without coding for every potential xpath I find along the way? Thanks.
I didn't find an alternate method to identify that element, but found that with only that second /div index changing, a wildcard character suited my needs.
so it ended up as:
driver.find_element(By.XPATH,'//*[#id="7d977bf8-9863-5be0-ab89-c90cff57953d"]/div[3]/div[*]/div[2]/div/div[1]/div/div[2]/button[1]').click()
And that XPATH matches any instance of the button that may pop up.
Thanks to Prophet and Akzy for keeping me on my toes!

Click on parent element based on two conditions in child elements Selenium Driver

Using Selenium 4.8 in .NET 6, I have the following html structure to parse.
<ul class="search-results">
<li>
<a href=//to somewhere>
<span class="book-desc">
<div class="book-title">some title</div>
<span class="book-author">some author</span>
</span>
</a>
</li>
</ul>
I need to find and click on the right li where the book-title matches my variable input (ideally ignore sentence case too) AND the book author also matches my variable input. So far I'm not getting that xpath syntax correct. I've tried different variations of something along these lines:
var matchingBooks = driver.FindElements(By.XPath($"//li[.//span[#class='book-author' and text()='{b.Authors}' and #class='book-title' and text()='{b.Title}']]"));
then I check if matchingBooks has a length before clicking on the first element. But matchingBooks is always coming back as 0.
class="book-author" belongs to span while class="book-title" belongs to div child element.
Also it cane be extra spaces additionally to the text, so it's better to use contains instead of exact equals validation.
So, instead of "//li[.//span[#class='book-author' and text()='{b.Authors}' and #class='book-title' and text()='{b.Title}']]" please try this:
"//li[.//span[#class='book-author' and(contains(text(),'{b.Authors}'))] and .//div[#class='book-title' and(contains(text(),'{b.Title}'))]]"
UPD
The following XPath should work. This is a example specific XPath I tried and it worked "//li[.//span[#class='book-author' and(contains(text(),'anima'))] and .//div[#class='book-title' and(contains(text(),'Coloring'))]]" for blood of the fold search input.
Also, I guess you should click on a element inside the li, not on the li itself. So, it's try to click the following element:
"//li[.//span[#class='book-author' and(contains(text(),'{b.Authors}'))] and .//div[#class='book-title' and(contains(text(),'{b.Title}'))]]//a"

How to find element of the below HTML?

Am curious if anyone might know which Selenium locating element method would be used to identify the below html.
I am trying to locate and 'click'
button type="submit" tabindex="3" data-ng-click="login()" class="btn btn-default" data-ng-disabled="loginForm.$invalid" data-ng-class="{ 'gray': loginForm.$invalid }">Login</button
It depends, if you know text is not gonna change, direct use text
//button[text()='Login']
or based on attributes
//button[#data-ng-click='login()']
You can combine these two like below :
//button[#data-ng-click='login()' and text()='Login']
PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
You can following xpath,
//button[#type='submit']
//button[#data-ng-click='login()']
//button[text()='login']
driver.findElement(By.xpath("//button[text()='X']")).click();

If multiple edit buttons is having same HTML coding how will I click the button in Selenium

I'm new to Selenium. Below is code:
<i _ngcontent-c13="" aria-hidden="true" class="fa fa-edit" style="color: green;cursor: pointer;"></i>
I have all edit buttons with the same type. How do I click on each of the buttons? Can anyone help me with the XPath?
EASY
Right click on element in browser > inspect > right click on the highlighted code > copy > copy xpath. Now we have the xpath so:
driver.findElement(By.xpath("paste_xpath")).some_action();
Let me know if this works, there are more other options to discuss + add the code block that contains all the buttons.
HARD
First we need to get the xpath, you can build it based on the formula:
Xpath=//tagname[#attribute='value']
Where:
// : Select current node.
Tagname: Tagname of the particular node.
#:Select attribute. Attribute: Attribute name of the node.
Value: Value of the attribute.
More details you can find HERE
Thanks,

Click on a specific part of HTML element

I have a checkbox element on my web-page which has a partial link which reads as Read the conduct risk manual where in conduct risk manual is a link which when clicked on navigates to page that has conduct risk manual listed down.
The HTML structure for this element is as below:
<div class="checkbox">
<label>
<input ng-disabled="readonly" type="checkbox" name="policyRead" required="" ng-model="confirmOa.confirmation.policyRead" class="ng-pristine ng-untouched ng-invalid ng-invalid-required xh-highlight">
<span>Read the <a target="_blank" href="http://somesite.xyz/Conduct%Risk%Manual.pdf">Conduct Risk Manual</a></span>
</label>
</div>
Now I want to click on a check-box which used to work if I click on span element but now even if I try with below combinations of web-driver is still clicking on link Conduct Risk Manual
1) .//div/label/input[#name='policyRead']
2) .//input[#name='policyRead' and #type='checkbox']
3) .//span[contains(text(),'Read the')]
4) .//span[contains(text(),'Read')]
5) .//input[#name='startDateConfirmed']//preceding::span[1]
In the 5th xpath I have tried clicking on span element using the following HTML element which is correctly identified and clicked.
I have tried many combinations apart from those mentioned above and all the xpath's correctly highlight the expected element which means it is correctly identified. But still web-driver clicks on Conduct Risk Manual link and navigates to a new page instead of clicking corresponding checkbox.
Can we make web-driver click on a specific part of an element?
Please check xpath's wherein I have already tried using only 'Read' or 'Read the' portion of span element.
Try this below code.
Explanation: Use text method with span tag, then move ahead with preceding-sibling keyword to find input tag for clicking the checkbox element.
Note: span tag use here for reference to get the check-box element text.
WebElement checkbox = driver.findElement(By.xpath("//span[contains(text(),'Read the')]//preceding-sibling::input[#name='policyRead']"));
if(!checkbox.isSelected()) // if checkbox is not selected, then only if is condition will execute.
{
checkbox.click();
}
OR
Using Java-script executor to click the checkbox web-element.
WebElement checkbox = driver.findElement(By.xpath("//span[contains(text(),'Read the')]//preceding-sibling::input[#name='policyRead']"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", checkbox);
You can try with this code also as a tag is coming over to the checkbox.
WebElement checkBox= driver.findElement(By.xpath("//span[contains(text(),'Read the')]//preceding-sibling::input[#type='checkbox']"));
Actions action = new Actions(driver);
action.moveToElement(checkBox).click().build().perform();`
Also add import org.openqa.selenium.interactions.Actions; .