diff --git a/watir/lib/watir/close_all.rb b/watir/lib/watir/close_all.rb index bf4a49e0..88c713fc 100644 --- a/watir/lib/watir/close_all.rb +++ b/watir/lib/watir/close_all.rb @@ -23,15 +23,8 @@ def self.close_all_but(except=nil) # to appear and does not raise exception if no window is found. # returns true if modal was found and close, otherwise false def close_modal - begin - original_attach_timeout = IE.attach_timeout - IE.attach_timeout = 0 + while self.modal_dialog.exists?(0) do self.modal_dialog.close - true - rescue NoMatchingWindowFoundException, Wait::TimeoutError - false - ensure - IE.attach_timeout = original_attach_timeout end end end diff --git a/watir/lib/watir/container.rb b/watir/lib/watir/container.rb index 61bcd715..1eeaa60d 100644 --- a/watir/lib/watir/container.rb +++ b/watir/lib/watir/container.rb @@ -209,7 +209,7 @@ def rows # loaded. def modal_dialog(how=nil, what=nil) - ModalDialog.new(self, how, what) + ModalDialog.new(self) end # This is the main method for accessing a button. Often declared as an tag. diff --git a/watir/lib/watir/core.rb b/watir/lib/watir/core.rb index 1edb1d79..fe8bc0e0 100644 --- a/watir/lib/watir/core.rb +++ b/watir/lib/watir/core.rb @@ -28,6 +28,9 @@ require 'watir/link' require 'watir/html_element' +require 'watir/win32' +require 'watir/modal_dialog' + require 'watir/module' require 'rautomation' diff --git a/watir/lib/watir/modal_dialog.rb b/watir/lib/watir/modal_dialog.rb index 740d56b5..4c29022c 100644 --- a/watir/lib/watir/modal_dialog.rb +++ b/watir/lib/watir/modal_dialog.rb @@ -10,100 +10,33 @@ class ModalDialog include PageContainer include Win32 - # Return the current window handle - attr_reader :hwnd - - def find_modal_from_window - # Use handle of our parent window to see if we have any currently - # enabled popup. - hwnd = @container.hwnd - hwnd_modal = 0 - begin - Watir::until_with_timeout do - hwnd_modal, arr = GetWindow.call(hwnd, GW_ENABLEDPOPUP) # GW_ENABLEDPOPUP = 6 - hwnd_modal > 0 - end - rescue Wait::TimeoutError - return nil - end - if hwnd_modal == hwnd || hwnd_modal == 0 - hwnd_modal = nil - end - @hwnd = hwnd_modal + def initialize(container) + set_container container + @modal = ::RAutomation::Window.new(:hwnd=>@container.hwnd).child(:class => 'Internet Explorer_TridentDlgFrame') end - private :find_modal_from_window def locate - how = @how - what = @what - - case how - when nil - unless find_modal_from_window - raise NoMatchingWindowFoundException, - "Modal Dialog not found. Timeout = #{Watir::IE.attach_timeout}" - end - when :title - case what.class.to_s - # TODO: re-write like WET's so we can select on regular expressions too. - when "String" - begin - Watir::until_with_timeout do - title = "#{what} -- Web Page Dialog" - @hwnd, arr = FindWindowEx.call(0, 0, nil, title) - @hwnd > 0 - end - rescue Wait::TimeoutError - raise NoMatchingWindowFoundException, - "Modal Dialog with title #{what} not found. Timeout = #{Watir::IE.attach_timeout}" - end - else - raise ArgumentError, "Title value must be String" - end - else - raise ArgumentError, "Only null and :title methods are supported" - end - intUnknown = 0 begin Watir::until_with_timeout do intPointer = " " * 4 # will contain the int value of the IUnknown* - GetUnknown.call(@hwnd, intPointer) + GetUnknown.call(hwnd, intPointer) intArray = intPointer.unpack('L') intUnknown = intArray.first intUnknown > 0 end rescue Wait::TimeoutError => e - raise NoMatchingWindowFoundException, - "Unable to attach to Modal Window #{what.inspect} after #{e.duration} seconds." + raise NoMatchingWindowFoundException, + "Unable to attach to Modal Window after #{e.duration} seconds." end - - copy_test_config @parent_container @document = WIN32OLE.connect_unknown(intUnknown) end - def initialize(container, how, what=nil) - set_container container - @how = how - @what = what - @parent_container = container - # locate our modal dialog's Document object and save it - begin - locate - rescue NoMethodError => e - message = - "IE#modal_dialog not supported with the current version of Ruby (#{RUBY_VERSION}).\n" + - "See http://jira.openqa.org/browse/WTR-2 for details.\n" + - e.message - raise NoMethodError.new(message) - end - end - def document + locate @document end - # Return the title of the document def title document.title end @@ -117,12 +50,30 @@ def attach_command end def wait(no_sleep=false) + sleep 1 + if exists? + # do nothing + else + @container.page_container.wait + end end - # Return true if the modal exists. Mostly this is useful for testing whether - # a modal has closed. - def exists? - Watir::Win32::window_exists? @hwnd + def hwnd + @modal.hwnd + end + + def active? + @modal.active? + end + + # When checking to see if the modal exists we give it some time to + # find it. So if it does see a modal it returns immediately, otherwise it waits and checks + def exists?(timeout=5) + begin + Watir::Wait.until(timeout) {@modal.exists?} + rescue Watir::Wait::TimeoutError + end + return @modal.exists? end alias :exist? :exists? end diff --git a/watir/unittests/windows/modal_dialog_test.rb b/watir/unittests/windows/modal_dialog_test.rb index a661e663..c9475c1c 100644 --- a/watir/unittests/windows/modal_dialog_test.rb +++ b/watir/unittests/windows/modal_dialog_test.rb @@ -13,25 +13,16 @@ def setup IE.attach_timeout = 10.0 end - def teardown - if browser - while browser.close_modal do; end + def teardown + if browser + while browser.modal_dialog.exists?(0) do + browser.modal_dialog.close + sleep 0.5 + end end - sleep 0.1 - IE.attach_timeout = @original_timeout end - def assert_no_modals - IE.attach_timeout = 0.2 - begin - assert_raises(NoMatchingWindowFoundException) do - browser.modal_dialog - end - ensure - IE.attach_timeout = @original_timeout - end - end - + def test_modal_simple_use_case browser.button(:value, 'Launch Dialog').click_no_wait modal = browser.modal_dialog(:title, 'Modal Dialog') @@ -68,60 +59,37 @@ def test_modal_dialog_use_case_default modal.text_field(:name, 'modal_text').set('hello') modal.button(:value, 'Close').click - assert_no_modals + assert !browser.modal_dialog.exists? assert_equal('hello', browser.text_field(:name, 'modaloutput').value) end - # Now explicitly supply the :title parameter. - def test_modal_dialog_use_case_title - browser.button(:value, 'Launch Dialog').click_no_wait - - modal = browser.modal_dialog(:title, 'Modal Dialog') - assert_not_equal(browser.hwnd, modal.hwnd) - - assert_equal('Modal Dialog', modal.title) - - assert(modal.text.include?('Enter some text:')) - modal.button(:value, 'Close').click - end - - # Now explicitly supply the :title parameter with regexp match - def test_modal_dialog_use_case_title_regexp - assert_raises(ArgumentError){browser.modal_dialog(:title, /dal Dia/)} - end - - # Now explicitly supply an invalid "how" value - def test_modal_dialog_use_case_invalid - assert_raise(ArgumentError) { browser.modal_dialog(:esp) } - end - def test_double_modal browser.button(:value, 'Launch Dialog').click_no_wait - modal1 = browser.modal_dialog - modal1.button(:text, 'Another Modal').click_no_wait - modal2 = modal1.modal_dialog - assert_equal modal2.title, 'Pass Page' - modal2.close - modal1.close + browser.modal_dialog.button(:text, 'Another Modal').click_no_wait + assert_nothing_raised { + Watir::Wait.until {browser.modal_dialog.title == 'Pass Page'} + } + browser.modal_dialog.close + browser.modal_dialog.close end - + def xtest_modal_with_frames browser.button(:value, 'Launch Dialog').click_no_wait modal1 = browser.modal_dialog modal1.button(:value, 'Modal with Frames').click_no_wait modal2 = browser.modal_dialog modal2.frame('buttonFrame').button(:value, 'Click Me').click - assert(modal2.frame('buttonFrame').text.include?('PASS')) + assert(modal2.frame('buttonFrame').text.include?('PASS')) modal2.frame('buttonFrame').button(:value, 'Close Window').click modal1.close end - + def test_modal_exists browser.button(:value, 'Launch Dialog').click_no_wait - modal = browser.modal_dialog(:title, 'Modal Dialog') + modal = browser.modal_dialog assert(modal.exists?) modal.button(:value, 'Close').click assert_false(modal.exists?) end - + end