Perform continuous mouse hover with Canvas? - selenium

[https://i.stack.imgur.com/yKOOF.png]I have to click one of options from left widget (See the Image1.PNG) will display single row as shown in ( See the [https://i.stack.imgur.com/hBNTN.png]Image.PNG) and then mousehover on each and every value and have to capture the tooltip for each values of that particular row..
xpath for the left and right widgets are:
#FindBy(xpath="//*[#id='tabZoneId21']/div/div/div/div[1]/div[5]/div[1]/canvas")
WebElement wbcanvasWidgetLeft;
#FindBy(xpath="//*[#id=\"view5159778620503418402_17231458509407196328\"]/div[1]/div[2]/canvas[2]")
WebElement wbcanvasWidgetRight;
And when I mouse hover on each and every value the following code gets highlights and only the value of ‘left’ gets change otherwise its static for all options.
[![<div class = “ tab-tooltip tab-widget tab-tooltipAR” style=”user-select: none; -webkit-tap-highlight-color: transparent; top: 1px; **left:119px**;”>… </div>
<div class=”tab-tooltipContainer”>
<div class =”tab-tooltipContent” wairole=”alert” style>
<div class=”tab-ubertip tab-widget” style=”min-width: 368px;”>.
<div class =”tab-ubertipContent”>
<div class=”tab-ubertipTooltip”>
<span style =”white-space:pre-wrap;tab-size:10;-moz-tab-size:10”>
<div style=”text-align:left;”>
<span style=””>Health Group </span>
</div>
<table style=”vertical-align:top;padding:0px” cellspacing=”0”>
<tbody>
<tr>
<td style =”white-space:pre”>
span style=”font-family” >97</span>
</td>
<td >
<span style=”font-” >Minimum</span>
</td>][1]][1]
Only the value of ‘left’ gets change for each options with some specific margin.
I have tried with following code which mousehover either 87.7% or 30.2% and displays the tooltip. I am not able mousehover on the first option that is 19.9% and so on in continuous manner.
public void sikuli() throws FindFailed, Exception {
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[title='data visualization']")));
try{
//Captured image of first option(Health) and clicked on in it
Screen s = new Screen();
Pattern target = new Pattern("Health.PNG");
s.wait(target,20);
s.mouseMove(target);
s.click();
Actions act = new Actions(driver);
act.moveToElement(wbcanvasWidgetLeft).moveByOffset(-50,0).moveToElement(wbcanvasWidgetRight).build().perform();
//Capturing Tooltip
System.out.println(driver.findElement(By.xpath("//div[#class='tab-ubertipTooltip']/span/div[3]/span[1]")).getText());
System.out.println(driver.findElement(By.xpath("//div[#class='tab-ubertipTooltip']/span/div[4]/span")).getText());
}
catch(Exception e)
{
e.printStackTrace();
}
driver.switchTo().defaultContent();
}
Can I use javascript executor with help of style attribute where I set the margin values for ‘left’ but i don't know how to set margin for style attribute while writing xpath.
Any help will be appreciated.

Related

How to click an individual part of 'canvas' in selenium?

I am trying to click a specific part i.e first part(19.9%) of image but its always clicking any of the value which are after 14.3%. Please check the image.[![https://i.stack.imgur.com/WoUlM.png]]
The code is:
<div class="tvimagesContainer" style="width: 80px; height: 241px;">
<canvas class="tabCanvas tab-widget" width="71" height="213" style="display: block; width: 80px; height: 237px;"></canvas>
</div>
I tried with following:
#FindBy(xpath="//*[#id='tabZoneId21']/div/div/div/div[1]/div[5]/div[1]/canvas")
WebElement wbcanvas;
Actions builder = new Actions(driver);
Action drawAction = builder.moveToElement(wbcanvas, 213/12,10).//
.click()
.build();
drawAction.perform();
In place of 213/12,10 put different values and tried but its clicking every time on the middle part of image.
Any help will be appreciated.
Please try it like following, this will click the one above of the middle. You can change the value(213/12). If you want to click below fields then you need to change y to value below 0 :
Actions actions = new Actions(driver);
actions.moveToElement(wbcanvas).moveByOffset(0, (213/12)).click().build();
actions.perform();

How to compare value with list item and click on the desired element using selenium

I have 18 names in a list and want to click on the name after comparision with an another element.
List<WebElement> list = driver.findElements(By.xpath("//*[#class='w-100 f7 pv2 ph1 mb2 bg-white-20 pointer']// following :: span[#class='v-mid']"));
Iterator<WebElement> att = list.iterator();
WebElement e;
while(att.hasNext()) {
e= att.next();
if(e.getText().equalsIgnoreCase("Rohit Sharma"));
{
e.click();
break;
}
Below is the inner HTML Code
<div class="w-50 dib">
<img class="dib w2 h2 br-100 bg-dirty-green mr1 v-mid"
src="https://fanfight.com/images/player.png" alt="">
<span class="v-mid">Saurabh Tiwary</span> // i am taking this in my list and want to compare with a another name if both match it will select
</div>
<div class="dib tc ttu" style="width: 15%;">MI</div>
<div class="dib tc" style="width: 15%;">0</div>
<div class="dib tc" style="width: 15%;">7.2</div>
<div class="dib tc" style="width: 5%;"></div>
Like the above HTML code i have 18 div's
As you are creating a List you can easily iterate over the List items and invoke click() to your matched condition as follows :
List<WebElement> list = driver.findElements(By.xpath("//div[#class='w-50 dib']//span[#class='v-mid']"));
for(WebElement ele:list)
if(ele.getText().equalsIgnoreCase("Rohit Sharma"));
{
e.click();
break;
}
Note : While invoking findElements() I have constructed the Locator Strategy with the elements present in the HTML you have provided which you may suffice to your needs or else you may require to change the Locator Strategy accordingly.

trouble making in xpath for "ul" html code in selenium webdriver

HTML code:
<div id="routingPanel" class="">
<div id="routingPanelRight">
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a>
<span class="fa fa-trash"/>
<span class="type">[srl]</span>
</li>
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="queue" data-id="119">
<a class="ui-corner-all" tabindex="-1">AS-EMEA-NORTH</a>
<span class="fa fa-trash"/>
<span class="type">[queue]</span>
</li></ul></div></div>
I need to click on a button which is having the span class"fa fa-trash" but it is inside li class. And i have list on buttons on the page with li class changing.
I am giving testdata from excel file so i can't use the direct value.
i tried to use this xpath
.//*[#id='routingList']/li[5]/span[1] //testdata1
.//*[#id='routingList']/li[2]/span[1] //testdata2
where li value changes everytime from excel file.
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))).click();
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/span[1]"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.click();
Tried above code but it is deleting only one from the list ,where i have passed two more testdata that needs to be deleted.
Need suggestions Please
According to the information you gave me in comments, I think the problem is that you are trying to get a text from an element that doesn't contain text.
Let's say your testData is AS-HTTS-US-LAN-SW. In the HTML you provided and the xpath you mentioned, you are selecting an autoclosing tag <span class="fa fa-trash"/>. Once this tag is selected, you are trying to get the text inside of it, and there is none.
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
===========================
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a> ----> The text is contained here
<span class="fa fa-trash"/> ---> No text in that tag
===========================
<span class="type">[srl]</span>
</li>
</ul>
So, basically, you have to modify a little bit your xpath from : //ul[#id='routingList']/li/span[1] to : //ul[#id='routingList']/li/a to get the text, and then go back to the parent node to find your button with : ../span[contains(#class, 'fa fa-trash')]
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))) // removed the click here because you were clicking on the first element of the list
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/a"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.findElement(By.xpath("../span[contains(#class, 'fa fa-trash')]")).click();
Tell me if it helped
I know you already accepted an answer but there's a more efficient way to do this. You can specify the text you are looking for as part of the XPath. So, you do a single search instead of looping through all the options which can be a performance hit if there are many options. Also, with something like this you are likely to use it more than once so put it in a function.
In this case, the function would take in the string you are looking for and then click the appropriate element.
public void selectRegion(String regionName)
{
driver.findElement(By.xpath("//a[.='" + regionName + "']/following-sibling::span[#class='fa fa-trash']")).click();
}
and you would call it like
selectRegion(testData);
The function looks for an A tag that contains the desired text and then clicks the sibling SPAN with class fa fa-trash.

No such element Exception. class name with double__

I am trying to get the text under the tag. That is Arduus, Gstaad, Switzerland. I tried with the classname and also with xpath.
driver.findElement(By.className("chalet-details__title"));
String chaletTitle = driver.findElement(By.xpath("//div/h1[#class='chalet-details_title']")).getText();
But its giving NoSuchElementException. The classname has double underscore(__) .Is it because of that not working? Can anyone help me with this?
<div class="col-md-12 col-sm-12 col-xs-12">
<h1 class="chalet-details__title">
<span class="chalet-details__title-property">Arduus</span>,
<a class="chalet-details__title-resort" href="/ski- resorts/switzerland/gstaad">Gstaad</a>,
<a class="chalet-details__title-country" href="/ski- resorts/switzerland">Switzerland</a>
</h1>
<div class="chalet-details__rating">
<div class="chalet-details__wrapper">
<span class="chalet-details__star" style="width: 108px;"></span>
<span class="chalet-details__mask"></span>
</div>
</div>
</div>
You can try something like:
driver.findElement(by.cssSelector("h1.chalet-details__title"))
I just tried this and it worked fine with the provided html, if this still fails for you, can you verify that there aren't any iframes on the page.
Both your locators are OK, but you might need to wait for your element to be present in DOM:
WebDriverWait wait= new WebDriverWait(driver,20 );
String chaletTitle = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("chalet-details__title"))).getText();
Another reason for NoSuchElementException: your element could be located inside an iframe, so you need to switch to that frame before handling target element:
driver.switchTo().frame("iframeNameOrId");
If it has no attributes as id or name:
WebElement someFrame = driver.findElement(By.xpath("//iframe[#someAttr='someValue']"));
driver.switchTo().frame(someFrame);
To get all the text under h1 tag find all elements using locator as follows:
List<WebElement> items = driver.findElements(By.cssSelector("h1.chalet-details__title > *")); //it will find all elements immediately under the h1 tag
Now, iterate over the elements.
Complete code:
List<WebElement> items = driver.findElements(By.cssSelector("h1.chalet-details__title > *"));
for(WebElement item : items){
System.out.println(item.getText());
}

