Still Life

A Series of Mental Snapshots

Taking action on JavaScript Popups with Ruby/Watir in Firefox and Internet Explorer

Posted by Steve on July 12, 2010

A long time ago I did a post on catching JavaScript popups, but have a much better way of catching them.

These JavaScript popups cause trouble as they interrupt the page from fully loading, causing Watir to wait (as the page is waiting), which means the next command in your script will never be reached. Previous work arounds to this were to use watirs built in click_no_wait, but I have that to be extremely temperamental and did not always work depending on which element the click was being performed on.

The new and improved method is to have a completely separate process that runs in the background and is continually checking for JavaScript pop ups. AutoIt commands are used to first locate the pop-up and then depending on what text or title is present in the pop up and different action can be performed on it. Unfortunately the same code cannot be used for both IE and FF due to the fact that the AutoIt controls cannot perform the same actions on IE pop-ups as it can on FF pop-ups.  I have included the code for both below:

clickPopupsIE.rb

require 'win32ole'
begin
    autoit WIN32OLE.new('AutoItX3.Control')
    loop do
       autoit.ControlClick("Windows Internet Explorer",'', 'OK')
       autoit.ControlClick("Security Information",'', '&Yes')
       autoit.ControlClick("Security Alert",'', '&Yes')
       autoit.ControlClick("Security Warning",'', 'Yes')
       autoit.ControlClick("Message from webpage",'', 'OK')
       sleep 1
    end
rescue Exception > e
    puts e
end

clickPopupsFF.rb

require 'win32ole'
websiteName = "w3schools.com"
begin
    autoit = WIN32OLE.new('AutoItX3.Control')
    loop do
       autoit.winActivate("The page at http://#{websiteName} says:")
       autoit.Send("{ENTER}") if(autoit.WinWait("The page at http://#{websiteName} says:",'',2) == 1)
    end
rescue Exception => e
    puts e
end

These two scripts can then be called from any of your other Watir scripts using the following two functions scripts:

