How to resolve this click conflict? - selenium

<div id="mainTag" class='mainTag'>
<div id="subMainTag1" class="subMainTag1">
<div id="subTag1" class="subTag1">
<Detail Explanation below>
<div id="subTag1" class="subTag1">
<Same as above, only difference would be some text message >
<div id="subTag1" class="subTag1">
<Same as above, only difference would be some text message>
Detailed snippet of subtag1
<div id="mainTag" class='mainTag'>
<div id="subMainTag1" class="subMainTag1">
<div id="subTag1" class="subTag1">
<div id="subTag2" class="subTag2">
<div id="subTag2A" class="subTag2A"></div>
<div id="datapreview" class="dataPreview"> <!-- These below lines will not be enabled/expanded -->
<div id="dataNote" class="dataNote">
<div id="titleBar" class="titleBar">
<span id="dataTime" class="datTime">9/10/2017 7:01 pm</span>
<div id="deleteButton" class="deleteButton">
<img class="someimg" src="someimg">
</div>
</div>
<div id="contentDiv" class="contentDiv">
<div id="dataTitle" class="dataTitle">Some Data1</div>
<div id="dataContent" class="dataContent">Some Data1 Body text </div>
</div>
</div>
</div> <!-- Lines will be disabled till here-->
</div>
</div>
On clicking on the subTag1, those disabled line gets enabled/expanded.
Unable to click on div element.
//div[#id="mainTag"]/div[#id='subMainTag1']/div[1]
//div[#id="mainTag"]/div[#id='subMainTag1']/div[2]
//div[#id="mainTag"]/div[#id='subMainTag1']/div[3]
When I click on any of the above elements, it says WebDriverException:
Message: unknown error: Element
//div[#id="mainTag"]/div[#id='subMainTag1'/div[2] is not clickable at
point (433, 239). Other element would receive the click:
//div[#id="mainTag"]/div[#id='subMainTag1'/div[2] (Session info:
chrome=60.0.3112.113) (Driver info: chromedriver=2.31.488774
(7e15618d1bf16df8bf0ecf2914ed1964a387ba0b),platform=Mac OS X 10.11.6
x86_64)

