Strange Object Not Found Exception

Ask general questions here.
User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Strange Object Not Found Exception

Post by Ciege » Fri Apr 10, 2009 9:38 pm

I have an area of my automation code that opens a dialog, searches for and clicks a radio button by it's control name.

When the radio button is searched for during a complete run of my automation (i.e. other forms are opened, manipulated, closed, etc...) I get an exception:

Code: Select all

Ranorex.ElementNotFoundException: No element found for path './/self::radiobutton[@controlname='rbOptionFile']' within 10s. at Ranorex.Core.Element.FindSingle(RxPath path, Duration timeout) at Ranorex.Adapter.FindSingle(RxPath path, Duration timeout) at H_ReportsTest.Program.RadioButtonClick(Form RanorexFormName, String RadioButtonName) in C:\Documents and Settings\Admin\My Documents\Visual Studio 2008\Projects\H$ReportsTest\H$ReportsTest\Program.cs:line 1223 
If I leave that dialog open, comment out the automation code before the search and just search for the radiobutton on that dialog it works. I can also look at the dialog with Ranorex Spy right before and/or right after the exception and verify that the radio button does in fact exist with the correct controlname.

Another starnge thing is when I get the exception, the CPU pegs to 100% during the find. When I run the code with commenting out the steps prior and it does find the radio button the CPU stays at a nomal percentage level.

The code used to search for the radio button (from within my own method) is:

Code: Select all

RanorexFormName.EnsureVisible();
RanorexFormName.Activate();
Thread.Sleep(1000);
HDradiobutton = RanorexFormName.FindSingle(".//radiobutton[@controlname='" + RadioButtonName + "']", 10000);
As you can see I ensure the form to search is visible and activated before I search for the radio button so it doesn't appear like a timing issue.

Any pointers or ideas you can share with me to help figure out this issue? Or any other information you need?

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Fri Apr 10, 2009 10:08 pm

As an update I've tried the following.

1) I've added a messagebox.show after the form is found and before the radio button is searched for just to make sure (in my mind) that the form is ready.

2) I've tried instead of searching for the radio button, setting the radio button manually based on what Spy finds:

Code: Select all

HDradiobutton = "/form[@controlname='ReportPrintForm']/container[@controlname='panelOptions']/radiobutton[@controlname='rbOptionFile']";
Even with #2 above I get this exception:

Code: Select all

[2009/04/10 14:03:17.781][Error  ][User]: Ranorex.ElementNotFoundException: No e
lement found for path '/form[@controlname='ReportPrintForm']/container[@controln
ame='panelOptions']/radiobutton[@controlname='rbOptionFile']' within 5000ms.
   at Ranorex.Core.Element.FindSingle(RxPath path, Duration timeout)
   at Ranorex.Core.Element.op_Implicit(String path)
   at Ranorex.RadioButton.op_Implicit(String path)
   at H_ReportsTest.Program.RadioButtonClick(Form RanorexFormName, String RadioB
uttonName) in C:\Documents and Settings\Admin\My Documents\Visual Studio 2008\Pr
ojects\H$ReportsTest\H$ReportsTest\Program.cs:line 1223

Now I KNOW the form is active and ready and I KNOW the radio button is there. (at least I see it with my eyes and Spy sees it with the RanoreXPath entered above).

I'm stumped...

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Tue Apr 14, 2009 3:56 pm

Hey Support,
Do you guys have any thoughts or ideas on this? Once I hit this error I am unable to continue my script. I've noticed that it is not just the RadioButton control that gets "lost", it's all controls on the form that become unrecognizable. I've had to, in the mean time, just assume that the correct RadioButton is selected (which in this case it usually is) and just do a send keys to press {ENTER} to simulate clicking the OK button (which is also no longer recognized when this error manifests).

Thanks...

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Post by Support Team » Tue Apr 14, 2009 4:56 pm

Hi Ciege!

Sorry that we could not reply earlier to your post, everyone was on Easter holidays and we had to discuss that strange error :-)

The CPU should only go to (and stay at) 100% during the search if the subtree you are searching is not traversed completely. In other words, it seems like thousands of elements are searched and there are still elements that should be searched in that subtree when the timeout is reached.
Now, the odd thing is, you sayed that spying that element or searching for it in a separate run works smoothly. So, consequently something has to be different in the full test run. Currently, I can only think of the following reasons:
- the RanorexFormName form has thousands of elements more than usual
- the RanorexFormName variable corresponds to a false form (another form has the same RxPath and you are searching in that form)
- the element you are searching for changed it's control name
- there's a bug in Ranorex that prevents it to get the control name from the radio button (but then spying the control should not work either).

