How can i verify if a Contextmenu exists upon right click? - testcomplete

I need to verify if a right click menu/Context menu appears on clicking a specific element in my WPF application.
At present, my script fails when i use the entire reference of the Context menu after the right-click. Is Find Child a good option?
I am using TC9 and jscript.
Thanks in advance!

Yes, you can use the FindChild method to make sure that an object exists and visible. For example:
function Test1()
{
var orders = Sys.Process("Orders");
var listView = orders.WPFObject("HwndSource: MainForm").WPFObject("MainForm").WPFObject("gridMain").WPFObject("OrdersView");
listView.ClickR(106, 82);
var menu = orders.FindChild(["NativeClrObject.Name", "VisibleOnScreen"], ["ViewContextMenu", true], 10);
if (menu.Exists)
Log.Message("The menu is displayed");
else
Log.Error("The menu is not displayed");
}
A tricky thing here can be getting the properties of the context menu object since it can be not listed in the Object Browser while the menu is not displayed. To overcome this, use the Object Spy tool with the Point to the object and fix feature.

Related

Get item that caused context menu to open?

Is there a way to get the element the user right clicked on to open a context menu?
( The only method i see is looking for an item with .k-state-focused.. hopefully, there is a better way )
edit: in my code context menus are created using a filter and not a target.
You can find it in target field of the event object received by you Event Handler.
Example:
$("#container").on("contextmenu", function(e) {
console.log("target", e.target);
});
See an example here: http://jsfiddle.net/OnaBai/crobgjyf/

Make a click event based on a control's name value property

I'm using TestComplete for the automation of QA process.
TestComplete detects click events based on the postion of the mouse on the screen. But when I run the same test on a different machine (a larger/smaller screen) the mouse button won't click on the correct position.
Therefore I want to know is there a method which I can search a control based on its name (i.e. name of a button) and then run a script to click on that particular word (or position).
Any help is appreciated :)
Additional Details
This is a sample script generated by TestComplete for clicking the search button on a web page.
Sub Test6()
'Opens the specified URL in a running instance of the specified browser.
Call Browsers.Item(btIExplorer).Navigate("http://www.simplyrecipes.com/search/?cx=003084314295129404805%3Ai2-mkfc4cai&cof=FORID%3A11&q=&sa.x=48&sa.y=16")
'Clicks at point (173, 10) of the 'textboxQ' object.
Call Aliases.browser.pageHttpWwwSimplyrecipesComSearc.panelPage.headerMasthead.group.panelSiteSearch.formSearchbox0030843142951294048.textboxQ.Click(173, 10)
'Sets the text 'asd' in the 'textboxQ' text editor.
Call Aliases.browser.pageHttpWwwSimplyrecipesComSearc.panelPage.headerMasthead.group.panelSiteSearch.formSearchbox0030843142951294048.textboxQ.SetText("asd")
'Clicks at point (57, 12) of the 'imagebuttonSa' object.
Call Aliases.browser.pageHttpWwwSimplyrecipesComSearc.panelPage.headerMasthead.group.panelSiteSearch.formSearchbox0030843142951294048.imagebuttonSa.Click(57, 12)
End Sub
Here is the button click event captured in the RecordTest window
What I want to know is, is there a way I can specify the control name (i.e 'Search' or 'imagebuttonSa'), so the TestComplete will search for the name in the given GUI and then once it's found, make a click event on the word.
I'm using Windows 7 64bit OS, TestComplete 9 trial version and VBScript as the scripting language.
As far as I can see, TestComplete already works in your case with specific controls/objects: textboxQ and imagebuttonSa. These two names are given to objects by the Name Mapping functionality and you are free to change them as you like.
As for the coordinates, these coordinates are related to the top left corner of the corresponding control (textboxQ or imagebuttonSa). If you want, you can remove the coordinates from the action parameters (e.g. ...imagebuttonSa.Click()) and TestComplete will click the central point of the control.
In case you have any problems with playing back your tests and you cannot find out what the cause of these problems is, the best option for you will be contacting the SmartBear support team with detailed explanation of what happens. Send them your project with failed results logs.
Whenever I have a problem with not finding an object with TC I use one of this functions or a combination of them.
In case you have the table object (parent of the cell you want to click):
function clickCellByText(text,tablePath)
{
var table = tablePath;
if (!table.Exists)
{
Log.Error("A table with the following text cannot be found: " + table);
}
clickCell1(table, "*Cell*", "*Cell*");
function clickCell1(table, idText, linkText)
{
var propArray = new Array("innerText", "ObjectType");
var valArray = new Array(text,"Cell*");
var idCell = table.FindChild(propArray, valArray, 20000);
if (idCell.Exists)
{
// Row found, find the link in the same row
idCell.Click();
}
else
{
Log.Error("A cell with the following text cannot be found: " + text);
}
}
}
If you want to find the object or the parent of the object by any property:
function clickComponent(property,text)
{
// Using the Find method
var myObj = Sys.Browser("iexplore").Page("*").NativeWebObject.Find(property,text);
// Checks if the button exists
if (myObj.Exists)
{
myObj.Click();
}
else
Log.Error("Can't find the object","");
}
If you don't specify co-ordinate, it will click at the center of the object.
You can try doing FindChild or Find with the Object Name Mapping where the button resides, with Properties like (Eg:ObjectType as Button and Button Caption with your required button caption), once the FindChild finds the button with above specified properties you can use that object to click on it:
var button = ParentObj.FindChild(["ObjectType","Caption"],["Button","OK"],10);
if(button.Exists)
button.Click()

