How to check whether an Xpath is clickable? - selenium

I have an application developed in Liferay. It has a data grid which has pagination.
When ever i open the data grid for the first time Prev is not clickable and Next is clickable. Below is the html code for the same.
<section class="paginationArea">
<div id="pager">
<span id="prev" class="disablehyperlink"><< Previous Page</span>
<span id="next" class="enablehyperlink">Next Page >></span>
</div>
</section>
Please let me know how can i check whether that text is clickable or not??

You can always check it for a class attribute (assuming class change will cause enabling the button). You didn't specify a language so I will show you example in Java.
Element prevButton = driver.getElement(By.id("prev"));
if(prevButton.getAttribute("class").equals("disablehyperlink") {
// do something
}
or you can try WebDriver#isEnabled method but I don't know whether it will work because it depends how are you disabling the button
if(prevButton.isEnabled()) {
}

Generally, all the <a> anchor Tags will be clickable.
In your case, Prev is not clickable. Because prev [previous in paginator] is hidden; where else Next [next in paginator] is not hidden(enabled).
Use Firebug [firefox add-on] to track all the hidden anchor tags | href links and code accordingly.

Related

angular2 bootstrap4 tooltip doesn't render html, while popover does

I'm using angular2 and bootstrap4. Popover correctly renders raw html as bold text asdf
<img src="assets/images/1.jpg"
data-container="body" data-toggle="popover" data-html="true" data-placement="top"
[attr.data-content]="getM()"/>
However, tooltip renders as plain <b>asdf</b> text including tags
<img src="assets/images/2.jpg"
data-container="body" data-toggle="tooltip" data-html="true" data-placement="top"
[attr.title]="getM()"/>
Component method getM:
public getM(): string {
return '<b>asdf</b>';
}
Both tooltip and popover are initialized the same way
$(function () {
$('[data-toggle="tooltip"]').tooltip({container: 'body'});
$('[data-toggle="popover"]').popover({container: 'body'});
})
Could someone explain why is that and how to solve? It seems this is connected with initialization order, but I just don't know where to look further.
Well, the issue was that my element (which tooltip was attached to) was created dynamically.
In exact, I had a 1 sec delayed service. When new data arrived, the <img> element in my component was recreated, but $('[data-toggle="tooltip"]') selector doesn't work with dynamic elements.
Instead, I had to use this selector
$("body").tooltip({selector: '[data-toggle="tooltip"]'});
Now it works as intended.
PS I'm not a front-end developer, so anyone who can explain it in better terms is welcome.

How to validate Web element if xpath locator is dynamic in selenium webdriver

ID and Xpath is changing for "OK" button every time while saving(Account).
HTML Code:
<div class="modal-footer" style="display: block;">
<div class="bootstrap-dialog-footer">
<div class="bootstrap-dialog-footer-buttons">
<button id="fe02d6bd-6058-4871-b0e1-c1e914f64a6a" class="btn btn- default">Ok</button>
</div>
</div>
</div>
</div>
Xpath:.//*[#id='fe02d6bd-6058-4871-b0e1-c1e914f64a6a']
"ID"/XPath is not constant and it is varying while saving.
use the below code:
driver.findElement(By.cssSelector("div.bootstrap-dialog-footer-buttons>button.btn.btn-default"));
You can devise your own XPath locator to find the OK button by it's text content like so:
//button[.='Ok']
The first part of the XPath expression - //button - will select all <button> WebElements within the currently focused content.
The second part - [.='Ok'] - is a predicate that will filter out any WebElements whose exact text content is not equal to 'Ok'.
If it is the only OK button available on the page then you can probably use below code.
driver.findElement(By.xpath("//button[contains(.,'Ok')]"));
Else you can take a reference of parent window and locate a button on it as below
WebElement modalWin = driver.findElement(By.id("modal-window-id"));
modalWin.findElement(By.xpath("//button[contains(.,'Ok')]"));
This below code helps to click OK button in any page.
just call this method with parameter saying OK
public void buttonClick(String buttonname){
WebElemennt button = driver.findelement(by.xpath("//button[text(),'Ok']"))
or
WebElemennt button = driver.findelement(by.cssselector(".btn btn- default"))
for(int i=0; i<button.size;i++)
{
if(button.get(i).gettext().equalIgnorecase(buttonname))
{
button.get(i).click
}
}
}
Let me know result..

Selenium: Click on element in div container doesn't work

Fyi: I'm using the selenium package for R, the selection code is equal to javascript or python so I'm asking a general selenium question.
I have a container which I have to make visible by a click, this works.
Then I try to select an element inside this container, I think I find it correctly but the click on the element only makes the popup window disappear.
Example code:
<div class="dateRanges" style="top: 275.313px; display: block;">
<a class="top dateOption CUSTOM" id="id32" href="javascript:;">
Benutzerdefinierter Zeitraum
</a>
<a class="dateOption TODAY" id="id33" href="javascript:;">
Heute
</a>
...
</div>
Element I try to find is "top dateOption CUSTOM".
My different tries which all failed:
remDr$findElement(using = 'xpath','//a[contains(#class,"top")]')$clickElement()
remDr$findElement(value = '//a[#class = "top dateOption CUSTOM"]')$clickElement()
remDr$findElements(using = 'css selector','a[class="top dateOption CUSTOM"]')[[1]]$clickElement()
I don't get any error message, the click seems to happen as the popup disappears, but the effect of the button does not.
I tried to save the object, wait a few seconds and click afterwards with no different effect.
I also tried different approaches with "idc4" with the same outcome.
Would appreciate any help, thank you.

How to check if there is a strikethrough on some text in selenium webdriver?

There are many planbox, which are having same class and ids, inside them there are a number of <p> tags and decorated text.
<div class="planbox">
<p class="baseprice">
<span>
<strike> $70 </strike>
</span>
</p>
<p> New discount price is etc. </p>
</div>
<div class="planbox">
<p class="baseprice">
<span> $70 </span>
</p>
</div>
Now, My test case is - if the base price is strikethrough, only then <p> 'New discount price .. </p> will show, otherwise not.
How to check whether a text is strikethrough or not? And even if we get this how will I check that <p> New discount.. </p> should not show if the text is not striked.
As there is no class in <p> tag on which I can check whether it displayed or not.
One solution in my mind was - add one dummy class in <span> tag and using findChildren('span.dummyCLass') it will result all the webelements having dummyClass.
Now I will check whether web-elements have strike tag or not, and this is the place where I got stuck.
Initially, i was thinking of a Jquery solution, but is it possible to do without adding new class and jquery?
You don't need to add a class to any element to accomplish this task. In general, you don't want to edit the HTML. Another issue is... if you can find the element to add a class, then you don't need to add the class to find the element. :)
The way I approach tasks like these is to find the outermost element that contains all the elements that you are interested in. I refer to this as a "container". What you want to do in this case is to find the containers and loop through them looking for the strikethrough price and for the "New discount price..." text.
The containers are DIVs with the planbox class. The strikethrough price is indicated by the STRIKE tag. The "New discount price..." text is in a P tag. With this info we can write some code. This is Java because I don't know what language you want and I'm not familiar with the Galen framework.
// gets the collection of containers using a CSS selector
List<WebElement> containers = driver.findElements(By.cssSelector("div.planbox"));
// loops through the containers
for (WebElement container : containers)
{
// determine if the STRIKE tag exists
boolean strikeExists = !container.findElements(By.tagName("strike")).isEmpty();
// determine if the "New discount price is..." text exists in the 2nd P tag
boolean discountPriceExists = container.findElements(By.tagName("p")).get(1).getText().trim().contains("New discount price is");
// if both are true log a pass, otherwise log a fail
if (strikeExists && discountPriceExists)
{
// log a pass
}
else
{
// log a fail
}
}
I haven't used much of selenium. But you can port this jquery code to selenium,
//if there is a strike element
if($(".baseprice span strike").length > 0){
//next() will select the sibling of the p tag with baseprice class
$("p.baseprice).next() != undefined){
return true
}else{
return false
}
}
you can use Galen for this. There you can verify certain CSS properties.

safari - contenteditable, after making it empty, creates an element with text-align:center

In safari,
i had a simple edtable div with a input button, on deletion of the element (backspace or delete), caret moves to center of edtiable div with some inline styled p tag with text-align:center and inline style "color"
<div class="editable" contenteditable="true">
<input type="button" value="inputBtn" />
</div>
http://jsfiddle.net/VqCvt/
its a strange behavior observed only in safari.
Over a year after this post, this issue is still a problem. This issue is directly tied to the input tag. Once an input tag has been in a contenteditable element, Safari will attempt to make the style of the text similar to the input (I confirmed this by observing that the resulting style was different for type="text" vs type="button"). It's a very strange bug. I have found a workaround that works, but it's pretty absurd. My fix is basically to test when my main input no longer has content, and then removing the element, and re-adding it
<div id="content-wrapper">
<div contenteditable="true" id="content" role="textbox"></div>
</div>
and in my "keyup" listener, I put the following code
// Grab main editable content div
var element = document.getElementById("content");
// Check empty state conditions. These work for me, but you may have your own conditions.
if (element.getElementsByTagName("input").length == 0 &&
element.innerText.trim().length == 0) {
// Grab parent container
var elementContainer = document.getElementById("content-wrapper");
// Add a copy of your element to the same specifications. If you have custom style attributes that you set through javascript, don't forget to copy them over
elementContainer.innerHTML = '<div contenteditable="true" id="content" role="textbox"></div>';
// Re-focus the element so the user doesn't have to click again to keep typing
element = document.getElementById("content");
element.focus();
}
What this code does works for my case because input is the only elements which are allowed in my code other than text nodes and <br>, so I first check to make sure there are no input elements, and then make sure the innerText is empty (this indicates no content in my case, you may have to customize your conditions for the "empty" state). Once the empty state is confirmed, I replace the old div with a new one to the same specification, and the user never notices. A very strange issue with a hacky workaround, but I think contenteditables.
You could probably also strip out the HTML that Safari is generating, but for my case this solution is much simpler. I hope this helps someone in the future.