I have a little problem - I don't know how to Select a File and Open it in the Mozilla OpenFileDialog.
First, I open the Dialog by pressing "Browse" with Selenium and then I want to put in a File-Name (I know the exact location via Environment variable)
In my case: Environment.GetEnvironmentVariable("Testplatz_Config_Location") + "\TestConfig.fpc"
So my Question, does anyone know how to handle an already open OpenFileDialog using C# - Or is it perhaps possible to handle this with Selenium?
Selenium does not provide any native way to handle windows based pop ups. But we have some third party tools like AutoIT and RobotClass to handle those windows based pop ups. Refer those and give it a a try.
AutoIT with Selenium and Java
Selenium/SeleniumWebDriver does not provide any native way to handle windows based popups. Still, the best way is to miss this popup using
IWebElement element = driver.FindElement(By.Id("file_input"));
element.SendKeys(filePath);
but this is not allways is possible. And if it is not, you can use my lib:
https://github.com/ukushu/DialogCapabilities
by the following way:
OpenFileDialog:
// for English Windows
DialogsEn.OpenFileDialog(#"d:\test.txt");
//For windows with russian GUI
Dialogs.OpenFileDialog("Открыть", #"d:\test.txt");
MultiFile selection in OpenFileDialog:
var filePaths = new string[] {#"d:\test1.txt", #"d:\test2.txt", #"d:\test3.txt"};
//Or for Eng windows:
DialogsEn.OpenFileDialog(filePaths);
//for russian language OS
Dialogs.OpenFileDialog("Открыть", filePaths);
You can use sendKeys() on the file upload element to upload a file using selenium by path. I would suggest using this instead of AutoIT or Robot.
So instead of clicking on the browse button, you send the path directly to the file input element using sendKeys().
Example:
IWebElement element = driver.FindElement(By.Id("file_input"));
element.SendKeys(
Environment.GetEnvironmentVariable("Testplatz_Config_Location") + "\TestConfig.fpc");
i used selenium with Robot class from Java awt. This is my solution
public static void setClipboardData(String string) {
//StringSelection is a class that can be used for copy and paste operations.
StringSelection stringSelection = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
public static void uploadFile(String fileLocation) {
try {
//Setting clipboard with file location
setClipboardData(fileLocation);
//native key strokes for CTRL, V and ENTER keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
} catch (Exception exp) {
exp.printStackTrace();
}
}
Related
I have been working to automate some tests for my companies website using Selenium's IWebDriver, and have run into some ActiveX controls (a dialog to select and upload a file) that I cannot seem to automate. I haven't been able to find any specific information on this on the internet.
I am, however, able to actually load the dialog box by triggering the "open" element within the page (the user will have to manually click the file destination and the open button), but it fails the test (this code doesn't make sense to me as to why it opens the dialog box, I originally had the SendKeys and Click in reverse order).
private void UploadFile()
{
foreach (var element in driver.FindElements(By.TagName("button")))
{
string open = element.Text;
if (open == "Open")
{
element.SendKeys(#"My\Relative\Path");
element.Click();
}
}
}
I've tried to execute JavaScript within my code to open the file, but my attempts have failed each time and my coworkers have told me that it wouldn't work anyways since ActiveX controls the file upload.
Any thoughts?
Thanks!
AutoIt was the solution for this. I was able to execute a script within my C# project.
private void UploadFile()
{
foreach (var element in driver.FindElements(By.TagName("button")))
{
string open = element.Text;
if (open == "Open")
{
element.SendKeys(#"C:\My\Relative\Path\");
element.Click();
string executable = #"C:\My\Relative\Path\fileUploadScript2.exe";
System.Diagnostics.Process.Start(executable);
}
}
}
Thanks to #SiKing for the push in the right direction.
I get window dialog when try to open file (like that http://www2.warwick.ac.uk/services/its/servicessupport/web/sitebuilder2/faqs/files/upload_multiple/xp_file_browser.png ).
So I need set file path and click OK button. Selenium doesn't have native functionality for it. I have found how it do on java:
StringSelection abc= new StringSelection("E:\\Study Materials\\Resume And Cv\\Sample 1_0.doc");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(abc, null);
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
Does something like that support in C #?
I found answer in following article http://cheryjose.blogspot.com/2013/03/how-to-interact-with-dialog-windows.html - I sent path and Enter keypress.
I am trying to create a little helper application, one scenario is "file duplication finder". What I want to do is this:
I start my C# .NET app, it gives me an empty list.
Start the normal windows explorer, select a file in some folder
The C# app tells me stuff about this file (e.g. duplicates)
How can I monitor the currently selected file in the "normal" windows explorer instance. Do I have to start the instance using .NET to have a handle of the process. Do I need a handle, or is there some "global hook" I can monitor inside C#. Its a little bit like monitoring the clipboard, but not exactly the same...
Any help is appreciated (if you don't have code, just point me to the right interops, dlls or help pages :-) Thanks, Chris
EDIT 1 (current source, thanks to Mattias)
using SHDocVw;
using Shell32;
public static void ListExplorerWindows()
{
foreach (InternetExplorer ie in new ShellWindowsClass())
DebugExplorerInstance(ie);
}
public static void DebugExplorerInstance(InternetExplorer instance)
{
Debug.WriteLine("DebugExplorerInstance ".PadRight(30, '='));
Debug.WriteLine("FullName " + instance.FullName);
Debug.WriteLine("AdressBar " + instance.AddressBar);
var doc = instance.Document as IShellFolderViewDual ;
if (doc != null)
{
Debug.WriteLine(doc.Folder.Title);
foreach (FolderItem item in doc.SelectedItems())
{
Debug.WriteLine(item.Path);
}
}
}
You can do this with the shell automation interfaces. The basic process is to
Run Tlbimp on Shdocwv.dll and
Shell32.dll (or directly add a
reference from VS).
Create an
instance of the ShellWindows
collection and iterate. This will
contain both Windows Explorer and
Internet Explorer windows.
For
Windows Explorer windows, the
IWebBrowser2.Document property will
return a IShellFolderViewDual
reference.
The IShellFolderViewDual
has a SelectedItems method you can
query and an event for changes you
can handle.
I am trying to develop a util (using system-hook) for that works like an expander (user selects some text and presses a hotkey and it is expands). It should work with Visual Studio.
I want to implement this using Windows API because I want to develop an app that works globally with any application (whether you're using VS, or wordpad, you should get the same functionality).
I've been able to do this successfully with notepad, wordpad, etc. using EM_ GETSEL and EM_REPLACESEL messages. But these APIs are not working with Visual Studio, or ms word.
What APIs should I use to be able to
1. Detect what text is selected.
2. Send input to the editor.
I am programming in C#. If you must know what I am trying to do... I am trying to make a universal port of ZenCoding that works on any editor. So all help will be appreciated.
For part 2 you could try using Windows Input Simulator which is an open source project I've just released to Codeplex to wrap the Win32 SendInput. Instead of SendKeys which just simulates text input, you can actually simulate real key strokes and complex chords to the active window.
In your case, if the user can perform the task with the Keyboard, this project will help you, otherwise you'd need to find another solution.
Hope this helps.
Why don't you use a System.Windows.Forms.SendKeys class for simulating keyboard input from user?
You can use:
SendKeys.SendWait("^C"); //CTRL+C
var selectedText = Clipboard.GetText();
var newText = Replace(selectedText);
SendKEys.SendWait("^V"); //CTRL+V
You can use WPF's Automation functionality, encapsulated in these two namespaces:
System.Windows.Automation
System.Windows.Automation.Provider
As an example, this is a method for finding an automation target element (e.g. a typical win control):
public static AutomationElement FindElement(AutomationElement context, PropertyCondition[] conditions)
{
// if no conditions, there's no search to do: just return the context, will be used as target
if (conditions == null)
{
return (context);
}
// create the condition to find
System.Windows.Automation.Condition condition = null;
if (conditions.Length <= 0)
{
throw (new ArgumentException("No conditions specified"));
}
else if (conditions.Length == 1)
{
condition = conditions[0];
}
else
{
AndCondition ac = new AndCondition(conditions);
condition = ac;
}
// find the element
CacheRequest creq = new CacheRequest();
creq.TreeFilter = Automation.ControlViewCondition;
using (creq.Activate())
{
AutomationElement e = AutomationContext(context);
AutomationElement target = e.FindFirst(TreeScope.Subtree, condition);
return (target);
}
}
Whatever you try, be absolutely sure to try it, ASAP, with Visual Studio 2010 beta 2. The editor has largely been rewritten, and hacks that work with an earlier version should be tested again.
I know that I can display a PDF file in my c# executable (not web app) with:
private AxAcroPDFLib.AxAcroPDF axAcroPDF1;
axAcroPDF1.LoadFile(#"somefile.pdf");
axAcroPDF1.Show();
But that is the regular pdf viewer like in the browser. I don't want that. I want full Adobe Standard or Professional functionality in my C# application using the Adobe controls. For example, if I use the code above, it loads in the C# app and I can see the adobe toolbar (print, save, etc.) But it is useless to me because I need things like save which cannot be done with the activex viewer above. Specifically, you cannot save, just as you cannot within the broswer.
So, I referenced the acrobat.dll and am trying to use:
Acrobat.AcroAVDocClass _acroDoc = new Acrobat.AcroAVDocClass();
Acrobat.AcroApp _myAdobe = new Acrobat.AcroApp();
Acrobat.AcroPDDoc _pdDoc = null;
_acroDoc.Open(myPath, "test");
pdDoc = (Acrobat.AcroPDDoc)(_acroDoc.GetPDDoc());
_acroDoc.SetViewMode(2);
_myAdobe.Show();
It opens adobe acrobat but it opens it outside of my c# application. I need it to open in my c# application like the activex library does. Can it be done with these libraries?
If I cannot open it in my c# application I would like to be able to "hold" my c# app tied to it so the c# app knows when I close the adobe app. At least that way I'd have some measure of control. This means I would hit open, the adobe app opens. I close the adobe app, my C# app is aware of this and loads the newly changed doc with the activex library (because I don't need change ability anymore, just displaying.)
I have the full versions of adobe acrobat installed on my computer. It is not the reader.
Thank you for any help.
edit:
There is an example in vb in the adobe acrobat sdk. I believe it is called activeview.
you can check out ABCpdf. I dont know if it has this capability but we have used it for several of our apps
Using a webbrowser control would be an option to display the content.
IText# may help you out.
You can create PDF's and I believe you can use it to read and modify them.
As for displaying in the app..... I am not sure how to display them with iText or if it is possible (have not tried this yet), sorry. iText does let you convert to RTF which may be one approach.
Best option is to write a listener which tells your calling code when Adobe.exe is no longer running. Something like the following (with tweaks for your uses) should work:
public void Open(string myPath)
{
Acrobat.AcroAVDocClass _acroDoc = new Acrobat.AcroAVDocClass();
Acrobat.AcroApp _myAdobe = new Acrobat.AcroApp();
Acrobat.AcroPDDoc _pdDoc = null;
_acroDoc.Open(myPath, "test");
_pdDoc = (Acrobat.AcroPDDoc) (_acroDoc.GetPDDoc());
_acroDoc.SetViewMode(2);
_myAdobe.Show();
NotifyAdobeClosed += new EventHandler(Monitor_NotifyAdobeClosed);
MonitorAdobe();
}
private void Monitor_NotifyAdobeClosed(object sender, EventArgs e)
{
NotifyAdobeClosed -= Monitor_NotifyAdobeClosed;
//Do whatever it is you want to do when adobe is closed.
}
private void MonitorAdobe()
{
while(true)
{
var adcount = (from p in Process.GetProcesses()
where p.ProcessName.ToLower() == "acrobat"
select p).Count();
if (adcount == 0)
{
OnNotifyAdobeClosed();
break;
}
}
}
public event EventHandler NotifyAdobeClosed;
public void OnNotifyAdobeClosed()
{
if (NotifyAdobeClosed != null)
NotifyAdobeClosed(this, null);
}