cancel
Showing results for 
Search instead for 
Did you mean: 

Accessing Sub Menu Items from Context Menu

RandyJ5150
Occasional Contributor

Accessing Sub Menu Items from Context Menu

This is my first question to the community.  I'm testing a WPF app with TC v12.60 and trying to access sub menu items from a context menu generated from a right-click on an object.

 

The context menus are as follows:

  • ContextMenu_Item1
  • ContextMenu_Item2
    • SubMenu1_Item1
      • SubMenu2_Item1
      • SubMenu2_Item2
    • SubMenu_Item2
  • etc.

The object that gets the right-click is in a ListView.  I generate the right click as follows:

Aliases.MyApp.HwndSource_mainWindow.mainWindow.tabControl1.listBoxDevices.ClickItemR(0)

 

I then access the contextmenu as follows:

contextmenu = Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot

 

I can navigate the submenus as follows:

 

# Hover mouse over a menu item at X,Y coordinate

contextmenu.HoverMouse(60, 100)
Delay(500)

 

#Submenu1
mouseX = Sys.Desktop.MouseX
mouseY = Sys.Desktop.MouseY
mouseX = mouseX + contextmenu.Width
submenu1 = Sys.ObjectFromPoint(mouseX, mouseY)
objectPoint = submenu1.ScreenToWindow(mouseX, mouseY)
submenu1.HoverMouse(objectPoint.X, objectPoint.Y)
Delay(500)

 

#Submenu2
mouseX = Sys.Desktop.MouseX
mouseY = Sys.Desktop.MouseY
mouseX = mouseX + submenu1.Width
submenu2 = Sys.ObjectFromPoint(mouseX, mouseY)
objectPoint = submenu2.ScreenToWindow(mouseX, mouseY)
Delay(500)


submenu2.Click(objectPoint.X, objectPoint.Y)

 

This all works to click the menus, but I really want to access the menus by name instead of X,Y coordinates.  What is the best way to access the menu items by Header name or even by WPF Object name?

 

 

 

10 REPLIES 10
shankar_r
Community Hero

Re: Accessing Sub Menu Items from Context Menu

TestComplete provides access to popup menu objects. 

 

Have you tried below,

  1. Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.Click("<ITem name or Index>")
  2. Aliases.MyApp.HwndSource_mainWindow.mainWindow.tabControl1.listBoxDevices.Items(0).Popup.Clcik("<ITem name or Index>")
  3. If you are not able to find a solution with above two steps then try to record the action and see how TestComplete clicks. You will find a idea here.

Still you are not able to resolve prove some snapshots of Object properties etc.


Thanks
Shankar R

LinkedIn | CG-VAK Software | Bitbucket | shankarr.75@gmail.com

“You must expect great things from you, before you can do them”

Extension Available

RandyJ5150
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

The recorded action converted to the following steps:

Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.Click(58, 105)
Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.Click(68, 11)
Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.Click(64, 15)

 

The image snapshots for each step above showed the correct submenu, but when run, all of the clicks occured in the first-level menu, not the submenus.  Additionally, these are still based on relative X,Y coordinates of the object.  I would like to access the menu items by name, header, or possibly even a tag in the WPF object.

 

The TC Click Action accepts X,Y coordinates, so name or index will not work as parameters there.

 

Others report success using FindChild, but I have not been able to get FindChild to return the menu item object.

 

The object returned by Point and Fix object:
Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.WPFObject("Decorator", "", 1).WPFObject("NonLogicalAdornerDecorator", "", 1)

 

I'm thinking I need to poke around this object somehow.

 

RandyJ5150
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

Poking around the Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.WPFObject("Decorator", "", 1).WPFObject("NonLogicalAdornerDecorator", "", 1) object has been enlightening, but I cannot figure out how to access the menu items by name.  I know this has been solved because I see other solutions.  Can someone help me understand what I'm working with?

 

While poking around, I did write the following snippet and received the following results.  Am I barking up the right tree or pursuing a futile course of action?  Can someone explain what these object are?

 

 

Script:

# Attempting to figure out how to access context menu items by names, so far unsuccessful
arrayproperties=["ClrClassName"]
arrayvalues=["*"]
something = Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.FindAll(arrayproperties, arrayvalues, 100, True)
for x in range(len(something)):
  Log.Message("something[" + str(x) + "]" + something[x].ClrClassName + ", " + something[x].Name)
  somethingelse = something[x].FindAll(arrayproperties, arrayvalues, 100, True)
  for y in range(len(somethingelse)):
    Log.Message("somethingelse[" + str(y) + "]" + somethingelse[y].ClrClassName + ", " + somethingelse[y].Name)

 

Output:

something[0]PopupRoot, WPFObject("PopupRoot", "", 1)
somethingelse[0]PopupRoot, WPFObject("PopupRoot", "", 1)
somethingelse[1]Decorator, WPFObject("Decorator", "", 1)
somethingelse[2]NonLogicalAdornerDecorator, WPFObject("NonLogicalAdornerDecorator", "", 1)
somethingelse[3]AdornerLayer, WPFObject("AdornerLayer", "", 2)
somethingelse[4]AdornerLayer, WPFObject("AdornerLayer", "", 1)
something[1]Decorator, WPFObject("Decorator", "", 1)
somethingelse[0]Decorator, WPFObject("Decorator", "", 1)
somethingelse[1]NonLogicalAdornerDecorator, WPFObject("NonLogicalAdornerDecorator", "", 1)
somethingelse[2]AdornerLayer, WPFObject("AdornerLayer", "", 2)
somethingelse[3]AdornerLayer, WPFObject("AdornerLayer", "", 1)
something[2]NonLogicalAdornerDecorator, WPFObject("NonLogicalAdornerDecorator", "", 1)
somethingelse[0]NonLogicalAdornerDecorator, WPFObject("NonLogicalAdornerDecorator", "", 1)
somethingelse[1]AdornerLayer, WPFObject("AdornerLayer", "", 2)
somethingelse[2]AdornerLayer, WPFObject("AdornerLayer", "", 1)
something[3]AdornerLayer, WPFObject("AdornerLayer", "", 2)
somethingelse[0]AdornerLayer, WPFObject("AdornerLayer", "", 2)
something[4]AdornerLayer, WPFObject("AdornerLayer", "", 1)
somethingelse[0]AdornerLayer, WPFObject("AdornerLayer", "", 1)

 

