3

I am automating a file upload with C# and selenium (running Google Chrome), but I don't want to type the file path on the file input, I would like to emulate how a real user would do it (Typing the path in the file dialog box). Using the SendKeys.SendWait() method is the perfect solution for this, however I am encountering a problem.

I have the following code.

var e = driverWait.Until(driver => driver.FindElement(By.Id("file-button")));
e.Click();
SendKeys.SendWait(@"C:\Users\seawolf\Downloads\Result.pdf");

The problem is before the open file dialog pops up, SendWait begins typing on the keyboard, so the path is typed on the Webpage and not the dialog box.

Is there a way until an open file dialog pops up with C#? It doesn't have to be built into selenium as it's easy to integrate everything with driverWait. What I want to do is something like:

driverWait.Until(_ => DialogIsOpen() );

Thanks to @Jimi, here is my solution.

var chromeElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1"));
var openDialogClassName = "#32770";
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, chromeElement, TreeScope.Subtree, (sender, _) =>
    {
    var element = sender as AutomationElement;
    Console.WriteLine("running");
    if (element.Current.ClassName.Equals(openDialogClassName))
    {
        SendKeys.SendWait(@"C:\Users\seawolf\Downloads\Result.pdf");
    }
});
lightning_missile
  • 2,821
  • 5
  • 30
  • 58
  • 2
    Start a Timer? Add a delay? UI Automation to [detect when Dialog is opened](https://stackoverflow.com/a/58233065/7444103) and set the value of a child control? – Jimi Nov 10 '19 at 17:04
  • You would probably want to use something to do with `OpenFileDialog` (I don't know if there is a method to check if one is opened or not, there might be) – Menotdan Nov 10 '19 at 17:05
  • 1
    @Jimi I have thought of using Thread.Sleep, however it could be difficult to determine how long the dialog could open. – lightning_missile Nov 10 '19 at 17:06
  • 3
    I don't know whether Selenium can notify (or event knows) when a Dialog (that is not a popup) is opened. UI Automation is what I usually rely upon. [This is a simplified version](https://stackoverflow.com/a/55028688/7444103) of the code I linked in my previous comment. It works pretty well (to adapt to this use case, of course). Otherwise, you could start a Timer, giving it a long interval. – Jimi Nov 10 '19 at 17:13
  • Hi @Jimi. Can you look at my edit? I tried using the UIAutomation in your answer but my code does nothing. What am I doing worng? Thanks. – lightning_missile Nov 10 '19 at 19:15
  • First thing to do is to test with `Spy++` or `Inspect` what is the class name of the DialogBox and register that information. `#32770` is the generic Dialog class. It doesn't mean that your WebBrowser uses the standard Win32 dialog. Then, this dialog is not a chlld of the main Window. It's aTop level Window. But, it has the same ProcessID of the main Window. You have to detect when a Dialog (of the class type you have found) is opened and if it has the same ProcessID of the Application you're watching. The first code sample I linked does exactly this. Read the notes. – Jimi Nov 10 '19 at 19:21
  • @Jimi no. I have been absolutely stupid. My code did not work because it is not being executed. Now I fixed it and it is working fine now. I also verified the class name and the process id. Thanks for the idea! Though I got the solution from one of your answers, do you mind answering this question too so I can accept it? Thanks. – lightning_missile Nov 11 '19 at 13:20

1 Answers1

0

This is what I use. I just put a wait to allow for the window to appear before using sendwait. A majority of times, you will switch focus to the upload window once it appears.

//Click browse btn to open upload window
     driver.FindElement(By.ClassName("uploadbtn")).Click();

//Wait for Upload Window to appear(may not be necessary in some cases)
     Thread.Sleep(2000);

//Send the path and then click the Right arrow key
     SendKeys.SendWait(GetProjectRoot() + @"\DataFiles\red.png" + @"{RIGHT}");

//Click Enter Key to submit
     SendKeys.SendWait(@"{Enter}");
Isaac M
  • 56
  • 4