How can I switch between two frames with Capybara
Problem
The problem is that when you do page.driver.browser.switch_to.frame
, it switches the page's context to the frame. All actions against the page are now actually against the frame. So when you are switching frames the second time, you are actually saying find the 'header' frame inside the 'main' frame (rather than, what I assume you want, the 'header' frame inside the main page).
Solution - Capybara within_frame (recommended):
When working inside a frame, you should use Capybara's within_frame
method. You would want to do:
def check_balance
visit('/')
within_frame('main'){
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
}
within_frame('header'){
click_on 'Stanje'
}
end
Solution - Selenium switch_to:
If you want to do the frame management yourself (ie not use Capybara's built-in method), you can switch the page's context back to the browser and then to the second frame. This would look like the following. Though I would suggest using the built-in Capybara method.
def check_balance
visit('/')
page.driver.browser.switch_to.frame 'header'
click_on 'Stanje'
#Switch page context back to the main browser
page.driver.browser.switch_to.default_content
page.driver.browser.switch_to.frame 'main'
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
end
How can I switch Frame using Capybara and Ruby?
Based on the error message, it looks like switch_to_frame
wants the frame element passed as a parameter. I believe you need to find the frame before you can pass it into this method.
So, replace this line @session.switch_to_frame("//*[@id=\"OF_jreport\"]")
with these two lines:
# Find the frame
frame = @session.find("//*[@id=\"OF_jreport\"]")
# Switch to the frame
@session.switch_to_frame(frame)
How do I find an unnamed iframe with Capybara
Capybara::Selenium::Driver.within_frame passes frame_id
to webdriver:
browser.switch_to.frame(frame_id)
Webdriver's frame method invokes switchToFrame method that accepts index, name or id
So to access 3 iframes deep iframe you can do:
within_frame 0 do
within_frame 0 do
within_frame 0 do
# do something
end
end
end
How to fill value in text field with in iframe
This is ruby code with selenium to switch in iframe. you can do it by:
#Move into iframe
page.driver.browser.switch_to.frame "name or id of frame"
#Move to default content or outsite frame
page.driver.browser.switch_to.default_content
How can I back to current frame in Ruby?
Capybara:
I would suggest using within_frame
so that the handle will set back once the operations are done in the frame.
def check_report(report)
frame = @session.find("//*[@id=\"OF_jreport\"]")
within_frame(frame) do
# write your logic to perform operations in the frame
end
end
Or you can try the below to switch to the default frame.
@session.switch_to_frame(:top)
Ruby:
Please use the below to switch to the default content.
@session.switch_to_default_content
If you want to switch to the parent frame then use the below
@session.switch_to_parent_frame
Ruby Capybara Element not found error handling
First, stop using xpaths like that - they're going to be ultra-fragile and horrendous to read. Without seeing the HTML I can't give you a better one - but at least part way along there has to be an element with an id
you can target instead.
Next, you could catch the exception returned from find
and ignore it or better yet you could check if page has the element first
if internet.has_xpath?(...)
internet.find(:xpath, ...).text
...
else
... whatever you want to do when it's not on the page
end
Related Topics
Erroneous "Insecure World Writable Dir Foo in Path" When Running Ruby Script
What Does "Temps.Each(&:Valid)" Mean in Ruby
How to Run Code After Each Line in Ruby
Why Does Rails 4.2 + Responders Keeps Telling Me to Add Responders to the Gemfile
How to Change the Locale Through Url
Ruby 'Pass by Value' Clarification
Call Ruby Script from Powershell
Rvm and Osx Lion - Rvm 'Forgets' Gemsets on System Restart
Scaffolding Activerecord: Two Columns of the Same Data Type