Hooking arbitrary Windows applications

Last edited on

Synopsis

It is possible to hook arbitrary Windows applications when running Squish on Windows. In this case “arbitrary” means that the applications don’t have to be instrumented by hand, and they don’t need to be child applications of already hooked processes either.

Approach #1 - Hook up explicitly via window title

# -*- coding: utf-8 -*-

import os

def main():
    # Explicitly the start application that we want
    # to automate - this is just for sake of this
    # example, in other cases it will likely be
    # running already:
    os.system("cmd /c start wordpad")

    # Pause long enough for the application to
    # show its window:
    snooze(3)

    # Hook up the application that we want to
    # automate via its window title:
    hook_up_win_aut_by_title("* - WordPad")

    # To record on the application, execute to the
    # following command and choose...
    #
    #  Run > Record Snippet
    #
    # ...to start snippet recording:
    test.breakpoint()

def init():
    # To avoid having multiple instances of the AUT
    # running, let's kill it, and start a new
    # instance of it later:
    os.system("taskkill /f /im wordpad.exe 2>nul")

def cleanup():
    # Make sure we
    os.system("taskkill /f /im wordpad.exe 2>nul")

def hook_up_win_aut_by_title(window_title, timeout_secs=20, output_file_name="hook_up_win_aut.txt"):
    test.startSection("Hook up by window title")
    try:
        # An application context of an actual
        # AUT is required, so if there is none,
        # launch notepad.exe for this purpose:
        ctx = currentApplicationContext()
        dummy_aut_launched = False
        if len(ctx.environmentVariable("SQUISH_RUNNERID")) == 0:
            # Launch a dummy AUT:
            test.log("Launching dummy AUT")
            ctx = startApplication(r"C:\Windows\notepad")
            dummy_aut_launched = True

        # Required:
        os.putenv("SQUISH_RUNNERID", ctx.environmentVariable("SQUISH_RUNNERID"))
        os.putenv("SQUISH_PORT", "%s" % ctx.port)
        os.putenv("SQUISH_SERVERADDRESS", ctx.host)

        # Only to suppress error messages,
        # works without:
        os.putenv("SQUISH_RECORD", "0")
        os.putenv("SQUISH_APPID", "-1")

        # Hook up the AUT process via
        # squish_dir\bin\startaut.exe:
        cmd = 'start "startwinaut" /min cmd /c ""%s/bin/startwinaut" --window-title="%s" >"%s" 2>&1""' % (os.getenv("SQUISH_PREFIX"), window_title, output_file_name)
        test.log("Executing: %s" % cmd)
        os.system(cmd)

        # Verify hook up, log error if not:
        try:
            test.log("Waiting for hook up")
            return waitForApplicationLaunch(timeout_secs)
        except:
            test.fatal("hook_up_win_aut(): No new AUT hooked up")
            import codecs
            lines = codecs.open("hook_up_win_aut.txt", "r", "utf-8").read().replace("\r\n", "\n").replace("\r", "\n").split("\n")
            lines2 = []
            for l in lines:
                if len(l.strip()) > 0:
                    lines2.append(l.strip())
            if len(lines2) > 0:
                test.fatal("hook_up_win_aut(): Output from: %s/hook_up_win_aut.txt:" % os.getcwd())
                for l in lines2:
                    if len(l.strip()) > 0:
                        test.fatal("  " + l)
            raise
        finally:
            # Dummy AUT must be killed after hook up
            # of the desired AUT:
            if dummy_aut_launched:
                test.log("Stopping dummy AUT")
                ctx.detach()
    finally:
        test.endSection()
test.py

Approach #2 - Automatically hook up via window title

This works by editing the configuration file which is read by the code in Squish which handles interactions with native Windows controls (the fallback wrapper as it’s called — it kicks in when the particular toolkit wrapper, e.g. Qt, doesn’t know what to do with some control).

Open the file "<SQUISH_DIR>/etc/winwrapper.ini" and modify the entry Extra Windows to contain the window title of the respective, other application. For example:

[Windows Wrapper]
Extra Windows="Some window caption","Another window caption"
winwrapper.ini

Now you can record tests on applications that use Qt, Java, or some other toolkit, and whenever Squish notices a window that has a caption which matches one of those listed in the Extra Windows setting, it will hook into the window’s process so that you can record actions on it (and create verification points, etc).

The Extra Windows setting is a comma-separated list of strings, each being the caption of a window to hook into. Each window caption must be enclosed in double quotes.

Related Information: