Cannot find WPF windows by "title"

Aug 3, 2010 at 9:20 AM
Edited Aug 3, 2010 at 12:09 PM

Update: Just to clarify, I am able to capture non WPF windows in the normal expected way (i.e. by "title") this problem just applies to the WPF windows in the application under test.

Ok here's the funny thing when I do this:

 List<Window> WinRecU = app.GetWindows();

 for (int i = 0; i < WinRecU.Count; i++)

{

WriteMessage(i+" title = " + WinRecU[i].Title);

}

The output I get is:

Elapsed Time

Description

ID

Details

00:00:01:765

Message

 

0 title = FiReControl [dcampbel]

00:00:01:766

Message

 

1 title = Recommend Unit

00:00:01:908

Message

 

2 title = Incident Information

00:00:01:909

Message

 

3 title = Incidents

00:00:01:910

Message

 

4 title = Resources

But when I do this:

Window WinRec = app.GetWindow("Recommend Unit");

The output is:

White.Core.UIItems.UIActionException: Couldn't find window with title Recommend Unit in process 5280, after waiting for 5000 ms

Name: WPFTest - Forecast Test Controller,  Bounds: 1676,-4,1688,1058 ProcessId: 3020, Modal: False

Name: forecast Studio : workspace = ICAD,  project = WinDriverSample,  Bounds: 1682,2,1678,1048 ProcessId: 796, Modal: False

Name: WinDriverSample - Microsoft Visual C# 2008 Express Edition,  Bounds: 1676,-4,1688,1058 ProcessId: 4184, Modal: False

  Name: Find and Replace,  Bounds: 2693,608,275,328 ProcessId: 4184, Modal: False

Name: white - New Thread - Windows Internet Explorer,  Bounds: 1896,-7,1296,990 ProcessId: 2724, Modal: False

Name: http://web.mail.com/?ws_popup=true - Mail.com Message Read - Windows Internet Explorer,  Bounds: 2127,129,897,657 ProcessId: 2724, Modal: False

Name: FiReControl [dcampbel],  Bounds: 0,0,1680,1020 ProcessId: 5280, Modal: False

  Name: Recommend Unit,  Bounds: 198,198,996,557 ProcessId: 5280, Modal: False

  Name: Incident Information,  Bounds: 6,41,780,1049 ProcessId: 5280, Modal: False

  Name: Incidents,  Bounds: 783,629,446,361 ProcessId: 5280, Modal: False

  Name: Resources,  Bounds: 1229,630,450,362 ProcessId: 5280, Modal: False

Name: Inbox - Microsoft Outlook,  Bounds: 1676,-4,1688,1058 ProcessId: 5056, Modal: False

Name: white_0.2.0,  Bounds: -4,-4,1688,1028 ProcessId: 724, Modal: False

Name: Visual UI Automation Verify,  Bounds: 1977,249,1260,747 ProcessId: 5572, Modal: False

 

   at White.Core.Factory.WindowFactory.<>c__DisplayClass3.<WaitTillFound>b__1()

   at Bricks.Core.Clock.Perform(Do do, Matched matched, Expired expired)

   at White.Core.Factory.WindowFactory.WaitTillFound(Do find, String message)

   at White.Core.Factory.WindowFactory.FindWindowElement(Process process, String title)

   at White.Core.Factory.WindowFactory.CreateWindow(String title, Process process, InitializeOption option, WindowSession windowSession)

   at White.Core.Application.GetWindow(String title, InitializeOption option)

   at White.Core.Application.GetWindow(String title)

   at WinDriverSample.WPFTest.Script()

   at Facilita.Fc.Runtime.ScriptIterator.CallScript(VirtualUserScript script, Int32 iteration)

   at Facilita.Fc.Runtime.ScriptIterator.DoIteration()

I can access the window with:

WriteMessage("windows[1] = " + windows[1].Title);

And this will output:

 windows[1] = Recommend Unit

However, I need to NOT use a find all and just find the required window.  The reason is to speed up performance as I am using this for performance testing.

Much appreciate any input.

Cheers,

David

