Continue Button - Dynamic value - selenium

I have 3 registration pages and each page has continue button. I want to use one method for all 3 pages but they have same xpath with different id.
eg
First page xpath: //div[#id='personalInfo']//button[#class='btn btn-primary btn-block'][contains(text(),'Continue')]
Second page xpth: //div[#id='AccountInfo']//button[#class='btn btn-primary btn-block'][contains(text(),'Continue')]
Please let me know how can i use dynamic as I used or for #id but work for first page but in second page it says element not found.
Thanks
I used or for #id but work for first page but in second page it says element not found.
First page xpath: //div[#id='personalInfo']//button[#class='btn btn-primary btn-block'][contains(text(),'Continue')]
Second page xpath: //div[#id='AccountInfo']//button[#class='btn btn-primary btn-block'][contains(text(),'Continue')]

you can use this. It will always click on the button with the text Continue.
driver.findElements(By.tagName("button")).stream().filter(e -> e.getText().equals("Continue")).findFirst().get()
.click();

Option# 1- you can simply look for a button with text - continue if it is unique on your page.
"//button[contains(text(),'Continue')]"
Option# 2: just combine the ids using the OR operator like this,
"//div[#id='preferences' or #id='accountInfo' or #id='personalInfo']//button[contains(text(),'Continue')]"

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!

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();

className, tagName etc in selenium java

I tried to click the button using selenium.
The code of the button is as follows:
<button class="btn btnSearch" type="button" data-gtm="wyszukiwarka" szukaj">Szukaj</button>
I do not see any id?
It's possible to click the button like this?
While there are many ways to click a button without name and ID, and there are many duplicates of this question, my advise is always to use a relative XPath expression when there is no name or ID.
You can click the button with:
findElement(by.xpath("//button[#class='btn btnSearch']"))
As per the HTML provided to click on the button with text as Szukaj you can use the following line of code :
Java :
driver.findElement(By.xpath("//button[#class='btn btnSearch' and contains(.,'Szukaj')]")).click();
Python :
driver.find_element_by_xpath("//button[#class='btn btnSearch' and contains(.,'Szukaj')]").click()
Dot Net :
driver.FindElement(By.XPath("//button[#class='btn btnSearch' and contains(.,'Szukaj')]")).Click();

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; .

Selenium WebDriver : Not able find xpath for Paytm.com , Proceed button

I was trying to automate paytm.com site ,
Here i found Proceed button attribute has name but when i tried to use xpath checker for the name attribute , it was showing 13 matches but my question here is in the webpage from the UI level am not able to see 13 Proceed buttons instead only one Proceed button are present .
Even i tried with other attribute to find the xpath , but it showing more matches found.
Below is the HTML code for Proceed
<div class="msg-container">
<div class="btn-spinner" alt="Proceed to Recharge">
<div class="spinner hidden"></div>
<input class="btn proceed active" type="submit" data-express-text="Recharge Now" data-soft-block-text="Proceed anyway" data-default-text="Proceed" name="Proceed" value="Proceed" alt="Proceed to Recharge">
Can you please let me where am going wrong ?
This xpath returns 1 match for me
//form[#id='prepaidMobile']//input[#name='Proceed']
Also, if want use only //input[#name='Proceed'] you can get it from List of WebElements:
WebElement firstInput = driver.findElements(by.xpath("//input[#name='Proceed']"))[0];
This will work for you, I think:
driver.findElement(By.xpath("(//input[#name='Proceed'])[1]")));