Handling Iframe with Capybara Ruby

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



Leave a reply



Submit