Dojo: how to get row data in grid's context menu item handler?

I'm using Dojo 1.4.
Given a dojox.grid.DataGrid in markup:
<table jsId="grid1" dojoType="dojox.grid.DataGrid"
structure="layout"
delayScroll="true"
columnReordering="true"
selectable="true"
onRowDblClick="onRowDblClick"
onRowContextMenu="onRowContextMenu"
headerMenu="grid1_headerMenu"
>
<div dojoType="dijit.Menu" id="grid1_rowMenu" jsId="grid1_rowMenu" style="display: none;">
<div dojoType="dijit.MenuItem" onClick="gridRowContextMenu_onClick">Edit</div>
</div>
</table>
I haven't found a better way to show grid's contex menu that this one:
function onRowContextMenu(e) {
grid1_rowMenu.bindDomNode(e.grid.domNode);
}
It works, menu pops up and function 'gridRowContextMenu_onClick' has being called.
function gridRowContextMenu_onClick(e) {
// how to get a row data???
}
My question is how inside menuitem's onClick handler (gridRowContextMenu_onClick) can I get original row for which menu was poped up?
You can use the event grid object:
var item = e.grid.getItem(e.rowIndex);
I had a similar question. I wanted to create a context menu which allowed the user to remove the item that they right clicked on from the datagrid and delete the item from the datastore. Thought it should be pretty simple and with your help and some other sites, I came up with the following code. I hope this helps someone in the future.
Javascript
var selectedItem; // This has to be declared "globally" outside of any functions
function onRowContextMenuFunc(e) {
grid5_rowMenu.bindDomNode(e.grid.domNode);
selectedItem = e.grid.getItem(e.rowIndex);
}
function gridRowContextMenu_onClick(e) {
store3.deleteItem(selectedItem);
}
HTML
<div dojoType="dijit.Menu" id="grid5_rowMenu" jsId="grid5_rowMenu" style="display: none;">
<div dojoType="dijit.MenuItem" onClick="gridRowContextMenu_onClick">Delete</div>
<div dojoType="dijit.MenuItem">Cancel</div>
</div>
and
<div id="grid" dojoType="dojox.grid.DataGrid" jsId="grid5" store="store3" structure="layoutStructure" rowsPerPage="40" onRowContextMenu="onRowContextMenuFunc"></div>
Of course, if you were programatically creating your DataGrid, you would just add onRowContextMenu: onRowContextMenuFunc to your declaration, as you did in your question above.
Finally, to actually get information about the item:
console.log(e.grid.store.getValue(selectedItem, 'type'));
console.log(e.grid.store.getValue(selectedItem, 'color'));
// Where type and color are fields specified in the DataGrid Layout Structure //
Did you try e.rowIndex?