4

I'm trying to automate the testing of an application, and I'm stuck on an issue that I'm struggling to troubleshoot.

The application has standard windows buttons, and I've tried with both AutoIT and the User32 dll to click some of these buttons. Sometimes the buttons are clicked properly (yay!) and sometimes they fail (boo!) - but what's worse, AutoIT is convinced that it clicked the button (double-boo!) which then generates false-positives (triple-boo!). When I saw that it's convinced, I mean it returns that the click was successful when it wasn't.

I'm running the application on Win Server 2K8, there is nothing special about this application other than it uses MDI windows, and some of the buttons are contained in MDI windows. Some though, are not within MDI windows (login window, for example, before the parent window is created).

Here's my order of commands:

Find the button in the window (success, always) Bring the window the foreground (success) Activate the window (success) Active the button (success) Focus the button (success) If the button is focused, and the button is enabled, then click it. (Success/Failure, unpredictable behavior. I can't narrow down why it succeeds sometimes, and why it fails sometimes...)

Other details:

Sometimes the order has the button being clicked, which should open another window. That window is closed, then the button is clicked again - and this time around, nothing happens. Other times it works as expected.

I'm running as Administrator, and UAC is fully disabled.

It's not a timing issue, to my knowledge, because I do make sure the button is focused, and enabled before trying to click on it, and I see that the button does get the focused highlight around it.

And as I mentioned, I've also been trying this with just a simple User32/SendMessage call, and this also fails.

Last, but not least, this doesn't happen when I manually interact with the application. I have always had actual button clicks work.

Any thoughts?

UPDATE

Here's another variable to the equation I should have mentioned - this is happening on a VM (because that's where I need to run it). I can do some limited testing on my own machine, but to get some true testing, it needs to be on the VM. Clicking on my own dev box seems to be reliable, which makes this all the more puzzling.

I've been trying this out on another VM, and it also seems to be working there. As far as the two VMs going, they're running the same version of Windows, same version of my application, same version of AutoIT, etc.

I've reduced it down to one detail - which, as luck would have it, I'm not able to configure myself, and have to put in a ticket to change any configuration. The difference in configurations is this:

On the VM that isn't working, the device manager shows a mouse that is a vmware mouse. On the VM that is working, the device manager shows a mouse that is PS/2 mouse. Obviously both are software mice, but I'm wondering now if the VMWare mouse could be acting differently, and causing the button clicks to not always work. I'm not sure how likely this is as the solution, because from my understanding of it, using the User32 SendMessage call doesn't actually use the mouse, but instead sends the same message the mouse would have sent, but it's worth a shot...

AlishahNovin
  • 1,904
  • 3
  • 20
  • 37
  • There are multiple children, but there is only one instance of each form at a time - and I can confirm that the window housing the button *is* at the top, and is not obstructed by a topmost window – AlishahNovin Feb 09 '12 at 19:47
  • I am using the following command: ControlClick("My Sub Window Title", "", "CLASS:ThunderRT6CommandButton; INSTANCE:1]", "left"); I don't set the coordinates, because I always provide the control id (which is static, thankfully) – AlishahNovin Feb 09 '12 at 20:07
  • 2
    I'm pretty sure that when AutoIt is convinced it has found the button, it also has clicked it. In other words: It will only return error when the control can't be found. It's simply a windows messages being sent and when the other application doesn't handle it, AutoIt can't know. – Jos van Egmond Feb 10 '12 at 08:26
  • Try to use the hint from @M.Babcock and position your Mouse properly and do a click. There's a function [`_WinAPI_ClientToScreen`](http://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_ClientToScreen.htm) to help you get the exact screen position where to click at. Feed it with the coordinates from [`ControlGetPos`](http://www.autoitscript.com/autoit3/docs/functions/ControlGetPos.htm). Or you should just `Sleep(333)` some time before you click the button again or simulate the click with a `Send("{Space}")` since you already gave it the focus. – Samoth Feb 10 '12 at 10:04
  • I do use a sleep in my User32 call to send a click. I've set up my code to try AutoIT and then fall back to User32 if it fails - but false positives are the problem. It may be an obvious question, but in case I've missed something - are there any underlying messages I can hook into to validate the button has been pressed? Obviously, I could hack something together, but is there any underlying Windows messaging that I could tie into to verify that the button received some kind of 'click' state - maybe if it's class changes from an unclicked button class to a clicked on, or something like that? – AlishahNovin Feb 10 '12 at 15:52
  • Update: Clicking at an X,Y position rather than clicking with a handle has the same problem. – AlishahNovin Feb 13 '12 at 17:02
  • Another update: I've disabled the AutoIT call entirely and tried using the User32 SendMessage call. Same problem. – AlishahNovin Feb 14 '12 at 20:04

3 Answers3

2

You say that you've successfully Focused the button, so have you tried sending a Spacebar event rather than a MouseClick?

Send("{SPACE}")

(I think that's the syntax. I'm not really an AutoIt regular)

The spacebar can typically be used to interact with most clickable controls, such as buttons and checkboxes. In my experience, simulated mouse clicks, and even ControlClicks, are a lot less reliable than keystrokes for weird, inconsistent reasons. My sympathies.

As for detecting that the button is clicked, perhaps the easiest thing to do would be to have the button make a change to the form that AutoIT can detect. For example, a status label that reads Ready until the user presses the button. When the user presses the button, the text changes to Processing. If necessary, you may be able to make the label invisible (or positioned outside the boundaries of the form), such that the user cannot see it, but AutoIt can.

Nathan
  • 1,675
  • 17
  • 25
0

You probably succeeded to resolve this issue by the time you posted this question, but there's no good answer yet so I'll post mine:

I had the same issue on a Virtual Machine running Windows Server 2008 R2: I couldn't send a keystroke or do anything through Win32 API SendMessage to a particular program (and its main window).

According to this Q/A, this is a UIPI issue (which is there since Windows Vista). You should simply turn off your UAC to resolve this issue. I tested it and it works. More alternatives can be found through the link I provided.

Community
  • 1
  • 1
gdube
  • 77
  • 7
0

I have simulated your case and it works 100% on Windows 7:

using System.Runtime.InteropServices;

[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);

void ClickFocusedControl()
{
    const uint KEYEVENTF_EXTENDEDKEY = 0x1;
    const uint KEYEVENTF_KEYUP  = 0x2;

    keybd_event(13, Convert.ToByte(0), KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero); //Generates a KEY_DOWN
    keybd_event(13, Convert.ToByte(0), KEYEVENTF_KEYUP, UIntPtr.Zero); // Generates a KEY_UP
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Amen Ayach
  • 4,288
  • 1
  • 23
  • 23