How to call the same function that the ToolBar editbutton does

So I have created a context box upon right click that has Add/Edit/Delete Rows. I also have a bunch of code launched before the Dialog is shown. My problem is that when I use the context menu it doesn't go through some of the code. I have tried to call on the functions directly but it doesn't format correctly.
I am mainly concerned with the edit button, here is the code I am using to bring up the edit Dialog
function editRow() {
var grid = jQuery("#<%= Jqgrid1.ClientID %>");
var rowKey = grid.getGridParam("selrow");
if (rowKey) {
// I have tried calling functions here and it still doesn't work
grid.editGridRow(rowKey, grid.editDialogOptions);
}
else {
alert("No rows are selected");
}
}
So if I use this to display the editform it isn't formatted correctly nor does it go through the functions all correctly.
I am using the ASP Webforms version of Jqgrid so I call the function by doing this
<cc1:JQGrid1 ID="Jqgrid1
//other attributes
ClientSideEvents-BeforeEditDialogShown="ChangeMonitor"
//Rest of code />
So this works just fine, and I'm trying to get the Edit button on the context menu to display correctly.
My thought was to use Jquery to trigger a click on the actual Edit button once someone used the context menu. I couldn't find an ID that would work however.
Is there an easy way to connect my context menu Edit button, with the actual Edit button in the toolbar?
Well I found a solution to my problem.
The id field of the button was edit_ct100_cpMainContent_Jqgrid1_top so I just triggered a click with this code.
$("td[id^=edit][id$=top]").trigger("click")
For some reason when I used the _ct100_cpMainContent_Jqgrid1 it wasn't working, but now it does. Hope this helps someone.

How to Get Submenu in MFC?

