Cannot get past a modal overlay with Selenium, using Ruby - ruby

I am trying to click a button which appears in modal overlay pop up. The element of the button cannot be found using an xpath, which worked for all the steps before. If I try to find it by selecting a css class, it tries to click the overlay. But finding the overlay by itself, isn't possible.
The button that I need to click:
enter image description here
The script:
`
#click export as csv
$wait = Selenium::WebDriver::Wait.new(:timeout => 15)
input = wait.until {
element = driver.find_element(:xpath, '/html/body/div[6]/div/div/div/div[3]/div/button/div')
element if element.displayed?
}
driver.find_element(:xpath, '/html/body/div[6]/div/div/div/div[3]/div/button/div').click
`
I tried a few different things:
Selecting the xpath
`
#click export as csv
$wait = Selenium::WebDriver::Wait.new(:timeout => 15)
input = wait.until {
element = driver.find_element(:xpath, '/html/body/div[6]/div/div/div/div[3]/div/button/div')
element if element.displayed?
}
driver.find_element(:xpath, '/html/body/div[6]/div/div/div/div[3]/div/button/div').click
`
Selecting the css, which gave an interesting error:
`
#click export as csv
$wait = Selenium::WebDriver::Wait.new(:timeout => 15)
input = wait.until {
element = driver.find_element(:css, '.button-spinner-container')
element if element.displayed?
}
driver.find_element(:css, '.button-spinner-container').click
`
The error (it seems to click something else):
0x0000000103082a88 chromedriver + 4123272: element click intercepted: Element ... is not clickable at point (321, 96). Other element would receive the click: ...

Related

How to click on a button with just a text?

I have a button that has no class, id just a text
<button> Click me </button>
I tried the following:
driver.find_element(:xpath, "//button[contains(text(), 'Click me'")]
driver.find_element(:xpath, "//button(text() = 'Clck me'")
None of these work. Could someone put me in the right path?
Your code looks like syntactically incorrect, You should try as :-
driver.find_element(:xpath, "//button[normalize-space(text())='Click me']")
or
driver.find_element(:xpath, "//button[contains(text(), 'Click me')]")
Note :- Your button text seems as contains extra white spaces. So for avoiding these white spaces you should use normalize-space() in your xPath
Hope it will help you..:)
You have errors in your xpath. The correct one is:
# use button[] instead of button()
# you have weird order of ", ' and )
# space in the text 'Click me' also be considered ' Click me '
driver.find_element(:xpath, "//button[text() = ' Click me ']")
If it is not your typo in question, Try after changing:
driver.find_element(:xpath, "//button[contains(text(), 'Click me'")]
to
driver.find_element(:xpath, "//button[contains(text(), 'Click me')]")
Otherwise, find all the element on the page with tag name as "button" then traverse through the list of those elements to get the desired one.
Eg Code:
Get all buttons:
buttons = driver.find_elements(:class=> 'button');
Get the button with text 'Click Me'
clickMeButton = buttons.select{|el| el.text == 'Click Me'}.first
click on the button:
clickMeButton.click

Explicit wait for Selenium Webdriver