You already proved some of these explanations wrong, I guess. I'm a little stumped myself :?
How many elements are on that form? Could you send a sample application that the error happens with to support_at_ranorex.com? Then we could try to debug what's happening.

Regards,
Alex
Ranorex Support Team

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Tue Apr 14, 2009 5:54 pm

Well of course the answer for a sample app is no. :-) Isn't that always the case?

RE #1 - Thousands of elements:
The form in question is a simple Print dialog. It contains 5 RadioButtons, 6 Text elements, 2 PushButtons and a ComboBox. Pretty simple stuff.

RE #2 - the RanorexFormName variable corresponds to a false form (another form has the same RxPath and you are searching in that form):
I use a method of mine to pass in a form object and the string control name of what I want to click on. The method searches the form I pass in and finds (or not) the object to click (in this case a RadioButton) then clicks it. The method verifies the form is available and active before the search initiates so I know the form is valid, if it weren't I would suspect I would get an exception that it could not find the form in question. Using Spy before/after the exception also verifies that the form is correct.
Furthermore on this possibility, it works with the same print dialog several times before it fails. This automation script is basically individually selecting reports from out AUT and exporting them through the print dialog. There are more than 100 reports that I have to export and it works in the beginning but eventually fails.

RE #3 - the element you are searching for changed it's control name:
As I mentioned before, using Spy ensures me that the objects control name is correct and it works for several iterations before the failure. The Exception has the correct control name in it as well.

RE #4 - there's a bug in Ranorex:
Now that’s the question isn't it...

I can send you a screenshot of the form and/or output from RanorexSpy if that would help, or we can start going the debug route from you guys again. Please let me know.


P.S. Hope you all had a good Easter. My daughter learned the glorious wonders of Easter candy this past weekend. Ugh.... A 2 year old on a sugar high! What a blast... HA! :-)

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Post by Support Team » Wed Apr 15, 2009 3:12 pm

Ciege wrote:... or we can start going the debug route from you guys again
I still hope that we don't need that :-)

Could you please check the children (and descendants) of the form element once the error arises? Please, debug your code and watch the Children property of the Form! How many children are there? What type do they have?
Could you post the code that gets you the Form instance corresponding to the print dialog?
I'm still confused by the fact that RanorexSpy can spy the controls on your form after the error. And that the CPU goes to 100%, that should not happen if there are only a few elements in your form. Could you send a Ranorex snapshot of the dialog?

Regards,
Alex
Ranorex Support Team

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Wed Apr 15, 2009 5:08 pm

Here is the code I use to find the form. I will get the rest of the info you requested later today.

Call from main:

Code: Select all

Ranorex.Form HDReportPrintForm = null;
...
HDReportPrintForm = WaitForWindow("Print", 30);
WaitForWindow method:

Code: Select all

private static Ranorex.Form WaitForWindow(string WindowName, int Timeout)
{
    Ranorex.Form HDForm = null;
    int error = -1;
    bool boolFound = false;
    int intCount = 0;

    Report.Debug("Waiting for window: " + WindowName);
    while (boolFound == false)
    {
        try
        {
            HDForm = Host.Local.FindChild<Ranorex.Form>(WindowName);
            try
            {
                HDForm.Activate();
                error = 0;
                boolFound = true;
            }

            catch (RanorexException e)
            {
                error = -1;
                boolFound = false;
            }
        }

        catch (RanorexException e)
        {
            //Use DoEvents here so we don't get a ContextSwitchDeadlock error while debugging.
            Application.DoEvents();
            boolFound = false;
            Thread.Sleep(1000);
            intCount++;
            if (intCount == Timeout) break;
            error = -1;
        }
    }

    if (boolFound == true)
    {
        HDForm.Activate();
    }
    Thread.Sleep(1000);
    return HDForm;
} //End WaitForWindow

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Wed Apr 15, 2009 10:05 pm

How many children are there?
When the RadioButton click works correctly Ranorex reports that there are 5 children of the form.
When I get the Exception that the RadioButton was not found Ranorex reports that there are 2 children on the form.

I am using the following line of code to get the count:

Code: Select all

int ChildCount = RanorexFormName.Element.ChildIndex;
Report.Debug("Form Child Index Count: " + ChildCount);
EDIT: See note below later in this thread that I see I used the wrong method here by expecting ChildIndex to give me the child count on the form.

I'm not sure of the proper code to iterate all the children of a form and display their types. Can you help me with some C# to do that?

I will send an email to the support email with a Spy snapshot of the print dialog.
Last edited by Ciege on Thu Apr 16, 2009 12:19 am, edited 1 time in total.

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Wed Apr 15, 2009 11:00 pm

OK, here is what I got. (It's a kludge, but it seems to work). I know that there are supposed to be 5 children of the form (2 Container objects, 2 Button objects and 1 TitleBar object). So I wrote the following code:

Code: Select all

int ChildCount = RanorexFormName.Element.ChildIndex;
Report.Debug("Form Child Index Count: " + ChildCount);

IList<Ranorex.Container> Containers = RanorexFormName.FindChildren<Ranorex.Container>();
IList<Ranorex.Button> Buttons = RanorexFormName.FindChildren<Ranorex.Button>();
IList<Ranorex.TitleBar> TitleBars = RanorexFormName.FindChildren<Ranorex.TitleBar>();

foreach (Ranorex.Container Container in Containers)
{
    Report.Debug("Containers: " + Container.ToString());
}

foreach (Ranorex.Button Button in Buttons)
{
    Report.Debug("Buttons: " + Button.ToString());
}

foreach (Ranorex.TitleBar TitleBar in TitleBars)
{
    Report.Debug("TitleBars: " + TitleBar.ToString());
}
When everything works correctly the debug output is as follows:

Code: Select all

[2009/04/15 14:37:31.511][Debug  ][User]: Waiting for window: Print
[2009/04/15 14:37:36.996][Debug  ][User]: Form Child Index Count: 5
[2009/04/15 14:37:58.465][Debug  ][User]: Containers: {Container:panelOptions}
[2009/04/15 14:38:05.199][Debug  ][User]: Containers: {Container:panelPrinter}
[2009/04/15 14:38:10.965][Debug  ][User]: Buttons: {Button:OK}
[2009/04/15 14:38:12.715][Debug  ][User]: Buttons: {Button:Cancel}
[2009/04/15 14:38:19.371][Debug  ][User]: TitleBars: {TitleBar:Print}
When it fails and I have VS in debug mode, I see that:
ChildCount = 4
Containers -> count = 0
Buttons -> count = 0
TitleBars -> count = 1

So the debug output looks like this:
NOTE The time stamps here are a little funny looking because I had a breakpoint that I paused at, stepped through the code and spied on the form while this code was paused.

Code: Select all

[2009/04/15 14:47:46.496][Debug  ][User]: Waiting for window: Print
[2009/04/15 14:47:50.105][Debug  ][User]: Form Child Index Count: 4
[2009/04/15 14:54:03.480][Debug  ][User]: TitleBars: {TitleBar:Print}
While the debugger is paused on my breakpoint, after the foreach statements above are executed, but BEFORE the exception occurs I launch Ranorex Spy and I see all 5 expected children of the form.

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Thu Apr 16, 2009 12:16 am

I noticed that I was using the wrong code to get the child count on the form. I was using:

Code: Select all

int ChildCount = RanorexFormName.Element.ChildIndex; 
but should have been using:

Code: Select all

int ChildCount = RanorexFormName.Element.Children.Count;
Now that I have that straightened out, I get 5 for the child count when everything works and 5 for the child count when there is a failure. But as noted below, the container count and button count = 0 when the failure occurs.

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Post by Support Team » Thu Apr 16, 2009 2:55 pm

Ok, I think we get closer :-)
My guess is that when the exception occurs, the print form is not recognized as a Windows Forms control and neither are its children. I don't know why this should happen, but we should check that.

Could you please add another debug statement that prints out the Element.FlavorName property of the print form and its children? I.e. add the following code:

Code: Select all

Report.Debug("Form FlavorName: " + RanorexFormName.Element.FormName);
foreach (Unknown child in RanorexFormName.Children)
    Report.Debug(child + " FlavorName: " + child.Element.FlavorName);
Another thing I would be interested in is: What happens if you search for the form again after the error occurs? Does it ever work again or do you always get the error?

Thanks!

Regards,
Alex
Ranorex Support Team

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Thu Apr 16, 2009 4:34 pm

I had to tweak the code you sent because it wouldn't compile. This is how I tweaked it:

Code: Select all

Report.Debug("Form FlavorName: " + RanorexFormName.Element.FlavorName);
foreach (Unknown child in RanorexFormName.Element.Children)
    Report.Debug(child + " FlavorName: " + child.Element.FlavorName); 
This is the result I got:

Code: Select all

[2009/04/16 08:22:25.265][Debug  ][User]: Waiting for window: Print
[2009/04/16 08:22:28.046][Info   ][User]: Found Print Dialog.
[2009/04/16 08:22:29.203][Debug  ][User]: Form Child Index Count: 5
[2009/04/16 08:22:29.203][Debug  ][User]: Visible: True
[2009/04/16 08:22:29.203][Debug  ][User]: Form FlavorName: win32
[2009/04/16 08:22:29.328][Debug  ][User]: {Unknown:MainInterface} FlavorName: win32
[2009/04/16 08:22:29.343][Debug  ][User]: {Unknown:MainInterface} FlavorName: win32
[2009/04/16 08:22:29.343][Debug  ][User]: {Unknown:MainInterface} FlavorName: win32
[2009/04/16 08:22:29.343][Debug  ][User]: {Unknown:MainInterface} FlavorName: win32
[2009/04/16 08:22:29.343][Debug  ][User]: {TitleBar:Print} FlavorName: msaa
[2009/04/16 08:23:00.078][Debug  ][User]: TitleBars: {TitleBar:Print}

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Thu Apr 16, 2009 4:50 pm

Another thing I would be interested in is: What happens if you search for the form again after the error occurs? Does it ever work again or do you always get the error?
After the exception, if I add a call back to search for the form (with a new form object) and again do all the debug code and search for child objects I get the same results as above. So in short it would seem once it fails, it fails for good.

But as I said before, if I now stop the automation (i.e. stop debugging in VS) and restart the automation while leaving the print dialog up, skip all the automation that currently goes on and just search for the print dialog it all seems to just work:

Code: Select all

[2009/04/16 08:49:35.953][Debug  ][User]: Waiting for window: Print
[2009/04/16 08:49:42.468][Debug  ][User]: Form Child Index Count: 5
[2009/04/16 08:49:42.484][Debug  ][User]: Visible: True
[2009/04/16 08:49:42.484][Debug  ][User]: Form FlavorName: winforms
[2009/04/16 08:49:42.578][Debug  ][User]: {Container:panelOptions} FlavorName: winforms
[2009/04/16 08:49:42.578][Debug  ][User]: {Button:OK} FlavorName: winforms
[2009/04/16 08:49:42.578][Debug  ][User]: {Button:Cancel} FlavorName: winforms
[2009/04/16 08:49:42.593][Debug  ][User]: {Container:panelPrinter} FlavorName: winforms
[2009/04/16 08:49:42.593][Debug  ][User]: {TitleBar:Print} FlavorName: msaa
[2009/04/16 08:49:54.921][Debug  ][User]: Containers: {Container:panelOptions}
[2009/04/16 08:49:54.937][Debug  ][User]: Containers: {Container:panelPrinter}
[2009/04/16 08:49:54.937][Debug  ][User]: Buttons: {Button:OK}
[2009/04/16 08:49:54.937][Debug  ][User]: Buttons: {Button:Cancel}
[2009/04/16 08:49:54.937][Debug  ][User]: TitleBars: {TitleBar:Print}

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Post by Support Team » Thu Apr 16, 2009 4:59 pm

Ciege wrote: had to tweak the code you sent because it wouldn't compile.
Oh, sorry, I used the Adapter.Children property that will be added in Ranorex V2.1 :-)

The result is what I guessed, the elements inside your form are not identified as Windows Forms controls, but as simple Win32 windows. We have to dig into that :(

Please, confirm that I correctly understand the circumstances under which the error occurs:
- your application is a .NET Windows Forms app
- the print dialog is shown several times by the application in the same process, i.e. the main form opens the print dialog which is also a Windows Forms form
- you do not restart the application during the test
- you have a single testing application, i.e. a single process running Ranorex and the same process is running the whole test
- you do not have concurrent threads in your testing app that invoke Ranorex methods
- after the error occurs, you will always get the error, i.e. you can't successfully access the elements as usual (without getting an error).

Well, I think currently that's all the info we need. Thanks for your efforts!

Regards,
Alex
Ranorex Support Team
Last edited by Support Team on Fri Apr 17, 2009 8:02 am, edited 1 time in total.

User avatar
Ciege
Posts: 1336
Joined: Thu Oct 16, 2008 6:46 pm
Location: Arizona, USA

Post by Ciege » Thu Apr 16, 2009 5:07 pm

your application is a .NET Windows Forms app
Correct.
the print dialog is shown several times by the application in the same process, i.e. the main form opens the print dialog which is also a Windows Forms form
Correct.
you do not restart the application during the test
Correct.
you have a single testing application, i.e. a single process running Ranorex and the same process is running the whole test
Correct.
you do not have concurrent threads in your testing app that invoke Ranorex methods
Correct.
after the error occurs, you will always get the error, i.e. you can't successfully access the elements as usual (without getting an error).
Correct.


Can you send me an email so I can get your email address? I need to ask a question of you off line.

Thanks...