Opening windows file dialog with selenium - c#

I know this issue has been addressed a lot, but I haven't found a problem similar to mine, so please tell me if there's a solution.
I'm using selenium webdriver (chrome) and C# to test a web application.
In the application I have a button, which opens a windows file dialog in order to select and upload the file.
I am using Click() to click on the button and SendKeys() to paste the file's path in the windows dialog and to hit "Enter".
I'm not trying to control the dialog with selenium.
It's successful most of the time, but sometimes the dialog isn't opened once the button is clicked and it seems to be frozen for several minutes (it's impossible to click the button manually as well), but the test resumes as if the dialog had been opened. After 2-3 minutes the windows dialog finally appears, but needless to say that the entire test is messed up.
It is not a problem in the program itself, as the problem never occurres when the click is preformed manually.
What could be the problem and how can I solve it?
Please have in mind I cannot change the program I'm testing.
Thank you

You can do it without White using Microsoft UI Automation directly.
Without TestStack White. No sense to use the whole library for one window automation. White is wrapper only.
var FirefoxWindowElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty,"MozillaWindowClass"));
FirefoxWindowElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty,"#32770"))
//You can navigate directly to input field or just use the keyboard because input field is always focussed
SendKeys.SendWait("YOUR FILE PATH here");
Keyboard.Press(Key.Return);

What if you create a wait for dialog?
public void waitForElement()
{
while(!yourDialogElement.Displayed)
{
yourButtonElement.Click()
System.Threading.Thread.Sleep(1000) // sleep for 1000 milliseconds
}
}
You will probably want to build a try/catch into that button click, and perhaps build a counter into your loop and pass a timeout limit.
Let me know if this works or if you need more help!

You should consider adding a library called WHITE to your framework. This acts like Selenium but for Win32 applications and can handle most types of Windows dialog objects via Microsoft UI Automation.
With WHITE set up, you can add a method at the point in your code where the button is clicked by Selenium that opens up the dialog window. This method can poll for the presence of the dialog and if, after a set time, the window does not appear you could either fail the test there and then or try clicking the button again.
You could also poll indefinitely until the window appears if you are confident it always will. I would set an upper limit myself though to 5 minutes or whatever you feel is right here to prevent some sort of infinite loop situation.

Related

How to add extension to running remote multilogin webdriver? (Selenium C#)

First I tried to add extension directly from chrome webstore, but problem is alert popup which appears after you click "add to chrome" is not reachable by selenium. After I wanted to try using options.AddExtension, but multilogin profile starts before selenium takes control so this method is useless. I know that I can manually import .crx for every profile but there are thousands of profiles and I need to automate process of installing extensions. I don't know what to do, I heared there's option to reach popup alert in chrome webstore but can't find it. Or maybe there are other ways to install extension after browser started? I'm glad for any help or advice
I have 2 possible scenarios for you, hope that works out since I don't have direct access to this specific need you have because the extensions may differ.
Not using Selenium, you gonna start the chrome process using the class Process and add the flag --load-extension= to load the specific profile/extension that you need. You can see the entire comma here. To sum, you can use this snippet below to load:
chrome --user-data-dir=/tmp/someuniquedirname --load-extension=path/to/extension --no-first-run //Note: some flags may change between versions of chrome, see full documentation
After defining the extension and start chrome, you can now get hold of the process with Selenium by using another flag: --remote-debugging-port=http://localhost:[localporthere]. After that, start the process than tell to Selenium to get hold of that process with the port and do your job.
Another way is to start the process installing the extension manually and in another Thread use some Automation UI (Teststack.White or FlaUI) to click on the popup you have. I can't extend here in the entire code for this solution because it will go to a opinion-based answer, but you can check on FlaUI for that use, and follow that path:
Selenium starts the program, click on the install extension and wait for the popup to show-up;
New Thread;
FlaUI gets hold of the process that you already start;
Using UIElements, click on the "ok" button you need;
FlaUI drops;
Back to the main thread.
If you need any clarifications about the solutions above, just comment and I'll try to help you further.

How to make a pop-up dialog that does not stop the program execution?

I am doing automation testing and while writing the test cases I don't want to go looking at the logs after the testing is done, because I sit in front of my PC when the automation tests are run.
Is there any way that I can make pop up dialogs?
Like if a button is clicked, the pop up dialog should appear saying the button is clicked, but the program execution shouldn't be stopped. I tried with messagebox.show but the problem is it stops execution of the program.
Is there anyway to do this without stopping the execution of the program?
Simply use modeless dialogs. See here.
in essence: Use form.Show() instead of form.ShowDialog().

WPF accessing opened print dialog and close them

I have a WPF application, which needs to log out user after 5 min of inactivity.
But if user open a print dialog of any page, and do not touch screen for 5 minutes,
even if I log out user and clear all child elements, print dialog still stays on top of WPF form and somebody can come and continue to print what ever page user stayed.
I tried to use;
Window window = Application.Current.MainWindow;
or
FocusManager.GetFocusedElement();
but could not achieve to access to PrintDialog and close it.
Is there any way to access it and close if user did not respond to print dialog?
I fixed this weird problem by using
white project.
http://white.codeplex.com/wikipage?title=Working%20with%20window&referringTitle=Programming%20using%20white
By using application class, I am able to access all ModalDialogs in WPF project, and close them.
Application application = White.Core.Application.Attach(Process.GetCurrentProcess().Id);
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
White.Core.UIItems.WindowItems.Window window = application.GetWindow("MainWindow");
List<White.Core.UIItems.WindowItems.Window> modalWindows = window.ModalWindows();
foreach (White.Core.UIItems.WindowItems.Window modalWindow in modalWindows)
{
modalWindow.Close();
}
}
You can use p/invoke for this.
Use findwindow to find any window and destroywindow to close it.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
If I understand correctly, you're able to do the user logout at the 5 minute mark (I presume via the timer event handler), but if the print dialog was open, then the printout can still end up happening.
The question is, what's really the important thing here, closing the dialog, or preventing the subsequent printout? Also, are you logging out the user but keeping the program going, or is the program quitting?
If the app is supposed to shut down, then your code can call the Application object's Shutdown() method, which will close any modal dialogs as part of the shutdown process.
If the app is supposed to keep running without a current user, then I would think the White library is your best bet. It's unclear why you've moved away from this.
With or without closing the print dialog, however, the printing code should check to see if the user is still logged in before it actually prints something. If the login expired while the print dialog was on screen, the printing code should simply exit without printing anything.

In WinForms, has anyone seen invoking of one modal dialog from another modal dialog cause the modality to get undone?

The Questions:
Has anyone seen invoking of one modal dialog from another modal dialog cause the modality to get undone?
If you wanted to make a call with ShowDialog so that you get back a result, but without it being modal (other Forms still respond), how would you do it? (We're not trying to do that... but if there is a way to do that, maybe we're doing that accidentally.)
The Details:
We have implemented our own Print dialog that has buttons that bring up the standard PrintDialog, the standard PageSetupDialog, and the standard PrintPreviewDialog. And the printing is all done with our own PrintDocument class derived from the standard PrintDocument class. So, we're trying to follow the standard practices... we just have a few extra settings that we need the user to start with.
We invoke our Print dialog from a menu using ourPrintDialog.ShowDialog(mainWindow). When it comes up, it is properly modal (all other windows are non-responsive... in particular, that mainWindow). From that Print dialog, there are buttons to invoke each of the other three dialogs... and all are invoked with ShowDialog(ourPrintDialog), making that first Print dialog as its parent. In the case of the PrintDialog and the PageSetupDialog, they come up modal (mainWindow and ourPrintDialog and all other windows are non-responsive). And when we OK or Cancel those, it returns to the first Print dialog (ourPrintDialog) which is still modal (no other windows respond).
However, in the case of the standard PrintPreviewDialog, although we invoke it the same way (ShowDialog with the first dialog as its parent), it comes up not entirely modal. Our main window becomes responsive again. So, you can start manipulating the underlying document that the Print dialog is in the process of printing... which of course violates many assumptions. And when you close the Preview dialog, returning to the original Print dialog, it is also now not in a modal state... the main window is still responding.
We have tried doing this in a plain test app, and it works fine... the modality is not broken when going into the PrintPreviewDialog. So, it seems to be some specific interaction between the PrintPreviewDialog (since it doesn't happen with the other two) and our app's main window (since it doesn't happen with the test app). Any suggestions on what that might be? (And hence my two questions above.)
Thanks in advance for any suggestions!
Not sure why it's happening , but you might try running Spy++ on the windows and watch the messages that flow, might give you a clue as to what is happening between the windows, or the properties of the windows in question.

Dialog MessageBox sometimes hidden behind the main form

Some of our non-technical users are having problems where a dialog MessageBox in our application can sometimes be displayed behind the main form and the application does not accept any input until the messagebox (which they can't see) is dismissed.
The application is written in C# and the message boxes are standard eg the code can be as simple as MessageBox.Show(message, caption) and the messageboxes can be created by the main UI thread (ie not some background thread). The Application does not have to be run full-screen, but 90% of our users do run it full-screen.
Most of the time ((maybe > 99%) the messageboxes display correctly and I have never managed to see how it goes wrong, but I have seen a machine when it has gone wrong.
One thing I did notice is that if you have an application which displays a dialog box, then when you look at your taskmanager, you normal only see one entry in the application list. Whenever the messagebox is hidden, you will see two entries, one for the main application and another entry for this message box.
It is easy enough to fix the problem once you know what has happened, but some of our non-technical users are confused by it and end up switching off their computers. (And the ones who are using Remote Desktop are even more confused when that doesn't solve the problem).
I do not think it is related to the operating system as I have seen it happen in Vista and have been told it also happens in a terminal session on a Windows 2003 server.
Does anything know why this is happening and more importantly if anything can be done to avoid it?
Some overloads of the MessageBox.Show() method take an IWin32Window parameter as the first argument. If you pass in your Form as that first argument it should prevent this from happening.
Is it always the same message box (for the same message?) coming the same form?
Ideally, you should try to find some way to reproduce the problem at will, or at least automatically. This will make your debugging easier and you can then be sure that your future change will have fixed the bug, rather than have to wait for a few weeks for the feedback from your users.
If it is always the same message and in the same window, resulting from the same action, and if the MessageBox call is reasonably easy to trigger from an user point-of-view and if your UI is relatively standard, you could automate the UI with an AutoIT script and have it run in a loop until the problem happens.
And/or, you could create a "debug"-build of your applications that you could give it to some users (preferably the ones that seem to run into the problem the most often) that would write the contents of a StackFrame object to a log file or something similar everytime before calling a MessageBox (you could create a wrapper around the MessageBox to make this easier).
Then, when one of your users gets the problem, you can look at the log file and see where it came from (source code file, line, calls stack etc). You could also compare this to the logs from other users and see if, everytime, the MessageBox comes from the same location or if it varies.
This would show you where the problematic MessageBox is called from and where.
There may be easier solutions (especially if your application has a lot of assemblies) involving some .Net debugger that you would attach to your application when the problem occurs in order to see the call stack, etc, but I only did this with native applications (using OllyDbg) so far and not .Net. Others may be able to expand further on this idea...
Confirm the problem. What we do to fix it is following:
Run new Task and display the message box
In the main UI thread while task is still running - wait in the loop that does DoEvents. Something like this
UPDATED 2015-12-17.
Reproduced problem yestarday. To repo in my case - minimize the app, "wait" popup occures (in our case it happens after some idle time), then in the task bar click on the main app icon. This "hides" the popup so it is not possible to bring it on the screen. The code below was tested and solves the problem. But I still do not understand what/why it happens.
private static DialogResult ShowMessageBox(
string message,
string caption,
MessageBoxButtons buttons,
MessageBoxIcon icon)
{
var showMessageBoxTask = new Task<DialogResult>(() =>
{
var form = new Form() {TopMost = true};
var result = MessageBox.Show(
form,
PrepareMessage(message),
caption,
buttons,
icon);
form.Dispose();
return result;
});
showMessageBoxTask.Start();
while (!showMessageBoxTask.IsCompleted && !showMessageBoxTask.IsFaulted)
{
Application.DoEvents();
}
return showMessageBoxTask.Result;
}
You say "the messageboxes can be created by the main UI thread", which I assume means they aren't always created by the main UI thread. Your problem sounds like MessageBox.Show is occasionally called from another thread.
In the parent form, add this before MessageBox.Show():
this.TopMost = false;

Categories

Resources