Set ActivClient Login dialog PIN field value with UI Automation SetValue VS 2019 .Net 4.8

Kuntze, Gerry P. - US 96 Reputation points
2020-10-13T19:01:52.75+00:00

Configuration: VS 2019 .Net 4.8 Unit Test solution/project using hybrid Selenium/UI Automation framework

Scenario: A script launches an IE 11 browser and navigates to an https website that authenticates access with a CAC/PIN.

Issue: The automation is successful in launching the browser, navigating to the URL, selecting the certificate from the Windows Security (Select a Certificate) dialog and correctly recognizes the 'ActiveClient Login' dialog and its PIN value field. HOWEVER, the UI Automation ValuePattern SetValue command sporadically sets the PIN value with something other than the supplied plain text PIN value! When it incorrectly sets the value, the process halts after the OK button is selected due to an invalid PIN entry attempt. Refer to code snippet at bottom for details.

What I've done to diagnose the issue so far without success:

  1. Placed Thread.Sleep commands between SetFocus command and SetValue command -AND- between SetValue and Invoke of OK button
  2. Adjusted length of Thread.Sleep in hopes to slow things down enough without throwing an exception for Alert dialog display
  3. Modeled process based on commands offered in following MS site: https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/add-content-to-a-text-box-using-ui-automation

Background: Migrating CodedUI implementation to UI Automation since CodedUI is going away. The below CodedUI code snippet worked in VS 2015 .Net 4.7.1: Keyboard.SendKeys(plainTextPin, true);

==============
Code Snippet =================

AutomationElement dialog = FindActivClientPinDialog();  
  
AutomationElement pinElement = null;  
Wait.WaitForUiWithIntervalOverrides(() =>  
{  
    pinElement = dialog.FindFirst(TreeScope.Descendants, new AndCondition(  
        new PropertyCondition(AutomationElement.NameProperty, PinName),  
        new PropertyCondition(AutomationElement.ClassNameProperty, PinEditClassName)));  
    return pinElement != null;  
}, _waitForElementLocationGeneral);  
  
  
pinElement.SetFocus();  
  
Thread.Sleep(100);  
Pattern.GetValuePattern(pinElement).SetValue(plainTextPin); **// THIS IS THE ISSUE**  
  
Thread.Sleep(100);  
  
AutomationElement buttonElement = selectionWindow.FindFirst(TreeScope.Children,  
  new AndCondition(new PropertyCondition(AutomationElement.ClassNameProperty, ButtonClassName),  
    new PropertyCondition(AutomationElement.NameProperty, OkayButtonName)));  
  
if (!buttonElement.Current.IsEnabled)  
{  
    throw new InvalidOperationException("The 'OK' button IS NOT ENABLED!");  
}  
  
Pattern.GetInvokePattern(buttonElement).Invoke();  
  
  
=========  
  
private static AutomationElement FindActivClientPinDialog()  
{  
    AutomationElement acElement = null;  
    Wait.WaitForUiWithIntervalOverrides(() =>  
    {  
       acElement = AutomationElement.RootElement.FindFirst(TreeScope.Descendants,  
         new PropertyCondition(AutomationElement.ClassNameProperty, ActivClientClassNameProperty));  
       return acElement != null;  
    }, _waitForElementLocationGeneral);  
Pattern.CheckResultAndThrow(acElement == null, "The ActivClient PIN selection dialog was NOT FOUND!");  
return acElement;  
}
Visual Studio Testing
Visual Studio Testing
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Testing: The act or process of applying tests as a means of analysis or diagnosis.
351 questions
{count} votes

Accepted answer
  1. Kuntze, Gerry P. - US 96 Reputation points
    2020-10-23T12:42:10.36+00:00

    The final solution to key in the PIN and select the OK button had to be done without UIAutomation as shown below:

    AutomationElement dialog = FindActivClientPinDialog();
    
    AutomationElement pinElement = null;
    
    Wait.WaitForUiWithIntervalOverrides(() =>
    {
        pinElement = dialog.FindFirst(TreeScope.Descendants, new AndCondition(
            new PropertyCondition(AutomationElement.NameProperty, PinName),
            new PropertyCondition(AutomationElement.ClassNameProperty, PinEditClassName)));
        return pinElement != null;
    }, _waitForElementLocationGeneral);
    
    Thread.Sleep (1000); 
    SendKeys.SendWait(plainTextPin);
    
    Thread.Sleep (100); 
    SendKeys.SendWait("{ENTER}");
    
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.