In Ranorex how to handle popup - c#

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

Related

How to check whether the assigned work for button click( click method or command) is completed or not. without accessing the code behind

Consider I am having a button called "Add" and is bind with the command "AddBtnExceuteCommand".
Consider Execute() method of this Command having very large and time consuming calculations.
I am developing a tool which will save the Actions like Click, Entering text into textbox etc. When I play it back the same actions will executed automatically.
consider I started recording actions. Lets say I have Clicked on Button called "Add". this click actions will save in some file called "Actions.xml". When I Started playing back that saved action by reading "Actions.xml" file. I have only Control over the Button not on the code behind of that button(means I do not have access to the AddBtnExceuteCommand command).
My Actions.Xml have lot of such actions which will be executed serially.
What I want===>
When I started Reading Actions.xml that will execute saved Actions(Clicks) automatically without considering whether the Code behind of button is executed or not. I want to Restrict the execution of second action unless The code behind of first Button is executed. So to do that I need to know whether the Code behind for that button click is executed or not. I am not having access to the code behind. I have controls(this is not wpf Controls) on Button.
I have Used White TestStack framework to get the control of Windows controls(like Button)
My UI may be Responsive while button click method performing lengthy calculations. UI might be on different thread.
So is it possible to check whether the code behind for that button click is executed or not. I wanted to check it only from button control.
Thanks.
Basically you are telling you having two logics:
Logic for the click
Logic for "enabling" the button
I guess you need to use a RelayCommand from the GalaSoft.MvvmLight.Command (please check this URL on how to install and this one on how use it).
Basically, you just bind your command in the view:
<Button Command="{Binding StoreActionCommand}"/>
And in the ViewModel ("code behind"), you specify two different actions: one is what the button do, and the next one is if this code can be executed.
You need to add this to the constructor of your ViewModel:
// declare your public attribute (it can be a property too if you want)
public ICommand StoreActionCommand;
// and on your ViewModel constructor
StoreActionCommand = new RelayCommand(StoreCommandExecute, CanStoreCommand);
private void StoreCommandExecute()
{
// here you add actions to your queue
}
private bool CanStoreCommand()
{
// here, you can check if your queue is empty or not..
return true;
}
If you want to add items, do you need to store it on an XML? Could it be just memory based? You could use a Queue for it.
For the background Thread, I would advise you to start working with the Task library. Besides being easier to understand, it is easier to control it. And never from your background thread try to interact with the UI. you can do it with some thread synchronization, but I would not recommend it. If you are doing something in the background, let it only do something and then return. Otherwise, use the IProgress classes to notify changes in the UI.
EDIT
I still note sure if that's what your looking for, but I'll try to help you again.
I usually do that do notify the UI when I have to do a background task notifying changes to the UI. You can use the IProgress to change some properties that are used by your UI. Note that you do not change the UI directly.. never! You just need to make a set of properties that do that for you.
First, create some properties so that your UI can connect to them:
private string executionStatus = string.Empty;
public string ExecutionStatus
{
get { return executionStatus; }
set
{
executionStatus = value;
RaisePropertyChanged(nameof(ExecutionStatus));
}
}
private bool canRun = true;
public bool CanRun
{
get { return canRun; }
set
{
canRun = value;
RaisePropertyChanged(nameof(CanRun));
}
}
Then, change the StoreActionCommand and CanStoreCommand to something like:
private bool CanStoreCommand()
{
return CanRun;
}
// note the async here
private async void StoreActionCommand()
{
CanRun = false;
// notification
var progressNotification = new Progress<string>((value) => ExecutionStatus = value);
// real background thread goes here, without blocking the UI
await Task.Run(() => {
DoWork(progressNotification);
});
CanRun = True;
}
private void DoWork(IProgress<string> progress)
{
progress.Report("Starting...");
try
{
progress.Report("doing x...");
progress.Report("doing y...");
}
catch(Exception err)
{
progress.Report(err);
}
progress.Report("Process finished");
}
Hope this helps you.
If you have to work on more items, you could control the CanRun as you want.
Another interesting stuff is that you could create a Model class in order to send more than just a string (you can pass a status and a flag indicating the possibility of the user to click the CanRun button during the work, but then a new Thread would be fired in parallel do the one that is already running).

