March 31, 2006

Activate macro with screen click

Filed under: Automation,Scripting — Marcus Tettmar @ 9:00 am

Someone sparked an interesting thread in the Macro Scheduler forums recently when they asked if it was possible to activate a macro by detecting a click on a specific area of the screen. They wanted to know if you could define a portion of the screen so that if a click is detected in that portion of screen a macro could be fired.

Macro Scheduler can do most things and I very rarely respond negatively by saying it can’t be done. Even when I can’t see a solution immediately, I usually have a good think about it, try a few ideas and come back with a solution. In this case I missed a nice solution and replied saying it isn’t yet possible. I don’t know what I was thinking! This sparked a few forum regulars to suggest some solutions ranging from maximised custom dialogs with image maps, to active desktop configurations. Then Dick suggested using the OnEvent function and VK1 – the virtual key code for a left mouse click. Of course! I kicked myself. Why didn’t I think of that?

So I set about writing an example to test the theory. The script actually turns out to be quite simple and elegant. Here it is:

// Set Bounds Here
Let>X1=440
Let>X2=630
Let>Y1=40
Let>Y2=200

// Only detect clicks on Desktop, or Anywhere?
Let>OnlyDesktop=1

OnEvent>KEY_DOWN,VK1,0,MouseClick

Label>MainLoop
 Wait>0.2
Goto>MainLoop

SRT>MouseClick
  GetActiveWindow>title,xact,yact

  // OnlyDesktop/all window check
  Let>OkToContinue=FALSE
  If>OnlyDesktop=1
    If>title=Program Manager
       Let>OkToContinue=TRUE
    Endif
  Else
    Let>OkToContinue=TRUE
  Endif

  If>OkToContinue=TRUE
    // Check Cursor is Within Bounds
    GetCursorPos>X,Y
    If>{((%X% >= %X1%) AND (%X% <= %X2%)) AND ((%Y% >= %Y1%) AND (%Y% <= %Y2%))}
        // Replace next line with call to macro using Macro> command or call to a subroutine
        MessageModal>Hello
        // Macro>your_macro
        // Pass LClick on?
        // LClick
     Endif
  Endif
END>MouseClick

This script sets up a continuous loop and an OnEvent function which responds to the key down event of virtual keycode 1, which happens to be a mouse left click. Yes, perhaps because this is considered a keydown event and uses a virtual key code it is not immediately obvious that you can detect a mouse click. The subroutine that is called when the event occurs checks which window is active and gets the mouse position. If the active window is one in which we should check for mouse clicks (in this case the script works either only on the desktop or on any window) and if the mouse cursor position is within the defined bounds, our routine is called. In this case the event is just a message box, but that can be replaced with a call to another macro or an external application, a subroutine call, or any code you like. If necessary the left click can then be passed on to the underlying window as it was intended – but this should only be necessary if your routine steals focus or does something to prevent the underlying window getting the click. The code could be modified to make it work only against a specific window.

This macro needs to run all the while you want the screen clicks to be detected. If that is all the time then you could set the macro to run on startup, or compile it to an executable and have that run on startup. Or maybe you only need to start the script for a short while when the screen click detection is required.

I’ve also posted the code and an explanation to the forum here. I’ve also added this to Scripts & Tips.

March 20, 2006

Running UI macros when logged out with Remote Desktop

Filed under: Automation,Scripting,Vista — Marcus Tettmar @ 9:35 am

Scheduling User Interface (UI) automation macros to occur when Windows is logged off or locked is problematic. A full user session needs to be active for a UI macro to work. Why is this? Windows consists of “Window Stations” and “Desktops”. A window station is a secure object that contains a clipboard, a set of global atoms and a group of Desktops. The interactive window station assigned to the logon session of the interactive user also contains the keyboard, mouse, and display device. The interactive window station is visible to, and can receive input from, the user. All other window stations are non-interactive, which means that they cannot be made visible to the user, and cannot receive input. So only one Window Station, and one Desktop at a time can receive keyboard and mouse input, while all others are invisible. While logged out the only thing you can do is log in. Services can run while Windows is logged out but they run in their own session and there is no desktop to interact with. So any macros scheduled from a service will run invisibly and cannot mimic user input.

Usually, if you have a UI macro which must run regularly, the simplest and most reliable approach is to schedule it on a machine which is left logged in and never logged out. Many of our clients even dedicate an old machine to Macro Scheduler. Where security is an issue they leave it locked in an office or secure computer room. This is fine where you have control of the machine, but what if you need to schedule a UI automation routine on a client’s computer and they, understandably, insist that this machine should not be left logged in?

Well, with Macro Scheduler version 8.0 we introduced the Scheduler Service and AutoLogon which allows macros to be scheduled when Macro Scheduler is not running and to automate a Windows Logon so that the full session is available. However, there are still some problems with this approach. One is that interactive services are being phased out with Vista and even in XP sometimes have problems – the concept of interactive services has always been a bit of a workaround and Microsoft are finally removing them altogether to guard against OS shatter attacks and other issues that allowing interactive services can cause. Another problem is that AutoLogon cannot work with fast user switching. Of course, the other obvious issue with AutoLogon is that although the machine doesn’t have to be left logged in, AutoLogon does mean that for the duration of the macro Windows is unlocked. For some, even this temporary log in might be unacceptable – and what if the macro fails half way through, leaving the session open?

With Vista dropping interactive services and changing the entire logon mechanism we are currently investigating whether or not there is any way we can implement an alternative AutoLogon solution. Vista is still in beta and with the Vista SDK and documentation being incomplete and sketchy it’s still too early to tell whether or not we can implement a Vista compatible version of AutoLogon. But there is already an approach, using existing Windows functionality, which works well with XP and Vista.

This approach involves two PCs and Remote Desktop Connection. The machine on which the routine must run needs to allow Remote Desktop Connections. A good guide on enabling Remote Desktop Connections can be found here. Macro Scheduler and the UI macro must be installed on this machine.

On the other machine create a Remote Desktop Profile (RDP) file. To do this click Start/Run and type mstsc.exe. On the Remote Desktop Connection dialog that appears click “Options”. You’ll get this screen:

rdp1.JPG

Select the name of the computer you will connect to and enter the username and password. Check “Save my password”.

Click the “Programs” tab. Here you tell Remote Desktop Connection to run the Macro Scheduler macro:

rdp2.JPG

Enter the path to Macro Scheduler’s executable followed by the macro name:

“c:\program files\mjt net ltd\macro scheduler\msched.exe” myMacro

Under “Display” you can set whether the desktop session should run full screen, or whatever resolution you like. It doesn’t really matter.

Back under the “General” tab hit “Save As” and save the rdp file.

Now, when you want to run the routine you just issue:

mstsc.exe rdpfile.rdp

E.g. if you saved the file to c:\my documents\serverauto.rdp you would run:

mstsc.exe “c:\my documents\serverauto.rdp”

When this runs, a desktop session is created and the UI macro is executed – it works because the only interactive Window Station is the one created by Remote Desktop Connection. When the macro finishes, the session is logged out again. The desktop session appears on your screen. Nothing appears on the remote machine – it remains logged out. But Remote Desktop Session creates a window session and the Macro Scheduler UI routine runs within it. You can now schedule this command to run at the required time, either in Macro Scheduler or in Windows Task Scheduler.

The beauty of this approach is that it works even when both machines are locked or logged out. The only time it won’t work is if you minimize the Remote Desktop Connection. When you do that the session stops responding to keystrokes and mouse events. So if you are logged in, leave it open.

This method is ideal for scheduling processes to run on remote machines or on customer machines, where you can control the schedule from your end. But it is equally useful for scheduling processes internally where you don’t want the machine physically logged in. Until we find a replacement for AutoLogon in Vista, it is also a nice workaround if you need to schedule macros in Vista and do not want to leave the server unlocked.

Instead of setting the macro to run in the Remote Desktop Connection dialog, you could set the macro to run on startup and have the script check to see whether the current user is logged in via the console or via RDP (to avoid it running when a regular log in takes place). An example of how to determine whether the user is logged in locally or via Remote Desktop can be found here.

With Macro Scheduler scheduling the script on the client, other ways to start the script once the desktop connection is open could include assigning the remote script to a hotkey and having the client script send the key sequence; installing msNet on the server and issuing a HTTPRequest to run the script once the desktop connection is up; or if the two computers clocks are well synchronised just schedule the script on the server to happen shortly after the desktop connection is scheduled, allowing enough time for the log in to take place. Instead of installing Macro Scheduler on the remote machine you could also compile the macro to an executable and install just the executable macro on the server, and set it to run when Remote Desktop connects.