RandyJ5150
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

No solution found on how to access context menu items by Name or by Header name.

brohrbacher
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

@RandyJ5150 

 

Did you ever get the items in the Context menu to work based on their names? Having the same issue right now. 

RandyJ5150
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

I haven't revisted the project in a very long time.  I will go back and review where we left-off.  I don't think we ever found a fool-proof solution, but I'll let you know where we ended-up.

tristaanogre
Community Hero

Re: Accessing Sub Menu Items from Context Menu

While I don't recommend keeping unedited Mappings and code from a recording for your final test, have you tried recording interacting with the context menu?  What happens when you use Object Spy?  


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
brohrbacher
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

@tristaanogre 

 

Object spy sees it as a context menu which is a good sign. However, my problem is that I have items like "Add..., Remove..., Properties..., etc.) which TestComplete recognizes (they get highlighted in the menu) but the actual Click that I want doesn't occur. In other words, TestComplete is highlighting (hovering over) the items in the list and not actually clicking on them.  I even tried using integers like 0,1,2,3 (which is something I don't want to do for obvious reasons) but that method didn't work.

 

It recognizes that it's a popup context menu and works when I use X,Y coordinates within the context menu and a click occurs. 

 

I have tried various methods from the documentation and other support cases but can't seem to get anywhere and this issue seems to fall in line with mine. 

RandyJ5150
Occasional Contributor

Re: Accessing Sub Menu Items from Context Menu

When we recorded keyword tests, the recording would save the wrong objects from name-mapping. It was over a year-ago and my memory is a little vague, but the results were not what we expected, and we had trouble discerning what we needed.

 

Here's a Test Visualizer image of the context menu's.  I believe this was produced with the code below.

 

TestVisualizerContextMenus.png

Three level context menu accessed by right-clicking on an object

 

Sample Code:

This is the code where we left-off.  Maybe it will give you some ideas.

The code:

#. Set the scroll position
#. right-click an item in a listbox to cause the 1st level context menu to popup
#. Call FindAll on PopupRoot and call FindAll of the result to log the results for viewing/debugging (trying to find accessible objects)
#. Hover the mouse over 1st level menu (looks like the coordinates are hard-coded)
#. Determine positionally (x,y) where level 2 submenu is
#. Hover the mouse over the level 2 submenu to cause the 3rd level menu to popup
#. Determine the position of an item in the 3rd level menu by adding the width of the 2nd level menu
#. Click on the determined position

 

Hopefully this will help you find a path forward.  I'm sure we will need to revisit this in the future.  We desperately need a solution.  We use context menu's in many places.

 

# Script is not complete.
# TODO: need to figure out way to access multi-level context menu items

import ScriptGetMCU

def SystemDiagramOnline1():
    Aliases.CrewWare.HwndSource_mainWindow.mainWindow.tabControl1.scrollViewer1.VScroll.Pos = 0
    Aliases.CrewWare.HwndSource_mainWindow.mainWindow.tabControl1.scrollViewer1.HScroll.Pos = 0

    x = ScriptGetMCU.GetMCUIndex()
    Aliases.CrewWare.HwndSource_mainWindow.mainWindow.tabControl1.listBoxDevices.ClickItemR(x)

    # Attempting to figure out how to access context menu items by names, so far unsuccessful
    arrayproperties=["ClrClassName"]
    arrayvalues=["*"]
    something = Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot.FindAll(arrayproperties, arrayvalues, 100, True)
    for x in range(len(something)):
      Log.Message("something[" + str(x) + "]" + something[x].ClrClassName + ", " + something[x].Name)
      somethingelse = something[x].FindAll(arrayproperties, arrayvalues, 100, True)
      for y in range(len(somethingelse)):
        Log.Message("somethingelse[" + str(y) + "]" + somethingelse[y].ClrClassName + ", " + somethingelse[y].Name)

    contextmenu = Aliases.CrewWare.HwndSource_PopupRoot.PopupRoot
    contextmenu.HoverMouse(60, 100)
    Delay(500)
    
    #Submenu1
    mouseX = Sys.Desktop.MouseX
    mouseY = Sys.Desktop.MouseY
    mouseX = mouseX + contextmenu.Width
    submenu1 = Sys.ObjectFromPoint(mouseX, mouseY)
    objectPoint = submenu1.ScreenToWindow(mouseX, mouseY)
    submenu1.HoverMouse(objectPoint.X, objectPoint.Y)
    Delay(500)

    #Submenu2    
    mouseX = Sys.Desktop.MouseX
    mouseY = Sys.Desktop.MouseY
    mouseX = mouseX + submenu1.Width
    submenu2 = Sys.ObjectFromPoint(mouseX, mouseY)
    objectPoint = submenu2.ScreenToWindow(mouseX, mouseY)
    Delay(500)
    submenu2.Click(objectPoint.X, objectPoint.Y)

 

New Here?
Join us and watch the welcome video:
Announcements
Top Kudoed Authors