Presenting Win32-autogui. A Ruby Win32 GUI testing framework packaged as a RubyGem.
Win32-autogui provides a framework to enable GUI application testing with Ruby. This facilitates integration testing of Windows binaries using Ruby based tools like RSpec and Cucumber regardless of the language used to create the binaries.
The source code repository is available here: http://github.com/robertwahler/win32-autogui. The repository contains specs and an example Win32 program with source and specs written in Delphi (Object Pascal).
Here is a quick demo using the Ruby Interactive Shell (IRB) under Cygwin on Windows XP to drive "calc.exe."
Win32-autogui is available on RubyGems.org
gem install win32-autogui
          Start up IRB
irb
          Paste the following lines into your shell's IRB session.
Note: Window's "calc.exe" is used as the target binary by Win32-autogui's internal specs. The complete source to the wrapper is available here: spec/applications/calculator.rb.
    require 'win32/autogui'
    include Autogui::Input
    class Calculator < Autogui::Application
      def initialize
        super :name => "calc", :title => "Calculator"
      end
      def edit_window
        main_window.children.find {|w| w.window_class == 'Edit'}
      end
    end
          Now we can start up the calculator
calc = Calculator.new
calc.running?
          Session screenshot
Get some information
calc.pid
calc.main_window.window_class
calc.main_window.children.count
          Perform a calculation
calc.set_focus; type_in('2+2=')
          Get the result
calc.edit_window.text
          Shut it down
calc.close
calc.running?
          Session screenshot
The Win32-autogui repository contains an example Win32 program with source, testable binary, and specs written in Delphi (Object Pascal) located here: http://github.com/robertwahler/win32-autogui/tree/master/examples/quicknote.
Quicknote is a bare bones notepad clone. Here is the spec file spec/form_splash_spec.rb for the splash screen functionality.
    require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
    include Autogui::Input
    describe "FormSplash" do
      after(:all) do
        if @application.running?
          @application.splash.wait_for_close if @application.splash
          @application.file_exit 
          # still running? force it to close
          @application.close(:wait_for_close => true)
          @application.should_not be_running
        end
      end
      describe "startup with no command line parameters" do
        before(:all) do
          # --nosplash is the default, turn it back on
          @application = Quicknote.new :parameters => ''
          @application.should be_running
        end
        it "should show" do
          @application.splash.should_not be_nil
        end
        it "should close within 5 seconds" do
          @application.splash.should_not be_nil
          seconds = 5
          timeout(seconds) do
            @application.splash.wait_for_close
          end
          @application.splash.should be_nil
        end
      end
      describe "startup with '--nosplash' command line parameter" do
        it "should not show" do
          @application = Quicknote.new :parameters => '--nosplash'
          @application.should be_running
          @application.splash.should be_nil
        end
      end
    end
          The Quicknote.exe application wrapper. Each of the testable application windows must be defined in a subclass of Autogui::Application. Partial code from lib/quicknote.rb.
    class Quicknote < Autogui::Application
      def initialize(options = {})
        # relative path to app using Windows style path
        @name ="exe\\quicknote.exe"  
        defaults = {
                     :title=> "QuickNote -", 
                     :parameters => '--nosplash', 
                     :main_window_timeout => 20
                   }
        super defaults.merge(options)
      end
      def edit_window
        main_window.children.find {|w| w.window_class == 'TMemo'}
      end
      def status_bar
        main_window.children.find {|w| w.window_class == 'TStatusBar'}
      end
      def dialog_about
        Autogui::EnumerateDesktopWindows.new.find do |w| 
          w.title.match(/About QuickNote/) && (w.pid == pid)
        end
      end
      def splash
        Autogui::EnumerateDesktopWindows.new.find do |w| 
          w.title.match(/FormSplash/) && (w.pid == pid)
        end
      end
      def message_dialog_confirm
        Autogui::EnumerateDesktopWindows.new.find do |w| 
          w.title.match(/Confirm/) && (w.pid == pid)
        end
      end
      # Title and class are the same as dialog_overwrite_confirm
      # Use child windows to differentiate
      def dialog_overwrite_confirm
        Autogui::EnumerateDesktopWindows.new.find do |w| 
          w.title.match(/^Text File Save$/) && 
            (w.pid == pid) && 
            (w.window_class == "#32770") &&
            (w.combined_text.match(/already exists/))
        end
      end
      # Title and class are the same as dialog_overwrite_confirm
      def file_save_as_dialog
        Autogui::EnumerateDesktopWindows.new.find do |w| 
          w.title.match(/Text File Save/) && 
            (w.pid == pid) &&
            (w.window_class == "#32770") &&
            (w.combined_text.match(/Save \&in:/))
        end
      end
      ...
          Watchr provides a flexible alternative to Autotest.
NOTE: The following assumes a global setting of 'git config core.autocrlf input' and that you want to modify the Delphi 7 source to Quicknote which requires CRLF line endings.
Grab the source for Quicknote
cd ~/workspace
git clone http://github.com/robertwahler/win32-autogui -n
cd win32-autogui
git config core.autocrlf true
git checkout
          Install watchr
gem install watchr
          Run watchr
watchr spec/watchr.rb
          Watchr will now watch the files defined in 'spec/watchr.rb' and run RSpec or Cucumber, as appropriate.
Session screenshot
For more information, please consult the source: http://github.com/robertwahler/win32-autogui.
article comments powered by DisqusCopyright 1999-2013,  GearheadForHire, LLC
GearheadForHire, LLC
      Site design by GearheadForHire, LLC | v2.3.0