Unable to enter a string in text box

Dec 8, 2011 at 6:33 PM

Hi,

Please find the code below that I have written to enter the user id on a login screen.  The code does detect the text box for the user id.  [The object 'control' is not null.] However, it fails to enter the value "admin" in the text box.

Note: I have used AutomationElement because I am not able to distinguish between the text fields 'User Id' and 'Password' with WHITE framework since they have same Automation Id value.

Any pointers on resolving the issue? Is there any other way enter string value in the text-box?

thanks & regards,

Rajendra

 

 

AutomationElement ae = w.AutomationElement; //w is a window object

AndCondition cond1 = new AndCondition(
new PropertyCondition(AutomationElementIdentifiers.NameProperty, "User ID"),
new PropertyCondition(AutomationElementIdentifiers.AutomationIdProperty, "65535"));

AutomationElement control = ae.FindFirst(TreeScope.Descendants, cond1);

            if (control != null)
            {
                Console.WriteLine("Found User ID text box  ... ");
                control.SetFocus(); 
                Keyboard.Instance.Enter("admin");
             
                System.Threading.Thread.Sleep(5000);

            }

 

 

uidControl 
Dec 9, 2011 at 6:46 AM

Hi

1. since White 2.0 you can search for Name property  with white

2. try this:

 

if (control != null) 
{ 
  Console.WriteLine("Found User ID text box ... ");
  TextBox box = new TextBox(control, w.ActionListener);
  box.Click();
  box.BulkText = "admin";
}
Dec 11, 2011 at 8:56 AM
Edited Dec 11, 2011 at 8:58 AM

1. Thondorin meant that you can use w.Get(SearchCriteria.ByText("User Id"))

2. The key point here that your AutomationElement should implement ValuePattern (System.Windows.Automation.ValuePattern)

Also it need to be Enabled,IsKeyboardFocusable and not ReadOnly

You can use this piece of code.

 

 

     	/// <summary>
        /// Inserts a string into a text control that supports ValuePattern.
        /// </summary>
        /// <param name="targetControl">A text control.</param>
        /// <param name="value">The string to be inserted.</param>        
        private void InsertText(AutomationElement targetControl,
                                            string value)
        {
            // Validate arguments / initial setup
            if (value == null)
                throw new ArgumentNullException(
                    "Text parameter must not be null.");

            if (targetControl == null)
                throw new ArgumentNullException(
                    "AutomationElement parameter must not be null");

            // A series of basic checks prior to attempting an insertion.
            //
            // Check #1: Is control enabled?
            // An alternative to testing for static or read-only controls 
            // is to filter using 
            // PropertyCondition(AutomationElement.IsEnabledProperty, true) 
            // and exclude all read-only text controls from the collection.
            if (!targetControl.Current.IsEnabled)
            {
                throw new InvalidOperationException(
                    "UIItem is not enabled.");
            }

            // Check #2: Are there styles that prohibit us 
            //           from sending text to this control?
            if (!targetControl.Current.IsKeyboardFocusable)
            {
                throw new InvalidOperationException(
                    "UIItem is not focusable.");
            }

            // Once you have an instance of an AutomationElement,  
            // check if it supports the ValuePattern pattern.
            object valuePattern = null;

            if (!targetControl.TryGetCurrentPattern(
                ValuePattern.Pattern, out valuePattern))
            {
                // Elements that support TextPattern 
                // do not support ValuePattern and TextPattern
                // does not support setting the text of 
                // multi-line edit or document controls.
                // For this reason, text input must be simulated.
                throw new UIItemNotImplementingPatternException(string.Format(Res.UIITEM_NOT_IMPLEMENTING_PATTERN, "Value"));
            }
            // Control supports the ValuePattern pattern so we can 
            // use the SetValue method to insert content.
            else
            {
                if (((ValuePattern)valuePattern).Current.IsReadOnly)
                {
                    throw new InvalidOperationException(
                        "UIitem is read-only.");
                }
                else
                {
                    ((ValuePattern)valuePattern).SetValue(value);
                }
            }
        }
Dec 12, 2011 at 8:05 AM

1. does not mean SearchCritera.ByText :)

but this:

w.Get<TextBox>( SearchCriteria.ByNativeProperty( AutomationElement.NameProperty, "User ID" ) );
Dec 12, 2011 at 9:03 AM

Hi Throndorin & niosocket,

Thank you for the reply!

For option #1 suggested by you, I tried the two ways to get the textBox1 object.  However, both have failed with the following exception:

System.NullReferenceException : Object reference not set to an instance of an object.

 

I will try the option#2 [suggested by Throndorin] & get back to you.

 

thanks,

Rajendra

 

CODE:

--------------------------------------------
TextBox textBox1 = w.Get( SearchCriteria.ByNativeProperty( AutomationElement.NameProperty, "User ID" ) );
            
