Selenium WebDriver to test an ActiveX Control - c#

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.

Related

C# Selenium Edge Driver unable to download file - Keep file prompt shows up

I am using C# with Selenium for QA automation, and I am having issues with downloading an .xml file, because a prompt is always showing up asking if I want to keep the file. It also opens a second tab to execute the download, closing it after the prompt shows up.
[keep file prompt][1]
Using Chrome I do not see this behavior.
I searched all over and could not find a EdgeOptions() and/or AddArguments() capable of taking care of this issue.
Any ideas?
You need to use JS to interact with elements in another browser. I have had such experience and I used if else statement in my method to handle that problem. Just look trough the Selenium documentation, JS with selenium examples and so long so for.
Just add this to your OneTimeSetup method. Make sure to run Visual Studio as administrator. This works since Edge 105+:
public void SetEdgeXmlDownloadPolicy()
{
var keyName = "Software\\Policies\\Microsoft\\Edge\\";
var valueName = "ExemptFileTypeDownloadWarnings";
var valueData = #"{""domains"": ["" * ""], ""file_extension"": ""xml""}";
var currentUser = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
var currentKey = currentUser.OpenSubKey(keyName, true);
if (currentKey == null)
currentKey = currentUser.CreateSubKey(keyName);
if (currentKey.GetValue(valueName) == null)
currentKey.SetValue(valueName, valueData);
}

Choose a File from OpenFileDialog with C#

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

Visual Studio Command for going to a specific item in source control explorer

Im looking for a way to automatically open Source Control Explorer from inside a plugincode.
So far I managed to open it by executing the command
View.TfsSourceControlExplorer
However, this does not seem to accept any arguments.
My goal here is to do something like this:
destination = "$/dev/framework/someFolder";
_dteObject.ExecuteCommand("View.TfsSourceControlExplorer", destination);
Which will them show me Source Control Explorer in the specified destination.
To anwser CSharpie's comment :
Also there seems to be a bug, if you call navigate to a file of the same directory as the explorer currently is in, everything will disappear.
I had the same problem, got two ways of solving this :
Truncate the filename from the path to only Navigate to folders.
Navigate to root first ("$/"), then navigate to the file you want.
Both works fine in VS2013.
And thanks for the "Application.DoEvent()" fix when the SourceControlExplorer's not opened.
Use the following code to show Source Control Explorer in the specified destination:
public void SelectFolder(string path)
{
dte.ExecuteCommand("View.TfsSourceControlExplorer");
Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExplorerExt explorer =
GetSourceControlExplorer();
if (explorer != null)
explorer.Navigate(path);
}
private Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExplorerExt GetSourceControlExplorer()
{
Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt versionControl =
dte.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as
Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt;
if (versionControl == null)
return null;
return versionControl.Explorer;
}
I believe this is not possible. The source explorer detects the team project and drops you at the root of the team project node. $/myproject/ ..
Happy to be proven wrong on this one...

Monitor file selection in explorer (like clipboard monitoring) in C#

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.

Is it possible to open a PDF inside a c# application with Acrobat.dll?

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

Categories