Working on the method trying to understand the explicit wait.
require 'rubygems'
require 'selenium-webdriver'
require 'cucumber'
$driver = Selenium::WebDriver.for :firefox
$driver.manage.timeouts.implicit_wait = 3
Then /^do search$/ do
driver = $driver
one_way = driver.find_element(:id, "search.ar.type.code.oneWay").click
sleep 5
from = driver.find_element :xpath => "//div[#class = 'origin column1']//input[#type = 'text']"
from.click
So after one_way radio button is clicked and input form changed , so I put sleep 5 to give it a time element to appear, otherwise would be error "element not visible ...". So I thought it would be good time to understand explicit wait, because I need to wait till element will appear.
wait = Selenium::WebDriver::Wait.new(:timeout => 40)
wait.until {from = driver.find_element(:xpath, "//div[#class = 'origin column1']//input[#type = 'text']")
from.click
}
But getting error "Selenium::WebDriver::Error::ElementNotVisibleError: Element is not currently visible and so may not be interacted with" . Why this code doesn't wait till element appears and click it?
The issue is that the element isn't in the DOM yet, hence your needing to put a time delay in there.
That said, the API doco for ruby says you should do it this way
require 'rubygems' # not required for ruby 1.9 or if you installed without gem
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.get "http://somedomain/url_that_delays_loading"
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
begin
element = wait.until { driver.find_element(:id => "some-dynamic-element") }
ensure
driver.quit
end
note that the element that you can then .click() is assigned from the wait.until method not the find_element() method as in your code.
However that arbitrary delays don't always work, if the site is busy then the delay may not be long enough.
A better option is to wait for the element to become clickable or visible.
The Java API's have ExpectedConditions convenience methods that cn be used like this...
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
element.click();
Unfortunatly I don't think Ruby has this yet. You may need to code up your own ExpectedCondition class or package.
I'm not a Ruby dev but here is the idea of a function in Java that could be used to implement your ExpectedCondition
public WebElement findElementInTime(WebDriver driver, By by, int timeoutInSeconds)
{
log.debug("==================+>>>>>> looking for element for "+ timeoutInSeconds + " seconds");
WebElement ret = null;
for (int second = 0; second < timeoutInSeconds; second++) {
try { if (isElementPresent(driver,by)) {
log.debug("found element :-)");
ret = driver.findElement(by);
break;
}} catch (Exception e) {
log.debug("oops... sleeping 1 sec wait for button");
}
log.debug("sleeping 1 sec wait for button");
}
return ret;
}

how to click on text area to send long text using ruby with selenium web driver

