XamlParseException when testing WPF app with StaticResourceReference

Aug 10, 2009 at 7:01 PM

I am testing the sample app that comes with this library by making a few changes. One of them is to use a StaticResource reference to a brush (specified in App.xaml), something like:

 

<Grid Width="500"
          Height="300"
          Name="mainGrid"
          Background="{StaticResource PreferencesBackground}">

 

I am using the WpfInProcessApplication type which has been setup like so:

 

        string sampleAppPath = Path.Combine(Environment.CurrentDirectory, "SampleApp.exe");
        var a = new InProcessApplication(new WpfInProcessApplicationSettings
                                                              {
                                                                  Path = sampleAppPath,
                                                                  InProcessApplicationType =
                                                                      InProcessApplicationType.InProcessSameThread,
                                                                  ApplicationImplementationFactory =
                                                                      new WpfInProcessApplicationFactory(),
                                                                  WindowClassName = typeof(Window1).FullName

                                                              });
        a.Start();

        try
        {
            a.WaitForMainWindow(TimeSpan.FromSeconds(10));


However when I start the app, it crashes with a XamlParseException for the static resource reference.
-- Exception Details --
Test method UIAutomationTests.VerifyInput threw exception:  System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> 
System.Windows.Markup.XamlParseException: Cannot find resource named '{PreferencesBackground}'. Resource names are case sensitive.
 Error at object 'mainGrid' in markup file 'SampleApp;component/window1.xaml' Line 27 Position 5..


The app runs perfectly fine outside the test setup. Greatly appreciate any pointers to help resolve this ?

Thanks!

 

 

Aug 11, 2009 at 1:35 AM

Pavan, there is a bug in InProcessSameThread where it can only find resources within the window.xaml file.  If you use InProcessSeparateThread, then it should work correctly.  For InProcSeparateThread, however, you can only do operations inside a dispatcher.  For example:

        string sampleAppPath = Path.Combine(Environment.CurrentDirectory, "SampleApp.exe");
        var a = new InProcessApplication(new WpfInProcessApplicationSettings
        {
            Path = sampleAppPath,
            InProcessApplicationType = InProcessApplicationType.InProcessSeparateThread,
            ApplicationImplementationFactory = new WpfInProcessApplicationFactory()
        });
        a.Start();

        try
        {
            a.WaitForMainWindow(TimeSpan.FromSeconds(10));
            (a.ApplicationDriver as Application).Dispatcher.Invoke(DispatcherPriority.Normal,
                (ThreadStart)delegate
                {
                    var mainWindow = a.MainWindow as Window;
                    mainWindow.Activate();
                    var inputTextBox = TestHelper.GetVisualChild<TextBox>(mainWindow);

                    //
                    // Click on the input text box and simulate typing
                    //
                    var clickPointWPF = inputTextBox.PointToScreen(new Point(2, 2));
                    var clickPoint = new System.Drawing.Point();
                    clickPoint.X = (int)clickPointWPF.X;
                    clickPoint.Y = (int)clickPointWPF.Y;
                    Microsoft.Test.Input.Mouse.MoveTo(clickPoint);
                    a.WaitForInputIdle(DefaultTimeoutTimeSpan);

                    Microsoft.Test.Input.Mouse.Click(System.Windows.Input.MouseButton.Left);
                    a.WaitForInputIdle(DefaultTimeoutTimeSpan);

                    string inputText = "TestTest";
                    string expectedText = inputText + "\n";
                    Microsoft.Test.Input.Keyboard.Type(inputText);
                    a.WaitForInputIdle(DefaultTimeoutTimeSpan);

                   ....
                });

 

Aug 11, 2009 at 2:31 AM

Hi Vincent,

         Thanks for the speedy response. The InProcessSeparateThread does the trick. Now this gives me confidence to try out some of the more complex tests :)

 

Cheers!

Pavan

 

 

Aug 11, 2009 at 1:04 PM

That's great.  I'd also love to hear your feedback on how the InProcessSeparateThread works for you.  When we designed it, we had to think long and hard about usability and due to resource constraints made the decision to just have it work with the Dispatcher as I describe above.  It does feel like an annoying extra step but I'm sure you realize why it's necessary.  Anyway, any feedback would be much appreciated for future iterations.  Thanks!

Aug 11, 2009 at 2:56 PM

Vincent,

           The InProcess app is a natural choice for me since working with AutomationElements in OutOfProcess is kind of awkward and limited in the amount of introspection. Some of my custom controls are fairly specialized and can't be

represented faithfully with the control patterns. I think Microsoft should spend equal or more efforts on this scenario by providing convenience methods and helpers. It is certainly more powerful and close to native WPF tree compared

to the Automation tree. The use of Dispatcher is certainly a detail that one can hide through API abstractions. Better yet, languages like F# and IronPython can reduce the syntactic noise and make it a better experience :)

 

I'll let you know the pain points as I explore this further.

Sep 2, 2009 at 11:05 AM

Totally agree on "...providing convenience methods and helpers. It is certainly more powerful and close to native WPF tree compared to the Automation tree.".

In-process application control seems to be the only way to manipulate tricky UI controls which are not accessible using UIAutomation approach.