TestStack / White

DEPRECATED - no longer actively maintained
Other
1.02k stars 486 forks source link

inputting non-English characters into a textbox results in a lot of '?' #203

Open cuipengfei opened 10 years ago

cuipengfei commented 10 years ago

textBox.Text="非英文字符"; results in a lot of '?'s

I debugged the code and found out that white uses VKKeyScan(a win32 api that turns a char into a keyboard type-able key) to process every character before simulating a keyboard event.

this means that all the characters are not on the keyboard can not be set to the Text property of TextBox directly.

right now, i am putting all the non-English characters to the clipboard and simulating a control+v keyboard event.

is there any better way to do this?

JakeGinnivan commented 10 years ago

The BulkText property allows the text to be set as you would expect.

cuipengfei commented 10 years ago

HI Jake,

Thank you for your response.

I have tried the BulkText property, it also results in a lot of ?

I debugged the code and found out that BulkText calls Text when a current pattern can not be found. In my case the TryGetCurrentPattern method always returns false, thus BulkText always calls Text.

I am not sure why the pattern can not be found. Could you shed some light on this?

Thanks very much.

cuipengfei commented 10 years ago

Hi Jake,

I did a little more playing around and found out that it only happens to ControlType.Document. The TryGetCurrentPattern method always fails to get a pattern for ControlType.Document.

So now I am using SendKeys.SendWait(text); instead. It can input Chinese characters.

But I am not sure if that is the best way to solve this problem. Do you have any better suggestions?

Thanks

JakeGinnivan commented 10 years ago

Hrrmm, is this winforms or WPF?

What pattern are you trying to get? Document has different patterns to Text controls

cuipengfei commented 10 years ago

it's notepad and wordpad, both installed with windows7, i am not sure if they were winforms or wpf(is there an easy way to tell?).

and i am not trying to get the pattern, it's the BulkText property of TextBox in white:

        public virtual string BulkText
        {
            set
            {
                try
                {
                    var pattern = Pattern(ValuePattern.Pattern) as ValuePattern;
                    if (pattern != null) pattern.SetValue(value);
                    else
                    {
                        Logger.WarnFormat("BulkText failed, {0} does not support ValuePattern. Trying Text", ToString());
                        Text = value;
                        actionListener.ActionPerformed(Action.WindowMessage);
                    }
                }
                catch (System.InvalidOperationException)
                {
                    Logger.Warn("BulkText failed, now trying Text on " + ToString());
                    Text = value;
                    actionListener.ActionPerformed(Action.WindowMessage);
                }
            }
            get { return Text; }
        }

this property tries to get a pattern and set the value with the pattern, if it fails then resort to Text.

cuipengfei commented 10 years ago

This code can reproduce the problem on my win7 machine(it is bootcamped on a mac book, could that be the problem?).

uncomment this line to reproduce the problem: // box.BulkText = text;

using System.Linq;
using System.Windows.Automation;
using System.Windows.Forms;
using TestStack.White.UIItems.Finders;
using TestStack.White.UIItems.WindowItems;
using Application = TestStack.White.Application;
using TextBox = TestStack.White.UIItems.TextBox;

namespace ConsoleApplication1
{
    internal class Program
    {
        private const string _text = "english 中文";

        private static void Main(string[] myArgs)
        {
            TypeChineseIntoWordPad();
            TypeChineseIntoNotepad();
        }

        private static void TypeChineseIntoWordPad()
        {
            Window window = Application.Attach("wordpad").GetWindows().First();

            SearchCriteria fontFamilySearchCriteria = SearchCriteria.ByText("Font family");
            SearchCriteria mainDocumentSearchCriteria = SearchCriteria.ByText("Rich Text Window");

            FillText(window, fontFamilySearchCriteria, _text);
            FillText(window, mainDocumentSearchCriteria, _text);
        }

        private static void TypeChineseIntoNotepad()
        {
            Window window = Application.Attach("notepad").GetWindows().First();
            SearchCriteria fontFamilySearchCriteria = SearchCriteria.ByControlType(ControlType.Document);

            FillText(window, fontFamilySearchCriteria, _text);
        }

        private static void FillText(Window window, SearchCriteria searchCriteria, string text)
        {
            var box = window.Get<TextBox>(searchCriteria);
            box.Focus();
//            box.BulkText = text;
//          this way we can not type chinese characters into ControlType.Document(notepad and word pad)    

            SendKeys.SendWait(text);
            //this way, we can type chinese characters into a text box
            //but not sure if it will also cause the data area too small problem
        }
    }
}
JakeGinnivan commented 10 years ago

Thanks for the repro code, I will try it out and get back to you over the next few days

cuipengfei commented 10 years ago

Hi Jake,

There is a new issue. The error "the data area passed to a system call is too small" happens when we try to set the Text or BulkText of a ControlType.Document element represented by a TextBox. But this only happens on a pretty old client laptop, I can not reproduce this issue on my machine.

Have you seen this issue before?

JakeGinnivan commented 10 years ago

Hi,

I have just tried to reproduce in Linqpad using your provided code. Text does not work as you say (it typed ??) but Bulk text works as expected.

Though instead of .ByText() I use SearchCriteria.ByAutomationId("1") for the font family and "59648" for the rich text box in wordpad.

I have not seen the issue you are describing before, sorry

JakeGinnivan commented 10 years ago

What operating system are you using?

If it is XP make sure the windows automation API v3 is installed. http://support.microsoft.com/kb/981741

cuipengfei commented 10 years ago

Hi Jake,

Thank you for the tip, I will install the automation API v3 and try again.

And about the ?? issue, I just tried again using automation id instead of using text as criteria, it still happens on my win7 x64 machine. Same as before, the rich text box displayed ??.

This is the log I got: 'TestStack.White.UIItems.UIItem' BulkText failed, TextBox. AutomationId:59648, Name:Rich Text Window, ControlType:document, Framew orkId:Win32 does not support ValuePattern. Trying Text

Seems like for ControlType:document, we can not get a value pattern. (As I debugged the code, line 140 of UIItem.cs always returns false for the rich text box of wordpad.)

And I found more information here: http://msdn.microsoft.com/en-us/library/system.windows.automation.valuepattern.setvalue(v=vs.90).aspx

It says that : "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."

So it seems like BulkText should not work for the rich text box of wordpad. Could you share your code that inserts text into wordpad? I can try it and see if it works on my machine.

Thanks

JakeGinnivan commented 10 years ago

Hrrmm, on Windows 8.1 wordpad supports the value pattern.

What operating system are you using?

cuipengfei commented 10 years ago

Hi Jake,

I just tried another win7 machine, it also got ??.

The two machines I tried: one is bootcamped on a mac book, another is running in virtual box on a mac.

capture

the image above is how it results in both machines.

cuipengfei commented 10 years ago

both win7 x64

cuipengfei commented 10 years ago

ok, i will get a win8.1 virtual machine and try it out again, thanks

cuipengfei commented 10 years ago

Hi Jake,

I just got a win8 virtual machine set up, it's really interesting, it works for wordpad, but still does not work for notepad. This is the result:

capture

Any idea if we can port the win8 solution to win7 or even xp?