I tried xpath and id
getting `until': timed out after 10 seconds (no such element (Selenium::WebDriver::Error::TimeOutError)
I am using rubymine editor.
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { #driver.find_element(:xpath => "//*[#id='j_id0:pb:j_id35']") }
#driver.find_element(:xpath => "//*[#id='j_id0:pb:j_id35']").send_keys "test send sms"
Text area element is placed on bottom of the page.Do I need to scroll down the page and click and sendkeys in the text area.
in the below code I am trying to find nearest element to the text box and do scroll down later click on text area and sendkeys.But even it's not working..
#wait = Selenium::WebDriver::Wait.new(:timeout => 10)
#wait.until { #driver.find_element(:name => "j_id0:pb:j_id33") }
#scroll = #driver.find_element(:name => "j_id0:pb:j_id33")
#scroll.location_once_scrolled_into_view
Please help on this..
Thanks!!
I don't have idea on rudy but can help you logically..
1) first scroll the page from your code to the text area.
2) select the text area by id, xpath or etc. driver.findelement(by.id(...)).sendkey(..........);
Thanks Shukla!#sourabh shukla
Mine inside has frame so I need to switch to frame that is why I am not able ciclk that element!!
#driver.switch_to.frame("06618000000Crrp"#this is id);
Then my element found and entered text!!

Bringing elements behind fixed element into view with page-object gem

My page contains two divs at the top (a header and another section) that are fixed while the rest of the page can be scrolled. I need to hover over a link element and then click on a button that appears when hovering over the link. Since I am using the page-object gem I tried to use scroll_into_view. However the link still remains behind the fixed divs. This prevents the button from showing. Is there anything that can be done to force it into view? Links at the top and bottom of the scrollable area of the page work fine but items in the middle of the page have issues as they appear behind the fixed divs when scrolled. I am using ruby+watir-webdriver with page-object gem.
Unfortunately I can't post the site.
My code looks something like this:
class MyPage
div(:items, :class => 'product_items')
def index_for(product)
index = items_elements.find_index{|x| x.h4_element.text == product}
index
end
def add_product(product)
index = index_for(product)
product = items_elements[index.to_i]
product.link_element(:class => 'product_more_info').when_present.scroll_into_view
product.link_element(:class => 'product_more_info').hover
product.button_element(:class => 'product_info_button').when_present.click
end
end
The links in the middle of the page remain behind the fixed divs. When it hovers it actually triggers a nav dropdown that is in the header since the link is directly behind it. Seems to work for 70% of the links. The 30% in the middle are the issue right now.
I think I have reproduced your problem with the following page. When the div element to hover on is scrolled into view, it appears below the menu. Hovering does not cause the onmouseover to trigger.
<html>
<body>
<div style="position:fixed; left:0; top:0; z-index=99999; border:2px solid red; width:100%">menu</div>
<div class="spacer" style="height:2000px"></div>
<div id="hoverable" onmouseover="document.getElementById('target').style.display = '';">to hover</div>
<button id="target" style="display:none;">the button</button>
<div class="spacer" style="height:2000px"></div>
</body>
</html>
One solution that works (at least for this example page), was to try hovering over the element. If the button did not appear, assume that the menu is in the way, scroll back up the page a bit and try again. Assuming the above page, this could be done with the page object:
class MyPage
include PageObject
div(:hoverable, :id => "hoverable")
button(:target, :id => "target")
def hover()
# Try to hover over the element
hoverable_element.when_present.hover
# If the button element does not appear, the menu must be in the way.
# Scroll back up 100 px so that the div appears below the menu and try again.
unless target_element.visible?
execute_script('window.scrollBy(0,-100);')
hoverable_element.hover
end
# Check that the button appears as expected
p target_element.visible?
#=> true
end
end
Applying the same idea to your page object, the add_product method would become:
def add_product(product)
index = index_for(product)
product = items_elements[index.to_i]
product.link_element(:class => 'product_more_info').hover
unless button_element(:class => 'product_info_button').visible?
execute_script('window.scrollBy(0,-100);')
product.link_element(:class => 'product_more_info').hover
end
product.button_element(:class => 'product_info_button').click
end

Webdriver. Click on Canvas element by coordinates

I have canvas element on my page and i want to click on some part of it.
I know, that I must use ActionBuilder to do this, so I tryed this code:
element = driver.find_element(:xpath, canvas_xpath)
action.move_to(element, 100, 100).click.perform
But this code only click in center of canvas element and don't move mouse in any way.
Is there any other possible way to move mouse to some coordinates?
(Don't mention AutoIT scripts - I develop under Linux)
I have the same problem in IE. ShockwaveNN's code works for me in Firefox and Chrome. I think the problem is that "click" clicks in the middle of the element. Below is the documentation in action_builder.rb:
#
# Clicks in the middle of the given element. Equivalent to:
#
# driver.action.move_to(element).click
#
# When no element is passed, the current mouse position will be clicked.
#
# #example Clicking on an element
#
# el = driver.find_element(:id, "some_id")
# driver.action.click(el).perform
#
# #example Clicking at the current mouse position
#
# driver.action.click.perform
#
# #param [Selenium::WebDriver::Element] element An optional element to click.
# #return [ActionBuilder] A self reference.
#
According to this and my conclusions, it should just be to execute these actions in two lines like:
element = driver.find_element(:xpath, canvas_xpath)
driver.action.move_to(element, 100, 100).perform
driver.action.click.perform
or
element = driver.find_element(:xpath, canvas_xpath)
driver.action.move_to(element).perform
driver.action.move_by(100, 100).click.perform
Sadly, none of this works (for me in IE) : (
Did you try action.move_to(element).move_by(100, 100).click.perform ?
The click occurs at the center of the target element (see comments 3 and 5 http://code.google.com/p/selenium/issues/detail?id=3578)
Commands: http://selenium.googlecode.com/svn/trunk/rb/lib/selenium/webdriver/remote/commands.rb
ActionBuilder: http://selenium.googlecode.com/svn/trunk/rb/lib/selenium/webdriver/common/action_builder.rb

Resources