Coordinator
Aug 6, 2010 at 5:38 PM
you have to first get the FiReControl window and then get modal window from it.
Aug 9, 2010 at 8:35 AM
Edited Aug 9, 2010 at 8:45 AM
Thanks for the advice.
I have actually been able to find the window as a modal but for some reason I am unable to access the modal window object.
Here is the code I am trying:
---------------------------------------------------------------------------------------------------------------------------		
	bool booRU;
            Process[] myProcess = Process.GetProcessesByName("idisp");
            Application app = Application.Attach(myProcess[0]);
            Window WinFC = app.GetWindow("FiReControl [dcampbel]");
            List modalWindows = WinFC.ModalWindows();
            WriteMessage("just did a .ModalWindows() and got the following windows back:");
            for (int i = 0; i < modalWindows.Count; i++)
            {
                WriteMessage(i + " title = " + modalWindows[i].Title);
            }
            WriteMessage("about to try and find modal window with title = \"Recommend Unit\"");
            Window WinRU = WinFC.ModalWindow("Recommend Unit");
            WriteMessage("about to try and access the modal window object:");
            booRU = WinRU.IsModal;
            WriteMessage("booRU = " + booRU);
---------------------------------------------------------------------------------------------------------------------------
Everthing works fine till I try access the object with "booRU = WinRU.IsModal" although I get the same result with trying
to assign the .Title or .Name property to a string.  Here is the error:
---------------------------------------------------------------------------------------------------------------------------

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

   at WinDriverSample.WPFTest.WPFTest2()

   at WinDriverSample.WPFTest.Script()

   at Facilita.Fc.Runtime.ScriptIterator.CallScript(VirtualUserScript script, Int32 iteration)

   at Facilita.Fc.Runtime.ScriptIterator.DoIteration()

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

Thanks again for your help with this, much appreciated.

Aug 9, 2010 at 10:29 AM

Hi

can you try

Window WinRU = modalWindows.Where (p=>p.Title == "Recommend Unit").First();

is the window null?

 

Throndorin

Aug 9, 2010 at 11:13 AM

Thanks Throndorin.  I tried this but I seem to be missing a reference, do you know which one I need for this to work?

Also this looks like it will be using a list which means it will have to return the entire list before finding the right one, which would not give me the performance I need.  The reason I need to identify the window individually is so that I can use the caching i.e.:

Window WinRU = WinFC.ModalWindow("Recommend Unit",InitializeOption.NoCache.AndIdentifiedBy("RecommendUnit"));
app.ApplicationSession.Save();

Really appreciate your support with this.

Cheers,

David

 


Aug 9, 2010 at 12:01 PM

 

Hey


I think you need

using System.Linq;

but did you think that ModalWindow("name") is faster than a list operationusing a Linq expression?

I'm not sure.

 

Throndorin

Aug 9, 2010 at 12:06 PM

Thanks Throndorin.  I'm not sure what is faster but I was hoping to speed up performance by using the caching as outlined above.  I only know how to do this by modalwindow("name")...

Aug 9, 2010 at 5:08 PM

Hi - I am also finding that ModalWindows() and ModalWindow("Title") do not work as expected.

They seem to be searching for different items.  Items in the list returned by ModalWindows() cannot always found using ModalWindow("Title")
(or other search criterea).   Conversly, a Window found using ModalWindow() does not always show in the list returned by ModalWindows().

Using the white-project WPF test application: WindowsPresentationFramework.exe as an example.
If you click the button "Launches Modal" to have the ModalForm diaplayed.

            Window w = Desktop.Instance.Windows().Find(obj => obj.Title.Contains("Form1"));
            List<Window> mws = w.ModalWindows();    AN EMPTY LIST

             Window mf = w.ModalWindow("ModalForm");  SUCCESS!

Close the modal dialog and click the "Button Launches MessageBox" to open the "Close Me" modal dialog.

List<Window> mws = w.ModalWindows(); SUCCESS - the list contains the "Close Me" dialog
Window
mf = w.ModalWindow("Close Me"); SUCCESS - returns the "Close Me" dialog

Finally using notepad, with the "Font" dialog diplayed, ModalWindows() returns a list containing the single expected "Font" modal dialog,
but ModalWindow("Font") fails.

Similary app.GetWindows(), returns a list with both the top-level and the Font window, but app.GetWindow("Font"); fails and raises an timed out exception.

The serious problem is being not being able to find windows using either get() or ModalWindow().  Finding other controls such a buttons, even on child windows seems to work OK.