For any automation frameworks, handling pop-ups is somehow difficult. By opening a pop-up window, the window changes so you can not control the new window with existing webdriver since it is already assigned to main windows when it was initiated. Normally automation framework can not work if you don't switch to pop-up windows. For Capybara you can easily handle it by assigning the webdriver to new pop-up window. Then you can perform your test case as same way what you have done and when you are done with the pop-up, close the pop-up and then switch back the webdriver to the main window.
main = page.driver.browser.window_handles.first
popup = page.driver.browser.window_handles.last
page.driver.browser.switch_to.window(popup)
Since iframe is a part of another source which is used to display another webpage in a webpage, you must handle it exactly same as pop-up windows.
page.driver.browser.switch_to.frame(iframe_name)
However, for iframe you must take the name of iframe to use it for assigning the webdriver. You can see the code below.
page.driver.browser.switch_to.frame(iframe_name)