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

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()

Related

Coded UI Test - Set UI property not returning (hanging indefinitely)

I am getting crazy with a problem that I found when executing a Visual Studio Coded UI Test.
The scenario is as follows.
I recorded a Coded UI Tests that do the following steps in a Web Application (Microsoft Dynamics CRM 2011):
Login into an application
Navigate into a page
On the page set the selected value of a html combobox
The test is able to do all those steps without a problem, even selecting the value in the combobox.
The web application have a piece of Javascript that is executed when the selected item changes.
if one of the values is selected then an alert message is presented to the user and the application will set the selected item to a default one!
The javascript code look like this:
switch (Xrm.Page.getAttribute("status").getValue()) {
case 3: //Authorised
alert("Please use the method XPTO to update the record status to Authorised!");
Xrm.Page.getAttribute("status").setValue(1);
Xrm.Page.getControl("tatus").setFocus(true);
return false;
The UI Test method that is performing the change in the combobox is as follows:
/// <summary>
/// Select a value in the Status dropdown box
/// </summary>
public void SelectStatus()
{
#region Variable Declarations
HtmlComboBox uIStatusComboBox = this.UIHttpsappWindow200.UIModuleUITEDocument5.UIWorkplaceDashboardsFrame.UIModuleUITEDocument.UIStatusComboBox;
// Select 'Authorised' in 'Status' combo box
uIStatusComboBox.SelectedItem = this.SelectStatus_SPParams.UIStatusComboBoxSelectedItem;
}
The test method is able to change the value in the combobox, and an alert message is displayed to the user. However this part of the code uIStatusComboBox.SelectedItem = this.SelectStatus_SPParams.UIStatusComboBoxSelectedItem;
never returns and the test just hangs there until it timeouts!
I have no ideia how to work arround this issue! I was thinking that maybe the problem could be in the fact that we have javascript code that is executed after the alert is displayed to the user. I changed the JS so that the alert message is the last thing to be displayed but it also didn´t help!
I also noticed that if I click Ok on the alert message the test Pass!
If I select other value that dont trigger any JS the test also Pass!
Does anyone have any idea about this issue?
Edit 1:
I noticed another thing, I can use the BrowserWindow object to send a JS script to the browser. If I try to create an alert message the call also gets blocked until I click on the Ok button, on the alert!
BrowserWindow bw = BrowserWindow.Locate("My window");
bw.ExecuteScript("alert('This is just a simple alert.');");
The ExecuteScript statement also gets blocked until I click on the OK button!
This seems very very strange!
I believe I have found a workaround.
I was googling to find anything that could help me with this issue and I end up finding this question on StackOverflow Coded ui test - Select an item from a combobox without using mouse coordinates
I try to select the same item in the Dropdown without using the "SelectedItem" property of the HtmlComboBox element.
I try to use the keyboard to select the element in the dropdown box, first I click on the Dropdown and then I use the Down key and Enter key to select the element that I want:
public void SelectStatus_SP(string SelectedItem)
{
#region Variable Declarations
HtmlComboBox uIStatusComboBox = this.UIHttpsappWindow200.UIpopupUITEDocument5.UIWorkplaceDashboardsFrame.UIpopupUITEDocument.UIStatusComboBox;
#endregion
Mouse.Click(uIStatusComboBox);
Keyboard.SendKeys(uIStatusComboBox, "{Down}{Down}{Enter}", ModifierKeys.None);
}
In my case the element that I want to select is the 3rd one, so I go down 2 times and then hit enter on the element I want to select.
This workaround is not so good because if the element changes position I will select the worng one! But this was the only way I got for the test not to be stock in that part!
I wonder if anyone had a similar issue. Because to me this seems like a bug in the Coded UI Test engine, It doesn´t make any scence for the test to be stocked while the alert is not closed!

Open a dialog using openDialog and pass an object parameter

I'm developing a Firefox extension which has this code to open some dialog:
Cu.import("resource://gre/modules/Services.jsm");
function showPanel()
{
let mainWindow = Services.wm.getMostRecentWindow("navigator:browser");
mainWindow.openDialog(data.url("ui/options.html"),
"Dictionary settings",
"chrome,centerscreen,dialog,modal,resizable,scrollbars,height=400,width=400",
{ a: 123 });
}
On the dialog side, when I access window.arguments[0] I get an empty object with no fields.
If I pass primitives like strings and numbers, they are passed correctly to the dialog.
What's the problem with this code?
Regards,
Update:
As I won't be able to commit my code, I've created a whole branch of the project.
Please check this repository https://github.com/ashrafsabrym/firefox-dict-switcher
Using an object or array as parameter sends an empty object to the dialog, while primitives work well.

Find a button on a web page looking for part of its InnerText string in Visual Studio

I am writing automated tests for a website. On the website there is a button that will have the inner text "All Open" + four random digits. For example: "All Open2957". Is there a way to find the button using only the "All Open" part of the string?
This does not work since the string is missing the four last digits:
HtmlSpan uIAllOpenPane = new HtmlSpan();
uIAllOpenPane.SearchProperties[HtmlDiv.PropertyNames.InnerText] = "All Open";
The simple answer is to use the PropertyExpressionOperator.Contains rather than PropertyExpressionOperator.EqualTo comparator and search for just the required text.
For recorded tests, find the control in the UI Map editor and view its properties panel. Click the "Search properties" field and then click the ellipsis. The window that appears allows the comparator and the required text to be altered.
For hand coded tests use code of the form:
uIAllOpenPane.SearchProperties.Add(HtmlDiv.PropertyNames.InnerText,
"All Open",
PropertyExpressionOperator.Contains);
According to this Microsoft blog the array index style (ie with [ and ]) as used in the question internally calls the SearchProperties.Add(...) but that style has no variation to specify ...Contains, so call the ...Add(...) explicitly.
Check this out
Button allOpenButton = (Button)BrowserWindow.ExecuteScript("allOpenButton = function(){var found; $('input[type=\"button\"]').each(function(){ if($(this).val().indexOf('All Open') > -1){ found = $(this);};}); return found;}; return allOpenButton();");
When trying to locate the controller I only got the FailedToPerformActionOnHiddenC‌​ontrolException. Eventually I was able to locate the DIV container that contained the controller I was trying to locate instead of focusing on finding the controller directly. After finding the container I could locate the controller using
HtmlSpan uIAllOpenPane = new HtmlSpan(container);
uIAllOpenPane.SearchProperties.Add(HtmlDiv.PropertyNames.InnerText, "All Open",
PropertyExpressionOperator.Contains);
The code from #AdrianHHH helped with the problem when part of the string is randomized each time you encounter the controller.

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

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.

Calculation from Value-List in Archer GRC based on date (with non-empty validation)

I've been trying to implement what's been asked in this Stack Overflow question, here:
Calculation for status in Archer GRC based on date
Trying to create a status field based on a number of Value Lists that
users select from, but a request has been made that we check a date
field for a value to ensure an estimated date has been set so that the
calculation can determine if the status of the record is "In
Progress", "Late" or "Not Started".
...and now, I have a requirement for an actual popup warning message of some sort to prompt the user to make sure the date field is not blank.
How would I add this functionality?
In order to deliver the functionality you are looking for you have to use a "Custom Object". It is an object you put on the layout of the application in Archer that contains JavaScript code. This code will be executed as soon as the form of the application is loaded. There is a special type of the field "Custom Object" available in the Layout editor for each application in the Application Builder in Archer.
Note - I don't recommend to use custom objects in general and neither RSA Support. Every time you modify the layout in the given application, you have retest and sometimes correct IDs for your custom object. You can write an ID independent custom object and use field names, but in this case custom object will have more code. I prefer to make custom objects as short as possible.
Your custom object should do the following:
Override the behavior of the "Save" and "Apply" button in the top tool bar available for every application form in Archer.
Once "Save" and "Apply" buttons are "overwritten", every time they are clicked on your function will be called. So you need to create a click handler function.
Your click handler function will check values user is required to populate and will either return warning, or will call the original handler for "Save/Apply" buttons.
This is a code template you can start with:
<script type="text/javascript">
// ids are used to locate buttons
var buttons_ids = [
"master_btnSave", // "Save" button ID
"master_btnApply" // "Apply" button ID
];
// parameters are used in the "onclick" default handlers to call original handlers
var buttons_parameters = [
"master$btnSave", // "Save" parameter
"master$btnApply" // "Apply" parameter
];
document.getElementById(buttons_ids[0]).onclick = function(){ Validator_of_required_fields(buttons_parameters[0])};
document.getElementById(buttons_ids[1]).onclick = function(){ Validator_of_required_fields(buttons_parameters[1])};
// end of the script body
//==== Validator function attached to Save and Apply buttons
function Validator_of_required_fields(parameter){
// ids of the input fields to validate
var inputs_to_validate_ip_address = [ "master_DefaultContent_rts_XXX_YYY_t" ];
// jQuery selector is used here. Archer v5.x has jQuery library loaded by default
// you will need to modify this selector
var field_value = $('#'+inputs_to_validate_ip_address[0]+':first').val();
if(field_value.length = 0) {
// Here you are calling Archer Warning function
var msg = "[Text to display to user]";
var title = 'Required Field';
WarningAlert(msg,title);
return false;
};
// default onclick processor
ShowAnimationAndPostback(parameter);
return false;
};
Some comments on this code:
You will need to modify the validation function to work with values stored in the fields you need.
I used a rather 'unusual' way to override the behavior of the "Save" and "Apply" buttons using the following code:
document.getElementById(buttons_ids[0]).onclick = function(){ bla, bla, bla }There are simpler way to do the same, but this way custom object works fine in IE8-11, FF, Chrome and Opera. Let me know if you find a simpler way to override buttons that is browser agnostic.
Function WarningAlert(msg,title); is a build-in Archer warning message function. It worked fine in Archer v5.4. You might need to use simple JavaScript Alert function if WarningAlert doesn't work in your version of Archer.
Note that behavior of the "Save" and "Apply" buttons might be overwritten back to default in case if user opens up any pop-up dialog windows to populate a value list or cross-reference field. If that is the case, you will have to wrap the code provided into another function and attach it to the OnLoadWindow event (or similar).
I try to avoid using any JavaScript libraries in my custom objects. This way it is simpler to support them and you have less dependencies. I used jQuery in the provided example only because Archer already uses this library once the page is loaded.
Flak, make sure to test your custom object very well and good luck!

Resources