require 'vapir-common/win_window' require 'vapir-common/modal_dialog' require 'vapir-ie/page_container' require 'Win32API' module Vapir class IE::ModalDialog include Vapir::ModalDialog def locate @modal_window=@browser.win_window.enabled_popup end def exists? @modal_window && @modal_window.exists? end def text assert_exists @modal_window.children.select{|child| child.class_name.downcase=='static' && child.text!=''}.map{|c| c.text }.join(' ') end def set_text_field(value) assert_exists edit_field=@modal_window.children.detect{|child| child.class_name=='Edit'} || (raise "No Edit field in the popup!") edit_field.send_set_text!(value) value end def click_button(button_text, options={}) assert_exists options=handle_options(options, :timeout => ModalDialog::DEFAULT_TIMEOUT) @modal_window.click_child_button_try_for!(button_text, options[:timeout]) end def close if (document=IE::ModalDialogDocument.new(self, :error => false, :timeout => 0)) && document.exists? document.close else @modal_window.send_close! end ::Waiter.try_for(ModalDialog::DEFAULT_TIMEOUT, :exception => Vapir::Exception::WindowException.new("The modal window failed to close")) do !exists? end end def hwnd assert_exists @modal_window.hwnd end def win_window @modal_window end def document assert_exists IE::ModalDialogDocument.new(self) end end class IE::ModalDialogDocument include IE::PageContainer @@iedialog_file = (File.expand_path(File.dirname(__FILE__) + '/..') + "/vapir-ie/IEDialog/Release/IEDialog.dll").gsub('/', '\\') GetUnknown = Win32API.new(@@iedialog_file, 'GetUnknown', ['l', 'p'], 'v') def initialize(containing_modal_dialog, options={}) options=handle_options(options, :timeout => ModalDialog::DEFAULT_TIMEOUT, :error => true) @containing_modal_dialog=containing_modal_dialog intUnknown = nil ::Waiter.try_for(options[:timeout], :exception => (options[:error] && "Unable to attach to Modal Window after #{options[:timeout]} seconds.")) do intPointer = [0].pack("L") # will contain the int value of the IUnknown* GetUnknown.call(@containing_modal_dialog.hwnd, intPointer) intArray = intPointer.unpack('L') intUnknown = intArray.first intUnknown > 0 end if intUnknown && intUnknown > 0 @document_object = WIN32OLE.connect_unknown(intUnknown) end end attr_reader :containing_modal_dialog attr_reader :document_object def locate!(options={}) exists? || raise(Vapir::Exception::NoMatchingWindowFoundException, "The modal dialog seems to have stopped existing.") end def exists? # todo/fix: will the document object change / become invalid / need to be relocated? @document_object && @containing_modal_dialog.exists? end # this looks for a modal dialog on this modal dialog. but really it's modal to the same browser window # that this is modal to, so we will check for the modal on the browser, see if it isn't the same as our # self, and return it if so. def modal_dialog(options={}) ::Waiter.try_for(ModalDialog::DEFAULT_TIMEOUT, :exception => NoMatchingWindowFoundException.new("No other modal dialog was found on the browser."), :condition => proc{|md| md.hwnd != containing_modal_dialog.hwnd } ) do modal_dialog=containing_modal_dialog.browser.modal_dialog(options) end end end end =begin module Watir class IE::ModalDialog include IE::Container include IE::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 TimeOutException return nil end if hwnd_modal == hwnd || hwnd_modal == 0 hwnd_modal = nil end @hwnd = hwnd_modal 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 TimeOutException 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) intArray = intPointer.unpack('L') intUnknown = intArray.first intUnknown > 0 end rescue TimeOutException => e raise NoMatchingWindowFoundException, "Unable to attach to Modal Window #{what.inspect} 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 @document end # Return the title of the document def title document.title end def attach_command "Watir::IE.find(:hwnd, #{@container.hwnd}).modal_dialog" end def wait(options={}) 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 end alias :exist? :exists? end end =end