I am trying to design a simple Coded UI tests that access the two following functions. Currently they are written with the CUITe framework but I see the same issue when using Coded UI code.
I have a test case which first calls GLJEEnterDescription, then calls GLJEEnterNotes. When the test runs, GLJEEnterDescription is manipulated and BOTH strings passed into the functions are entered into it. Nothing is ever entered into GLJEEnterNotes. I have checked and rechecked and the properties for the controls are correct.
The only difference between the two controls is GLJEEnterDescription is a standard single line text box and GLJEEnterNotes is a custom (derived from standard) multiline text box. Any thoughts on why I would not be able to access and use the GLJEEnterNotes text box but not the GLJEEnterDescription text box? Below is my functions called from the Coded UI tests:
public void GLJEEnterDescription(string JEDescription)
{
akwindow.Find<WinEdit>(By.ControlName("txtJEDescription")).Text = JEDescription;
}
public void GLJEEnterNotes(string JENotes)
{
akwindow.Find<WinEdit>(By.ControlName("txtMultiJENotes")).Text = JENotes;
}
You most likely need to specify more search criteria for those controls.
Ideally, I would recommend trying to use control ID's or even AutomationID's for your controls. These are the HIGHEST priority for the search algorithm
Like in This Post
var textBox = new WinEdit(yourAppWindow);
textBox.SearchProperties.Add(WinEdit.PropertyNames.Name, "txtMultiJENotes");
textBox.SearchProperties.Add(WinEdit.PropertyNames.LineCount, "1");
else you might have to use FindMatchingControls and cycle each control for the right things you want.
Related
I am testing a WPF application and am not privy to it's exact workings but I am finding many instances where I need to find if a control is shown. All the traditional answers on this on Stack Overflow and MS forums etc say to use one of the following ...
IsVisible,
Exists,
TryGetClickablePoint,
State (e.g. OffScreen
The problem is that for this system, many controls return true for all of those even when the control cannot be seen! They also return a point with co-ordinates (-1, -1, -1, -1) whether the control is visible or not.
The only thing I have had any success with is using a try catch finally. I try to click on the control and if that fails, I go in to the catch block. That takes 60 seconds to time out though and I am getting intermittent issues with tests that run 9 times out of 10. Maybe the constant use of try catch is causing performance issues.
Is there an approach that actually works when all the standard approaches fail? I have noticed lots of other people asking these question are also testing WPF. Is there something WPF developers are doing to hide controls that makes CodedUI think they are still present and visible etc. Are they just behind something?
Many thanks in advance.
The solution was two-fold. Firstly I had to find the element and this was not working properly with my recorded steps. The element was buried too deeply in the system under test which is WPF (XAML). Secondly I had to prove I had found the element and for this I can't use TryGetClickablePoint, Exists, Top or Width. None of them seemed to work properly at all for my element. I had to use State.
public void Assert_MyElementShown()
{
#region Variable Declarations
WpfCustom uISurfaceCustom = this.UISysUnderTestClientShWindow.UIItemCustom1.UISurfaceCustom;
WpfCustom uIYAxisLabelsCustom = new WpfCustom();
#endregion
//Find the Element using it's Container and SearchProperties
uIYAxisLabelsCustom.Container = uISurfaceCustom;
uIYAxisLabelsCustom.SearchProperties[WpfControl.PropertyNames.ClassName] = "Uia.AxisLabelControl";
uIYAxisLabelsCustom.SearchProperties[WpfControl.PropertyNames.AutomationId] = "YAxisLabels";
//Use the State to find if it's on screen or not
var state = uIYAxisLabelsCustom.State;
if (state == Microsoft.VisualStudio.TestTools.UITest.Extension.ControlStates.Default)
{
//Element is visible, do stuff here!
}
else if (state == Microsoft.VisualStudio.TestTools.UITest.Extension.ControlStates.Offscreen)
{
//The control may exist, it may have location on screen and may even
//appear to be clickable according to coded ui framework but is is NOT
//shown on the screen.
}
}
You can try this approach for your application..if control properties are showing true for viable than we can go for height and width.Means if control is not visible in UI and but still all properties are showing true than check control height and width must be in -ve number.Than we can keep a assertion like
If control.height<0
Not visible in UI
I’m in love with IUP! However I cannot figure out how to get programmatic access (in C) to GUI elements in a dialog loaded by IupLoad() from a LED file.
One extremely laborious way would be to edit the LED file so as to manually give handle names to each single GUI element, then manually define corresponding variables for each element in C, then manually load handles into each variable by using IupGetHandle().
One comfortable way to do it would be to convert the LED file to a C header file using the built-in Layout Dialog tool. The resulting code makes each element available to the application in a simple array called Ihandle* containers[]. But this way deprives us of the benefits of LED files, such as the ability to edit GUI of a binary application by the user and keeping the C code small.
Is there no good way to do it?
Do I overrate the benefits of a third way, if it existed?
I cannot find any IupLoad() example in the directory with C examples.
My own example below explicitly defines one handle name for the top element (dialog) only. It features a very simple dialog where defining each element manually wouldn’t be a hard work at all. But this is only a test example for Stack Overflow and my question is relevant to complex dialogs.
C file:
#include <stdlib.h>
#include <iup.h>
int main(int argc, char **argv)
{
IupSetGlobal("UTF8MODE", "YES");
// IupSetGlobal("UTF8MODE_FILE", "YES");
IupOpen(&argc, &argv);
if(IupLoad("dropdown.led")) IupMessage("Error", "Failed to load LED.");
else {
Ihandle *dropdown = IupGetHandle("dropdown");
IupShow(dropdown);
IupMainLoop();
}
IupClose();
return EXIT_SUCCESS;
}
Corresponding dropdown.led file:
dropdown = DIALOG[TITLE=dropdown.led](
HBOX[CMARGIN=10x10,CGAP=10](
LIST[VALUE=3, 1=я, 2=ты, 3=оно, 4=мы, 5=вы, 6=они, DROPDOWN=YES](do_nothing),
LIST[VALUE=3, 1=ik, 2=je, 3=hij, 4=we, DROPDOWN=YES](do_nothing)
)
)
Which brings us to another question: how can I make Russian characters visible? But this issue is owed a separate thread which I will accordingly create.
All questions that pertain to this particular example:
How do I get access to GUI elements in a IUP dialog loaded from a LED file? (current)
How can I make Russian letters visible in a IUP dialog loaded from a LED file?
A gap in IUP dropdown lists
The way os to use IupGetHandle to get access to some element then use IupGetChild*, GetBrother, GetParent functions to get the element you want.
Another option is to use the NAME attribute. You set it on the element you want then use IupGetDialogChild to retrieve the element given the NAME value.
I try to make an interface for the device using WinForms. I have a class which stores all parameters and methods, like below:
// device.h:
class Device {
double parameter_a;
double parameter_b;
double setParameterA(double new_value);
double setParameterB(double new_value);
}
Then, I would create an instance and use it's methods to modify parameters by event handling and return either corrected value for UI Control or just 0 if everything is fine.
However, I found that this solution doesn't really make my code shorter, as I still have to modify UI inside my Form document, where all my controls are reachable (if errors / out of range values encountered).
What would I like to do is to somehow pass a kind of pointer to UI Control (like TextBox) to the function and make it like below:
void setParameterA(double new_value, *ui_ctrl_pointer* ) {
// simple value check
if (new_value > 0) {
// numToMStr() - function I have to convert numbers to managed string
*ui_ctrl_pointer*->Text = numToMStr(new_value);
return;
}
}
and modify the control inside the setParameterA() along with input control and setting my device.
1. Is it possible to make such a thing in C++-cli? (if so, what would ui_ctrl_pointer look like?)
2. Is this a correct approach or should I stick to the basic solution, which would force me to check for function output to determine what to do with value set by user inside my UI?
This drives me crazy:
i'm using a datagridview (bound to a dataset) and textboxes also bound to the dataset (which means that everything typed into the textboxes is reflected in the datagridview). The datagridview is actually used only to show up the values (user is NOT able to edit anything in the cells).
So: when the user pushes the add new record button (automatically created by visual studio using binding navigator etc. ) i would like to programmatically select this new line (remember: user has not the ability to select with the mouse) and insert some values.
I tried to use the
DefaultValuesNeeded
event, but this is firing only if the user selects the row with the asterisk indicator (what the user is not allowed to do).
How can i simulate that behavior? Should i take another approach?
Thanks in advance!!
Was searching for alternatives to how I currently do this and just wanted to let you know about a couple ways I know of. Both of these will set defaults when using the * (new row) or using a BindingNavigator.
private void CityBindingSource_AddingNew(object sender,
AddingNewEventArgs e)
{
// Simply set the default value to the next viable ID,
// will automatically set the value when needed.
locationDataSet.CITY.CITY_IDColumn.DefaultValue =
CityTableAdapter.GetNewID(); // ++maxID;
}
Or
private void CityDataGridView_DefaultValuesNeeded(object sender,
DataGridViewRowEventArgs e)
{
// Gets called when datagridview's */NewRow is entered.
e.Row.Cells[0].Value = CityTableAdapter.GetNewID(); // ++maxID;
}
private void bindingNavigatorAddNewItem_Click(object sender,
EventArgs e)
{
// BindingNavigator button's AddNewItem automatic tie-
// in to bindingSource's AddNew() is removed.
// This sets the current cell to the NewRow's cell to trigger
// DefaultValuesNeeded event.
CityDataGridView.CurrentCell =
CityDataGridView.Rows[CityDataGridView.NewRowIndex].Cells[1];
}
I was really hoping to use this:
private void CityBindingSource_AddingNew(object sender,
AddingNewEventArgs e)
{
// Cast your strongly-typed
// bindingsource List to a DataView and add a new DataRowView
DataRowView rowView =
((DataView)CityBindingSource.List).AddNew();
var newRow = (LocationDTSDataSet.CITYRow)rowView.Row;
newRow.CITY_ID = CityTableAdapter.GetNewID();
newRow.CMMT_TXT = "Whatever defaults I want";
e.NewObject = rowView;
}
But when adding using the BindingNavigator or any code based bindingSource.AddNew() it results in just a blank row. Hopefully someone finds a better way, but this is working for me so far.
Revised:
How about the Datatable's TableNewRow event, then? If that gets fired when the BindingNavigator creates a new row, then that's an opportunity to populate the object.
I have a requirement to be able to auto-tab from one control to the "next control" in a SL3 app. For example, a TextBox is limited to 3 characters - on typing the 3rd character the focus should automatically move to the next control on the form (my actual usage is slightly different but that example suffices).
However, as SL automatically determines the tab sequence there doesn't seem to be a way of doing this apart from reverse engineering/duplicating Silverlight's logic to figure out which control in the visual tree should be the next control to gain focus.
Has anybody implemented this already?
I was looking for a fairly generalised solution - but I've been able to make do with something fairly specific - basically it uses the VisualTreeHelper to find children with the same parent as the control that I want to tab next to, and sets focus to that.
It's a more palatable solution than having to go through all my controls (and this is for a fairly large LOB application) and configure the "next" control for each of them.
Here's my code, in case it helps somebody else. (VisualTreeeHelperUtil is a class of my own that adds some utility functions to VisualTreeHelper)
public static void TabNext(DependencyObject parentElement, Control fromControl)
{
var children = VisualTreeHelperUtil.FindChildren<Control>(parentElement).
Where(c => c.IsEnabled && c.IsTabStop && c.Visibility == Visibility.Visible).
ToList();
if (children.Contains(fromControl))
{
var thisIndex = children.IndexOf(fromControl);
var targetIndex = thisIndex + 1;
if (children.Count > targetIndex)
{
var targetChild = children[targetIndex];
fromControl.Dispatcher.BeginInvoke(() =>
{
targetChild.Focus();
var txt = targetChild as TextBox;
if (txt != null)
{
txt.SelectAll();
}
});
}
}
}
If you're looking for a generalized solution, and are OK basing it on the visual tree ordering (as opposed to arranged layout), I imagine it would not be so bad. Haven't heard of it being done, though.
Most of the phone number or credit card entry forms I've seen with this behavior honestly just hard-code the next field in the proper change handler when the right # of characters have been entered.
Since it sounds like your auto-focusing solution (for 3 chars) is going to already require some sort of event hookup, monitoring the TextChanged event, couldn't you just go ahead and either 1) hard-code a Focus() to the next form element that you know, 2) use the Tag property to store the name of the control that you'd like to focus next, then do a FindName + Focus on that, or 3) do some sort of VisualTreeHelper (or logical tree search through peers)?