Access to other window of application - WhiteStack - c#

I would like to test to Outlook application and send an email to me by using White Stack framework. I implemented code who click on 'New Item' and after that the new window appears. I want to type a my mail to TextBox 'To' but I don't know how get to access to second window 'Untitled - Message (HTML)'. Photo
[TestMethod]
public void mail()
{
var application = Application.Launch(appPatch);
Thread.Sleep(2000);
var window = application.GetWindow(appTitle, InitializeOption.NoCache);
SearchCriteria searchCriteriaNewEmail = SearchCriteria.ByText("New Email");
Button buttonNewEmail = window.Get<Button>(searchCriteriaNewEmail);
buttonNewEmail.Click();
Thread.Sleep(1000);
string windowTitle = "Untitled‬ - Message(HTML)";
var window2 = application.GetWindow(windowTitle, InitializeOption.NoCache);
SearchCriteria searchCriteriaTo = SearchCriteria.ByText("To");
TextBox tbxTo = window2.Get<TextBox>(searchCriteriaTo);
tbxTo.BulkText = "mymail#gmail.com";
Thread.Sleep(2000);
window.Close();
}

The "second window" is in the same process id, so with that you can't simply use the .GetWindow() method.
For MDI applications you should use MdiChild(), or if it is a modal window, use .ModalWindow() on the parent window, or go back to the application then use Window() to get the window.
I would add that getting the window by it's title is not recommended, since that will change as you type the new title of the e-mail.

Related

C# Coded UI testing - enter text into a javascript window.prompt text box

I'm running coded UI tests in Visual Studio Enterprise 2017.
My webpage under test has a javascript popup asking for an e-mail address to be entered. I can locate the confirmationPopup (highlight is drawn correctly), and I can click buttons within it, such as the cancel.
confirmationPopup = new WinWindow();
confirmationPopup.SearchProperties.Add(WinWindow.PropertyNames.ControlType, "Dialog");
confirmationPopup.SearchProperties.Add(WinWindow.PropertyNames.ClassName, "#32770");
confirmationPopup.TechnologyName = "MSAA";
confirmationPopup.Find();
confirmationPopup.DrawHighlight();
var cancelButton = new WinButton(confirmationPopup);
cancelButton.SearchProperties.Add(WinButton.PropertyNames.Name, "Cancel");
Mouse.Click(cancelButton);
What I am struggling to do is enter text in the popup's input box:
var textInput = new WinEdit(confirmationPopup);
textInput.SearchProperties.Add(WinEdit.PropertyNames.ClassName, "Edit");
textInput.TechnologyName = "MSAA";
textInput.DrawHighlight();
textInput.Text = "bill#microsoft.com";
The highlight is drawn around the correct control, but the textInput.Text= line gives an error
Additional information: SetProperty of "Text" is not supported on control type: Window
Any ideas what I'm doing wrong?
Here is an example of interacting with javascript prompt window.
// go to a public site which has a prompt
var window = BrowserWindow.Launch("http://www.javascriptkit.com/javatutors/alert2.shtml");
var contentDiv = new HtmlDiv(window);
contentDiv.SearchProperties.Add(HtmlDiv.PropertyNames.Id, "contentcolumn", PropertyExpressionOperator.EqualTo);
var promptButton = new HtmlInputButton(contentDiv);
promptButton.SearchProperties.Add(HtmlInputButton.PropertyNames.ControlDefinition, "name=\"B4\"", PropertyExpressionOperator.Contains);
promptButton.SetFocus();
Keyboard.SendKeys("{ENTER}");
// now the prompt is showing, find it and set text
var promptWindow = new WinWindow();
promptWindow.SearchProperties.Add(WinWindow.PropertyNames.ControlType, "Dialog");
promptWindow.SearchProperties.Add(WinWindow.PropertyNames.ClassName, "#32770");
promptWindow.DrawHighlight();
var middleWindow = new WinWindow(promptWindow);
middleWindow.DrawHighlight();
var inputBox = new WinEdit(middleWindow);
inputBox.DrawHighlight();
inputBox.Text = "Hello world!";
When using the inspect feature of coded ui, I see there is a middle window. Using it or not, I am able to find the edit.

How to use TestStack.White to click the button under the menu

I tried to use white to click the new project button, I try using the below code, but it can not work, anyone can help me?
public void Notepad()
{
Application app = Application.Launch("C:\\Program Files (x86)\\SourceMonitor\\SourceMonitor.exe");
Window window = app.GetWindow("SourceMonitor", InitializeOption.NoCache);
Button button = window.Get<Button>("File");
button.Click();
app.Kill();
}
I already figured out how to do it, below is the correct code:
public void Notepad()
{
// Arrange
Application app = Application.Launch("C:\\Program Files (x86)\\SourceMonitor\\SourceMonitor.exe");
Window window = app.GetWindow("SourceMonitor", InitializeOption.NoCache);
// Act
MenuBar menuBar = window.MenuBar;
menuBar.MenuItem("File","New Project").Click(); ; //can use any other search criteria as well.
}

Get Form Data Using DLL Name

I am creating a tool on an application that opens some windows forms to get information from users, my tool should deal with these windows forms by itself without users' interactions.
I have initiated an event to get the opened form's process when it opens by the following code:
mgmtWtch = new ManagementEventWatcher("Select * From Win32_ProcessStartTrace");
mgmtWtch.EventArrived += WatchManagementEvent;
mgmtWtch.Start();
The shown window has OK button which i want to click, and i don't know how to make this action. while the parameter that i can get from this event is
EventArrivedEventArgs e
my question is how can i click the OK button through this event handler?
thanks in advance.
Have you looked at .Net's GUI automation API?
You'll want the UIAutomationClient and UIAutomationTypes assemblies.
I've used this API to drive installers, UIs during testing etc.
I found this link useful initially.
http://blogs.msdn.com/b/oldnewthing/archive/2013/04/08/10409196.aspx
e.g. assuming you have the parent window (i.e. the Form) for the button and you know the button's ID:
using System.Windows.Automation;
....
static AutomationElement FindById(AutomationElement root, string id, bool directChild)
{
Assert(root != null, "Invalid input: ParentWindow element 'root' is null.");
Condition conditions = new PropertyCondition(AutomationElement.AutomationIdProperty, id);
return root.FindFirst(directChild ? TreeScope.Children : TreeScope.Descendants, conditions);
}
....
AutomationElement button = FindById(containerWindow, id.ToString(), true);
InvokePattern invokePattern = null;
try
{
invokePattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
}
catch (InvalidOperationException)
{
MessageBox.Show("The UI element named " + button.GetCurrentPropertyValue(AutomationElement.NameProperty) + " is not a button");
return false;
}
invokePattern.Invoke();
If you don't know the button's ID but do know it's name i.e. the text on the button then replace AutomationElement.AutomationIdProperty with AutomationElement.NameProperty in FindById (and rename the method appropriately)
Assuming the button is in the top-level Form window and you know the title displayed in this Form window, the following code will get the button's parent window:
bool ignoreCase = true; // or false if preferred
Condition conditions = new PropertyCondition(
AutomationElement.NameProperty,
windowTitle,
ignoreCase ? PropertyConditionFlags.IgnoreCase : PropertyConditionFlags.None
);
AutomationElement myForm =
AutomationElement.RootElement.FindFirst(
TreeScope.Children,
conditions );
The Window Title can be retrieved from the process you already have via the process' MainWindowTitle property.

Show Dialog is not showing the dialog box

I am trying to find out reason why ShowDialog() is not showing the dialog box for me.
I have an application where I have a credential dialog box(A) for the user to enter credentials. And I have another dialog box(B) to display some custom msg based on the user's credential.
After the user enter's credentials in A, I am doing something with it.
when I am trying to show the msg in B, ShowDialog() is not showing dialog B.
Can you guys think of any reason?
Here is the code:
bool isInternetConnected = class.CheckInternetConnection(ref error);
if(!String.IsnUllOrEMpty(error))
{
DialogBox dialogBox = new DialogBox();
dialogBox.Title = "Credentials";
dialogBox.State = DialogBox.States.NoFooter;
dialogBox.ShowInTaskbar = false;
CredentialsContent Credentials = new CredentialsContent();
Credentials.ContentCompleted += new EventHandler<ContentCompletedEventArgs>(
dialogBox.OnContentCompleted);
dialogBox.MainContent = Credentials;
bool? result = dialogBox.ShowDialog();
hasAccess = result.HasValue ? result.Value : false;
}
UpdateDialog updateDialog = new UpdateDialog();
updateDialog.ShowModal = true;
bool? isTrue = updateDialog.ShowDialog();
I got it resolved.
What was happening is that windows was treating the first window(A) as main window.When it was getting closed the next window(B) as inconsequential.
So even with showdialog() it was not showing it.
The trick was to define UpdateDialog() at the start of the application.
The same question is answered here:
Open new window after first

How to test file download with Watin / IE9?

I'm trying to test file download with Watin 2.1.0 against IE9. I used the suggested code from the accepted answer to the question Downloading a file with Watin in IE9, like this:
var downloadHandler = new FileDownloadHandler(fname);
WebBrowser.Current.AddDialogHandler(downloadHandler);
link.ClickNoWait();
downloadHandler.WaitUntilFileDownloadDialogIsHandled(15);
downloadHandler.WaitUntilDownloadCompleted(200);
However, the downloadHandler.WaitUntilFileDownloadDialogIsHandled(15) call times out. What should I do?
File download dialog doesn't work in IE9 (Windows7) NetFramework 4.0.
Following code snippet might help you resolve the issue:
First you must add references UIAutomationClient and UIAutomationTypes to your test project.
After In Ie9 Tools -> View Downloads -> Options define path to your save folder.
The next method extends Browser class
public static void DownloadIEFile(this Browser browser)
{
// see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx)
Window windowMain = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(browser.hWnd, 5));
System.Windows.Automation.TreeWalker trw = new System.Windows.Automation.TreeWalker(System.Windows.Automation.Condition.TrueCondition);
System.Windows.Automation.AutomationElement mainWindow = trw.GetParent(System.Windows.Automation.AutomationElement.FromHandle(browser.hWnd));
Window windowDialog = new Window(WatiN.Core.Native.Windows.NativeMethods.GetWindow(windowMain.Hwnd, 5));
// if doesn't work try to increase sleep interval or write your own waitUntill method
Thread.Sleep(1000);
windowDialog.SetActivate();
System.Windows.Automation.AutomationElementCollection amc = System.Windows.Automation.AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Condition.TrueCondition);
foreach (System.Windows.Automation.AutomationElement element in amc)
{
// You can use "Save ", "Open", ''Cancel', or "Close" to find necessary button Or write your own enum
if (element.Current.Name.Equals("Save"))
{
// if doesn't work try to increase sleep interval or write your own waitUntil method
// WaitUntilButtonExsist(element,100);
Thread.Sleep(1000);
System.Windows.Automation.AutomationPattern[] pats = element.GetSupportedPatterns();
// replace this foreach if you need 'Save as' with code bellow
foreach (System.Windows.Automation.AutomationPattern pat in pats)
{
// '10000' button click event id
if (pat.Id == 10000)
{
System.Windows.Automation.InvokePattern click = (System.Windows.Automation.InvokePattern)element.GetCurrentPattern(pat);
click.Invoke();
}
}
}
}
}
if you want click 'Save As' replace foreach code with this
System.Windows.Automation.AutomationElementCollection bmc = element.FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Automation.ControlViewCondition);
System.Windows.Automation.InvokePattern click1 = (System.Windows.Automation.InvokePattern)bmc[0].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000));
click1.Invoke();
Thread.Sleep(10000);
System.Windows.Automation.AutomationElementCollection main = mainWindow.FindAll(System.Windows.Automation.TreeScope.Children
,System.Windows.Automation.Condition.TrueCondition);
foreach (System.Windows.Automation.AutomationElement el in main)
{
if (el.Current.LocalizedControlType == "menu")
{
// first array element 'Save', second array element 'Save as', third second array element 'Save and open'
System.Windows.Automation.InvokePattern clickMenu = (System.Windows.Automation.InvokePattern)
el.FindAll(System.Windows.Automation.TreeScope.Children, System.Windows.Automation.Condition.TrueCondition) [1].GetCurrentPattern(System.Windows.Automation.AutomationPattern.LookupById(10000));
clickMenu.Invoke();
//add ControlSaveDialog(mainWindow, filename) here if needed
break;
}
}
Edit:
Also if you need to automate the save as dialog specifying a path and clicking save you can do it by adding this code just before break;
private static void ControlSaveDialog(System.Windows.Automation.AutomationElement mainWindow, string path)
{
//obtain the save as dialog
var saveAsDialog = mainWindow
.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.NameProperty, "Save As"));
//get the file name box
var saveAsText = saveAsDialog
.FindFirst(TreeScope.Descendants,
new AndCondition(
new PropertyCondition(AutomationElement.NameProperty, "File name:"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)))
.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
//fill the filename box
saveAsText.SetValue(path);
Thread.Sleep(1000);
//find the save button
var saveButton =
saveAsDialog.FindFirst(TreeScope.Descendants,
new AndCondition(
new PropertyCondition(AutomationElement.NameProperty, "Save"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button)));
//invoke the button
var pattern = saveButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
pattern.Invoke();
}
IE9 no longer uses a dialog window for saving files. Instead, it uses the notification bar to prevent focus from being removed from the web site. See http://msdn.microsoft.com/en-us/ie/ff959805.aspx under "Download Manager" for reference.
Unfortunately, this means that the current FileDownloadHandler in WatiN will not work. It instantiates a "DialogWatcher" class per browser instance that is a basic message pump for any kind of child window. When child windows are encountered, the DialogWatcher checks to see if the window is specifically a dialog (which the notification bar is not). If it is a dialog, it then iterates over the registered IDialogHandler instances calling "CanHandleDialog." Even if the notification bar were a dialog, it is of a different Window Style (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx), which is how WatiN detects the type of dialog.
From what I can see, there is no support yet for detecting the IE 9 notification bar and its prompts in WatiN. Until that support is added, you will not be able to automate downloading files in IE9.

Categories