Coded UI: Test cases having recording action are failed while executing through custom code - coded-ui-tests

public void RecordedMethod_Sample(int x)
{
#region Variable Declarations
HtmlCell uISALESREVENUECell = this.UIDashboardWindowsInteWindow1.UIDashboardDocument.UITblWrapperOnlineStorTable.UISALESREVENUECell;
HtmlImage uIImagegifbase64R0lGODImage = this.UIDashboardWindowsInteWindow1.UIDashboardDocument.UIImagegifbase64R0lGODImage;
HtmlHyperlink uIPostPurchase4Hyperlink = this.UISalesRevenueandGrossWindow.UISalesRevenueandGrossDocument.UIPostPurchase4ReturnsCustom.UIPostPurchase4Hyperlink;
HtmlDiv uISalesRevenueByDataSoPane = this.UISalesRevenueandGrossWindow.UISalesRevenueandGrossDocument.UISalesRevenueByDataSoPane;
#endregion
// Set flag to allow play back to continue if non-essential actions fail. (For example, if a mouse hover action fails.)
Playback.PlaybackSettings.ContinueOnError = true;
// Mouse hover 'SALES REVENUE' cell at (82, 27)
Mouse.Hover(uISALESREVENUECell, new Point(82, 27));
// Reset flag to ensure that play back stops if there is an error.
Playback.PlaybackSettings.ContinueOnError = true;
// Click 'image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAA...' image
Mouse.Click(uIImagegifbase64R0lGODImage, new Point(139, 64));
// Set flag to allow play back to continue if non-essential actions fail. (For example, if a mouse hover action fails.)
Playback.PlaybackSettings.ContinueOnError = true;
// Mouse hover 'Post Purchase4' link at (144, 19)
Mouse.Hover(uIPostPurchase4Hyperlink, new Point(144, 19));
// Reset flag to ensure that play back stops if there is an error.
Playback.PlaybackSettings.ContinueOnError = true;
// Move 'Sales Revenue By Data Source' pane
Mouse.StartDragging(uISalesRevenueByDataSoPane, new Point(79, 15));
Mouse.StopDragging(uISalesRevenueByDataSoPane, 224, -4);
string title = uISalesRevenueByDataSoPane.InnerText.ToString();
if (title == "Sales Revenue By Data Source")
{
}
while Executing Mouse.Hover(uISALESREVENUECell, new Point(82, 27)); it is giving
following error
Specified method is not supported.
whenever i try to execute it as test case then everything is working as expected
while executing through custom code it is giving above mentioned error
can anybody please help me out...
thanks in advance for all your inputs

What does "custom code" mean? If it means custom controls then the error is likely because the custom control has not been written to support Coded UI. For a custom control to work with Coded UI it must support MSAA or UIA interfaces, or have support from the newer proxy mechanisms.
For more details try web searching for Coded UI, MSAA and UIA. Also have look at this blog http://blogs.msdn.com/b/visualstudioalm/archive/2012/05/24/coded-ui-test-new-extensibility-qfe.aspx

I had this exact problem.
Your best bet is to use the recorder as much as possible ,and then only move stuff away from UI map when you need dynamic execution and only for those bits.
Let the recorder do all the work for you, and you will get much better reliability during playback.

Related

MFC MDI dynamically changing tab style from a property dialog

It has been 10 months since I worked on my app due to a death in the family, just started looking at it again and still not sure how to solve the problem.
The project inquires/help started here:
MFC MDI Collecting control states for the "apply" button routine
Since this is a specific focused question, I didn't want to muck up my other thread, so what I'd like to do is change the documents tab styles after the view is loaded. I know that this can be done because the master repository from Microsoft with all the code examples has a project called VCSamples-master\VCSamples-master\VC2010Samples\MFC\Visual C++ 2008 Feature Pack\TabControl which I have looked at. It dawns on me that even though I can follow its code, the calls are from within the MDI window itself where my issue is I'm trying to do this via a property page dialog using OnApply which changes things.
I was able to do part of this properly with the help of the thread above to the OutputPane successfully because I was able to get the Pane handle and execute. I was told that for the MDI tabs after creation that I need to parse the tabs, count them, and then execute. So my issue here is after I capture the tabs......how to change their styles.
Here is the code as it stands:
BOOL CSettingsUserTabs::OnApply()
{
BOOL bResult = CMFCPropertyPage::OnApply();
if (bResult)
{
// Update Output Pane Tab Styles (Works 100%)
AfxGetApp()->WriteProfileInt(_T("Settings"), _T("UserTabStyle"), m_style_tabs); // Save value to registry
((CMainFrame*)AfxGetMainWnd())->m_wndOutput.m_wndTabs.ModifyTabStyle((CMFCTabCtrl::Style)m_style_tabs);
((CMainFrame*)AfxGetMainWnd())->m_wndOutput.m_wndTabs.RecalcLayout();
//Get the open file tabs in the MDI
for (POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition(); pos != NULL; )
{
CDocTemplate* pTempl = AfxGetApp()->GetNextDocTemplate(pos);
for (POSITION pos1 = pTempl->GetFirstDocPosition(); pos1 != NULL; )
{
CDocument* pDoc = pTempl->GetNextDoc(pos1);
for (POSITION pos2 = pDoc->GetFirstViewPosition(); pos2 != NULL; )
{
CView* pView = pDoc->GetNextView(pos2);
if (pView->IsKindOf(RUNTIME_CLASS(CTrainView)))
{
// THIS IS WHERE MY ISSUE IS, NOW THAT ALL THE TABS ARE
// CAPTURED, HOW DO I ADDRESS THEM LIKE WHAT IS SHOWN
// ABOVE:
//((CMainFrame*)AfxGetMainWnd())->xxxxxx.yyyyyy.ModifyTabStyle((CMFCTabCtrl::Style)m_style_tabs);
}
}
}
}
}
return bResult;
}
If I can figure this last piece out, I'll be basically finished, I just can't seem to find a solution on how to do this via property sheet via OnApply.
Any suggestions or actual code examples I can see to solve my problem?
FYI: No, I haven't had any time to take additional OOP to solve this. I'm hoping someone can provide some guidance so I can move on after getting this sorted.
Thanks,
Chris
EDIT 1:
So I took a closer look at Constantine's suggestion and here is what I came up with:
BOOL CSettingsUserTabs::OnApply()
{
BOOL bResult = CMFCPropertyPage::OnApply();
if (bResult)
{
// Update Output Pane Tab Styles
AfxGetApp()->WriteProfileInt(_T("Settings"), _T("UserTabStyle"), m_style_tabs); // Save value to registry
((CMainFrame*)AfxGetMainWnd())->m_wndOutput.m_wndTabs.ModifyTabStyle((CMFCTabCtrl::Style)m_style_tabs);
((CMainFrame*)AfxGetMainWnd())->m_wndOutput.m_wndTabs.RecalcLayout();
CMFCTabCtrl& MDI_STYLES = ((CMainFrame*)AfxGetMainWnd())->GetMDITabs();
MDI_STYLES.ModifyTabStyle((CMFCTabCtrl::Style)m_style_tabs);
MDI_STYLES.RecalcLayout();
CMDIFrameWndEx* pMainFrame = DYNAMIC_DOWNCAST(CMDIFrameWndEx, GetTopLevelFrame());
pMainFrame->SetFocus();
pMainFrame->RecalcLayout();
}
return bResult;
}
The m_styles_tabs is getting the index value of 0-8 when I select the radio button. The code compiles and runs and I see the index value change when I break on it, but the tabs for the MDI are still not updating. Does the edited code make sense based on the members shown here:
https://learn.microsoft.com/en-us/cpp/mfc/reference/cmfctabctrl-class?view=msvc-170#modifytabstyle
I think this the right direction, am I missing something?

Can't select value in combo box using Coded UI Test

WinComboBox comboxBox = new WinComboBox();
comboxBox.SearchProperties[WinComboBox.PropertyNames.Name] = "Server:";
comboxBox.WindowTitles.Add("Server Settings");
comboxBox.SearchProperties[WinComboBox.PropertyNames.TechnologyName] = "Server";
comboxBox.SearchProperties[WinComboBox.PropertyNames.ControlName] = "comboBoxPlatforms";
comboxBox.SelectedItem = "Value3";
I used above code for selecting a value in a combo box using Coded UI test.
But I am getting the error
System.NotSupportedException: GetProperty of "SelectedItem" is not supported on control type: Window
Can anyone tell me what I am doing wrong or show me an alternative solution?
Sometimes i add this : comboxBox.TechnologyName = “MSAA”;
I think WindowTitles is not needed.
Try also
Mouse.click (comboBox) and playback.wait(1000); above comboxBox.SelectedItem = "Value3"; To exclude some common problems. If that solves your issue then you can start refactoring.
Ik hope it helps.
As the exception points out, the UITestControl object you have is of ControlType WINDOW, which is why you are not able to do SetProperty on it.
I will specify parent control also while searching.
WinComboBox comboxBox = new WinComboBox(WinWIndow Parent);
If your control is WinCombobox try:
combobox.SetProperty("SelectedItem", "Value3");
Also If you know the index of the item try:
combobox.SetProperty("SelectedIndex", 3);
Let me know if it resolves your issue

F# Winforms Charting Asynchronous Updating

I'm trying to create a chart in winforms that databinds to a list in memory, and gets updated dynamically as the list changes. Here is my code:
open System
open System.Linq
open System.Collections
open System.Collections.Generic
open System.Drawing
open System.Windows.Forms
open System.Windows.Forms.DataVisualization
open System.Windows.Forms.DataVisualization.Charting
let link = new LinkedList<double>()
let rnd = new System.Random()
for i in 1 .. 10 do link.AddFirst(rnd.NextDouble()) |> ignore
let series = new Series()
let chart = new System.Windows.Forms.DataVisualization.Charting.Chart(Dock = DockStyle.Fill, Palette = ChartColorPalette.Pastel)
series.Points.DataBindY(link)
let form = new Form(Visible = true, Width = 700, Height = 500)
form.Controls.Add(chart)
let formloop = async {
while not chart.IsDisposed do
link.AddFirst((new System.Random()).NextDouble()) |> ignore
link.RemoveLast()
}
do
Async.StartImmediate(formloop)
Application.Run(form)
Console.WriteLine("Done")
Console.ReadLine() |> ignore
The async seems to work, but the chart never shows anything. It just shows a blank window. What am I doing wrong?
LinkedList<T> has no way to signal that it's been updated, so Chart has no way of knowing when to redraw itself.
In order for databinding to update the view, the source list must implement IBindingList and raise appropriate event when the contents change.
Separately, I must point out that it's dangerous to directly access UI properties/methods from non-UI threads (such as chart.IsDisposed in your code). In WinForms, this limitation is rarely actually enforced, so sometimes this might seem to work fine, only to crash later on a customer's machine with no way to attach a debugger.
You need to add the series to the SeriesCollection of the chart.
chart.Series.Add series
You need to construct a chart area and add it to the ChartAreaCollection of the chart.
let area = new ChartArea()
chart.ChartAreas.Add area
You need to make sure that the data binding method is called after the chart and form are set up.
...
form.Controls.Add chart
series.Points.DataBindY link
And now there's no way to communicate changes of your bound collection to the DataPointCollection of the series, as mentioned in Fyodor Soikin's answer. I'm not quite sure that IBindingList is an appropriate response;
while it's possible to hook into the ListChanged event, we could as well manipulate the series' DataPointCollection directly.
let formloop = async{
while not chart.IsDisposed do
series.Points.RemoveAt 0
series.Points.AddY(rnd.NextDouble()) |> ignore
do! Async.Sleep 100 }
Finally I'd like to point out this contribution by John Atwood which adresses both points raised by Fyodor; the data binding issue (by not using it) and the UI-thread safety issue.

Distinguish single click from double click C++

I have an application in which double clicking over an image view area changes the layout of the image view. Also on single click a dot will be placed on the image.
My problem is, both functionality is working when double clicked.
Of course I know that, when a double click occurs the control first goes to LButtonDown. I don't want the dot functionality to work when double click occurs. I have been working around this for more than a week. Please help.
The easiest way to solve this is to build a finite-state machine for handling mouse clicks.
Basically, this will be a singleton object, which takes input from the mouse click events you're currently using.
It's output will be SingleClickDetected, DoubleClickDetected, ....
Red arrows indicate events which you are reporting to the rest of your application.
Parentheses indicate what event you are reporting.
Of course, this state machine will have to be modified if you have to deal directly with MouseDown and MouseUp events, instead of MouseClick events.
It will be slightly larger, but the idea is basically the same.
EDIT:
From the comments, it looks like Windows doesn't cleanly report single- vs double-clicks, and you need to separate them.
A state-machine for this scenario:
This is probably overkill for what you're trying to do, especially since most, if not all GUI-based programs in the history of everything have never ever used a double-click drag.
It does show the basic idea, and shows how you can extend your state machine to handle different types of button clicks.
Furthermore, if you wanted to, you could handle double-right-clicks, a drag that involves both left and right buttons, or any other scenario you could think of and incorporate into your UI.
I wrote the following code and it works.
UINT TimerId;
int clicks;
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
KillTimer(NULL, TimerId);
if (clicks < 2 && !double_click){
MessageBox(hWnd, L"Show Widget", L"Widget", MB_OK);
}
clicks = 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
UINT uID;
UINT uMouseMsg;
uID = (UINT)wParam;
uMouseMsg = (UINT)lParam;
if (uMouseMsg == WM_LBUTTONDBLCLK){
double_click = true;
MessageBox(hWnd, L"Double click", L"CAPT", MB_OK);
return 0;
}
if (uMouseMsg == WM_LBUTTONDOWN){
double_click = false;
clicks++;
//single click opens context menu
if (clicks == 1){
TimerId = SetTimer(NULL, 0, 500, &TimerProc);
}
return 0;
}
,...
}
Try storing the timestamp of the last LButtonDown; if the time difference between the last timestamp and the timestamp produced in the current event is too short, you can just cancel your operation (but still store the new LButtonDown timestamp)
The only thing you can do is wait for a short amount of time each time you receive click event, and test if in the meantime the equivalent of a double click event doesn't occur before performing the single click response. This may be source to new bugs and unresponsive UI. Maybe try to change the user interaction to toss the problem away.
EDIT: The fact that you are working around this for more than a week is a symptom of bad user interaction design. A "double click" still means two clicks occurs, which means the application naturally should perform the operation of a single click. Check the ui of the apps installed on your desktop to verify this. Have you considered using a different user medium to trigger the UI response? For instance, you can use the right button to put the dot on the image.
#E.T's answer is spot-on. To implement something like that, you really need a timer running along with your message loop.
In my application I wanted to be able to distinguish mouse down/up from double click because I want a double click to not undo a drag operation (imagine selection box with left button drag and double click to zoom to fit).
The following code does this using PreTranslateMessage. I did not add the timer out of laziness. So the UI behaves a bit "funny" if you don't immediately move the mouse after the left button is held down. In my case, this is a minor issue.
BOOL MyWindow::PreTranslateMessage(MSG *pMsg)
{
//From https://msdn.microsoft.com/en-us/library/windows/desktop/ms645606(v=vs.85).aspx
//Double-clicking the left mouse button actually generates a sequence of four messages:
//WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP
//So here's the problem. If an button up message arrives, we can't just
//take it, because it may be followed by a double click message. So we check
//for this.
//Ideally you need a timer - what happens if you don't get any messages
//after the button up or down? But here we get lazy and assume a message
//will come "soon enough".
static bool upMessageStored = false;
static bool dnMessageStored = false;
static MSG upMessage, dnMessage;
static bool processDnNow = false, processUpNow = false;
//This logic sequence absorbs all button up and down messages, storing them to be sent
//if something other than a double click message immediately follows.
if (!(pMsg->message == WM_LBUTTONDBLCLK ||
pMsg->message == WM_LBUTTONDOWN ||
pMsg->message == WM_LBUTTONUP) &&
(upMessageStored || dnMessageStored))
{
//If we receive any message other than double click and we've stored the messages,
//then post them.
Output::Message(L"Stored messages posted.\n");
if (upMessageStored)
{
processUpNow = true;
upMessageStored = false;
this->PostMessage(upMessage.message, upMessage.wParam, upMessage.lParam);
}
if (dnMessageStored)
{
processDnNow = true;
dnMessageStored = false;
this->PostMessage(dnMessage.message, dnMessage.wParam, dnMessage.lParam);
}
return TitlelessWindow::PreTranslateMessage(pMsg);
}
if (pMsg->message == WM_LBUTTONDOWN && !processDnNow)
{
Output::Message(L"WM_LBUTTONDOWN absorbed; message stored\n");
dnMessage = *pMsg;
dnMessageStored = true;
return TRUE; //swallow this message.
}
else if (pMsg->message == WM_LBUTTONUP && !processUpNow)
{
Output::Message(L"WM_LBUTTONUP absorbed; message stored\n");
upMessage = *pMsg;
upMessageStored = true;
return TRUE; //swallow this message.
}
else if (pMsg->message == WM_LBUTTONDBLCLK)
{
Output::Message(L"WM_LBUTTONDBLCLK; stored message discarded\n");
upMessageStored = false;
dnMessageStored = false;
processUpNow = false;
processDnNow = false;
}
//If we get here, we are processing messages normally. Be sure we clear the flags
//for up and down.
processDnNow = false;
processUpNow = false;
return ParentClass::PreTranslateMessage(pMsg);
}
I really liked the finite state machine answer BUT there is a flaw in it.
There is no such thing as "single click time" which you can exceed.
If you look at a the working of your mouse closely you will see that:-
single click not one event but = WM_LBUTTONDOWN, WM_LBUTTONUP which is independent of time in between, the appropriate action will take place anyway
Double-clicking the left mouse button actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP
so you should use the 3rd flag to your advantage
BTW, I am also working on something like this. Thanks!

Hold-Hover drop down menu Delay Time

Im creating a drop down menu and i want to know if there is anyway to implement the following:
I need to keep the sub-menu open for like 1 sec if the user moves the mouse away from the tab he selected. Much likely like in current intel web page www.intel.com , here u hover over menu, but if u take the mouse away from the tab or the sub-menu is opens it takes a few to hide the sub menu.
Im using .mouseover from jquery to show the menu (a div) but i cant find a way to make it stay for a few moments.
Thanks in advance
This may be of service
What is the JavaScript version of sleep()?
If you want to do something in the interim setTimeout() takes the arguments as shown where continue execution is another subroutine. If you just want this one tab to work this way have mouseover call doStuff and set a boolean (e.g. mouseStillIn) to TRUE. When the mouse exits set this boolean to FALSE, call a recursive function everytime mouseStillIn is TRUE.
e.g.
var mouseStillIn : boolean = false;
function MouseIn()
{
mouseStillIn=true;
CheckMouse();
}
function CheckMouse()
{
if(mouseStillIn)
{
setTimeout(CheckMouse, 1000);
}
}
function MouseOut()
{
mouseStillIn=false;
}

Resources