Selenium - Multiple anchor - Same ID - Not able to fetch - selenium

I want to click on anchor tag whose class id is clsArrowClick and the same id is on another anchor tag.
<td class="text-center" style="width: 25% !important;">
<td class="arrow" data-toggle="tooltip" data-container="body" title=""
style="width: 25% !important; text-align:center" data-original-
title="Select/Show Data">
**<a id="clsArrowClick" class="clsarrowClick" href="#"
onclick="javascript:OpenAddNewWellPopup(this);">
<i class="fa fa-arrow-right"/>
</a>**
<input id="hdnIsSaved0" class="hdnIsArrowSaved" value="0" type="hidden"/>
</td>
</tr>
<tr id="2">
<td style="width:50%; class=" '="" data-container="body" data-
toggle="tooltip" title="" data-original-title="abcd">abcd</td>
<td class="text-center" style="width: 25% !important;">
<td class="arrow" data-toggle="tooltip" data-container="body" title=""
style="width: 25% !important; text-align:center" data-original-
title="Select/Show Data">
**<a id="clsArrowClick" class="clsarrowClick" href="#"
onclick="javascript:OpenAddNewPopup(this);">
<i class="fa fa-arrow-right"/>
</a>**
<input id="hdnIsSaved1" class="hdnIsArrowSaved" value="0" type="hidden"/>
</td>
I tried list, wait method and simple way everything, but my program throws an error
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException
Like
//WebDriverWait wait = new WebDriverWait(driver,30);
//wait.until(ExpectedConditions.presenceOfElementLocated(By.className("clsArrowClick")));
//driver.findElement(By.className("clsarrowClick"));
driver.findElement(By.xpath("(.//*[#id='clsArrowClick'])[1]")).click();

Try following xpaths might work for second link. I haven't tested that and I don't know the whole html of your page so I said might.
//a[#id='clsArrowClick'][2]
or this one
//input[#id='hdnIsSaved1']../a[#id='clsArrowClick']
or following if you are interested in clickin first link
//td[#class='arrow']/a[#id='clsArrowClick']

In your code you are using presenceOfElementLocated condition before finding the element. An important thing to note is that presenceOfElementLocated only checks for presence of element on DOM, irrespective of it's visibility. You need to make sure that the element you are fetching is visible, so for that you should use ExpectedConditions.visibilityOfElementLocated. visibilityOfElementLocated guarantees that the element is available on the DOM and also visible, so that will help in overcoming the org.openqa.selenium.ElementNotVisibleException you are facing.
So your code should look something like this:
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("(.//*[#id='clsArrowClick'])[1]")));
driver.findElement(By.xpath("(.//*[#id='clsArrowClick'])[1]")); //this step can be skipped
driver.findElement(By.xpath("(.//*[#id='clsArrowClick'])[1]")).click();

As mentioned by alessandro-da-rugna, the id should be unique and I think it should be fixed. Selenium also have limitation in terms of find element, if there are two or more elements, it will choose the first one that present, regardless it is visible or not, which click method requires the element to be visible and enabled
To solve this, there are several ways
Make sure your xpath is unique, so you get , for example //a[::following-sibling/input[#id='hdnIsSaved1']] when you find element
As mentioned by jayesh Doolani, you could use
WebElement myElement = wait.until(ExpectedConditions.elementToBeClickable(By.xpath())
myElement.click()
The second way is to use find elements, then find which element that meet your criteria, by checking its attribute, and make sure element clickable, by checks the enable method. Then do click on element that match your criteria

element = driver.findElement(By.xpath("html/body/div[9]/div/div/div[3]/button[2]"));
js = (JavascriptExecutor)driver;
js.executeScript("arguments[0].click();", element);
element = null;
js = null;

Related

xpath with Multiple condition in Selenium

Wants to locate element with multiple condition on particular row,
I want to Click on div which contains ng-click="condition001" which has parent link contains Auto-001
So query become like : Select element xpath("//div[contains(#ng-click,'condition001')]") where Link("Auto-001")
<tr ng-repeat="(abc, xyz)" ng-show="data.length > 0">
<td class="x001">
<div class="x002">
<a class="x003" href="#">Auto-001</a>
</div>
</td>
<td class="x004">
<div class="x005">
<div class="x006">
<div class="x007" ng-click="condition001" tabindex="0">
<i class="x008"></i>
</div>
</div>
</div>
</td>
</tr>
Please suggest relevant xpath code which can work for above criteria,
To click on the WebElement identified through xpath as ("//div[contains(#ng-click,'condition001')]") where it has partialLinkText as ("Auto-001") you can use the following line of Java code :
WebElement myElem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='x003' and contains(.,'Auto-001')]//following::td[1]//div[#class='x007' and #ng-click='condition001']")));