March 6, 2006

Simulate the Mouse Wheel

Filed under: Automation,Scripting — Marcus Tettmar @ 9:29 am

Want to automate a mouse wheel event? I posted an answer in the forum showing how to do this here: Roll the mouse wheel?

Downloading and Parsing RSS Feeds

Filed under: Automation,Scripting — Marcus Tettmar @ 9:25 am

Probably the simplest way to parse XML, such as an RSS feed, is to use Microsoft’s MSXML object which is built into Windows. I wrote a very quick and dirty routine using MSXML2 to download and parse this blog’s RSS feed. All it does is put the title, link and content of each item into arrays. You can then get the data easily by querying the array. My example runs a VBScript function which populates the arrays and then some native MacroScript loops through the array showing the data in a message box, as a simple example. You will find my code on the forum, here.

January 18, 2006

Thou shalt not waste time doing repetitive and mundane tasks

Filed under: Automation,General — Marcus Tettmar @ 1:53 pm

This is the 10th commandment of system administration according to Brian Warshawsky’s article “Ten Commandments of system administration” over at NewsForge. I couldn’t agree more. You’ll find the article with links to the other nine commandments here. These articles are for Linux administrators so much of the content and the example scripts won’t be much use to Windows admins. But the message is perfectly valid. Linux admins have always had the power of scripting at their disposal and the benefit of an operating system which is powered by command line interfaces. Windows, though, is primarily GUI based, designed more for desktop users. That’s why you need Macro Scheduler to automate Windows applications and obey the 10th commandment!

January 17, 2006

How to Start Writing an Automation Script

Filed under: Automation,Scripting — Tags: — Marcus Tettmar @ 11:35 am

These are my tips for getting started with writing an automation script.  While I’m, writing this with our Windows Automation tool, Macro Scheduler, in mind, these tips will be appropriate whichever automation tool you are using.

The most important thing before attempting to write a routine to automate a software process is to be familiar with the process itself. Run through the full process several times and find the simplest path. If you’re using the mouse excessively try to find keyboard alternatives.

Write down every step you take. Make a note of the keys you press, note down the title of each new window and how long each step takes. Try to determine what indicates the completion of each step. Make a note of it. You’ll end up with a list of keystrokes and window titles. This is the basis of your script. You’re now most of the way there. This list will translate well into a Macro Scheduler script.

I find it is best to break the script down into manageable chunks. Don’t try to write the whole thing at once. Start by just scripting the first few steps. E.g. write the code that opens the app, waits for it to be active and sends the first keystroke. Run it and make sure the process ends up where you expected. Tweak it if necessary. Now add the next couple of steps. Run it again. And so on. Building the script up in this way will iron out issues as you go rather than leaving you desperately trying to hunt down the cause of an error amongst one long script. You can also use the debugger to step through the script line by line.

Use SetFocus! When sending keystrokes Macro Scheduler just simulates what you do when you press keys on the keyboard. When you do that the keystrokes land on the active window. So you need to make sure the window you want the keystrokes to land in is the active window. Use SetFocus to do this. Get into the habit of using SetFocus even after running a program with the Run Program command. When you start a program it nearly always becomes the active window, but other applications can steal the focus. So it’s a good habit to get into to use SetFocus before sending a set of keystrokes.

Try not to use absolute wait times to wait for events to complete. The process may take longer on another occasion and fail. Also remember that when you do something manually you will subconsciously wait for the outcome of each action. A script isn’t quite so clever and unless you tell it to wait for certain actions to complete it will blindly move on to the next step. Always use WaitWindowOpen after running a program or sending an event that causes a new window to appear. This will ensure the script waits for that window to appear before continuing. Use WaitWindowClosed after issuing a command that causes the window to close. There are ways to wait for all sorts of other events to take place too, some more advanced than others. You can wait for pixel colors to change, mouse cursors and windows to change, detect object captions and wait for files, and portions of the screen to change amongst other things. When starting an application with Run Program use RP_WAIT=2 to tell it to wait until the application is ready for input before continuing.

