I have encountered an issue that really makes me confused. I'm able to find elements on a page but after I interact with elements from bottom of page, I cannot click element that are on top of page without scrolling to top of page. This only happens on Edge browser (Chrome, Firefox work well).
My code is as below:
page.fill_in_form # This part is middle/bottom of page
page.click_button 'SAVE' # This button is middle/bottom of page
page.select_sub_menu 'Category' #This sub menu is top navigation of page
And this is error message.
Unable to find css "#subnav"
My select_sub_menu funciton:
def select_sub_menu(sub_menu)
within('#subnav') { click_link(sub_menu) }
end
It looks like Capybara does not recognise the elements are on top of page after scrolling into middle of page although they are available.
My driver is configured as below:
Selenium::WebDriver::Edge.driver_path = "#{file_path}/MicrosoftWebDriver.exe"
Is there any solution for this?
Related
I'm trying to click on a button that contains the words "Add To Cart" using ruby/watir.
If I use
cart = browser.link(text: 'Add To Cart')
if cart.present?
cart.click
It works (item gets added to cart) but I get a element click intercepted: Element ... is not clickable at point (441, 20). Other element would receive the click: (Selenium::WebDriver::Error::ElementClickInterceptedError
I'm new to ruby/watir so any help would be greatly appreciated.
Try this code whether it works. If it's not working then as you have stated, even after the error, it works, So I assume we have to issue the click on the element which is overlaying the target element. So Paste the entire error message. The error message must contain the element which is actually obscuring.
require 'watir'
b = Watir::Browser.new
cart = browser.link(text: 'Add To Cart')
if cart.present?
b.wait_while { cart.obscured? }
cart.click
end
Update
Okay, there are other two ways you have to try.
One is to use JavaScript.
cart.click!
Or click the element which is overlaying your element.From your error the element is division with class attribute 'row'. If you have more detail about that element, you can locate that element by yourself. But now, with the given detail, I form the locator.
b.div(class: 'row').click
there are few ways you can figure what is going on
try looking around the element
check if watir sees more than one link, this should produce 1
browser.as(text: 'Add To Cart').count
then try to click every element if it has more than 1
browser.as(text: 'Add To Cart')[0].click
browser.as(text: 'Add To Cart')[1].click
or try to click its parent, link can be behind overlay
browser.a(text: 'Add To Cart').parent.click
then check if same can be acomplished by clicking parent element directly
browser.div(class: 'wishlist_cart_button').click
or you can try with different approach, find element by some other attribute
browser.a(href: /setCurrentId/).click
also maybe there is a parent element with id so you can find the cart button easier
browser.element(id: "asdf").a(text: "Add To Cart").click
browser.element(id: "asdf").as.last.click
if everything above fails, then click it with selenium, since watir is worried about click being intercepted
browser.driver.action.move_to(browser.a(text: 'Add To Cart').wd).click.perform
hope something helps :D
I was trying to use capybara to help me upload vocabulary to memrise.com, but I encounter some problems in its login page.
Here is what I've written.
def sign_in
self.visit 'https://www.memrise.com/login/'
find(".inpt-large[name='username']").set 'my-username' # Step 1
find(".inpt-large[name='password']").set 'my-password' # Step 2
find('input.btn-success.btn-large').click # Step 3
end
It can finish the step1 and setp2 but fail at step3 sometimes.
And below is the error message.
gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok': Element is not clickable at point (592.5, 23). Other element would receive the click: <span class="nav-item-btn-text"></span> (Selenium::WebDriver::Error::UnknownError)
Since the only items on the page I can find matching <span class="nav-item-btn-text"></span> are in the fixed header, I'm guessing you're running your tests with too small of a window size, so the actual Login button you want to hit is off the page when the test is run. This means when the test goes to click the button, it needs to scroll the item into view and it does that by scrolling it to the top of the page. That leaves the button behind the fixed header and unable to be clicked. To fix that you can either
increase your window size so the form doesn't need to be scrolled
set the elementScrollBehavior capability to 1 in your driver registration which will cause elements to be scrolled until they're visible at the bottom of the page rather than top.
scroll the page yourself before clicking the button
Additionally is there are reason you're using find(...).set vs just using fill_in for this form?
def sign_in
visit 'https://www.memrise.com/login/'
within('form#login') do
fill_in('username', with: 'my-username')
fill_in('password', with: 'my-password')
click_button('Login')
end
assert_text('You are now logged in') # whatever messagge is shown once login complete
end
I am trying to automate tests in Ruby using the latest Watir-Webdriver 0.9.1, Selenium-Webdriver 2.53.0 and Chrome extension 2.21. However the website that I am testing has static headers at the top or sometimes static footers at the bottom. Hence since Watir auto-scrolls an element into view before clicking, the elements get hidden under the static header or the static footer. I do not want to set desired_capabitlites (ElementScrollBehavior) to 1 or 0 as the websites I am testing can have both - static header or static footer or both.
Hence the question are:
1) Why does Watir throw an exception Element not clickable even when the element is visible and present? See ruby code ( I have picked a random company website for an example) and the results below.
2) How can I resolve this without resorting to ElementScrollBehaviour?
Ruby code:
require 'watir-webdriver'
browser = Watir::Browser.new :chrome
begin
# Step 1
browser.goto "shop.coles.com.au/online/mobile/national"
# Step 2 - click on 'Full Website' link at the bottom
link = browser.link(text: "Full website")
#check if link exists, present and visible?
puts link.exists?
puts link.present?
puts link.visible?
#click on link
link.click
rescue => e
puts e.inspect
ensure
sleep 5
end
puts browser.url
browser.close
Result:
$ ruby link_not_clickable.rb
true
true
true
Selenium::WebDriver::Error::UnknownError: unknown error: Element is not clickable at point (460, 1295). Other element would receive the click: div class="shoppingFooter"...div
(Session info: chrome=50.0.2661.75)
(Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Mac OS X 10.10.5 x86_64)>
http://shop.coles.com.au/online/mobile/national
thanks!
You can do a click at any element without getting it visible. Check this out:
link.fire_event('click')
BUT It is very very very not good decision as far as it will click the element even if it is not actually visible or in case when it is just impossible to click it (because of broken sticky footer for example).
That's why much better to wait the fooler, scroll the page and then click like:
browser.div(id: "footerMessageArea").wait_until_present
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
link.click
The sticky footer is blocking webdriver from performing the click, hence the message that says 'other element would receive the click'.
There are several different ways you can get around this.
Scroll down to the bottom of the page before the click
Hide/Delete the sticky footer before any/all link clicks
Focus on an element below the element you want to click before you perform the click
I Guess your element is visible in the screen.
Before clicking on the element first you have to scroll the webpage so that element is visible then perform the click. Hope it should work.
I had similar issue,
I just used following javascript code with watir:
link = browser.link(text: "Full website")
#browser.execute_script("arguments[0].focus(); arguments[0].click();", link)
Sometimes I have to use .click! which i believe is the fire_event equivalent. Basically something is layered weird, and you just have to go around the front end mess.
Watir code which is working but add condition link is not identifying again here :(
require 'spec'
require 'watir'
browser = Watir::Browser.new
pages = { "RCM Workspace Homepage" => "http://rcm-bpmt.apmoller.net/workspace/faces/jsf/workspace/workspace.xhtml" }
Given(/^that I am on the (.*?)$/) do |page|
# Opening new browser and going to the page which is specified
browser.goto(pages[page])
#Maximizing the opened browser window
browser.maximize
end
When(/^I search for (.*?)$/) do |text|
# Ensuring that we have opened expected page only by verifying the page content
browser.html.include?(text).should == true
end
Then(/^I click on Show Filters link$/) do
#Opening the Conditions window by clicking on the show filters link
browser.link(:id, "portletComponentWorkList_viewNormalModeWorkList_viewPanel_showFiltersLink").click
#Clicking on Add condition link which is placed in a frame and it opnes when I click on Show filters link
browser.element(:id, 'portletComponentWorkList_viewNormalModeWorkList_viewPanel_conditionButton').click
end
HTML details:
<A id=portletComponentWorkList_viewNormalModeWorkList_viewPanel_conditionButton onclick="oc.ajax.jsf.doCallback('portletComponentWorkList','portletComponentWorkList:viewNormalModeWorkList:viewPanel:conditionButton');return false;" href="http://rcm-bpmt.apmoller.net/workspace/faces/jsf/workspace/workspace.xhtml#">
Add condition
</A>
In the following line, Watir will look for the element anywhere except for in the frames.
browser.element(:id, 'portletComponentWorkList_viewNormalModeWorkList_viewPanel_conditionButton').click
Unlike other elements, you must tell Watir when an element is in a frame. This is done similar to how you would scope the search of an element to a specific element.
For example, if there is only 1 frame or your element is in the first frame, you can do (noting the addition of the .frame):
browser.frame.element(:id, 'portletComponentWorkList_viewNormalModeWorkList_viewPanel_conditionButton').click
If there are multiple frames, you will need to add parameters to be more specific about which frame to use. For example, if the frame has an id:
browser.frame(:id => 'myframe').element(:id, 'portletComponentWorkList_viewNormalModeWorkList_viewPanel_conditionButton').click
I am using watir webdriver to do some automated testing of web pages. The pages have many images which are lazy loaded when the user scrolls the content into view (uses jquery lazyload plugin)
I am doing
10.times do
browser.send_keys :space
end
To scroll items in view and it loads fine
I also do
browser.div(:id => 'footer').wd.location_once_scrolled_into_view
which scrolls it to the bottom
and then I do
browser.screenshot.save
This does not seem to capture any images that are lazy loaded via jquery plugin.
What can I do to capture the entire page
The simplest thing you could do is to scroll to the bottom of the page. Count the images, send space, count the images again. If the number of images increased, send space again. If the number is the same, you have loaded all images.
Something like this (not tested):
old_image_count = 0
new_image_count = browser.imgs
while old_image_count < new_image_count
old_image_count = browser.imgs
browser.send_keys :space
new_image_count = browser.imgs
end
Instead of:
browser.screenshot.save
try:
browser.driver.save_screenshot("<path>/photo.jpg")