selenium xpath to select following-sibling

I have the following HTML:
<tr class="k-grouping-row" role="row">
<td aria-expanded="true" colspan="6">
<p class="k-reset">
<a class="k-icon k-i-collapse" tabindex="-1" href="#"></a>
<span class="consolidation-group" style="font-weight: bold;" data-key="aedfdb66-bb11-4350-9d25-21941820141b">jhmfgjf (2 Items)</span>
</p>
<a class="k-button unconsolidation-link" onclick="UnConsolidateGroup("aedfdb66-bb11-4350-9d25-21941820141b", "8780f45d-0e81-4f5c-b206-61b682b27d67")" title="Unconsolidate all matter entries in this group">
<span class="marginRight5 icon-unlink"></span>
Unconsolidate All
</a>
</td>
I would like to click on the span "Unconsolidate All" using following-sibling operator. I tried the following code:
//span[contains(text(), 'jhmfgjf')]/../following-sibling::class[#title='Unconsolidate all matter entries in this group']
But it does not work, the first part does work, it's just the following-sibling part that does not work.
Any help would be helpful
The element's name is <a>, not <class>.
You should do the following:
//span[contains(text(), 'jhmfgjf')]/../following-sibling::a[#title='Unconsolidate all matter entries in this group']
Unconsolidate All is not a span element. Its a "a" element.
You can use
//a[contains(text(),'Unconsolidate All')]
And if you specifically want to use following-sibling , you can use in this way
//span[contains(text(), 'jhmfgjf')]//following-sibling::a[#title='Unconsolidate all matter entries in this group']
For reference and learning about sibling, ancestors in xpath , you can see click here

Unable to Click on Element

I am unable to click on the element. I am able to locate it with xpath, the object with statements
"element.getText()"
returns correct values
"element.isDisplayed()"
returns true
but when i say "element.click()" throws an exception
"Element is not currently visible and so may not be interacted with"
The above exception is thrown in selenium 2.34 and higher versions.
When I use older selenium version say "2.25" it doesn't throw an exception but the click has no effect.
I am using FF browser on Win7 machine.Below is the HTML
<div class="dojoxGrid-row dojoxGrid-row-over row-read" style="">
<table class="dojoxGrid-row-table" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td class="dojoxGrid-cell " style="width:36px;" idx="0" tabindex="-1">
<td class="dojoxGrid-cell gridColFrom " style="width:150px;" idx="1" tabindex="-1">
<td class="dojoxGrid-cell gridColType " style="width:16px;" idx="2" tabindex="-1"/>
<td class="dojoxGrid-cell gridColAttach " style="width:16px;" idx="3" tabindex="-1"/>
<td class="dojoxGrid-cell gridColSub dojoxGrid-cell-over" style="width:400px;" idx="4" tabindex="-1">
<span style="white-space: nowrap;" title="(No subject)">(No subject)</span>
</td>
<td class="dojoxGrid-cell " style="width:72px;" idx="5" tabindex="-1">Tue May 13</td>
<td class="dojoxGrid-cell gridColHov " style="width:16px;" idx="6" tabindex="-1">
<td class="dojoxGrid-cell gridColFlag " style="width:16px;" idx="7" tabindex="-1">
</tr>
</tbody>
</table>
</div>
Element is not currently visible and so may not be interacted with
What you're seeing is commonly caused by multiple elements on the screen matching the search criteria. WebElement.findElement returns the first match, which may not actually be visible. You can check by calling "isDisplayed" on it.
Try to locate that element using same xpath in firebug and check whether it is showing element which is visible on screen.
Try to click element using jsExecuter:
JavascriptExecutor myJSExecutor = (JavascriptExecutor)myDriver;
myJSExecutor.executeScript("arguments[0].click();", myElement);
//where myDriver and myElement are already defined WebDriver and WebElement
It seems your application uses Dojo for UI. I faced same problem while clicking on an element which has dojo property and I solved it using JavaScriptExecutor in similar way as you mentioned above. The other solution to this problem is use .sendKeys(Keys.Enter).

