Handle popup messages - Coded UI Test - c#

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.

Related

Xamarin Forms Navigation PopAsync isn't working

I'm working on an app in Xamarin.Forms, and things have been going pretty steadily, until I ran into a navigation error. The thing that mystifies me about it is that I've already been successfully using the same code calls on other pages, but suddenly with this page, it isn't working.
I have designed a bit of a unique navigation flow because of the visual result that I'm trying to accomplish, using a combination of master-detail that has two tiers of navigation pages using the normal push / pop code. I was following suggestions from this article on medium.com.
The app initializes a main page called "Root Navigation" that initializes the master and detail pages.
public App()
{
InitializeComponent();
MainPage = new RootNavigation();
}
Root Navigation page:
public partial class RootNavigation : MasterDetailPage
{
private MenuPage menuPage;
private NavigationPage OuterPage;
private NavigationPage InnerPage;
public RootNavigation()
{
this.Master = this.menuPage = new MenuPage();
this.menuPage.MenuItemsListView.ItemSelected += Menu_ItemSelected;
var viewModel = new SelectEmployeeViewModel();
var page = new SelectEmployeePage(viewModel);
SetAsDetailPage(page);
}
To navigate forward in the app, I'm using a method called "set as detail page," that bridges the gap between master-detail behavior and navigation push / pop behavior.
private void SetAsDetailPage(ContentPage page)
{
NavigationPage.SetHasNavigationBar(newPage, false);
if (newPage.GetType() == typeof(JobDetailPage))
{
newPage.ToolbarItems.Add(
new ToolbarItem()
{
Text = "Back",
Command = new Command(() => BackButton_Clicked())
});
}
this.InnerPage = this.InnerPage ?? new NavigationPage();
this.InnerPage.Navigation.PushAsync(page);
this.OuterPage = this.OuterPage ?? new NavigationPage(this.InnerPage);
this.Detail = this.Detail ?? this.OuterPage;
}
Then, navigating backward calls one of two methods: "BackButton_Clicked()" or "ReturnToJobList()".
private void ReturnToJobList()
{
while (InnerPage.CurrentPage.GetType() != typeof(JobsPage))
{
var current = InnerPage.CurrentPage.ToString();
System.Diagnostics.Debug.WriteLine($"'{current}' attempting Navigation.Pop()");
InnerPage.PopAsync();
}
}
private void BackButton_Clicked()
{
this.InnerPage.PopAsync();
}
All of the pages that display read-only data have navigated without issue. When I'm done with the page, I have it raise a call to the MessagingCenter, and the root navigation receives the message and performs the desired navigation. For example, the "MenuPage_ItemSelected" event handler fires the code:
if (e.SelectedItem.ToString().ToLower() == "log out")
{
Device.InvokeOnMainThreadAsync(() =>
{
InnerPage.PopToRootAsync();
this.IsPresented = false;
});
}
This seems to be working fine, after I spent a while researching that when a secondary page calls 'pop to root' on a background thread, I have to invoke it on the main thread.
Ok, so finally to the problem page: The "update job notes" page. The page raises a call to the Messaging Center, and the Root Navigation page picks that up and executes the following code:
private async void SaveJobNotes(ContentPage sender)
{
if (sender is UpdateJobNotesPage notesPage)
{
bool result = await SaveNewJobNote(notesPage);
var message = result ? "Saved changes" : "An error occurred; changes not saved";
await DisplayAlert("Save", message, "OK");
}
ReturnToJobList();
}
Stepping through the code, it correctly executes SaveNewJobNote() and returns true. Then, it awaits displaying the alert "Saved Changes". Then, the code then gets stuck in an infinite while loop in the "ReturnToJobList()," forever printing out into the debug output [0:] 'Application.Views.UpdateJobNotesPage' attempting Navigation.Pop(). After about a million cycles I get tired of waiting and quit the debugger. I can't seem to do anything to make the page go away!
I've tried a bunch of stuff with investigating the differences between PopAsync and PopModalAsync. After checking what's on the navigation stacks for the different pages in question, everything looks exactly like what I'd expect -- there's nothing on the modal stacks for anything (because I never called PushModalAsync on anything), there's 0 on the RootNavigation stack, 1 on the OuterPage stack, and 4 on the InnerPage stack. That all makes perfect sense to me, but it still doesn't pop the Update Job Notes page. I also tried code with Navigation.RemovePage(page) with no success. The only difference there was that the debugger included printing a warning about my code and suggesting I use PopAsync() instead.
I also tried some different things with making the PopAsync() call from this.Navigation, this.Outer, this.Outer.Navigation, this.Inner, this.Inner.Navigation, all with no success.
I have already looked at a bunch of other questions on Stack Overflow including this question and this question but none of them seem to apply in this case. Any assistance would be greatly appreciated!!
I remember this was happening to me.
I forget exactly what was the cause, but I had some funky navigation going on as well. My problem was around popups and at one point, they were creating a new stack. So when I popped, I was getting unexpected results.
I would suspect you are also creating another stack somewhere, especially if you are at 0 in the debugger.
The culprit is most likely lurking around that InvokeOnMainThread().
I haven't really figured out what the problem is with the code block that I created that was supposed to call InnerNavigation.PopAsync() until the Job List page was visible. It seems like all the variables in that code block evaluate to values that I'd expect, but somehow it doesn't seem to be able to pop anything off the stack.
However, I did change my code block that handles saving Job Notes, and it does now pop the Save Job Notes page off the stack.
private async void SaveJobNotes(ContentPage sender)
{
this.InnerPage.PopAsync(); //I don't understand why this works and the
//other didn't, but it correctly pops the page
if (sender is UpdateJobNotesPage notesPage)
{
bool noteSaved = await SaveNewJobNote(notesPage);
bool progressSaved = await SaveJobProgress(notesPage);
var message = noteSaved && progressSaved ?
"Changes were save successfully" :
"An error occurred; changes not saved";
await DisplayAlert("Save", message, "OK");
}
}

In Ranorex how to handle popup

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

Selenium - How to handle popup with event listener (C#)

I'm using selenium with C# (default browser - FireFoX).
There are some sites that popup message after unknown time (if any).
I can't use wait or sleep, because I don't know on which screen the popup will appear. Using 'try-Catch' on each page is not very smart....
The solution I thought of, is to use an event listener to listen to the popup/s and then it will clicks the 'X' button. Of course the listener has to be in a Thread, and each test might have an array of Threads that gets the list of events and xpath/ ID's.
Did anyone do such things? Is there any example / article / tutorial to help me with it ?
10X,
Gil
Thinking of an old Chinese proverb, when faced with such questions, I go to the SeleniumHQ github repository and look at the tests.
You want your wait time to be small so that you don't waste too much time waiting when no alert is present. You can call the pop-up handling code when a page opens or just before your test leaves that page; depends on your application's behavior.
I would simply override the FirefoxDriver to automatically accept the alert and silence the alert exception:
class FirefoxDriverEx : FirefoxDriver {
private static DesiredCapabilities Capabilities() {
var capa = DesiredCapabilities.Firefox();
capa.SetCapability(CapabilityType.UnexpectedAlertBehavior, "accept");
return capa;
}
public FirefoxDriverEx()
: base(Capabilities()) { }
protected override Response Execute(string driverCommandToExecute, Dictionary<string, object> parameters) {
try{
return base.Execute(driverCommandToExecute, parameters);
} catch (UnhandledAlertException) {
return base.Execute(driverCommandToExecute, parameters);
}
}
}
Here is a usage example:
var driver = new FirefoxDriverEx();
driver.Navigate().GoToUrl("http://the-internet.herokuapp.com/javascript_alerts");
driver.FindElementByXPath("//button[.='Click for JS Alert']").Click();
string text = driver.FindElementById("result").Text;

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.

Categories