what does Object GetAttributeValue( string name ) return?

Class library usage, coding and language questions.
taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

what does Object GetAttributeValue( string name ) return?

Post by taralex » Mon Dec 01, 2008 5:38 pm

Guys,
I'm really stuck here, I depend greatly on the GetAttributeValue function, but not all the elements I browse through contain the specific attribute, that's why I check if it's not null in the following way:

Code: Select all

if (element.GetAttributeValue(attributeName) != (Object)null)
and this string throws a Null Reference exception on me. What do I do wrong? How should I check if the attribute is not there?

Thanx in advance.

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Mon Dec 01, 2008 6:10 pm

This is getting more and more weird..
to be able to evaluate what is returned by the function I'm using the following code:

Code: Select all

foreach (IElement elem in currentElement.Children)
{
    obj = elem.GetAttributeValue(attributeName);                            
    if (obj != (Object)null)
    {
          ....
     }
}
I watch the obj variable and it is null for the objects that don't have the specified attribute, exactly as I expect it.
But then after a couple of null objects have been successfully evaluated, it throws a Null Reference exception in the following string:

Code: Select all

obj = elem.GetAttributeValue(attributeName);      
how is it at all possible?

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Tue Dec 02, 2008 11:14 am

Could you please provide us the complete exception message including the stacktrace? Thx.

Regards,
Alex
Ranorex Support Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Tue Dec 02, 2008 4:35 pm

sure, here it is. the weird part is that this exception occurs randomly. Yesterday the code started to work exactly as I intended it to and today I again got the exception in the same place and I made no changes to the code..

Code: Select all

System.NullReferenceException was unhandled
  Message="Object reference not set to an instance of an object."
  Source="Ranorex.Plugin.WinForms"
  StackTrace:
       at Ranorex.Plugin.WinFormsFlavorElement.GetAttributeValue(IElement element, String name)
       at Ranorex.Core.Element.GetAttributeValue(String name)
       at bobcatTests.HelperFunctions.FindChildElement(IElement parentElement, List`1 attributeNames, List`1 attributeValues) in D:\work\Testing\C#\BobcatTests\BobcatTests\HelperFunctions.cs:line 633
       at bobcatTests.BobcatTestsForm.Temp_Click(Object sender, EventArgs e) in D:\work\Testing\C#\BobcatTests\BobcatTests\bobcatTests.cs:line 1232
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at bobcatTests.BobcatTestsForm.Main() in D:\work\Testing\C#\BobcatTests\BobcatTests\bobcatTests.cs:line 688
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Tue Dec 02, 2008 5:29 pm

By "randomly" you mean: 1) there is no particular attribute name the error occurs with or 2) there is no particular element the error occurs with?

What kind of control do you automate?
Are the automating and the automated application the same? I.e. does your application try to automate/inspect itself?

Regards,
Alex
Ranorex Support Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Tue Dec 02, 2008 7:20 pm

No, by randomly I mean that the error sometimes occurs and sometimes not.
However, when it occurs, it occurs for the same attribute name, and I'm pretty sure it occurs with the same element... I could try to find out which element it is if it can help..

I'm automating a whole appication, I don't know whether it inspects itself, probobly not..

In order to find the required elements by their attributes, I wrote a function that receives the parent element (usually the main application form, which I get using ElementRepository.CreateAdapterForPath), a list of attribute names, and a list of attribute values. I'm using this function everywhere, but sometimes it throws this null reference exception which undermines all my tests, because all of them use this function and potentially could fail. Here is the function:

Code: Select all

public static List<IElement> FindChildElement(IElement parentElement, List<string> attributeNames, List<string> attributeValues)
        {
            //this functions searches the tree of child Ranorex elements given the parent Ranorex element and returns a
            // collection of result passing the specified criteria.
            // an object passes if all its attributes listed in attributeNames collection have values specified 
            // in the attributeValues collection.

            List<IElement> result = new List<IElement>();
            Stack<IElement> elements = new Stack<IElement>(100);
            elements.Push(parentElement);
            if (attributeNames.Count != attributeValues.Count)
            {
                throw new ArgumentException("The number of items in both lists should be the same");
            }

            if (parentElement == null)
            {
                throw new ArgumentException("The parent element cannot be null");
            }
            if (parentElement.Children != null)
            {
                while (elements.Count > 0)
                {
                    IElement currentElement = elements.Pop();
                    foreach (IElement elem in currentElement.Children)
                    {
                        elements.Push(elem);
                        int validateelements = 0;
                        for (int i = 0; i < attributeNames.Count; i++)
                        {
                           
                            object obj;
                            string str = attributeNames[i];                           
this one throws the exception -->  obj = elem.GetAttributeValue(attributeNames[i]);                            
                            if (obj != null)
                            {
                                if (elem.GetAttributeValue(attributeNames[i]).ToString() == attributeValues[i])
                                {
                                    validateelements = validateelements + 1;
                                }
                            }
                           
                        }
                        if (validateelements == attributeNames.Count)
                        {
                            result.Add(elem);
                        }
                    }
                }
            }
            return result;
        }   

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Wed Dec 03, 2008 1:36 pm

Could you please tell me the name of the attribute that throws the exception? That would make searching for the bug a lot easier.