Selenium Webdriver - (Java) - Click a button with dynamic ID

1) I have a dialog on my web page having 2 buttons, Yes & No.
2) IDs of these buttons are dynamicaly changing every time.
3) How to handle this situation and click on Yes button?
4) Both buttons, Yes & No, have same classname 1.e. rwInnerSpan
5) Here is the Xpath for Yes button
(.//*[#id='confirm1381468352443_content']/div/div[2]/a[1]/span/span)
the part 1381468352443 in xpath is dynamically changing.
Below is the source code of page
`
<tr class="rwTitleRow">
<tr class="rwContentRow">
<td class="rwCorner rwBodyLeft"> </td>
<td class="rwWindowContent" valign="top">
<iframe frameborder="0" name="confirm1381468352443" src="javascript:'<html></html>';" style="width: 100%; height: 100%; border: 0px none; display: none;" tabindex="0">
<div id="confirm1381468352443_content">
<div class="rwDialogPopup">
<div class="rwDialogText">
<div>
<a class="rwPopupButton" href="javascript:void(0);" onclick="$find('confirm1381468352443').close(true);" tabindex="-1">
<span class="rwOuterSpan">
<span class="rwInnerSpan">Yes</span>
</span>
</a>
<a class="rwPopupButton" href="javascript:void(0);" onclick="$find('confirm1381468352443').close(false);" tabindex="-1">
<span class="rwOuterSpan">
<span class="rwInnerSpan">No</span>
</span>
</a>`
Thanks in Advance !!
You can directly check for the text in your Xpath:
driver.findElements(By.xpath("//a[#class='rwPopupButton']/span/span[contains(text(), 'Yes')]"))
There is a way to locate objects using partial link text, so you can try this:
driver.findElement(By.partialLinkText("Yes")).click();
Plain By.linkText may not work because of additional spaces or characters in the link.
You can click on the button based on the Text. Following method will give you a webelement based on the class locator and text.
WebElement getElementBasedOnClassAndText(String classLocator, String text){
List<WebElement> elements = driver.findElements(By.className(classLocator))
for(WebElement element : elements){
if(element.getText().contentEquals(text)){
return element
}
}
Assert.fail("Unable to find any element with the said Text")
}
Once you get the element you can take any action on it.
Since it is dynamic I would look for the changed name:
//Find the dynamicly created ID
String dynamicID = driver.findElement(By
.xpath("//iframe[contains(#name,'confirm')]")
.getAttribute("name");
//Use that ID to find the Yes option
driver.findElement(By
.xpath("//*[#id='"+dynamicID +"_content']/div/div[2]/a[1]/span/span")
.click();

Facing issues in Identify button in selenium

I am working on 1 project, where i have to locate button, i have used xpath for same, but button id change on every refresh, so i am facing problem in it..
Below is screenshot for same - let me know you can i identify that button so that it will not cause error even if id chages
<button type="button" id="ext-gen11" class=" x-btn-text">Login</button>
Code HTML
<tr>
<td></td>
<td><div id="LoginButton" style="float: left;"><table style="width: auto;" id="ext-comp-1032" class="x-btn x-btn-noicon x-btn-over x-btn-focus" cellspacing="0"><tbody class="x-btn-small x-btn-icon-small-left"><tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr><tr><td class="x-btn-ml"><i> </i></td><td class="x-btn-mc"><em class="" unselectable="on"><button class=" x-btn-text" id="ext-gen12" type="button">Login</button></em></td><td class="x-btn-mr"><i> </i></td></tr><tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr></tbody></table></div></td>
</tr>
xPath:
//button[text()='Login']
XPath should do the trick:
Command: clickAndWait
Target: //input[#value='Login']
Edit
Assuming, that there is only one button with value "Login" on it