How to hover over (mouseover) an element in Selenium Ruby? - ruby

Anyone know how to hover over an element in Selenium Ruby Webdriver?
My code is like this:
el = driver.find_element(:css => "#foo")
driver.move_to el # How do I trigger a mouseover event on this element?
I'm using selenium-webdriver gem with Firefox in Linux 32-bit.

I used driver.action.move_to(el).perform which differs ever so slightly from the other answers, so I thought I would include it for completeness sake.

Turns out the answer is:
driver.move_to(el).perform
I forgot the .perform.

This works for me:
driver.mouse.move_to el

You need to use Selenium's Action Builder to access more complex actions like hovering (which is what seanny123's answer is demonstrating).
Also, if you are working with a hover, odds are you will need to dynamically wait for it to display before taking your next action (e.g., using an explicit wait).
I put together an example on how to do this -- you can see the full write-up here.

To hover an element:
driver.action.move_to(element).perform
# e.g.
driver.action.move_to(driver.find_element(css: 'a')).perform
To hover an element at a specific location:
driver.action.move_to(element, mouse_x, mouse_y).perform
# e.g.
driver.action.move_to(driver.find_element(css: 'a'), 100, 100).perform

Related

Laravel Dusk how to check if element is visible/clickable?

I have a scenario where I'd like not check IF an element exists and is visible/clickable. If not, script processing continues.
While Laravel Dusk provides $browser->assertVisible($selector) method, this ends up in an exception if the element is not visible. Or $browser->waitFor('.selector'); but this also ends the script processing if element doesn't appear.
Here is the criteria Selenium uses to check for an element being visible is found here: How to force Selenium WebDriver to click on element which is not currently visible?
Apparently Dusk doesn't provide this kind of method. What would be the best way to implement it?
Better late than never I suppose.
isDisplayed() works pretty well (though not if it's covered up by other elements)...
if($browser->driver->findElement(WebDriverBy::cssSelector('#my-selector'))->isDisplayed()) {
// do something
}
if I have overlays covering my elements, I use ->waitUntilMissing(), or in extreme cases I call on $browser->driver->executeScript() and run some jQuery to temporarily manipulate an element that is "in the way".
You can try to find the element and try to retrieve properties of it. If the properties are empty, the element is not visible. E.g.
$hiddenBtn = $browser->element('#show-more');
if($hiddenBtn && $hiddenBtn->getText()){
$browser->click('#show-more');
}
This worked for me.
Without a good idea of what you're trying to accomplish you can always wait until the element is visible:
https://laravel.com/docs/5.5/dusk#waiting-for-elements

Capybara - Click element by class name

For what seems to be a simple question I've been on this for a stupidly long time and can't seem to find anything on Google. I have this button I need to click which has no id but a class is included
<button class="filter-case-studies" onclick="initBootpag(filterForContentType('CASE STUDIES', searchHits))" type="button">
<b>CASE STUDIES</b>
(2)
</button>
I've tried using click_on which I now know is only for links and buttons so of course won't work. This is what I have so far:
When(/^I filter the results to only see case studies$/) do
click_on('filter-case-studies')
end
I've also tried page.find('filter-case-studies').click, this too doesn't work.
page.find(:class, 'filter-case-studies').click defualts to :css so this also failed for me.
Is there no way to click an element by the class name in Capybara?
Thanks in advance for the help.
The standard way of doing this in Capybara is
find('button.filter-case-studies').click
In relatively recent versions of Capybara you should also be able to do
click_on(class: 'filter-case-studies')
find('.filter-case-studies').click as recommended here https://robots.thoughtbot.com/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element
I had a button that could not be found (Unable to find visible link or button nil with classes [close-modal]) using the methods above.
This worked for me: page.execute_script('$.find(".close-modal")[0].click()')
click_on('.filter-case-studies')
You need the . selector for classes, and # for ids.
Thanks to Mr Schutte for the idea to use . selectors.
I had to use page.find(:class, '.filter-case-studies').click in the end. The absolute navbar got in the way of the button so I then had to include page.execute_script "window.scrollBy(0,500)" to complete the test.

How to find a css element on the page if it is display: none?

I'm running automated testing in Ruby.
I'm trying to write a script that finds id with display:none (visible only in mobile form), and clicks it.
Here is my code:
def open_menu
page.find[:css, "a[id='mobile-nav-link']", visible: false].click
end
It gives me an error:
Selenium::WebDriver::Error::InvalidSelectorError:
invalid selector: No selector specified
A quick search reveals similar code using round brackets, not square. I.e.:
def open_menu
page.find(:css, "a[id='mobile-nav-link']", visible: false).click
end
Selenium only interacts with elements the way a user would.
If the link is only visible in mobile, I would suggest one of the following.
View the page via the mobile URL.
It's possible that you may be able to use Ruby's javascript execute to either update the control to be visible, or set the value that indicates you are viewing the page via a mobile device.
Updating the control to be visible
This link discusses how to set an element to visible using javascript execute: Selenium Webdriver - click on hidden elements
This link discusses how to use ruby's javascript execute: How to execute Javascript in Ruby written Webdriver test?
Put the two together, and you get something like this?
def open_menu
elem = page.find[:css, "a[id='mobile-nav-link']", visible: false]
js = "arguments[0].style.height='auto' arguments[0].style.visibility='visible';"
driver.execute_script(js , elem)
page.find[:css, "a[id='mobile-nav-link']", visible: true].click
end
I'm not entirely familiar with Ruby syntax, so I make no guarantees it will work copy/paste.

I can not locate proper element - click on link Ruby

I tried to click on link (see screenshots)
http://imgur.com/q66g7z6
http://imgur.com/KNF1y7z
I tried using few examples
e.g
#browser.button(:class=> '//*[#class="login"]//ul/li[0]/a').click
and
browser.button(:xpath=> "//a[#data-viewmodel='PagesAsync/RegisterPrivate/RegisterPrivateViewModel']").click
but is not correct
I can see the message that unable to locate element
Can somebody help?
The main problem is that you are telling Watir to look for a button when you actually want a link. While the UI may be styled to look like a button, you will notice that the HTML has a a tag instead.
The first example, which also has the wrong locator type, should be:
#browser.link(:xpath => '//*[#class="login"]//ul/li[0]/a').click
The second example should be:
browser.link(:xpath => "//a[#data-viewmodel='PagesAsync/RegisterPrivate/RegisterPrivateViewModel']").click
Note that the second example would be more Watir-like if you use the normal attribute locators:
browser.link(data_viewmodel: 'PagesAsync/RegisterPrivate/RegisterPrivateViewModel').click
There are two options. One is get your developers to add better IDs.
If that is not possible, try this:
how does ruby webdriver get element with hyphen in <name, value> pair
It worked for me in several similar situations.
I wonder how you can find a button by using an xpath to a link. It is also not clear whether you use browser or #browser. You would need to look into how the browser instance is defined, which likely is one of these:
#browser = Watir::Browser.new :chrome
###or###
browser = Watir::Browser.start 'example.com', :firefox
and if you haven't create a browser instance, then you would need to do it before you can use Watir-Webdriver. ;)
As for your question, you could try searching using the text if it is unique like this, though it may be a brittle test:
#browser.div(:class => 'login').link(:text => /For priva/).click
but I would recommend to double check the number of elements found using the div and link locators like this to make sure you got the right element:
#browser.divs(:class => 'login').length
#browser.div(:class => 'login').links(:text => /For priva/).length

Is "enabled?" method available on Watir and/or Page-Objects for a link?

Yesterday i was working on determining is this link was or not enabled, waiting until enabled in order to click it. I'm using Cucumber + Ruby + Watir + Page-Object gem. The link is very similar to:
<a id="the_link" href="#" disabled="disabled">Proceed with your order</a>
Once you fill some fields, the link is enabled and the source changes to:
<a id="the_link" href="#">Proceed with your order</a>
The idea is to wait until the link is enabled in this way, which works with buttons:
def click_on_link
Watir::Wait.until { self.the_link_element.element.enabled? }
self.the_link
end
...but does not work with the link. I made it work determining if the attribute exists, this way:
def click_on_proceed_form
Watir::Wait.until { !self.the_link_element.element.attribute_value('disabled') }
self.proceed_form_submit
end
Looking for the "enabled?" method at the Watir documentation here or at the Page-Object gem here, it seems that is available for all elements. But looking for the same method in the Watir documentation here, seems it's only available for Buttons, Selects and Inputs.
So, i wonder is there is an "enabled?" method for links (anchors) and, if it exists, how to use it. Can you help clarify this issue, please? Thank you very much!
Watir-webdriver does not support the enabled? method for links. I believe this is because the disabled attribute is not a standard attribute for links.
On the other hand, Watir-classic does support the enabled? method for links. However, it will always return false (again because links cannot be disabled).
Therefore, I think your approach is correct (unless you want to monkey patch the link elements to support the enabled?).
However, you should try to avoid using Watir-webdriver directly where possible. The page-object gem has its own methods for waiting and getting attribute values:
def click_on_proceed_form
wait_until{ !the_link_element.attribute('disabled') }
proceed_form_submit
end

Resources