Selenium ActionDriver.click not working in Firefox - firefox

I've got a test where I need to use the action click. I can't directly click the element I need because it's a ::before element, and the element it's before is 0x14 so it's not interactable. I'm using watir-webdriver instead of selenium directly, which is why wd is used. It accesses Selenium's objects instead of Watir's.
I have an element, I am going to use the parent to find the location I need to click.
$browser.wd.action
.move_to(element.parent.wd)
.move_by(12, 0)
.click
.perform
This code works fine in Chrome, however nothing gets clicked in Firefox. Both zooms are set to 100%. Relative to the parent, the object I need to click is in the same place.
I don't know where else to look.
I've tried this with: Selenium 2.42 on Firefox 29 and Selenium 2.44 on Firefox 34.
Thanks in advance.
UPDATE
I've downgraded to FF 31.1.1 and have changed my Driver instantiation code to include native events:
if $BROWSER == :firefox
profile = Selenium::WebDriver::Firefox::Profile.new
profile.native_events = true
return Watir::Browser.new $BROWSER, profile: profile
else
return Watir::Browser.new $BROWSER
end
No luck with click.
I'm trying it on a website where I can see mouse movement and clicking: http://www.escapemotions.com/experiments/flame/. It's an interactive drawing program. The mouse moves just fine, click_and_hold seems to work,and drag_and_drop_by works fine too. I run into trouble on click.
Chaining click_and_hold.release works. I'm going to submit a defect for 2.44.

Seems to be a defect. As a work around click_and_hold and release can be chained to simulate a click.
driver.action.click_and_hold.release.perform
The defect is logged: https://code.google.com/p/selenium/issues/detail?id=8353

Related

Access browser print popup for testing purposes

I'm using capybara to write end to end test.
I have a print feature inside my app and would like to access its DOM in order to assert different things on my printed document.
How could I access the popup DOM using Capybara?
+How could I programmatically close the print popup when I'm done asserting? It seems that Capybara is stuck after executing the print method.
ps: I'm using an headless Chrome.
Note: This answer only applies to using the Selenium driver with non-deadless chrome, and once you're inside the shadowDOM you can only use CSS selectors which means you can't use any of the Capybara methods that involve Capybaras built-in selectors ('fill_in', 'select', etc). This may also break with any release of Chrome or chromedriver.
Because of the way chromedriver/chrome works, it isn't returning from whatever action you did to open the print window until the print window is closed. It is technically possible to work around this by triggering the print window asynchronously. But then you run into the issue that most of the print window is inside shadow DOM elements which the WebDriver spec doesn't currently provide an API for. You can however work around that using evaluate_script.
Therefore to open and then close a print window would be something like this
print_window = page.window_opened_by do
page.execute_script('window.setTimeout(function(){ window.print();}, 50)')
end
page.within_window(print_window) do
print_app = page.find('print-preview-app')
print_app_shadow = print_app.evaluate_script('this.shadowRoot')
print_header = print_app_shadow.find('print-preview-header')
print_header_shadow = print_header.evaluate_script('this.shadowRoot')
print_header_shadow.find('.cancel-button').click
end
Obviously all those calls could be chained together, the intermediate elements are only spelled out to make it clearer what is being done.

Is there a way to determine if an element is clickable in Chrome Browser using Selenium and Watir?