//TextBox textBox1 = w.Get(SearchCriteria.ByText("User Id"));
            
textBox1.BulkText = "admin";

--------------------------------------------



Dec 12, 2011 at 9:31 AM

Hi Throndorin,

 

I tried the option #2 suggested by you. I got the following NullReferenceException with the option.  I am not able to make out why the exception did not occur at line [box.Click();]

instead of [box.BulkText = "admin";]  in code below.

CODE:

--------

 

AutomationElement ae = w.AutomationElement;

AndCondition cond1 = new AndCondition(
new PropertyCondition(AutomationElementIdentifiers.NameProperty, "User ID"), new PropertyCondition(AutomationElementIdentifiers.AutomationIdProperty, "65535"));

AutomationElement control = ae.FindFirst(TreeScope.Descendants, cond1);

            if (control != null)
            {
                Console.WriteLine("Found User ID text box ... ");
                TextBox box = new TextBox(control, w.ActionListener);
                box.Click();
                box.BulkText = "admin";
            }

Exception:

------------

System.NullReferenceException : Object reference not set to an instance of an object.
   at White.Core.UIItems.TextBox.set_BulkText(String value) in c:\white\Components\Core\Source\UIItems\TextBox.cs:line 43

 

Dec 12, 2011 at 10:47 AM

Hi,

c:\white\Components\Core\Source\UIItems\TextBox.cs:line 43

 

((ValuePattern) Pattern(ValuePattern.Pattern)).SetValue(value);

 

Pattern method at the end is

 

        internal static BasePattern Pattern(AutomationElement automationElement, AutomationPattern pattern)
        {
            object patternObject;
            if (automationElement.TryGetCurrentPattern(pattern, out patternObject))
            {
                return (BasePattern) patternObject;
            }
            return null;
        }

 

You are sure that your element implementing ValuePattern?

If you are looking at UISpy you should see in  properties 

  Value
    Value:	""
    IsReadOnly:	"False"

Dec 12, 2011 at 11:29 AM

Hi niosocket,

 

I am using UISPY.  I notice that the section 'ControlPatterns' is empty for the concerned text-boxes ('USER ID' & 'Password').  Any other option to move ahead?  Meanwhile, I will try using index position.

How much code change does it require to implement 'ValuePattern'?  FYI - The log-in console is likely to be very old as far the development history is concerned. 

 

thanks & regards,

Rajendra

Dec 12, 2011 at 11:38 AM

It's weird that you don't have ValuePattern there, but anyway you can always use 

box.Click() // To get focus

string keys = "text you want to insert";

Keyboard.Instance.Enter(keys);

Dec 12, 2011 at 12:01 PM

No success even after using "Keyboard.Instance.Enter ...".  I really need to move past the 'Log On' window. There are more challenges ahead for sure.

thanks,

Rajendra

Dec 12, 2011 at 12:16 PM

There is no chance that Keyboard.Instance.Enter not working. It simply send keyboard press button events.

If you are capable of clicking on this text box and inserting data from your keyboard it must work.

You need to pay attention that you are not have any break point between box.Click() and Keyboard.Enter because you will lose focus.

Is box.Click() work ? You are getting focus on element that you want ?

You can also try 

w.Keyboard.Enter // w is your window

Dec 12, 2011 at 1:59 PM

maybe the test is to fast ? and the Textbox is disabled?

Dec 12, 2011 at 2:08 PM

I added the code to check the focus as below.  I checked the state of text-box at the end of run with UISPY for the focus.  Following are the details:

State
    IsEnabled:    "True"
    HasKeyboardFocus:    "False"

CODE:

                box.Click();
                if (box.IsFocussed == true)
                {
                  .......... //This code did not get executed
                }

thanks,

Rajendra

Dec 12, 2011 at 2:12 PM

Forgot to add that the test completes the run (successfully) after 'box.Click();' statement.  There are no errors on the console.

thanks,

Rajendra

Dec 12, 2011 at 2:18 PM

Some more things from UISPY on the 'USER ID' text-box as below. The attribute 'IsKeyboardFocusable' is 'False'.

 

AutomationElement
  General Accessibility
    AccessKey:    ""
    AcceleratorKey:    ""
    IsKeyboardFocusable:    "False"
    LabeledBy:    "(null)"
    HelpText:    ""

 

-------------

thanks,

Rajendra

Dec 12, 2011 at 4:31 PM

You tried ?

box.Click();
w.Keyboard.Enter // w is your window

And nothing else. You don't need IsFocussed or IsKeyboardFocusable because your element not support ValuePattern.

If this not working something is horribly wrong out there. Without app it will be extremely hard to help you. Sorry.

One thing that can help. Print box.LogStructure() and post it here.

Dec 16, 2011 at 1:52 AM

Hi,

