In a program that I'm testing with Coded UI Tests, I've got a window that opens for only a second or so, and I want to verify that this window is opening.
Is there a way to freeze the program, or make it run slow so that the test is able to find that window?
As I already mentioned in my comment there isn't much (perhaps nothing) you can do by the CodedUi Test to catch the window, since this functionality is built into the application.
My suggestion is to make this property configurable. Some of the properties in the applications under test need to be configurable so it can be tested. Consider the following requirements:
The service is restarting every month.
The user is deleted after one year of inactivity.
How would you test them? Will you wait a month or a year to go by? Those kind of parameters have to be available for the Qa team, otherwise they cannot be tested. I know that with this approach you have to do changes to your app's code and build but I think is the only way to solve it.
How about adding a Thread.Sleep(100);
http://msdn.microsoft.com/en-us/library/d00bd51t
From what I understand, the best approach is to break up your tasks as small as possible. So for a UI test I did that opens a shortcut on my toolbar, clicks login on a popup within, then clicks a tab in the application, the code looks like this:
namespace CodedUITestProject1
{
/// <summary>
/// Summary description for CodedUITest1
/// </summary>
[CodedUITest]
public class CodedUITest1
{
public CodedUITest1()
{
}
[TestMethod]
public void CodedUITestMethod1()
{
// To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
// For more information on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
this.UIMap.OpenWindow();
this.UIMap.ClickLogin();
this.UIMap.ClickDevelopment();
}
//snip
}
So then in the ClickDevelopment() method, I know that the program should be visible, so rather than just dive right into the method actions, I can throw a Thread.Sleep() to make it visible for a little while longer.
public void ClickDevelopment()
{
Thread.Sleep(10000);
#region Variable Declarations
WinClient uIDevelopmentClient = this.UIQualityTrack30Window.UIItemWindow.UIQualityTrack30Client.UIDevelopmentClient;
#endregion
// Click 'Development' client
Mouse.Click(uIDevelopmentClient, new Point(39, 52));
}
Use Playback.Wait(2000) instead of Thread.Sleep(2000);
Best possible method is to add polling mechanism.
As soon as you perform the action which will open the window, call a function which will keep checking whether the window appeared for say, 1 min or so.
Be sure to call this function as soon as you perform action.
So even if the window stays for 500 millisecond, the info will be captured.
We have done similar thing in our project.
Related
My question is: How do I add a windows context menu item for a specific application, not globally?
Quick Brief:
We use Access (groan) for our CRM system. We use a basic 'copy to local' process for multi-access. I have written a C# 'launcher' of which handles this much better than a .bat file (they click the launcher, the launcher downloads the db, launches the db and quits). I also currently use a C# console application to handle development, automating stuff like incrementing version number, moving files around etc.
My Question/Goal:
I want to combine the two programs into one but I don't want to hinder the launcher from it's main purpose by jarring the user asking if they want to develop or not. I use this launcher too as I am primarily an estimator, hence wanting to combine the two. I have read that you can add context menu items to Windows as a whole, but I want to be able to add a launch option into the context menu just for this application. i.e. right click on program, normal menu options but with the addition of "Development Mode", this opens the program with arguments that I can use to open the development window/console instead.
Things to note:
I have played around with holding a key on start but it can be vague when to press the key. Too early - you will end up typing "r" several times into the active window, too late - and it will miss the capture point.
I have also looked at having a button on the launcher that gives you the option to go into dev mode, but the launcher is only open for around a second so its really easy to miss.
Thanks in advance
EDIT: The launcher is made and run as a click-once app.
I dont really know about whether its possible to have a custom context for a specific program, as far as i know the context works with the extension. That being said, i think there are better ways to handle your problem. Have a look at this
static void Main(string[] args)
{
/* here normal flow of the launcher*/
if (args[0] == "-dev")
{
/*here de developer mode*/
Console.WriteLine("Developer mode activated");
}
}
The way to use it is simple, you make a shorcut, and where it says the shorcut target you will have something like this "C:\Users****\Documents\visual studio 2017\Projects\Test\Test\bin\Debug\Test.exe" and you should change it to something like this "C:\Users****\Documents\visual studio 2017\Projects\Test\Test\bin\Debug\Test.exe" -dev
Further to this I stumbled upon some code to make this work. Hopefully this will help someone in the future. I am doing this in WPF, but I am sure you could probably adapt this code to work elsewhere.
1) App.xaml - Adding the JumpList action
After (not inside) the Application.Resources property add the following and change to your liking (There are a lot of properties I haven't used for development sake, check out the link to learn more):
<Application.Resources>
...
</Application.Resources>
<JumpList.JumpList>
<JumpList ShowRecentCategory="False"
ShowFrequentCategory="False">
<JumpTask Title="Open Dev Mode"
Description="Use this to enter dev mode (admins only)"
Arguments="DevMode:true"/>
</JumpList>
</JumpList.JumpList>
This will create a "Task" in the jump list:
2) Create Global static class - this will allow you to store the variable for later use in other forms.
public static class Global
{
public static Boolean DevMode = false;
}
3) App.xaml.cs - Adding OnStartup handler
Inside the App class create an override method for OnStartup
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
Global.DevMode = Boolean.Parse(e.Args.FirstOrDefault().ToString().Split(':')[1]);
}
}
4) Read the variable in your form using Global.DevMode
private void Window_ContentRendered(object sender, EventArgs e)
{
if (Global.DevMode) RunYourDevScript();
}
As per a suggestion in a comment, that has gone for some reason. I am going to revert to keypress but use shift instead or "R".
Failing this, or if it causes problems it will look at creating a global context menu item for all programs, and just won't click it when I don't need to
In ranorex I have quick question about using conditional statement, or any suggestion to handle a cash drawer popup. Whenever I launch our application there will be a login screen but not every time so what do I do to handle this popup when is there.
These are the two required field that need to be clicked on
Username field: /form[#title='Windows Security']/?/?/element[#instance='0']/text[#class='Edit']
Password field: /form[#title='Windows Security']/?/?/element[#instance='1']/text[#class='Edit']
/form[#title='Windows Security']/?/?/element[#instance='2']/button[#text='OK']
How should I handle this? Using if then else statement? If so how do I do this.
Also after I log in there will be cash drawer initialization popup, this is one time for a whole day.
/dom[#domain='crs.pre.kofile.com']//input[#'cashdrawerinitialize-btn']
this is the button I need to click when this popup appears. Please let me know
Thanks
For your login popup I'd suggest using either optional actions within the Ranorex action table as described in the Ranorex Online User Guide or using a User code action that checks if the item exists.
If you decide to use the User code approach, you can use the following lines
if(repo.App.Form.UsernameInfo.Exists(duration))
{
//Do your steps here
}
else
{
//What to do, when the first popup is not here?
}
Please don't forget to use the Info object of your repository items.
For your second popup, you can use the Ranorex Popupwatcher class as described in the Ranorex code examples (Sorry, but I'm not allowed to post more than to links, yet)
A common problem in UI testing is the appearance of an unexpected dialog – e.g. the Update-Check dialog in KeePass.
To overcome this issue, you can use the PopupWatcher class. Using this class you can add watches for each dialog which might pop up during test execution. In these watches you can specify a RanoreXPath or a Repository item the PopupWatcher should keep watching for, as well as a method which should be triggered or a repository item which should be clicked.
void ITestModule.Run()
{
// Create PopupWatcher
PopupWatcher myPopupWatcher = new PopupWatcher();
// Add a Watch using a RanoreXPath and triggering the Method CloseUpdateCheckDialog
myPopupWatcher.Watch("/form[#controlname='UpdateCheckForm']/button[#controlname='m_btnClose']", CloseUpdateCheckDialog);
// Add a Watch using the info object of a button and triggering the Method CloseUpdateCheckDialog
// myPopupWatcher.Watch(repo.UpdateCheckDialog.btCloseInfo, CloseUpdateCheckDialog);
// Add a Watch using the info object of the dialog and the info object of the button to click
// myPopupWatcher.WatchAndClick(repo.UpdateCheckDialog.SelfInfo, repo.UpdateCheckDialog.btCloseInfo);
// Add a Watch using a repository folder object and the info object of the button to click
// myPopupWatcher.WatchAndClick(repo.UpdateCheckDialog, repo.UpdateCheckDialog.btCloseInfo);
// Start PopupWatcher
myPopupWatcher.Start();
}
public static void CloseUpdateCheckDialog(Ranorex.Core.Repository.RepoItemInfo myInfo, Ranorex.Core.Element myElement)
{
myElement.As<ranorex.button>().Click();
}
public static void CloseUpdateCheckDialog(Ranorex.Core.RxPath myPath, Ranorex.Core.Element myElement)
{
myElement.As<ranorex.button>().Click();
}
Or like this:
var watcher = new PopupWatcher();
//provide there two elements WatchAndClick(RepoItemInfo, RepoItemInfo);
watcher.WatchAndClick(RepoItemInfoFindElement, RepoItemInfoClickElement);
watcher.Start();
//some work
watcher.Stop();
Issue
I am running tests using the Coded UI Test builder and writing all the code from scratch. The issue I am facing is in the middle of the test there is a popup message with the results "Stay on this page" or "Leave this page". I want my test to be able to click "Stay on this page".
The popup sometimes appears straight after the event or sometimes appears a couple of seconds later.
Code
So the event that I run before the message appears is a button click:
ClickButton(browser, "login");
void ClickButton(UITestControl parent, string id)
{
var button = new HtmlButton(parent);
button.SearchProperties.Add(HtmlButton.PropertyNames.Id, id);
Mouse.Click(button);
}
I have tried Keyboard.SendKeys() but this just sends the keys to the browser window. I have also tried using the recording tool. Both are unsuccessful.
After this event I need to wait for the popup to appear and click "Stay on this page". Does anyone know how to achieve this?
We actually mapped this confirmation window and it works for us.
We start with a Window with name = Windows Internet Explorer
Followed by a Pane with name = Windows Internet Explorer
and finally with a Button of name Stay on this page
All with Technology = MSAA.
You must handle writing code to wait for readiness of the control and proper time out if you don't expect the confirmation every time.
Hope this helps.
Depending on what exactly that window is, you should be able to deal with it no problem. I would use the inspector to get the properties of the window and use one of the WaitFor* methods to give it some time. Here is an example of dealing with the security pop up that IE shows:
namespace CaptainPav.Testing.UI.CodedUI.PageModeling.Win
{
public class IESecurityWindow<T> : PageModelBase<WinWindow>
{
protected const string SecurityWindowName = "Internet Explorer Security";
internal protected override WinWindow Me => new WinWindow().Extend(WinWindow.PropertyNames.Name, SecurityWindowName, PropertyExpressionOperator.EqualTo);
protected WinButton AllowButton => this.Me.Find<WinButton>(WinButton.PropertyNames.Name, "Allow", PropertyExpressionOperator.EqualTo);
internal readonly T AllowModel;
public IESecurityWindow(T allowModel)
{
this.AllowModel = allowModel;
}
public T ClickAllow()
{
// if not IE, this will return false and the next model is returned; change the time if you need more or less wait
if (this.AllowButton.IsActionable(3000))
{
Mouse.Click(this.AllowButton);
}
return AllowModel;
}
}
}
In this case, the dialog is a Win* type, not Html*. There are some custom extension methods sprinkled in to make the searching and stuff easier, but this should give you an idea. If interested, the extensions (which are written by me) can be found on github.
I have spent the past few days working on bot for an MMO. It runs in one big loop, with 1-2 other smaller loops inside. So far its going great. When its running it is set to update a richtextbox with what it is currently doing, just so I can easily troubleshoot later.
My problem is while its active and looping it does not auto update the textbox until it has finished everything it is doing. Which is hard when its set in an infinite loop. I would like to be able to run the bot with the main program window on the other monitor giving me updates as it goes along.
The whole program seems to freeze up and I cant interact with it at all while running. This also causes problems when I want it to stop. The only way I have of stopping it at the minute is to click Stop in visual studio.
I have tried searching around, but I have no idea what to search for. I hope I explained it well enough.
Thanks in advance.
This would be a nice read :
http://www.beingdeveloper.com/use-dispatcher-in-wpf-to-build-responsive-applications/
To summaries
You can send in a delegate fx, which is responsible for a formatter or writter. In you implemetation it would be the one which does AppendText. and make sure the Richtextbox.AppendText is within Dispatcher.Invoke()
Code Sample
class BotRand
{
//Write Event is delegate
public execute(WriteEvent writeFx)
{
//Crawl
writeFx("message");
}
}
class MainWindow : Window
{
void WriteFunc(object message, EventArgs outline)
{
Dispatcher.Invoke(new Action(() => richText.AppendText(message));
}
}
This should help you start your search more effectively.
Thanks,
I recently made a custom ribbon in Sitecore. The two buttons in it fire off a command which activate a Xaml application using SheerResponse.ShowModalDialog. These applications effect the state of a database being read by another component on the ribbon.
I either need to be able to fire a custom event or function from the Xaml application to make the other ribbon component, or I need to be able to make the component on the ribbon aware that it needs to re-render when the ModalDialogs close. I don't see any obvious events which would do this, and I've gone about as far as I can when looking through the raw code with DotPeek and I haven't seen anything which even looks promising.
Apparently, the answer was there the whole time and I had missed it.
SheerResponse has a five parameter version of ShowModalDialog which accepts a boolean as a final parameter. This means I can couple it with ClientPage.Start:
Context.ClientPage.Start(this, "Run", kv);
}
private void Run(ClientPipelineArgs args)
{
var id = args.Parameters["id"];
if(!args.IsPostBack)
{
string controlUrl = string.Format("{0}&id={1}", UIUtil.GetUri("control:AltDelete"), id);
SheerResponse.ShowModalDialog(controlUrl,"","","",true);
args.WaitForPostBack();
}
else
{
Logger.LogDebug("post back");
}
Logger.LogDebug("out of if");
}