For a datepicker, why does one code snippet work, but the other doesn't? - watir

I want to populate two date fields on the same form, using "Today's date".
Both fields are read-only, to force the user to use the datepicker.
I can populate the first date field without problem.
Here is the HTML:
<div class="">
<div id="EffectiveFrom$CalendarBehavior_today" class="ajax__calendar_footer ajax__calendar_today"></div>
</div>
Here is my code:
#browser.div(:id => 'EffectiveFrom$CalendarBehavior_today', :class => 'ajax__calendar_footer ajax__calendar_today').click
Second date field
HTML:
<div class="">
<div id="RegistrationDate$CalendarBehavior_today" class="ajax__calendar_footer ajax__calendar_today">
Today: July 15, 2014
</div>
</div>
Code:
#browser.div(:id => 'RegistrationDate$CalendarBehavior_today', :class => 'ajax__calendar_footer ajax__calendar_today').click
The error is "Element not visible". But I can see exactly the same popup for the second field as I do for the first field.
(Edited) The popup that caused the "Element not visible" error message is fully displayed within the browser boundaries.
It seems to me (a non-techie) that the only difference between the first HTML and the second HTML is that the second HTML has inner text.

The element not visible exception means that the element exists on the page but is not displayed (eg has a style="display:none"). Given that you can see the popup, it is likely a timing issue.
What happens is:
You click something to trigger the popup to display.
Watir tries to click the div element.
The browser finishes updating the popup's style such that it is now visible.
Given that Watir tries to click the div before it gets displayed, you get the element not visible exception.
You can tell Watir to wait for the element to become visible before trying to interact with it:
#browser.div(:id => 'RegistrationDate$CalendarBehavior_today', :class => 'ajax__calendar_footer ajax__calendar_today').when_present.click

Related

HREF target='_blank' does not work in Chrome 79

Using simple HTML code, no JavaScript, nothing fancy, I use this HREF
Click here
Clicking on the link in IE, FireFox, Edge does open a new tab for https://www.example.com on click. In Chrome (version 79), the click just redisplays the current page.
This happens on Chrome desktop and phone (Android). There are no add-ins to my installation of Chrome; no popup or ad blocking installed.
Why doesn't Chrome open a new tab when target="_blank" is used? Thanks.
Added
The issue seems to be with an HREF being inside a FORM element. The FORM element is as follows:
<form action='' method='post'>
An HREF with target="_blank" outside the FORM element works properly. Just not inside the FORM element.
But still puzzled as to why that would be the case...and for a workaround or solution.
Added more - plus code
There's a button inside the form, and the button contains an image, and the link in the button will not open up a new tab.
Simple form with the button
<form action='' method='post'>
<p>inside the form</p>
<p><button><img src="https://via.placeholder.com/150 " width="24" height="24" class='button_img' alt='delete' /> that's a button</button></p>
<p><button>that's a button </button></p>
</form>
So, with even further testing, the click to open a new tab won't work in Chrome when the HREF is wrapped around an button with an image inside a form. But works in FireFox and Edge.
Why?
There are four image/buttons inside the form. The fourth one is the HREF/blank. Items 1-2-3 are form submittals; values need to be passed to the form processing page. The 4th item doesn't need to be processed by the form, but it is inside the form so that all four items will be on the same line. If I place the 4th (HREF/blank) outside of the form, then the 4th item is wrapped around to the next line.
a
The <button> tag cannot be opened in a new tab the same way an <a> does.
You can use this instead:
<p>
<button onClick="window.open('https://www.bklnk.com/B004RVZRL0');">
<img src="https://via.placeholder.com/150 " width="24" height="24" class='button_img' alt='delete' />
that's a button
</button>
</p>

Selenium select the first button that contains text matching

I am using the Firefox webdriver for Selenium to scrape a webpage that looks to be rendered with React on the client side. The classes in the rendered DOM look dynamically generated, and seem to change with every new request. There are also many button elements on the page, some of which are not in the viewport. So my strategy is to search for a way to click on a button that contains text that I enter using selenium. Several buttons will contain the text, and I want to just find the first such button.
Using selenium/xpath, how would I select the first button that contained the text E9 1QJ?
<button>
<div><svg ...> </div>
<div>
<div>London</div>
<div>E9 1QJ</div>
</div>
</button>
<button>
<div><svg ...> </div>
<div>
<div>London Foo Bar</div>
<div>E9 1QJ</div>
</div>
</button>
Thanks
This should work:
{driver}.find_element_by_xpath("//button[div/div[text()='E9 1QJ']][1]")
But keep in mind that a solution like this it is not very flexible and could break with a minimum change in the html structure.

Selenium automation - Dropdown on hover does not work