And please also post the build number of the Ranorex 2 Preview you use! (Click on the Ranorex sign in Ranorex Recorder or Spy to open the about dialog.)

Please remember that Ranorex 2 Preview is a technology preview only, not a full featured release. Hence, some features are not supported, yet, and there are quite a few bugs to be fixed. :)

Regards,
Alex
Ranorex Support Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Wed Dec 03, 2008 5:29 pm

I'm using version 2.0.0.4593
and I'm checking two attribute names: "ControlTypeName" and "ControlName".

Right now I can't tell you which causes the exception because now they both work fine, as I've told you, it's random, and I can't figure out any pattern behind the throwing of this exception. It is just sometimes thrown and sometimes not...

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Wed Dec 03, 2008 5:50 pm

I think I found some pattern.
It fails only for one of the controls (containers actually), while for 5 others of exactly same type it works fine. This one is different from the others only by its name (ControlName attribute): it is 'screen1' while the ones for which the exception is not thrown have ControlName attribute value of 'UserControl1'

now, after a couple of more tests, the above written is again sometimes true, and sometimes it fails on all controls that actuall has the required attributes.

one thing I'm sure of, and this might help you find the problem, is that the function doesn't fail if the element with the specified attribute name doesn't exist. I execute the function while the required application page is not open, and it is stable to return 0 elements, exactly as it is supposed to. Fun starts when I open the page actually containing the control I'm looking for, in this case it very often fails.

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Thu Dec 04, 2008 5:55 pm

Currently, I cannot reproduce that error, but I found a few code lines that look suspicious :)

It might be interesting what type of control the exception occurs with. And if the error occurs once, is it continuely thrown from then on until your application exits? Could you please describe the workflow your application/code?

Regards,
Alex
Ranorex Support Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Thu Dec 04, 2008 9:35 pm

I'm trying to get an object of Datasheet type. But the function parses all elements of the application and I am not sure where it throws the exception.

However! I have a strong reason to believe it is the same place where Ranorex Spy crashes when I try to get to the required element.
Here is the exception text reported by Ranorex Spy:

Code: Select all

System.NullReferenceException: Object reference not set to an instance of an object.
   at Ranorex.Libs.WinForms.ControlProxy.GetValue(String propertyName)
   at Ranorex.Plugin.WinFormsFlavorElement.GetPropertyValue[T](String propertyName)
   at Ranorex.Plugin.WinFormsFlavorElement.get_Visible()
   at Ranorex.Core.Element.GetVisible(CacheSession session)
   at Ranorex.Core.Element.get_Visible()
   at Ranorex.Controls.ElementTreeModel.CreateNodeFromElement(IElement elem)
   at Ranorex.Controls.ElementTreeModel.GetChildren(TreePath treePath)
   at Aga.Controls.Tree.TreeViewAdv.ReadChilds(TreeNodeAdv parentNode, Boolean performFullUpdate)
   at Aga.Controls.Tree.TreeViewAdv.SetIsExpanded(TreeNodeAdv node, Boolean value)
   at Aga.Controls.Tree.TreeViewAdv.SetIsExpanded(ExpandArgs eargs)
   at Aga.Controls.Tree.TreeViewAdv.SetIsExpanded(TreeNodeAdv node, Boolean value, Boolean ignoreChildren)
   at Aga.Controls.Tree.TreeNodeAdv.SetIsExpanded(Boolean value, Boolean ignoreChildren)
   at Aga.Controls.Tree.TreeNodeAdv.Expand(Boolean ignoreChildren)
   at Aga.Controls.Tree.TreeNodeAdv.Expand()
   at Ranorex.Controls.ElementTreeAdv.SelectElement(IElement element, Boolean updateTree, Boolean expandCurrent)
   at Ranorex.Controls.ElementTreeAdv.RefreshTree()
   at Ranorex.Controls.ElementTreeAdv.updateTreeNodeToolStripMenuItem_Click(Object sender, EventArgs e)
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I didn't compare, but something tells me the exception is the same as I'm getting in the GetAttribute method.

The strange part about it is, that in my application I have 5 pages with identical paths, I specifically copied and compared them, their RXPath are absolutely the same.
When I activate 4 out of these 5 pages, I can browse through all the elements both with Ranorex Spy and my function. But when I open the 5th one - I get a crash no matter what I use - spy or function.
It happens on the following control:
ControlName: designerRegion
ControlTypeName: OverlayControl

User avatar
Support Team
Site Admin
Site Admin
Posts: 11709
Joined: Fri Jul 07, 2006 4:30 pm
Location: Graz, Austria

Post by Support Team » Tue Dec 09, 2008 2:57 pm

We'll release a new Ranorex 2.0 Preview version by the end of the week with a whole lot of bugs fixed. Chances are good that this NullReference bug in the WinForms plugin is fixed, too.

Could you please post the RxPath of the elements that have exactly the same RxPath?

Regards,
Alex
Ranorex Support Team

taralex
Posts: 57
Joined: Tue Nov 04, 2008 3:50 pm
Location: Michigan
Contact:

Post by taralex » Thu Dec 11, 2008 4:17 pm

yea, here it is, if it can help you:

Code: Select all

/form[@controlname='BobCatSetupShellForm']/container/*/*/*/container[@controlname='mRightPanel']/container[@controlname='panelDesigner']/*/*/container[@controlname='designerRegion']