I'm trying to get a submenu so that I can make changes to it before it is displayed.
So I created an OnInitMenu() handler for my window. And I had planned to use pMenu->GetMenuItemInfo() to get the submenu.
However, it doesn't appear this will work. In order to locate the menu I want, I must supply the menu command ID (I do not consider it satisfactory to hard code item positions). But menu items that open submenus do not have command IDs. I can get a menu command that exists inside that submenu, but then I still don't have the menu itself.
How can I locate a submenu nested in my main menu, without relying on MF_BYPOSITION?
My solution to this same problem was to create a helper function to search through the menu and return the position based on the name of the menu.
int CEnviroView::FindMenuItem(CMenu* Menu, LPCTSTR MenuName) {
int count = Menu->GetMenuItemCount();
for (int i = 0; i < count; i++) {
CString str;
if (Menu->GetMenuString(i, str, MF_BYPOSITION) &&
str.Compare(MenuName) == 0)
return i;
}
return -1;
}
It appears the answer is that you can't. Using command IDs to locate a menu command makes great sense because such code will continue to work as you rearrange menu items. However, menu items that are sub menus simply do not have a command ID.
One approach is to have a known menu command, which you can search for by ID, and then insert new items next to that command. However, you still need the containing menu.
The approach I ended up using resulted from studying the code MFC uses to populate the most recently used file list in the File menu. The general technique is described in the somewhat dated Paul DiLascia's Q & A column from Microsoft Systems Journal.
It would be much simpler to use MFC Command routing that allows you to update menu items?
If this is MDI/SDI application you have it for free if not you will have to implement update mechanism.
Do not handle WM_INITMENU. You should handle WM_INITMENUPOPUP. WM_INITMENUPOPUP delivers pointer to the menu that is just about to popup.
In the handler you can write a code that will allow dialog updating specific menu items using UI update mechanism fo all menus, or you can handle only a change to the specific menu item you have to alter in the handler.
You can use the method GetSubMenu from the class CMenu.
http://msdn.microsoft.com/en-us/library/dtfc356x(v=vs.80).aspx

Prism 4: Unloading view from Region?

How do I unload a view from a Prism Region?
I am writing a WPF Prism app with a Ribbon control in the Shell. The Ribbon's Home tab contains a region, RibbonHomeTabRegion, into which one of my modules (call it ModuleA) loads a RibbonGroup. That works fine.
When the user navigates away from ModuleA, the RibbonGroup needs to be unloaded from the RibbonHomeTabRegion. I am not replacing the RibbonGroup with another view--the region should be empty.
EDIT: I have rewritten this part of the question:
When I try to remove the view, I get an error message that "The region does not contain the specified view." So, I wrote the following code to delete whatever view is in the region:
// Get the regions views
var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
var ribbonHomeTabRegion = regionManager.Regions["RibbonHomeTabRegion"];
var views = ribbonHomeTabRegion.Views;
// Unload the views
foreach (var view in views)
{
ribbonHomeTabRegion.Remove(view);
}
I am still getting the same error, which tells me there is something pretty basic that I am doing incorrectly.
Can anyone point me in the right direction? Thanks for your help.
I found my answer, although I can't say I fully understand it. I had used IRegionManager.RequestNavigate() to inject the RibbonGroup into the Ribbon's Home tab, like this:
// Load RibbonGroup into Navigator pane
var noteListNavigator = new Uri("NoteListRibbonGroup", UriKind.Relative);
regionManager.RequestNavigate("RibbonHomeTabRegion", noteListNavigator);
I changed the code to inject the view by Registering it with the region, like this:
// Load Ribbon Group into Home tab
regionManager.RegisterViewWithRegion("RibbonHomeTabRegion", typeof(NoteListRibbonGroup));
Now I can remove the RibbonGroup using this code:
if(ribbonHomeTabRegion.Views.Contains(this))
{
ribbonHomeTabRegion.Remove(this);
}
So, how you inject the view apparently matters. If you want to be able to remove the view, inject by registration with the Region Manager
StockTraderRI Example Project by Microsoft contains the following example of removing views from region in ViewModel.
private void RemoveOrdersView()
{
IRegion region = this._regionManager.Regions[RegionNames.ActionRegion];
object ordersView = region.GetView("OrdersView");
if (ordersView != null)
{
region.Remove(ordersView);
}
}
Is it possible you have a RegionAdapter that is wrapping the view inside another view before adding it? The ribbonHomeTabRegion should have a property with the collection of views - is there anything inside it?

Resources