Sometimes you do need a small Wait between events. Sometimes you need to slow down the key send rate. Scripts run faster than a human can type and not all applications can cope with that many keystrokes in such a short space of time. So the odd Wait>0.5 here and there can help. You can also slow down the key send rate with SK_DELAY.

When issuing shortcut keys such as ALT-F for the File menu use lowercase for the underscored character. E.g.:

Press ALT
Send>f
Release ALT

I have seen some applications fail to recognise shortcuts when Macro Scheduler sends the character in upper case. This is probably because it treats an upper case character send as having the Shift key pressed at the same time. So I always recommend issuing characters used in shortcut keystrokes in lower case.
It is best to avoid mouse events as much as possible, but if you do find you need to use the mouse for a particular action – maybe there’s no keyboard alternative – try to work out the relative mouse coordinates. Use the cursor monitor, set it to relative, and find the position relative to the window. Then use MouseMoveRel. This ensures that the mouse will always click on a position relative to the window rather than on an absolute screen position so that if the window opens in a different position next time around the macro will still work.

Clearly this article is all about automating via user simulation – by sending keyboard events to applications. Often there are better ways to automate an application such as via VBScript/ActiveX or DDE, or by reading data from files and databases. Before sitting down to automate an application by simulating user input stop to consider whether there are alternatives. For example, I’ve seen people write scripts to automate getting data from Excel by sending keystrokes to Excel to copy and paste. There’s no need to go to this trouble when Excel provides a DDE interface and can also be scripted with VBScript. See the sample script that comes with Macro Scheduler for an example of retrieving data from Excel directly. I’ve even seen macros which get data from a text file by driving Notepad with keystrokes. This is unnecessary and cumbersome when all you need to do is read data directly from the text file with the ReadLn command. If you need to get data from a database, you don’t need to send keystrokes to the query tool – you can read data directly into the script using VBScript/ADO/ODBC. Equally you can automate Internet Explorer elegantly via VBScript/ActiveX or with WebRecorder. There are usually at least two ways to automate something. Before writing your script stop and question whether there’s a better way.

Before writing your first script read Scripting Windows for Beginners in the Macro Scheduler help file/manual.

And browse the examples at the Scripts & Tips forum.

And if you don’t already have Macro Scheduler, you can download a trial version here.

January 16, 2006

Keyboard Shortcuts

Filed under: Automation,Scripting — Tags: — Marcus Tettmar @ 9:19 am

As mentioned in my last post, the easiest, most reliable way to automate an application is via keyboard shortcuts. But I’ve found that many people are so used to using the mouse that they don’t even realise you can use the keyboard to move around Windows applications.

Some things I take for granted are completely new to others. For example, moving from one field to the next is accomplished with the Tab key. After entering some information into an edit box just hit Tab to move to the next edit box. This is surely faster than moving your hand away from the keyboard, moving the mouse, clicking in the next edit box, moving back to the keyboard … and so on. Tab is all you need. Something a lot of people don’t realise is that this even works on web pages. Tab will move from form field to form field, but also from link to link. Try it now while you are reading this post. Press Tab a few times. You’ll notice a faint hashed box around the focused link. Press Tab again and the box moves to the next link. And so on. When you’re on a clickable object, or link, the Enter key will select or “click” it. Tab to a link and then press Enter and you will go to that page. In a Windows application you can tab to any standard object. You can tab through edit boxes as well as check boxes, menu items and buttons, and pretty much anything else. If you tab to a button pressing Enter will “click” it.

Checkboxes can be toggled from checked/unchecked and back again by pressing the space bar. Tab to a checkbox and hit the space bar. Its checked status will change. To select an item in a list box you can use the up and down arrows. Same goes for treeviews and combo boxes. But what you might not realise is that many list boxes and combo boxes have a kind of “drill down” feature. Type the first few characters of an entry and the selected item will change to the first item that starts with those characters. Type more characters in one go to narrow down the selection. This can be really useful when automating applications where you want to select an item in a list box or drop down – you can just send the text of the item you want to select. E.g. the following script automates the Regional Settings control panel applet to automatically change the default input language to Chinese (Hong Kong):

