Find out correct xpath - selenium

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")

Related

How to align a button right in Materialize card-action

I am using Materialize, and I need to align a button to the right side of the card in the card-action.
This is the code:
<div class="card-action">
This is a link
</div>
This is the result:
If I remove the class="right" then I get this result:
I want the result from the second image, except the button should be aligned to the right. Am I missing something about the materialize card-action? How should I get this behavior?
It should be right-align instead of right and you've to use it on card-action div. You can check about the alignment classes in Helper page of the documentation.
<div class="row">
<div class="col s12 m4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">Card Title</span>
<p>I am a very simple card. I am good at containing small bits of information. I am convenient because I
require little markup to use effectively.</p>
</div>
<div class="card-action right-align">
<a class="btn blue" href="#">Right</a>
</div>
</div>
</div>
</div>
You Just Need to Mention the Alignement in below way
<div class="card-action right-align">
YOUR CONTENT WILL ALIGHT TO RIGHT
</div>

How to resolve this click conflict?

<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]

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

Adding many buttons to header in JQuery Mobile

I know that we can add left and right buttons in a header in Jquery Mobile App.
But can we any more buttons or controls in the header section itself?
I think I have a better solution,
<header data-role ="header" data-theme="b">
<h1 class="ui-title" role="heading">Staff</h1>
<div class="ui-btn-right" data-role="controlgroup" data-type="horizontal">
filter
move
</div>
</header>
Screenshot;
with regard to this info:
you can find it here:
http://www.metaltoad.com/sites/default/files/Responsive-Widths_0.png
you can use this code:
<style type="text/css">
#media all{
.my-header-grid.ui-grid-b .ui-block-a { width: 30%; }
.my-header-grid.ui-grid-b .ui-block-b { width: 40%; }
.my-header-grid.ui-grid-b .ui-block-c { width: 30%; }
}
}
</style>
<div class="my-header-grid ui-grid-b" data-theme="a">
<div class="ui-block-a ui-bar-a" data-theme="a">
<div align="left" style="padding-left:5px;padding-top:3px;height:33px;height:40px;">
Back
Edit
</div>
</div>
<div class="ui-block-b ui-bar-a">
<div align="center" style="padding-top:3px;height:33px;text-align:center;height:40px;">
<div style="padding-top:7px;">
<article role="heading" aria-level="1">expand </article>
</div>
</div>
</div>
<div class="ui-block-c ui-bar-a">
<div align="right" style="padding-top:3px;height:33px;height:40px;">
Add
Refresh
</div>
</div>
</div><!-- /grid-b -->
if by any chance your programming with c# mvc razor engine don't forget to write the css media tag with 2 # like so ##media because the razor engine treats 2 # as one.
you see and can play with all of the designs shown here in this link:
http://jsfiddle.net/yakirmanor/BAat8/
iv added some links but i recommend youll read this:
http://appcropolis.com/blog/advanced-customization-jquery-mobile-buttons/
the simple implantation is:
<header data-role ="header" data-theme="a">
<a data-icon="back" href="/" rel="external">Back</a>
<h1 class="ui-title" role="heading">Staff</h1>
<a class="ui-btn-right" data-icon="back" href="#" rel="external">Refresh</a>
</header>
or this:
<div data-role="header" data-theme="b">
<a data-icon="back" href="/" rel="external">Back</a>
<h1 class="ui-title" role="heading">Staff</h1>
<div class="ui-btn-right" data-role="controlgroup" data-type="horizontal">
filter
move
</div>
</div>
or this:
<div data-role="header" data-theme="e">
<div class="ui-btn-left" data-role="controlgroup" data-type="horizontal">
filter
move
</div>
<h1 class="ui-title" role="heading">Staff</h1>
<div class="ui-btn-right" data-role="controlgroup" data-type="horizontal">
filter
move
</div>
</div>
hope iv helped.
It might be easier to create a custom navbar instead of modifying the header toolbar, Here si the docs: http://jquerymobile.com/demos/1.0a4.1/#docs/toolbars/docs-navbar.html
This might help:
<div class="ui-btn-right">
<!-- Home Button -->
<a href="index.html" data-role="button"
data-icon="refresh" data-iconpos="notext" data-direction="reverse" data-corners="true"
data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-theme="b" title="Refresh">
</a>
<!-- Home Button -->
<a href="index.html" data-role="button"
data-icon="home" data-iconpos="notext" data-direction="reverse" data-corners="true"
data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-theme="b" title="Home">
</a>
</div>
This gives me those nice rounded buttons, two side by side on the right side.
Just like on the mobile docs.
Works in 1.1.1, haven't tried the latest RC
I was able to achieve this by the following code:
<div data-role ="header" data-theme="b">
Prev
<div data-role="controlgroup" data-type="horizontal" style="margin-left:75px;margin-top:5px;" >
<a href="index.html" data-role="button" data-icon="arrow-l" >P.Week</a>
N.Week
</div>
Next
</div>
No, there is a hard limit of 2 as far as I have found. The best I was able to come up with was to get another unstyled link to appear.
There are however, navbars - On one of my projects, I needed a number of buttons in the header area, I placed a navbar directly below it, and was reasonable pleased with the results.
They are explained in detail here:
http://jquerymobile.com/test/docs/toolbars/docs-navbar.html