I am developing an automation script and a part of it requires me to hover over a navigation bar to display a dropdown menu. The script is written using NodeJS and the browser used is Internet Explorer.
Navigation source code
...
<ul class=navigation " data-dojo-attach-point="nonmMenu ">
<li class= "dropdown ">
<i class="fa fa-clipboard nav-icon " aria-hidden="true "></i><span>Accounts</span>
<div class='fulldrop i3">..</div>
</li>
</ul>
...
NodeJS code:
let xPathButton = "//span[text()='Accounts']";
//Find button to hover over
let buttonWithDropDown = driver.findElement(By.xpath(xPathButton));
//Hover
driver.actions().mouseMove(buttonWithDropDown).perform();
However, this does not work. The end goal is to click a link once the dropdown menu appears, which I have tried doing but as the element is not visible I get the exception ElementNotInteractableError: Cannot click on element. I would appreciate some pointers in the right direction to sort this out.
Update:
Been looking at this a bit more; Could the aria-hidden attribute in the anchor tag be causing the selenium driver to not detect the element?
Please note that changing the browser is not an option.
Try to hover over an a or li element. Also you can try click:
By.xpath("//a[span[.='Accounts']]")
By.xpath("//li[.//span[.='Accounts']]")
You can try open menu without opening menu with javascript:
executeJavaScript("arguments[0].click();", yourDropdownMenuElement);

Kentico - Bootstrap carousel to hide controller if there's only one item

I'm implementing a bootstrap 3 carousel on kentico 9 and need some help with automatically hiding the carousel control (including the circle indicator and the next/previous arrow) if there's only one item left, if possible.
What I've done for the carousel was setting up a new page type for this in which each banner is a page in the content tree under /hero/ folder. Then used 2 repeaters: the first one displays the circle indicator; the second one displays the banner info. All worked well.
Here's how the indicator repeater is set up:
Content before: <ol class="carousel-indicators">
Content after </ol>
Item transformation: <li data-target="#hero-banner" data-slide-to="<%# DataItemIndex%>" class="<%# (DataItemIndex == 0 ? "active" : "" ) %>"></li>
It means the first circle is always there. How to hide it and get rid of the <ol> tags in content before/after?
The next/previous arrows are again in the webpart zone content after, which has this html:
<a class="left carousel-control" href="#hero-banner" data-slide="prev"><span class="icon-prev"></span></a>
<a class="right carousel-control" href="#hero-banner" data-slide="next"><span class="icon-next"></span></a>
</div> <!--/#hero-banner-->
Using content before/after is like hard-coding it onto the page, but I don't know how to make it displayed dynamically and automatically only when we have more than one item. Could you help?
you can use <%# DataItemCount %> One of the [Transformation methods][1]
[1]: https://docs.kentico.com/display/K8/Reference+-+Transformation+methods to determine how many items there are. Then just have the html added in if there is more than one. Something like
<%# If(DataItemCount > 1,'html for more than one item','html for only one') %>
Of course, if you are using the envelope before / after to show arrows, you could also use jquery to determine how many items are there & hide the arrows based off that.
$(function(){
if($(".carousel-indicators li").length == 1){
$(".left.carousel-control").hide();
$(".right.carousel-control").hide();
}
});

watir issue with displaying new dropdown menu

manually clicking on tab(anchor tag) its displaying drop down menu(unordered list) with watir element is locating but drop down menu is not displaying
HTML
<ul>
<li id="NetworkAnalysisTabPanel__ext-comp-1038" class=" x-tab-strip-menuable x-tab-strip-active ">
<a class="x-tab-strip-close" onclick="return false;"></a>
<a class="x-tab-strip-menu" onclick="return false;"></a>
<a></a>
<a class="x-tab-right" onclick="return false;" href=""></a>
</li>
</ul>
Tried the following line of code to click on the tab
$ff.div(:id,"NetworkAnalysisTabPanel").div(:index,1).div(:index,1).ul(:index,1).li(:index,1).link(:index,2).fire_event("onClick")
I am using watir 1.6.6 version
Firstly since your HTML sample that you provided does not include the element you are using in the command you attmepted, it's hard to know where that might be going wrong. Secondly since the code you provided does have a div with a unique ID present, why not start there instead of with an outer container.
I think the problem is that you are using
.fire_event("onCLick")
However the code is monitoring for an event named "onclick" (all lower case)
Try using
.fire_event("onclick")
or if you have not already, perhaps just
.click
and see if that works for you
Also, I'd seriously recommend you upgrade to a more current version of Watir.. 1.6.6 is pretty behind the times.
Update: that html code is starting to look very familiar to me, if this is the same basic control from the other two questions you've posted so far, then try firing the 'onmousedown' event against the element that invokes the menu and see if that works

Resources