//Set to Chinese (Hong Kong …)
ExecuteFile>intl.cpl
WaitWindowOpen>Regional and Language Options
SetFocus>Regional and Language Options
Let>SK_DELAY=10
Send>Chinese (Hong Kong
Press Enter

This works by sending the first few characters unique to the entry we want to select. Unfortunately not all list boxes work like this. That’s why Macro Scheduler has advanced commands like GetListItem to determine the index of an item given it’s text caption.

Most of us know that we can select menu items using the Alt key. When you press the Alt key you should see certain characters in the menu items and on other objects become underscored. These are the shortcut keys. So to select the file menu in most applications you would press ALT-F. If an application has been designed properly other fields and buttons will have underlined characters also. Even labels associated with objects should have shortcut keys so that when you press ALT and that key you move focus immediately to that object. All this makes automation so much easier.

Other key combinations that are useful include CTRL-TAB to move from page to page or tab to tab in a tabbed window, such as Firefox. Try CTRL-TAB in firefox with several tabs open. You’ll move from one to the next.

Did you know you can select the next word in an editor by pressing CTRL-SHIFT-RIGHT? SHIFT-RIGHT on its own just moves the cursor to the end of the word and then to the next word and so on. Reverse it with SHIFT-LEFT. SHIFT-END will highlight to the end of the line. SHIFT-CTRL-END to go to the end of the document.

This is just the beginning. There are all sorts of keyboard shortcuts that make working in Windows so much faster and make automation so much easier and more reliable. I don’t know them all. But it’s worth getting to know them if you want to get the best out of Windows Automation.

Here are links to some pages that list useful keyboard shortcuts:

List of the keyboard shortcuts that are available in Windows XP
http://support.microsoft.com/default.aspx?scid=kb;en-us;301583

Shortcut keys in Windows 95,98,Me:
http://support.microsoft.com/default.aspx?scid=kb;en-us;q126449

Getting the most out of your Windows Keyboard
http://www.internet4classrooms.com/winkeyboard.htm

January 13, 2006

Why it’s Good to Automate

Filed under: Automation,Scripting — Marcus Tettmar @ 1:21 pm

One of the best ways to learn to use a software product fully is to try to automate it. Testers and automators have to learn the software’s interface really well, possibly better than the people who wrote it. Ok, the developers know the algorithms better than anyone else, but it is the person automating it who knows the ins and outs, pitfalls and quirks of the interface.

We all know how badly designed some Windows programs are. And in these days of fancy hi-res graphics and snazzy toolbar buttons it’s easy for the designers to forget about shortcut keys and keyboard navigation. The most productive way to use a PC is to forget the mouse and learn the keyboard shortcuts. You can get things done much more quickly. Yet even the most experienced Windows users don’t know half the keyboard shortcuts that exist in Windows (tips for keyboard navigation in Windows could be a post for another day).

Knowing these shortcuts makes automation so much easier and more reliable. Automating an application by sending mouse events and mouse clicks is unreliable and depends on the screen resolution never changing. Although you can use relative mouse coordinates, sooner or later something is going to change and the button you want to click is not in the place it was when the script was created.

The automation/test engineer is the one who figures out the keyboard shortcuts and finds the simplest, most reliable way of navigating an application. People who automate applications regularly have a good understanding of the different ways to move around Windows and Windows applications. Automated Software Testing can help find issues in the interface just from the process of building the automated test, even before the test script has been run. Building an automation routine for an application will help you find those missing or duplicated shortcut keys and other objects that can’t be driven by the keyboard.
Automators spend so much time fiddling with the software’s interface that they will often become more knowledgeable than the “power-users”. Testers also have the great advantage of being allowed to try unusual scenarios that developers never think about or are too busy to try. They are allowed to break things!

So it goes both ways. Find out the windows keyboard shortcuts and the hot-keys for the application you’re scripting and you can create a better script. Build an application with good keyboard support and your application can be automated more easily. If it can be automated easily it will be easy to use!

December 29, 2005

Automated Software Testing

Filed under: Automation,Testing — Tags: — Marcus Tettmar @ 4:36 pm

People have been using Macro Scheduler for Automated Software Testing and Load Testing for years. I’ve often been asked the best way to do this, and I’ve finally gotten around to putting some articles together on how best to use Macro Scheduler for automated testing. You’ll find them here:
http://www.mjtnet.com/automated_testing.htm

Automated Software Testing:
http://www.mjtnet.com/AutomatedTesting.pdf

Automated Load Testing:
http://www.mjtnet.com/loadtesting.pdf

« Newer Posts