As I understand it, this question is really only relevant when performing web test automation using Chrome browser due to the manner in which a click event is implemented with Selenium Webdriver and Chromedriver. To preface, I use and am aware of finding an element through the use of the Watir element function "present?", which as I understand is essentially a combination of "visible?" and "exists?". I could also, at need find an element with Webdriver element functions to identify if an element is present with a rescue for an exception if it is not. What I am trying to determine is the following:
At times, due to a lack of responsiveness to a page, there will be page elements that will be found and pass all validation tests for it's existence, but cannot actively actually be interacted with due to the aforementioned lack of page responsiveness. Using Chrome browser (with Chromedriver) attempts to interact with these elements will result in the error:
irb(main):003:0> #browser.button(:id, "button_login").present?
=> true
irb(main):004:0> #browser.button(:id, "button_login").click
Selenium::WebDriver::Error::UnknownError: unknown error: Element ... is not clickable at point (915,
nt would receive the click: ...
(Session info: chrome=66.0.3359.181)
(Driver info: chromedriver=2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),platform=Windows NT 6.3.9600 x86_64)
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/response.rb:69:in 'assert_ok'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/response.rb:32:in 'initialize'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/http/common.rb:83:in 'new'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/http/common.rb:83:in 'create_response'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/http/default.rb:107:in 'request'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/http/common.rb:61:in 'call'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/bridge.rb:170:in 'execute'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/oss/bridge.rb:579:in 'execute'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/remote/oss/bridge.rb:328:in 'click_element'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/selenium-webdriver-3.4.4/lib/selenium/webdriver/common/element.rb:74:in 'click'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/watir-6.4.1/lib/watir/elements/element.rb:131:in 'block in click'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/watir-6.4.1/lib/watir/elements/element.rb:656:in 'element_call'
from C:/Ruby23/lib/ruby/gems/2.3.0/gems/watir-6.4.1/lib/watir/elements/element.rb:122:in 'click'
from (irb):4
from C:/Ruby23/bin/irb.cmd:19:in ''
I know I can rescue at this point, but that entails that I actually click the element. Essentially I want to write a special function "clickable?" that will return a boolean output without actually clicking the element and possibly navigating away from the page. I would prefer not to attempt this with a type of --ctrl+click, if new window return true, close window, set focus on first window, rescue return false-- workflow.
Watir 6.15.0+
Element#obscured? has been added to check for this scenario. You can now do:
browser.element(id: 'target').wait_while(&:obscured?).click
Watir pre-6.15.0
For older versions, you will need to take a different approach.
I would try waiting for the overlapping element to go away. If the overlapping is something like an overlay that will eventually disappear, it's relatively straightforward - eg:
browser.element(id: 'overlapping_element').wait_while(&:present?)
If the overlapping element gets moved rather than disappears or you don't know the overlapping element, you could try approximating the overlapping element check. When Chrome clicks an element, it gets the element's center location and then clicks at that point. If there the top-level element at that point is not your element, the exception is thrown. The following wait will do this check until there is no overlapping element:
target = browser.button
target_children = target.elements.to_a
browser.wait_until do
location = target.location
size = target.size
center = [location.x + size.width/2, location.y + size.height/2]
element_at_point = browser.execute_script("return document.elementFromPoint(#{center[0]}, #{center[1]});")
[target, target_children].flatten.include?(element_at_point)
end
target.click
Note that I haven't had to do this before, so I don't know if there are edge cases. Seemed to work with Chrome and Firefox.
I can suggest you to wait this button to show on the web page. I experienced the same problem (I was using XPath in my tests). To fix it:
Firstly I defined 2 helper methods because I had to reuse them a lot. One for searching of a exact element on the page(this method is usually takes a while to return a result so you don't need to sleep the browser) and one for clicking a button with given "id".
module Helpers
module Common
def wait_for_element_id(value)
find(:xpath, "(//*[#id='#{value}'])[1]")
end
def click_button_with_id(value)
first(:xpath, "//button[#id='#{value}']").click
end
end
end
After that in your test you can use the helper methods like:
it 'clicks on the login button and magic is executed' do
logout(user)
wait_for_element_id('button_login')
click_button_with_id('button_login')
expect(magic).to be_executed
end
I am also not sure but you can also experience the same problem because of the browser window size (button is not shown because the size is too low) or because of the "headless" mode of your tests.

Watir - drag and drop not working

I need to test some functionality where I need to drag and drop some UI elements.
I tried to do this on this page http://www.html5rocks.com/en/tutorials/dnd/basics/ :
browser.divs(:class => "column")[-2].drag_and_drop_on browser.divs(:class => "column")[-3]
In chrome, I don’t see anything happening.
In firefox, I see the that the mouse button is down, but nothing else happens – the element didn't move.
I tried in other pages as well and this never seemed to work.
I also tried this workaround (which is recommended in multiple threads) and it doesn’t work either:
my_element = browser.divs(:class => "column")[-4]
target = browser.divs(:class => "column")[-3]
my_element.fire_event("onmousedown")
driver = browser.driver
driver.action.click_and_hold(my_element.wd).perform
driver.action.move_to(target.wd).perform
target.fire_event("onmouseup”)
I'm using ruby 1.9.3 on mac. I also tried ruby 2.1.5 on windows and the result was the same.
Is there a way to drag and drop with watir?
This is what eventually got it to work (not fancy at all, but it did it for me):
# monkey patch for webdriver: copy and paste in IRB
module Selenium
module WebDriver
class ActionBuilder
def drag_and_drop(source, target)
click_and_hold source
move_to target, 0, 0
release target
self
end
end # ActionBuilder
end # WebDriver
end # Selenium

The browser window may have been closed. (Selenium::WebDriver::Error::UnknownError)

I have multiple features when run together throw this error. If I run the scenarios by them self there is no issue. I think the issue is that popups are generated during the test run and are not closed properly. I have code in an After hook that closes all open windows except the very first window opened.
Error: Session [2c50a228-3ad7-a544-a6ca-5d173b86bc86] has no driver. The browser window may have been closed. (Selenium::WebDriver::Error::UnknownError)
I have added a bunch of print statements in my code to get the current state:
After:Session -> #<>Capybara::Session:0x00000100f811b8>
Before:Driver -> selenium
Before:Session Object -#<>Capybara::Session:0x00000100f811b8>
Before: (start) Driver Object #<>Capybara::Selenium::Driver:0x000001028ad790>
The scenario before this particular scenario fails, this HAS to be the culprit, but why? Can anyone point me in the right direction?
After hook
#assume ONLY last window opened is to be closed
page.driver.browser.switch_to.window(page.driver.browser.window_handles.last)
page.execute_script "window.close();"
#switch back to first window opened, make it the default window now
page.driver.browser.switch_to.window(page.driver.browser.window_handles.first)
Env:
capybara (2.0.3)
cucumber (1.1.9)
selenium-webdriver (2.29.0)
ruby 1.9.3p0
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.get "https://www.google.co.in/"
address = driver.find_element(:link_text, "Gmail").attribute('href')
driver.execute_script( "window.open()" )
p driver.window_handles.length
p driver.window_handles.first #=> "{f17eac79-daf9-4a6c-a1ff-1b524fef9faf}"
driver.switch_to.window( driver.window_handles.last )
driver.get address
driver.execute_script "window.close()"
driver.execute_script "window.close()"
# => Window not found. The browser window may have been closed. (Selenium::WebDriver::Error::NoSuchWindowError)
In the above code,I just tried to re-generate the error,and it happened.Error is very logical as I tried to close an already closed,non existent window.
Now I want to debug this way:
p driver.browser.window_handles.length # if this is 0,then below line obvious throw error.
page.driver.browser.switch_to.window(page.driver.browser.window_handles.last)
page.execute_script "window.close();"
p driver.browser.window_handles.length # if this is 0,then below line obvious throw error.
page.driver.browser.switch_to.window(page.driver.browser.window_handles.first)
Now debug and let me know your result.
The solution for this is to maximise the window at the first place. I've not been able to find a way to maximise the window yet. In the middle of the test i manually click the maximise browser button and the test runs perfectly.
https://github.com/fahenao/_bot

how to scroll with selenium

I have here a challenge that I spent some time addressing.
Selenium tells me that it cannot click a link that is not visible, so that means I need to scroll my canvas? I am using ubuntu 10, firefox 3, selenium 0.1, ruby 1.9.2, and selenium-webdriver 2.5.0
My code is
driver = Selenium::WebDriver.for :firefox;
driver.get login_url
wait = Selenium::WebDriver::Wait.new(:timeout => 2)
wait.until {
driver.find_element(:name => 'j_password')
}
driver.find_element(:name => 'j_username').send_keys(username)
driver.focus(:name => 'j_username')`
and it says that focus() is not defined. How should I modify my code to put the input element on screen?
Um, this is a hypothetical example, I really need to scroll so that some other element is on the screen, but for simplicity I would like to be able to scroll s.t. any element is on the screen, even
location_once_scrolled_into_view to scroll using ruby.
As per your question your element is not visible, so selenium web driver is unable to click on it.
Simple solution to this is:
Store the xpath of the element which is visible and nearby to your element.
Scroll till that visible element, to make your element visible.
Ensure your element is now visible, click on it
eg code:
element = dirver.find_element(:xpath, "xpath of nearby visible element")
element.location_once_scrolled_into_view
my_element = driver.find_element(:xpath, "xpath of your element")
my_element.click
I had an element at the bottom of the page with no other element close enough to select first. Finally got around it by tabbing from the last field in the form on the page.
element.send_keys(:tab)
When the documentation says "not visible" it's not refering the view port, but to the status of the element on the page. If something is hidden with CSS it cannot be clicked.
If you want to scroll on the firefox window using selenium webdriver, one of the way is to use javaScript in the java code, The javeScript code to scroll down is as follows:
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight," +
"document.body.scrollHeight,document.documentElement.clientHeight));");
I'm not aware of ruby but the above code can be used as a java Script which will scroll down the whole page.You can even define the area you want to scroll in the view window by simply hard- coding the window.scrollTo(200,350);

Resources