diff --git a/.gitignore b/.gitignore index 6ea3a351..b0e680b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea/ .DS_Store pkg *~ diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index bf34728b..3642a580 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -30,6 +30,10 @@ class Capybara::Driver::Base raise NotImplementedError end + def within_frame(frame_id) + raise Capybara::NotSupportedByDriverError + end + def source raise NotImplementedError end diff --git a/lib/capybara/driver/selenium_driver.rb b/lib/capybara/driver/selenium_driver.rb index 226a003e..b81c9606 100644 --- a/lib/capybara/driver/selenium_driver.rb +++ b/lib/capybara/driver/selenium_driver.rb @@ -70,7 +70,12 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base end def visible? - node.displayed? and node.displayed? != "false" + begin + node.displayed? and node.displayed? != "false" + rescue Selenium::WebDriver::Error::WebDriverError + # rescues the inevitable "Selenium::WebDriver::Error::WebDriverError: element is obsolete" if you check to see if an element that has been removed from the DOM is visible + return false + end end def trigger(event) @@ -140,6 +145,13 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base browser.manage.delete_all_cookies end + def within_frame(frame_id) + old_window = browser.window_handle + browser.switch_to.frame(frame_id) + 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 eeacc069..3f5dceb6 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -10,9 +10,9 @@ module Capybara :all, :attach_file, :body, :check, :choose, :click, :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, :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? + :visit, :wait_until, :within, :within_fieldset, :within_table, :within_frame, :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? ] attr_reader :mode, :app @@ -119,6 +119,12 @@ module Capybara end end + def within_frame frame_id + driver.within_frame(frame_id) do + yield + end + end + def has_xpath?(path, options={}) wait_conditionally_until do results = all(:xpath, path, options) diff --git a/lib/capybara/spec/driver.rb b/lib/capybara/spec/driver.rb index 4769e7bc..1a0eb326 100644 --- a/lib/capybara/spec/driver.rb +++ b/lib/capybara/spec/driver.rb @@ -129,3 +129,34 @@ shared_examples_for "driver with header support" do @driver.response_headers['Content-Type'].should == 'text/html' end end + +shared_examples_for "driver with frame support" do + describe '#within_frame' do + before(:each) do + @driver.visit('/within_frames') + end + + it "should find the div in frameOne" do + @driver.within_frame("frameOne") do + @driver.find("//*[@id='divInFrameOne']")[0].text.should eql 'This is the text of divInFrameOne' + end + end + it "should find the div in FrameTwo" do + @driver.within_frame("frameTwo") do + @driver.find("//*[@id='divInFrameTwo']")[0].text.should eql 'This is the text of divInFrameTwo' + end + end + it "should find the text div in the main window after finding text in frameOne" do + @driver.within_frame("frameOne") do + @driver.find("//*[@id='divInFrameOne']")[0].text.should eql 'This is the text of divInFrameOne' + end + @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' + end + it "should find the text div in the main window after finding text in frameTwo" do + @driver.within_frame("frameTwo") do + @driver.find("//*[@id='divInFrameTwo']")[0].text.should eql 'This is the text of divInFrameTwo' + end + @driver.find("//*[@id='divInMainWindow']")[0].text.should eql 'This is the text for divInMainWindow' + end + end +end diff --git a/lib/capybara/spec/views/frame_one.erb b/lib/capybara/spec/views/frame_one.erb new file mode 100644 index 00000000..6b8f8a7b --- /dev/null +++ b/lib/capybara/spec/views/frame_one.erb @@ -0,0 +1,8 @@ + + + This is the title of frame one + + +
This is the text of divInFrameOne
+ + \ No newline at end of file diff --git a/lib/capybara/spec/views/frame_two.erb b/lib/capybara/spec/views/frame_two.erb new file mode 100644 index 00000000..b344964d --- /dev/null +++ b/lib/capybara/spec/views/frame_two.erb @@ -0,0 +1,8 @@ + + + This is the title of frame two + + +
This is the text of divInFrameTwo
+ + \ No newline at end of file diff --git a/lib/capybara/spec/views/within_frames.erb b/lib/capybara/spec/views/within_frames.erb new file mode 100644 index 00000000..871e5dc5 --- /dev/null +++ b/lib/capybara/spec/views/within_frames.erb @@ -0,0 +1,10 @@ + + + With Frames + + +
This is the text for divInMainWindow
+ + + + \ No newline at end of file diff --git a/spec/driver/selenium_driver_spec.rb b/spec/driver/selenium_driver_spec.rb index c2b2b4c1..c0b07658 100644 --- a/spec/driver/selenium_driver_spec.rb +++ b/spec/driver/selenium_driver_spec.rb @@ -7,5 +7,5 @@ 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" end