I think we need log4net to print the LogStructure.  However, I am trying to find a way to configure log4net for my 'Class Library' project.  Is app.config the only way to configure log4net?  For a 'Class Library' project, I don't see the app.config in 'Solution Explorer'.  I am using VS Express 2010.

I tried a using indexes for the two text-boxes and the script has moved past the 'Log-in' screen.

thanks,

Rajendra

Dec 16, 2011 at 2:37 AM

Where does the output of the line 'box.LogStructure();' get printed?  I don't see anything on the console where I invoke the Nunit test.

thanks,

Rajendra

Dec 16, 2011 at 7:55 AM

Hi

 

the ouput can be seen in:

1. white log file

2. VisualStudio Output

3. Nunit UI Output

 

we have added a lof4net.dll as reference and a log4net.config with the following content

 

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="Info" />
    <appender-ref ref="Console" />
    <appender-ref ref="White" />
  </root>

  <appender name="White" type="log4net.Appender.RollingFileAppender">
    <file value="White.log" />
    <appendToFile value="true" />
    <maximumFileSize value="5MB" />
    <maxSizeRollBackups value="10" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="[%d][%-5p] %m%n" />
    </layout>
  </appender>

  <appender name="Console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="[%d][%-5p] %m%n" />
    </layout>
  </appender>
</log4net>


Dec 26, 2011 at 1:15 PM

I have been busy with a release & couldn't get enough time to explore further.   Sorry for the delay in posting the output of LogStructure() ...

----------------

 

[2011-12-26 19:37:45,317][INFO ] Using BusyTimeout=5000 for White/Core
[2011-12-26 19:37:45,399][INFO ] Using WaitBasedOnHourGlass=True for White/Core
[2011-12-26 19:37:45,401][INFO ] Using WorkSessionLocation=. for White/Core
[2011-12-26 19:37:45,401][INFO ] Using UIAutomationZeroWindowBugTimeout=5000 for White/Core
[2011-12-26 19:37:45,401][INFO ] Using PopupTimeout=5000 for White/Core
[2011-12-26 19:37:45,401][INFO ] Using TooltipWaitTime=0 for White/Core
[2011-12-26 19:37:45,401][INFO ] Using SuggestionListTimeout=3000 for White/Core
[2011-12-26 19:37:45,402][INFO ] Using DefaultDateFormat=Month,Day,Year for White/Core
[2011-12-26 19:37:45,402][INFO ] Using DragStepCount=1 for White/Core
[2011-12-26 19:37:45,402][INFO ] Using InProc=False for White/Core
[2011-12-26 19:37:45,402][INFO ] Using ComboBoxItemsPopulatedWithoutDropDownOpen=True for White/Core
[2011-12-26 19:37:45,402][INFO ] Using RawElementBasedSearch=False for White/Core
[2011-12-26 19:37:45,403][INFO ] Using MaxElementSearchDepth=10 for White/Core
[2011-12-26 19:37:45,403][INFO ] Using DoubleClickInterval=0 for White/Core
[2011-12-26 19:37:45,403][INFO ] Using MoveMouseToGetStatusOfHourGlass=True for White/Core
[2011-12-26 19:37:46,329][INFO ] Using TableVerticalScrollBar=Vertical Scroll Bar for White/UIItemId
[2011-12-26 19:37:46,329][INFO ] Using TableHorizontalScrollBar=Horizontal Scroll Bar for White/UIItemId
[2011-12-26 19:37:46,329][INFO ] Using TableColumn=Row  for White/UIItemId
[2011-12-26 19:37:46,329][INFO ] Using TableTopLeftHeaderCell=Top Left Header Cell for White/UIItemId
[2011-12-26 19:37:46,329][INFO ] Using TableCellNullValue=(null) for White/UIItemId
[2011-12-26 19:37:46,329][INFO ] Using TableHeader=Top Row for White/UIItemId
[2011-12-26 19:37:46,330][INFO ] Using HorizontalScrollBar=Horizontal ScrollBar for White/UIItemId
[2011-12-26 19:37:46,330][INFO ] Using VerticalScrollBar=Vertical ScrollBar for White/UIItemId
[2011-12-26 19:37:46,330][INFO ] Using TableCellPrefix= Row  for White/UIItemId
[2011-12-26 19:37:53,402][INFO ]
AutomationId: 1327
ControlType: ControlType.Edit
Name:
HelpText:
Bounding rectangle: 642,318,161,20
ClassName: Edit
IsOffScreen: False
FrameworkId: Win32
ProcessId: 9992

System.Windows.Automation.ValuePattern
System.Windows.Automation.TextPattern


[2011-12-26 19:37:53,820][INFO ]
AutomationId: 1328
ControlType: ControlType.Edit
Name:
HelpText:
Bounding rectangle: 642,349,162,20
ClassName: Edit
IsOffScreen: False
FrameworkId: Win32
ProcessId: 9992

System.Windows.Automation.ValuePattern


-------------------

 

thanks,

Rajendra