简体   繁体   中英

Can't click button directly using TestStack.White

I'm trying to click a button on an external windows application. The following code successfully finds the element, brings the parent window into focus and then "manually" clicks the button

This works okay...

Process tProcess = Process.GetProcesses().FirstOrDefault(x => x.MainWindowTitle.StartsWith("MainWindowName"));
if (tProcess != null)
{
    TestStack.White.Application application = TestStack.White.Application.Attach(tProcess.Id);
    var tWindow = application.GetWindow(SearchCriteria.ByAutomationId("SubWindowName"), InitializeOption.NoCache);
    SearchCriteria searchCriteria = SearchCriteria.ByAutomationId("btnCalibrate");
    var calibrateBtn = tWindow.Get<TestStack.White.UIItems.Button>(searchCriteria);
    tWindow.Focus();
    var clickablePoint = calibrateBtn.AutomationElement.GetClickablePoint();
    Mouse.Instance.Click(clickablePoint);
}

The problem with this is that Mouse.Instance.Click(clickablePoint); moves the cursor, ideally I don't want the cursor moved.

My initial code tried to click the button directly using the following

Process tProcess = Process.GetProcesses().FirstOrDefault(x => x.MainWindowTitle.StartsWith("MainWindowName"));
if (tProcess != null)
{
    TestStack.White.Application application = TestStack.White.Application.Attach(tProcess.Id);
    var tWindow = application.GetWindow(SearchCriteria.ByAutomationId("SubWindowName"), InitializeOption.NoCache);
    SearchCriteria searchCriteria = SearchCriteria.ByAutomationId("btnCalibrate");
    var calibrateBtn = tWindow.Get<TestStack.White.UIItems.Button>(searchCriteria);
    tWindow.Focus();
    calibrateBtn.Click();
}

but this gives the following error every time

TestStack.White.AutomationException
  HResult=0x80131500
  Message=Cannot perform action on Button. AutomationId:btnCalibrate, Name:Calibrate, ControlType:button, FrameworkId:WinForm, 
  Source=TestStack.White
  StackTrace:
   at TestStack.White.UIItems.UIItem.PerformIfValid(Action action) in c:\TeamCity\buildAgent\work\89a20b30302799e\src\TestStack.White\UIItems\UIItem.cs:line 254
   at TestStack.White.UIItems.UIItem.Click() in c:\TeamCity\buildAgent\work\89a20b30302799e\src\TestStack.White\UIItems\UIItem.cs:line 231
   at BetfairStreamingAPI.RadForm1.radLabelBetTime_Click(Object sender, EventArgs e) in D:

Does anyone know why the second method is throwing this error and if it's possible to fix this so that the button can be clicked without manually moving the cursor?

Edit: Screenshot of attempt to set togglestate

在此输入图像描述

The solution to this particular problem appears to be use .RaiseClickEvent() instead of .Click()

The following code works

Process tProcess = Process.GetProcesses().FirstOrDefault(x => x.MainWindowTitle.StartsWith("MainWindowName"));
if (tProcess != null)
{
    TestStack.White.Application application = TestStack.White.Application.Attach(tProcess.Id);
    var tWindow = application.GetWindow(SearchCriteria.ByAutomationId("SubWindowName"), InitializeOption.NoCache);
    SearchCriteria searchCriteria = SearchCriteria.ByAutomationId("btnCalibrate");
    var calibrateBtn = tWindow.Get<TestStack.White.UIItems.Button>(searchCriteria);

    calibrateBtn.RaiseClickEvent();
}

It's not entirely clear from the White docs when/why this is preferred. I found method RaiseClickEvent this on this link https://github.com/TestStack/White/commit/7b6d4dbc0008c3375e2ebf8810c55cb1abf91b60

EDIT2

I think you might have found something interesting. Since your button state is Indeterminate, it could be worth turning it on before clicking it:

calibrateBtn.State = ToggleState.On;

EDIT1 Alright, let's sort this out together.

There are only two reasons for that action to fail:

  1. The button is not enabled, which I guess can't be the case
  2. The button is OffScreen

If you do something like

Console.WriteLine(calibrateBtn.IsOffScreen.ToString());

You should see

true

If so, try this before you click it:

var pattern = calibrateBtn.AutomationElement.GetCurrentPattern(System.Windows.Automation.InvokePattern.Pattern);
(pattern as System.Windows.Automation.InvokePattern).Invoke();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM