diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index 9751b0be..019e19c5 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -39,6 +39,10 @@ class Capybara::Driver::Base raise Capybara::NotSupportedByDriverError end + def within_popup(popup_handle) + raise Capybara::NotSupportedByDriverError + end + def wait? false end diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 7a1eec0d..17c03247 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -140,6 +140,13 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base browser.switch_to.window old_window end + def within_popup(popup_handle) + old_window = browser.window_handle + browser.switch_to.window popup_handle + yield + browser.switch_to.window old_window + end + private def url(path) diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 20f0c922..d8e34e39 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -30,7 +30,7 @@ module Capybara :all, :attach_file, :body, :check, :choose, :click_link_or_button, :click_button, :click_link, :current_url, :drag, :evaluate_script, :field_labeled, :fill_in, :find, :find_button, :find_by_id, :find_field, :find_link, :has_content?, :has_css?, :has_no_content?, :has_no_css?, :has_no_xpath?, :has_xpath?, :locate, :save_and_open_page, :select, :source, :uncheck, - :visit, :wait_until, :within, :within_fieldset, :within_table, :within_frame, :has_link?, :has_no_link?, :has_button?, + :visit, :wait_until, :within, :within_fieldset, :within_table, :within_frame, :within_popup, :has_link?, :has_no_link?, :has_button?, :has_no_button?, :has_field?, :has_no_field?, :has_checked_field?, :has_unchecked_field?, :has_no_table?, :has_table?, :unselect, :has_select?, :has_no_select?, :current_path, :scope_to, :click ] @@ -201,6 +201,19 @@ module Capybara end end + ## + # + # Execute the given block within the given popup given the id of that popup. Only works on + # some drivers (e.g. Selenium) + # + # @param [String] locator Id of the popup + # + def within_popup(popup_handle) + driver.within_popup(popup_handle) do + yield + end + end + ## # # Retry executing the block until a truthy result is returned or the timeout time is exceeded diff --git a/lib/capybara/spec/driver.rb b/lib/capybara/spec/driver.rb index d6cd9d14..f9661d98 100644 --- a/lib/capybara/spec/driver.rb +++ b/lib/capybara/spec/driver.rb @@ -154,6 +154,47 @@ shared_examples_for "driver with frame support" do end end +shared_examples_for "driver with popup support" do + describe '#within_popup' do + before(:each) do + @driver.visit('/within_popups') + end + after(:each) do + @driver.within_popup("firstPopup") do + @driver.evaluate_script('window.close()') + end + @driver.within_popup("secondPopup") do + @driver.evaluate_script('window.close()') + end + end + + it "should find the div in firstPopup" do + @driver.within_popup("firstPopup") do + @driver.find("//*[@id='divInPopupOne']")[0].text.should eql 'This is the text of divInPopupOne' + end + end + it "should find the div in secondPopup" do + @driver.within_popup("secondPopup") do + @driver.find("//*[@id='divInPopupTwo']")[0].text.should eql 'This is the text of divInPopupTwo' + end + end + it "should find the divs in both popups" do + @driver.within_popup("secondPopup") do + @driver.find("//*[@id='divInPopupTwo']")[0].text.should eql 'This is the text of divInPopupTwo' + end + @driver.within_popup("firstPopup") do + @driver.find("//*[@id='divInPopupOne']")[0].text.should eql 'This is the text of divInPopupOne' + end + end + it "should find the div in the main window after finding a div in a popup" do + @driver.within_popup("secondPopup") do + @driver.find("//*[@id='divInPopupTwo']")[0].text.should eql 'This is the text of divInPopupTwo' + end + @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' + end + end +end + shared_examples_for "driver with cookies support" do describe "#reset!" do it "should set and clean cookies" do diff --git a/lib/capybara/spec/views/popup_one.erb b/lib/capybara/spec/views/popup_one.erb new file mode 100644 index 00000000..f2a79fe6 --- /dev/null +++ b/lib/capybara/spec/views/popup_one.erb @@ -0,0 +1,8 @@ + + + This is the title of the first popup + + +
This is the text of divInPopupOne
+ + diff --git a/lib/capybara/spec/views/popup_two.erb b/lib/capybara/spec/views/popup_two.erb new file mode 100644 index 00000000..c7135d74 --- /dev/null +++ b/lib/capybara/spec/views/popup_two.erb @@ -0,0 +1,8 @@ + + + This is the title of popup two + + +
This is the text of divInPopupTwo
+ + diff --git a/lib/capybara/spec/views/within_popups.erb b/lib/capybara/spec/views/within_popups.erb new file mode 100644 index 00000000..56c6c0e4 --- /dev/null +++ b/lib/capybara/spec/views/within_popups.erb @@ -0,0 +1,25 @@ + + + With Popups + + + +
This is the text for divInMainWindow
+ + diff --git a/spec/driver/selenium_driver_spec.rb b/spec/driver/selenium_driver_spec.rb index ad17feb3..0c72857a 100644 --- a/spec/driver/selenium_driver_spec.rb +++ b/spec/driver/selenium_driver_spec.rb @@ -8,6 +8,7 @@ describe Capybara::Driver::Selenium do it_should_behave_like "driver" it_should_behave_like "driver with javascript support" it_should_behave_like "driver with frame support" + it_should_behave_like "driver with popup support" it_should_behave_like "driver without status code support" it_should_behave_like "driver with cookies support" end