Looking at the given code structure there is no second or third sibling, they are children. You'll need to adjust your xpath to get the right node.
For example, locate the second 'div' anywhere within 'subMainTag1':
xpath=(//div[#id="mainTag"]/div[#id='subMainTag1']//div)[2]
If you forgot the closing div's in your code example, adding the brackets should be enough:
xpath=(//div[#id="mainTag"]/div[#id='subMainTag1']/div)[2]

Related

Failed to get clickable element using selenium

Here is the scenario, I have multiple tiles on home page. when a user logins in for the first time some of them need to be disabled. Same i am trying to test using selenium.
To disable the div i am using ng-class by which i am applying .disableDiv class on the div which has below css
.disableDiv {
pointer-events: none;
opacity: 0.4; }
When i target it using .isEnabled() but it is showing true even if the disable class is applied on it.
Please suggest how should i target the disabled elements.
below as you see isNewUser is ng-class which applies .disableDiv on the element which makes is disabled for the end user.
Thanks in advance
HTML
<div class="col-md-6 col-sm-12 tile-box-1" id="div-importcontent" ng-class="isNewUser">
<div class="tile-box-2">
<div class="col-md-2 col-sm-2 col-xs-3 tile-box icon-box">
<!-- icon -->
<a class="d-icon-download icon" ui-sref="importcontent" id="a-importcontent"></a>
</div>
<div class="col-md-10 col-sm-9 col-xs-8 tile-box desc-box">
<h4 class="heading" ui-sref="importcontent" id="h4-importcontent">Import content</h4>
<!-- <a class="d-icon-info_circle icon-info"></a> -->
<span class="desc" ui-sref="importcontent" id="span-importcontent">Import installed applications reporting content into BMC Remedy Smart Reporting
</span>
</div>
</div>
</div>

Selenium webdriver: clicking not working for xpath

I'm trying to get the webdriver to click on the text "Breaking Things" through xpath/css selectors to no avail. Here is the HTML
<div class="org-option" ng-repeat="Org in Organizations" aria-label="Select Breaking Things Organization" ng-click="Org.SelectOrg()" role="button" tabindex="0">
<div class="data">
<div class="data-relative">
<!---->
<div class="image-wrapper" ng-show="Org.HasImage" ng-if="Org.HasImage" aria-hidden="false">
<img class="onboard-logo" ng-src="/apiimage/organizations/f1544944fac34442998a05890c400338-0" src="/apiimage/organizations/f1544944fac34442998a05890c400338-0">
</div>
<!---->
<div class="image-wrapper ng-hide" ng-show="!Org.HasImage" aria-hidden="true">
<div class="image-placeholder">
<div class="center-icon gicon-panorama"></div>
</div>
</div>
<div class="name-wrapper">
<div>Breaking Things</div>
Here is what I'm doing with the driver:
chromeDriver.findElement(By.xpath("//div[#class='name wrapper']//[text()='Breaking Things']")).click();
However it never clicks, what am I missing? I've also tried implicit waits etc with no results.
You should specify exact node name div or wild-card for "any node" - * in this part
//[text()='Breaking Things']
like below:
"//div[#class='name-wrapper']//div[text()='Breaking Things']"
or
"//div[#class='name-wrapper']//*[text()='Breaking Things']"
The class name is name-wrapper. The - is important
chromeDriver.findElement(By.xpath("//div[#class='name-wrapper']//[text()='Breaking Things']")).click();
In #class='name wrapper' you are actually telling the driver to look for an WebElement with two classes, name and wrapper.

How to click a parent element using the child element for the following scenario

I am using selenium webdriver to automate. I have a special case below.
<div id = "A">
<div id = "container">
<div id="innercontainer">
<div>
<div id="ruleContainer">
<span id="rule">CNET</span>
<div id="name">CNET></div>
</div>
</div>
</div>
</div>
<div id = "A">
<div id = "container">
<div id="innercontainer">
<div>
<div id="ruleContainer">
<span id="rule">GNET</span>
<div id="name">GNET></div>
</div>
</div>
</div>
</div>`<div id = "A">
<div id = "container">
<div id="innercontainer">
<div>
<div id="ruleContainer">
<span id="rule">DNET</span>
<div id="name">DNET></div>
</div>
</div>
</div>
</div>`
Here I need to click on element A with text CNET... I am able to get to the child CNET but it is a dead element. So I need to click on anchor for element A having that particular child.
How can I do that? Is there a way? I know the solution for looping but my application refreshes so often and I encounter stale exception because of it. So could some one give me a better solution like navigating back to the parent and then to the sibling and click().
try this xpath:
//div[#id='A' and .//span[contains(text(), 'CNET')]]//a
it searches for the div with id = 'A' that has a span that contains the text 'CNET', from that div it selects the anchor-child-element

Find out correct xpath

I have an html page like this:
...
<div class="container">
<div class="title">Meat</div>
<div class="someclass">
<div class="tile AAA">
<div class="text">AAA</div>
<img class="image" src="somewhat.jpg" />
</div>
</div>
<div class="someclass">
<div class="tile BBB">
<div class="text">BBB</div>
<img class="image" src="somewhat.jpg" />
</div>
</div>
</div>
<div class="container">
<div class="title">Fish</div>
<div class="someclass">
<div class="tile AAA">
<div class="text">AAA</div>
<img class="image" src="somewhat.jpg" />
</div>
</div>
<div class="someclass">
<div class="tile BBB">
<div class="text">BBB</div>
<img class="image" src="somewhat.jpg" />
</div>
</div>
</div>
...
I need to be able to get selenium click an img for a specific element (for example, i want Meat-BBB's img) but I can't find a way to get it by xpath
Any help will be appreciated...
This will click on the Meat-BBB's img:
driver.findElement(By.xpath("//div[.='Meat']/following-sibling::*[2]//img")).click();
It finds the 2nd sibling to the div element having text/innerHtml as "Meat", and then traverses to the first "img" element in it.
This will be the xpath for your Meat-BBB's img /html/body/div[1]/div[3]/div/img
You can find xpath of any element by following steps.
1. Open your HTML file with any browser
2. Press F12 and inspect that element by clicking on that element
3. Now right click in html panel on the element and click on Copy XPath
Done! Now you have XPath.
The xpath will be - yourText
//div[div[text()='yourText']]/descendant::img
To make this Xpath more Generic , we can define a string like
// assign the value under which you want to click image Meat or Fish
String classTitle = "Meat";
and chage the xpath as follows:
//div[.='+classTitle+']/following-sibling::*[2]//img")

Dijit: Why am I getting an "Uncaught Error: Invalid Template"?

I have a dijit that looks fine as far as I can tell, but it is raising Uncaught Error: Invalid template every time. I have not been able to figure out why. All variables (e.g. ${variableName} are defined in the widget correctly.
Here is the widget:
<div class="${classPrefix}-wrapper">
<div class="${classPrefix} flair" dojoAttachPoint="flairNode"></div>
<div class="${classPrefix}-count hidden" dojoAttachPoint="countWrapperNode">
<div class="count" dojoAttachPoint="countNode">0</div>
</div>
<div class="${classPrefix} ${secondaryClass} action hidden" dojoAttachPoint="secondaryClickNode" dojoAttachEvent="onclick:_onSecondaryClick">
<div class="${classPrefix}-inner"></div>
<div class="${classPrefix}-icon"></div>
</div>
<div class="${classPrefix} ${primaryClass} action" dojoAttachPoint="primaryClickNode" dojoAttachEvent="onclick:_onPrimaryClick">
<div class="${classPrefix}-inner"></div>
<div class="${classPrefix}-icon"></div>
</div>
<div class="${classPrefix}-message hidden" dojoAttachPoint="messageNode"></div>
</div>
<div class="${actionPromptNodeClass}" dojoAttachPoint="actionPromptMessageNode">
<span dojoAttachPoint="actionPromptMessage">${actionPromptText}</span>
<span dojoAttachPoint="actionCompletedMessage" class="hidden">${actionCompletedText</span>
</div>
Found the answer to my question. It turns out that you can only have one root node in a Dijit. I missed this in the docs, but it is at the bottom of this tutorial:
Common Pitfalls
Be sure to only have one root node in your template
Don’t start or end your template with a comment because that means you technically have two nodes
Avoid a trailing </div> at the end of your template
There may be only one root element in the template. Wrap your template into <div></div> and it should work.