How to manage frame in ruby selenium webdriver - ruby

I am working with RUBY selenium webdriver (not java, not c#, etc). Please, the solutions must be in ruby. So, I have the frame with Id "_wicket_window_3". To locate this element, I apply:
driver.switch_to.frame driver.find_element(:id, "_wicket_window_3")
My frama has the buttons "Adjuntar", "Exportar" and "Terminar".
Now, how can i manage the frame ? I want to click the button "Adjuntar","Terminar" or "Exportar".
If I try there:
frame = driver.switch_to.frame driver.find_element(:id, "_wicket_window_3")
frame.click_button("Adjuntar")
The response is: Undefined method.
Please, help me !!!
Regards, Agustín.

You can't manage the iframe you switched to as you planning.
When you do
driver.switch_to.frame driver.find_element(:id, "_wicket_window_3")
Your context start to be inside this iframe, all operations you will now do on driver, will be inside this iframe.
So, after the switch do:
driver.click_button("Adjuntar")
It should click on the button.

I dont think click_button is the right command, that's why the error you get is undefined method
you have to switch to the frame then look for the element of that button as you did before to look for the frame, then click it
something like
driver.switch_to.frame driver.find_element(:id, "_wicket_window_3")
driver.find_element(:id, "id_of_the_button_you_want_to_click").click
Note used :id there but you can use whatever the locator you want, :css, :xpath, :class whatever

Related

Capybara will not click button for Stripe SCA authentication

I cannot get Capybara to click on the SCA/3DS ‘Complete authentication’ button when running RSpec tests. Similar tests which do not trigger SCA pass just fine, and if I run VNC to view what Firefox is doing, the button is visible and I can click it myself in the browser.
My problem seems very similar to what’s discussed in the comments here, but the solutions do not work: I have tried changing the browser used, and flattening the iframe traversal.
Test code:
scenario "SCA required" do
create_payment_method(account, payment_method: "stripe", last_four: "1234")
visit "/billing"
click_on "Enter Card Payment"
within "#main-content" do
within_frame(find("iframe")) do # Stripe payment form is in an iframe.
find("input#Field-numberInput").set("4000002760003184") # SCA-required test card.
find("input#Field-expiryInput").set("1234")
find("input#Field-cvcInput").set("123")
find("input#Field-postalCodeInput").set("12345")
end
end
find("button#submit").click
# Stripe nests the popup in several layers of iframes.
stripe_frame = find("body > div > iframe") # Popup is prepended to the body element.
switch_to_frame(stripe_frame)
challenge_frame = find("iframe#challengeFrame")
switch_to_frame(challenge_frame)
fullscreen_frame = find("iframe.FullscreenFrame")
switch_to_frame(fullscreen_frame)
click_on "Complete authentication"
switch_to_frame(:top)
expect(page).to have_content "ends in 3184"
end
Is there some way to debug what Selenium is doing under the hood here? I don’t see any movement on the page when running click_on "Complete authentication", but if I click on the button myself in the Firefox instance being controlled by Selenium it does work.
Running click_on "Complete authentication" returns the element clicked, which appears to be the expected element when I drop into Pry and call native.dom_attribute("id").
I can see an error of some kind in the browser container’s logs:
1654078084345 Marionette WARN TimedPromise timed out after 500 ms: stacktrace:
TimedPromise/<#chrome://remote/content/marionette/sync.js:239:19
TimedPromise#chrome://remote/content/marionette/sync.js:224:10
interaction.flushEventLoop#chrome://remote/content/marionette/interaction.js:431:10
webdriverClickElement#chrome://remote/content/marionette/interaction.js:179:31
It’s a bit odd because it mentions #chrome but this is a headless Firefox instance.
Assuming no error is returned by the click_on call then I'm guessing the button is being clicked before it's ready to be clicked. You can test that by sleeping for a few seconds before calling 'click_on'/navigating through the frames. If that fixes it then you'd need to look at what changes on the button to indicate that the page has finished whatever work it's doing and the button is ready to be clicked.
I have solved this by clicking on the button directly with JavaScript:
execute_script(%Q{ document.querySelector("button#test-source-authorize-3ds").click() })
However, this does not in any way explain why click_on is not working, and if anything makes it more strange that it is not. If anyone has a better solution or a way to dig into why Capybara/Selenium are failing then that would be welcome.

links opening in new window - Cheezy page-object ruby gem with selenium

I'm new to page-object and selenium, but so far it's all been going ok. The last elements I'm testing for this page are social media links.
To check that the links are correct i usually click them and then use selenium's driver.current_url to check that the url of the window is what we'd expect for that link, but these social media buttons are opening links in a new window (this is just to their static facebook page rather than a login etc) which causes the test to fail
is there a way of either:
1-forcing the link to open in the current window, or
2-extracting the target url from the link_element?
this is what the tests look like atm:
def test_facebook_button
assert #testpage.facebook_icon?, 'Facebook button not found'
#testpage.facebook_icon_link
sleep 5
assert #browser.current_url == '<facebookurlforsite>', 'Facebook link does not open expected URL'
end
if not i'm guessing i'd just use the actual selenium methods as some sort of exception to manually grab the properties of the link, i'd rather not some elements be in the page model and some out in the test itself but i can see how it's probably necessary
If you are just checking that the link navigates to the right URL, checking the link's href attribute will be the quickest. The PageObject::Elements::Link elements have an href method for this.
Assuming that facebook_icon_link is your link defined by an accessor method, you would call:
facebook_icon_link_element.href
In other words, the assertion could be written as:
assert facebook_icon_link_element.href == '<facebookurlforsite>'

Watir-webdriver throws 'not clickable' error even when element is visible, present

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.

Press TAB and then ENTER key in Selenium WebDriver with Ruby

I am doing automated testing using Selenium WebDriver with Ruby. I need to click a button. I cannot get the button element by id or css or xpath as the button is transparent. I would like to use Tab and Enter key to press the button.
I can use Tab key to get the button as below:
#element.send_keys :tab
#element --> any javascript element visible in the browser
But how do I use the Enter key on the button?
Basically I need to achieve press Tab key and then press Enter key to click the button.
I am using Selenium WebDriver #driver = Selenium::WebDriver.for :firefox
In Ruby user1316's code looks like
driver.action.send_keys(elementVisible, :tab).send_keys(elementVisible, :return).perform
Keeping in mind the excerpt :
I can use tab key to get the button as
#element.send_keys :tab
#element --> any javascript element visible in
the browser
but how do i use the enter key on the button??
In order to use the enter key on the button, you could try one of the solution provided using Ruby here. This basically talks about sending the :return value and not the :enter value i.e #element.send_keys :return and some additional information.
UPDATED:
I could provide some code in Java which tries to implement the problem conceptually using the info provided here. You could try to translate for the corresponding Ruby Selenium API.
The Code:
Actions builder = new Actions(driver);
builder.sendKeys( elementVisible, Keys.TAB).sendKeys(Keys.RETURN);
Action submitTheTransperentButton = builder.build();
submitTheTransperentButton.perform();
use Selenium::WebDriver::Keys::KEYS[:tab]
ref: https://www.rubydoc.info/gems/selenium-webdriver/Selenium/WebDriver/Keys
send ENTER in ruby:
#browser.action.send_keys("\n").perform

How can I know what element is clicked in IE?

I'm automating IE with watir, and I want to know what html element(s) are clicked (selected). Can this be done using watir? win32ole? In a last chance, without ruby?
Something like:
Click a button -> button with id=213 and class=btn_class was clicked.
Click a text field -> text field with id=123 and value=my_text was clicked.
Try one of the recorders, Selenium IDE for example.
I'm not sure if I completely understand either, but would a custom function like this work?
def click(item, how, what)
#browser.item(how, what).click
puts "#{item} with #{how}->#{what} was clicked"
end
click("button", ":id", "awesome")
Edit: If you're attempting to identify page elements so that you can then use them in a Watir script, the Developer Toolbar is perfect for this application, much like Firebug for Firefox.
http://www.microsoft.com/download/en/details.aspx?id=18359
Your comment to me & your response to Zeljko appear to contradict each other. If you want to use WATIR for this task, the code above will execute a mouse click and post the information to console. The only other way to get information is to locate the object in WATIR and fish for more details:
object = #browser.button(:name, /myButton/)
object.id
object.title
object.status
object.height, etc.
or
#browser.divs.each do |div|
puts div.id, div.title
end
I'd recommend a strong look at the capabilities of the various developer tools, such as are provided with Chrome, Firefox, and IE. those are generally the best means to get this kind of information.
Watir is really about driving the browser, and getting info out of the DOM. it's not really setup to report on manual interactions with the browser.

Resources