Handle popup messages - Coded UI Test

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.

Is there a publicly accessible event to mark a ModalDialog close?

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");
}

Window disappears too fast for Coded UI Test

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.

ThreadState exception in initialization

It has been a long question, so here is the summary first,
I have a Client class for my messenger project.
My Client class has a Socket.
I use its BeginReceive method to get messages from server.
In async callback of BeginReceive, I get the message using EndReceive.
When I get the message, I fire the MessageReceived event with message itself.
I use this Client class in my message form.
In message form, I can get the received message by attaching a method to Client.MessageReceived.
I use OnMessageReceived method for this purpose.
When I get the message, I can show it on a TextBox (using Control.Invoke) or MessageBox.
I can also add a new tab to my TabControl in OnMessageReceived.
When I try to initialize a WebBrowser control, I get ThreadStateException.
The control I use to display messages derives from WebBrowser control, so I need it.
Threading.Thread.CurrentThread.ThreadState is "Background".
I don't think you'll need the details but you can find the detailed question I first intented to post below.
Many thanks.
I'm working on a messenger project (Server is a Windows Service and Client is a Windows Forms Application) using Net.Socket's async methods.
I fire Client's MessageReceived event in callback of Socket.BeginReceive;
Everything is how I want them to be until here.
I use MessageReceived event in my form (the one that two people writes to each other) I can do anything I want to the UI using Control.Invoke method (if required) with one annoying exception.
I have tabbed conversations in the form so when a message arrives, I check if there is an open conversation (tab) with the sender. If yes, I select that tab and display the message. If no, I create a new ConversationTab.
Now, I'm sorry if it's being a long question than it should be or if I can't explain myself sufficently. English is not my first language and this is my first question in Stack Overflow.
So, here is the ConversationTab:
public class ConversationTab : TabPage
{
public User Friend { get; private set; }
public MessageBrowser MessageBrowser { get; private set; }
public ConversationTab(User friend) : base(friend.DisplayName)
{
Friend = friend;
MessageBrowser = new MessageBrowser();
Controls.Add(MessageBrowser);
MessageBrowser.Dock = DockStyle.Fill;
}
}
MessageBrowser derives from WebBrowser and the reason I use this is because I could not apply custom styles (color, font, size) 'per message' using RichTextBox. RichTextBox.SelectedColor doesn't always work or I couldn't make it work as intended. MessageBrowser let's me use CSS instead. Wandering off of the subject? Sorry.
Here is the NewConversation method I call when MessageReceived event fires:
public void NewConversation(User friend)
{
ConversationTab tab = Conversations.FirstOrDefault(c => c.Friend.Id == friend.Id);
if (tab != null)
ActiveConversation = tab;
else
{
tab = new ConversationTab(friend);
// add tab to TabControl
}
// bla
}
"Conversations" gets the tab pages of the TabControl and "ActiveConversation" gets or sets the SelectedTab property of the TabControl.
My point in creating these properties are mostly thread-safety logic inside.
So the question: It's throwing ThreadStateException in "tab = new ConversationTab(friend)" part of the above code. It is the "MessageBrowser = new MessageBrowser()" part of the first code and the constructor of MessageBrowser. The reason of why I didn't provide MessageBrowser's constructor code is because the exception is thrown before any line of inner code gets executed (It is about WebBrowser's constructor, I get this exception when I try to initalize a WebBrowser, too.)
Actually I don't even get an exception, the application just closes there without notifying me about anything. I saw the exception when I try to call "MessageBrowser = new MessageBrowser()" on ConversationTab's constructor in Watch window.
I'm kind of new to using threads and asynchronous methods.
MSDN says:
ThreadStateException is thrown by methods that cannot perform the requested operation due to the current state of a thread.
In my case, the thread's state is "Background".
I have no clue about what am I doing wrong.
Thank you very much if you read the whole thing and thank you much more if you can help.
This seems to be related to using COM (web browser control uses COM) in .NET where thread apartment needs to be set to STA.
Try adding [STAThread] to your entry point.
Have a look at this.

Categories