require 'win32/process'
def callPopupKillerFF
    $pid = Process.create(:app_name => 'ruby clickPopupsFF.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end

def callPopupKillerIE
    $pid = Process.create(:app_name => 'ruby clickPopupsIE.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end

def killPopupKiller
    Process.kill(9,$pid)
end

As you can see above you do need to require one more ruby gem, ‘win32/process’, this is used to run the popup clicker as a separate process that runs in the background. Once you have those functions in place you can simply call:

callPopupKillerIE #Starts the IE popup killer
#Some watir code that results in a popup#
killPopupKiller #Kills the popup killer process, so that you do not end up with 5 of them running!

Well there you have it, a robust and effective popup killer for both IE and FF. If you have any questions let me know!

–Steve

Advertisements

12 Responses to “Taking action on JavaScript Popups with Ruby/Watir in Firefox and Internet Explorer”

  1. […] Taking movement upon JavaScript Popups with Ruby/Watir in Firefox as well as … […]

  2. Mario said

    but how do you click on the dialog box?

  3. Steve said

    Hi Mario,

    I am a little confused by your question, so if my explanation is incorrect, let me know and I will try to clarify further. The dialogue box is clicked on by the autoIt controlclick command here: autoit.ControlClick(“Windows Internet Explorer”,”, ‘OK’). What this command is doing is looking for an active window that has the title ‘Windows Internet Explorer’ and then it sends a mouse click to the ‘OK’ button.

    The syntax for the ControlClick command is: ControlClick(“WindowTitle”, “WindowText”, “Button1”, “Mousebutton”)

    The default Mousebutton is left click, otherwise it can be specified as a fourth parameter.

    The FireFox code is a little different, as the popup that appears is inherently different than the IE popup. For the FireFox code, it is looking for a window that has a certain title, and if that window is found, it brings it to the forefront and sends the ENTER key (essentially clicking OK).

    If you need any more clarification please let me know!

    –Steve

    • Mario said

      Thanks for your answer.
      I see… but it’s not working in my case. I’m using Ruby 1.8.7 and firewatir 1.6.5 on Vista, and FireFox 3.5.10
      I put clickPopupsFF.rb on the same folder where the script is running.
      This is the code:
      require ‘firewatir’
      require ‘win32/process’
      def callPopupKiller(browser=”IE”)
      $pid = Process.create(:app_name => ‘ruby clickPopups#{browser}.rb’, :creation_flags => Process::DETACHED_PROCESS).process_id
      Process::DETACHED_PROCESS).process_id
      end

      def killPopupKiller
      Process.kill(9,$pid)
      end

      b = Watir::Browser.new
      b.goto(“http://w3schools.com/js/tryit_view.asp?filename=tryjs_alert”)
      callPopupKiller(“FF”)
      b.button(:value,”Show alert box”).click

      killPopupKiller
      b.close()

      —————–
      when I run it, the script is just waiting forever when clicks on the button and if I finally click manually then you get the message:

      c:/ruby/lib/ruby/gems/1.8/gems/win32-process-0.6.2/lib/win32/process.rb:475:in `kill’: The handle is invalid. (Process::Error)
      from c:/ruby/lib/ruby/gems/1.8/gems/win32-process-0.6.2/lib/win32/process.rb:435:in `each’
      from c:/ruby/lib/ruby/gems/1.8/gems/win32-process-0.6.2/lib/win32/process.rb:435:in `kill’
      from EXAMPLETMP3.RB:10:in `killPopupKiller’

      • Steve said

        Hi Mario,

        So I found the answers to the mysteries. The error is occurring because for some reason when you use a variable when calling the file name, the process ID (PID) you get is incorrect, therefore when you try to kill it there is an error because the PID does not exist, this was my bad. I am not sure why the popup was not being handled properly, so I wrote out (and tested this time!) the code below, and it worked:

        ffclicker.rb (File that contains the functions to call/kill the popupKiller)

        require ‘win32ole’
        require ‘win32/process’

        def callPopupKiller
        $pid = Process.create(:app_name => ‘ruby clickPopupsFF.rb’, :creation_flags => Process::DETACHED_PROCESS).process_id
        end

        def killPopupKiller
        Process.kill(9,$pid)
        end

        clickPopupsFF.rb

        require ‘win32ole’
        require ‘win32/process’

        begin
        autoit = WIN32OLE.new(‘AutoItX3.Control’)
        loop do
        autoit.winActivate(“The page at http://w3schools.com says:”)
        autoit.Send(“{ENTER}”) if(autoit.WinWait(“The page at http://w3schools.com says:”,”,2) == 1)
        end
        rescue Exception => e
        puts e
        end

        Try this one out, if it doesnt work let me know, I did try this out myself and it worked fine! A quick way to ensure it works is to simply open an instance of firefox, navigate to: http://w3schools.com/js/tryit_view.asp?filename=tryjs_alert, click the button manually, then run callPopupKiller, this will work since the popupKiller does not actually have any firewatir dependencies.

        Let me know the results!

  4. Mario said

    Nothing… Still not working even not manually 😦
    I’m going on vacation today 🙂 so I will take a look in August when I’ll be back 🙂
    Thanks a lot for your help!!!

  5. Jason said

    Thanks for this. Got it working for me for IE, works very well. Nice one.

  6. SS said

    Hi Steve,

    I am also not able to solve the popup issue for IE using the above code. When we click on the submit button, it gives a popup when checked manually. But while running automatically, I see that the popup is not clicked and an error only shows when the script performs the next step.

    Can you please help me out of this?

    • Steve said

      Hi SS,

      Can you post the error message you are getting, I found issue, and it is actually with WordPress. The double and single quotes for the clickPopupsIE.rb are not copying properly and copy as ‘ticks’ instead of actual single/double quotes, I have corrected this, and verified that it now does copy properly, so give it an attempt now, if you still have issues, send me the error messages.

      thanks,
      Steve

  7. Adhi said

    Useful tutorial..

  8. Alex said

    Too bad this only works under Windows. Anyone knows about a similar solution for Firefox under Linux?

  9. PS said

    Hi Steve,

    I am currently trying to close the Windows Internet Explorer popup, which appears on clicking a button.

    Using the below code:

    clickPopupsIE.rb

    require ‘win32ole’
    begin
    autoit = WIN32OLE.new(‘AutoItX3.Control’)
    loop do
    autoit.ControlClick(“Windows Internet Explorer”, ”, ‘OK’) sleep 1
    end
    rescue Exception => e
    puts e
    end

    require ‘win32/process’

    def callPopupKillerIE
    path = File.expand_path(File.dirname(__FILE__) + ‘/../ext’)
    $pid = Process.create(:app_name => “ruby #{path}/clickPopupsIE.rb”, :creation_flags => Process::DETACHED_PROCESS).process_id
    end

    def killPopupKiller
    Process.kill(9, $pid)
    end

    I am getting “handle is invalid” error while calling “killPopupkiller” after performing the click (ie.next_button.click).I am able to capture PID effectively, but the popup is not getting closed.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: