I'm using selenium webdriver, C#.
Is it possible to make work webdriver with Firefox select file dialog?
Or must I use something like AutoIt?
If you are trying to select a file for upload Selenium 2 supports HTML file inputs. For example:
HTML
<input type="file" id="uploadhere" />
Selenium Code
IWebElement element = driver.FindElement(By.Id("uploadhere"));
element.SendKeys("C:\\Some_Folder\\MyFile.txt");
Basically you "type" (with SendKeys) the full file path to the file input element. Selenium handles the file selection dialog for you.
However if you want to manipulate an arbitrary file selection dialog, then like Anders said, you have to go outside of Selenium.
No, WebDriver cannot interact with dialogs - this is because dialogs are the domain of the operating system and not the webpage.
I know people that have had luck with autoit as well as the Automation API provided by .Net.
Another option would be to skip the file dialog entirely and issue a POST or a GET, but this requires more advanced knowledge of the website as well as understanding how construct a POST/GET.
You could try Webinator, it is similar to Selenium in the sense that it is powered by WebDriver. It provides file dialog capabilities and I've had great success with it.
Here is another solution using remotewebdriver, it works like magic and I loved it.
Here is the class I have:
driver.findElementByLinkText("Upload Files").click();
driver.setLogLevel(Level.ALL);
System.out.println(driver.getCurrentUrl());
WebElement element = driver.findElement(By.xpath("//input[#name='file_1']"));
LocalFileDetector detector = new LocalFileDetector();
//Now, give the file path and see the magic :)
String path = "D://test66T.txt";
File f = detector.getLocalFile(path);
((RemoteWebElement)element).setFileDetector(detector);
element.sendKeys(f.getAbsolutePath());
//now click the button to finish
driver.findElementByXPath("//html/body/div[9]/div[1]/a/span").click();
You asked for using AutoIt for the file dialog. This is easy and you can do it with C#.
Install nuget package AutoItX.Net
Use the demo code below
Change the dialog title string as you need
public static void InsertIntoFileDialog(string file, int timeout = 10)
{
int aiDialogHandle = AutoItX.WinWaitActive("Save As", "", timeout); // adjust string as you need
if (aiDialogHandle <= 0)
{
Assert.Fail("Can't find file dialog.");
}
AutoItX.Send(file);
Thread.Sleep(500);
AutoItX.Send("{ENTER}");
Thread.Sleep(500);
}
This helped me after I had trouble with Appium/Selenium related to file dialogs.
According to Nadim Saker
.Net has a library to handle file upload dialog. It has a SendKeys class that has a method SendWait(string keys). It sends the given key on the active application and waits for the message to be processed. It does not return any value.
This can be done as follows, tested and working with Internet Explorer and Chrome driver
var allowsDetection = this.Driver as IAllowsFileDetection;
if (allowsDetection != null)
{
allowsDetection.FileDetector = new LocalFileDetector();
}
Driver.FindElement(By.Id("your-upload-input")).SendKeys(#"C:\PathToYourFile");
Reference https://groups.google.com/forum/#!msg/webdriver/KxmRZ8MkM4M/45CT4ID_WjQJ
If you want to upload a file, and not use the WebDriver, the only solution I've come across is AutoIt. It allows you to write a script and convert it to an executable which you can then call from within your code. I've used it successfully while working with an ActiveX control.
Another approach is to use System.Windows.Forms.SendKeys.SendWait("pathToFile"). I use it with success everywhere where i cant just send keys to element like described by #prestomanifesto.
I used this to solve the problem... try it if all above does not works
Actions action = new Actions(driver);
action.SendKeys(pObjElement, Keys.Space).Build().Perform();
Thread.Sleep(TimeSpan.FromSeconds(2));
var dialogHWnd = FindWindow(null, "Elegir archivos para cargar"); // Here goes the title of the dialog window
var setFocus = SetForegroundWindow(dialogHWnd);
if (setFocus)
{
Thread.Sleep(TimeSpan.FromSeconds(2));
System.Windows.Forms.SendKeys.SendWait(pFile);
System.Windows.Forms.SendKeys.SendWait("{DOWN}");
System.Windows.Forms.SendKeys.SendWait("{TAB}");
System.Windows.Forms.SendKeys.SendWait("{TAB}");
System.Windows.Forms.SendKeys.SendWait("{ENTER}");
}
Thread.Sleep(TimeSpan.FromSeconds(2));
}
Related
How do I right-click on an image and Copy image address using selenium C#?
I used this code:
var productimgs = driver.FindElement(By.XPath("//*[#id='coconut-baby-organic']/div[1]/div[1]/div/a/div/img"));
Actions action = new Actions(driver);
action.ContextClick(productimgs).Build().Perform();
action.SendKeys(Keys.ArrowDown).Build().Perform();
action.SendKeys(Keys.ArrowDown).Build().Perform();
action.SendKeys(Keys.ArrowDown).Build().Perform();
action.SendKeys(Keys.ArrowDown).Build().Perform();
action.SendKeys(Keys.Enter).Build().Perform();
I expect it to right-click on the image and keep going down till it finds "Copy image address" then click it but it's not.
This is a known issue in the Chrome Selenium Web driver.
Alternatives:
Use Firebox web driver.
You can achieve a similar functionality, using the inputsimulator. Note: The Chrome window must be in focus.
// find the element and click on it.
IWebElement element = driver.FindElement(By.XPath("some_xpath"));
Actions action = new Actions(driver);
action.ContextClick(element).Build().Perform();
// navigate in menu
var input = new InputSimulator();
input.Keyboard.KeyPress(VirtualKeyCode.DOWN);
input.Keyboard.KeyPress(VirtualKeyCode.DOWN);
input.Keyboard.KeyPress(VirtualKeyCode.DOWN);
input.Keyboard.KeyPress(VirtualKeyCode.DOWN);
input.Keyboard.KeyPress(VirtualKeyCode.RETURN);
Why on earth you want to do this using context click? The approach will require browser constantly being in focus, it means that you will not be able to do anything else with your computer while the test is running, neither you will be able to run your Selenium tests in parallel mode.
Instead I would recommend fetching src attribute of the <img> tag - that would be the URL you're looking for. It can be done via IWebElement.GetAttribute() function
Example code:
var productimgs = driver.FindElement(By.XPath("//*[#id='coconut-baby-organic']/div[1]/div[1]/div/a/div/img"));
var src = productimgs.GetAttribute("src");
Console.WriteLine("Image URL is: " + src);
I'm doing a program in c # using scrapySharp or HtmlAgilityPack. But I have the disadvantage of that part of the information that I need, to appear when I click on an HTML element (Button, link ).
In some forums it was commented that when using Selenium you could manipulate the html elements, so I tried the following
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
// Defines the interface with the Chrome browser
IWebDriver driver = new ChromeDriver ();
// Auxiliary to store the label element in href
Element IWebElement;
// Go to the website
driver.Url = url;
// Click on the download button
driver.FindElement (By.Id ("Download button")). Click ();
but being a web automation test, it opens a browser and the website to perform the selection process (clicks), so it is not of my use, since I have to perform the inspection on several websites internally.
Although I can continue using Selenium, I am looking for ways to avoid using the browser and instead click without it.
Does anyone know how to achieve the click of the link or button, without the need to open a browser for web scraping?
Hope this would be helpful to anyone who has the same requirements.
If you want to avoid opening the browser, you could use below settings in the ChromeDriver.
// settings for avoid opening browser
var options = new ChromeOptions();
options.AddArgument("headless");
var service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
// url to access and scrape
var url = "https://example.com";
using (var driver = new ChromeDriver(service, options))
{
// access the url
driver.Navigate().GoToUrl(url);
// Click on the download button - copied from your code above
driver.FindElement (By.Id ("Download button")). Click ();
}
In addition to above below links also, you may find useful,
can-selenium-webdriver-open-browser-windows-silently-in-background
running-webdriver-without-opening-actual-browser-window
I have problem with browse button and switching to file dialog. I cannot use my file path control and just send there my string with file path and file itself, as it's readonly and in fact some behind control is my input filepath.
Here's my code
driver.FindElement(By.Id("browseButton")).Click();
driver.SwitchTo().ActiveElement().SendKeys(filepath);
Above code fills my control for file path, as i can see that on UI. But my open file dialog is still opened and i do not know how to close it and submit my upload.
Uploading files in Selenium can be a pain, to say the least. The real problem comes from the fact that it does not support dialog boxes such as file upload and download.
I go over this in an answer to another question, so I will just copy/paste my answer from there here. The code examples should actually be relevant in your case, since you are using C#:
Copied from previous answer on question here:
Selenium Webdriver doesn't really support this. Interacting with non-browser windows (such as native file upload dialogs and basic auth dialogs) has been a topic of much discussion on the WebDriver discussion board, but there has been little to no progress on the subject.
I have, in the past, been able to work around this by capturing the underlying request with a tool such as Fiddler2, and then just sending the request with the specified file attached as a byte blob.
If you need cookies from an authenticated session, WebDriver.magage().getCookies() should help you in that aspect.
edit: I have code for this somewhere that worked, I'll see if I can get ahold of something that you can use.
public RosterPage UploadRosterFile(String filePath){
Face().Log("Importing Roster...");
LoginRequest login = new LoginRequest();
login.username = Prefs.EmailLogin;
login.password = Prefs.PasswordLogin;
login.rememberMe = false;
login.forward = "";
login.schoolId = "";
//Set up request data
String url = "http://www.foo.bar.com" + "/ManageRoster/UploadRoster";
String javaScript = "return $('#seasons li.selected') .attr('data-season-id');";
String seasonId = (String)((IJavaScriptExecutor)Driver().GetBaseDriver()).ExecuteScript(javaScript);
javaScript = "return Foo.Bar.data.selectedTeamId;";
String teamId = (String)((IJavaScriptExecutor)Driver().GetBaseDriver()).ExecuteScript(javaScript);
//Send Request and parse the response into the new Driver URL
MultipartForm form = new MultipartForm(url);
form.SetField("teamId", teamId);
form.SetField("seasonId", seasonId);
form.SendFile(filePath,LoginRequest.sendLoginRequest(login));
String response = form.ResponseText.ToString();
String newURL = StaticBaseTestObjs.RemoveStringSubString("http://www.foo.bar.com" + response.Split('"')[1].Split('"')[0],"amp;");
Face().Log("Navigating to URL: "+ newURL);
Driver().GoTo(new Uri(newURL));
return this;
}
Where MultiPartForm is:
MultiPartForm
And LoginRequest/Response:
LoginRequest
LoginResponse
The code above is in C#, but there are equivalent base classes in Java that will do what you need them to do to mimic this functionality.
The most important part of all of that code is the MultiPartForm.SendFile method, which is where the magic happens.
One of the many ways to do that is to remove the disable attribute and then use typical selenium SendKeys() to accomplish that
public void test(string path)
{
By byId = By.Id("removeAttribute");
const string removeAttribute = #"document.getElementById('browseButton').removeAttribute('disabled');";
((IJavaScriptExecutor)Driver).ExecuteScript(removeAttribute);
driver.FindElement(byId).Clear();
driver.FindElement(byId).SendKeys(path);
}
You can use this Auto IT Script to Handle File Upload Option.
Auto IT Script for File Upload:
AutoItSetOption("WinTitleMatchMode","2") ; set the select mode to
Do
Sleep ("1000")
until WinExists("File Upload")
WinWait("File Upload")
WinActivate("File Upload")
ControlFocus("File Upload","","Edit1")
Sleep(2000)
ControlSetText("File Upload" , "", "Edit1", $CmdLineRaw)
Sleep(2000)
ControlClick("File Upload" , "","Button1");
Build and Compile the above code and place the EXE in a path and call it when u need it.
Call this Once you click in the Browse Button.
Process p = System.Diagnostics.Process.Start(txt_Browse.Text + "\\File Upload", DocFileName);
p.WaitForExit();
I want to make a small application that would read a title from current opened youtube video from my firefox or chrome browser and save it in .txt file on my computer.
I need an idea on how to accomplish this. Is it somehow possible to access tabs opened in firefox or chrome via c#?
Do you understand me? I want to somehow parse the data from browser from seleceted tab and save it into .txt file.
Would I have to use greasemonkey scripts for this?
If the tab is currently active then you could do this in C#:
string browser = "Firefox"; //or change to chrome/iexplore
var browserProc = Process.GetProcessesByName(browser)
.Where(b => b.MainWindowTitle.Contains("YouTube"))
.FirstOrDefault();
if (browserProc != null)
{
string mainTitle = browserProc.MainWindowTitle;
}
You can then parse the relevant parts of mainTitle if you need to.
You could use Win32 API calls to do this. FindWindowEx, GetWindowText, etc.
http://msdn.microsoft.com/en-us/library/windows/desktop/ff468919(v=vs.85).aspx
I have a C# application that When the user clicks Print the application creates a PDF in memorystream using ITextSharp. I need to print this PDF automatically to a specific printer and tray.
I have searched for this but all i can find is using javascript, but it doesn't print to a specific tray.
Does anyone have an examples of doing this?
Thank you.
You can change printer tray with this code.
string _paperSource = "TRAY 2"; // Printer Tray
string _paperName = "8x17"; // Printer paper name
//Tested code comment. The commented code was the one I tested, but when
//I was writing the post I realized that could be done with less code.
//PaperSize pSize = new PaperSize() //Tested code :)
//PaperSource pSource = new PaperSource(); //Tested code :)
/// Find selected paperSource and paperName.
foreach (PaperSource _pSource in printDoc.PrinterSettings.PaperSources)
if (_pSource.SourceName.ToUpper() == _paperSource.ToUpper())
{
printDoc.DefaultPageSettings.PaperSource = _pSource;
//pSource = _pSource; //Tested code :)
break;
}
foreach (PaperSize _pSize in printDoc.PrinterSettings.PaperSizes)
if (_pSize.PaperName.ToUpper() == _paperName.ToUpper())
{
printDoc.DefaultPageSettings.PaperSize = _pSize;
//pSize = _pSize; //Tested code :)
break;
}
//printDoc.DefaultPageSettings.PaperSize = pSize; //Tested code :)
//printDoc.DefaultPageSettings.PaperSource = pSource; //Tested code :)
in the past I spent a lot of time searching the web for solutions to print pdf files to specific printer trays.
My requirement was: collect several pdf files from server directory and send each file to a different printer tray in a loop.
So I have tested a lot of 3rd party tools (trials) and best practices found in web.
Generally all theese tools can be divide into two classifications: a) send pdf files to printer in a direct way (silent in UI) or b) open pdf files in UI using a built-in pdf previewer working with .Net-PrintDocument.
The only solution that fix my requirement was PDFPrint from veryPdf (drawback: it´s not priceless, but my company bought it). All the other tools and solutions didn´t work reliable, that means: calling their print-routines with parameter e.g. id = 258 (defines tray 2; getting from installed printer) but printing the pdf file in tray 3 or pdf was opened in print previewer (UI) with lost images or totally blank content and so on..
Hope that helps a little bit.
There is a tool called pdfprint:
http://www.verypdf.com/pdfprint/index.html
And here they discuss some solutions:
http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/da99765f-2706-4bb6-aa0e-b90730294cb4