使用Firefox的C#Selenium fileupload

时间:2018-03-23 11:43:42

标签: c# selenium

我的代码如下。这在Google Chrome上非常有用。我也可以更改下载文件夹。但是在Firefox上工作并不好。当我开始使用firefox进行测试时,它就是打开选择窗口。文件正在添加到fileupload对象但不是关闭窗口。此外,我尝试了一些firefox选项,但没有工作。如果不是,我想在Web应用程序中为此做一些方法。例如,fileupload和filedownload,例如。

var fileUpload = td.Driver.FindElement(By.XPath("//*[@id='fileInput']"));
fileUpload.SendKeys(@"C:\Users\xxxx\Desktop\Deneme.txt");


CreateDocument.RunTest(new TestData() {
 Driver = new ChromeDriver(Utils.GetFirefoxOptions("FileUpload")),
  TestPageUrl = theTestPageURL,
  UserName = "deneme",
  Password = "123",
  TestCode = "Deneme",
  TestName = File Upload Testi ",
 Version = "1.0.0.6",
});



public static FirefoxOptions GetFirefoxOptions(string TestCode) {
  CreateDownloadFolder(TestCode);
  FirefoxOptions pf = new FirefoxOptions();
  pf.SetPreference("browser.preferences.instantApply", true);
  pf.SetPreference("browser.helperApps.neverAsk.saveToDisk", "text/plain, application/octet-stream, application/binary, text/csv, application/csv, application/excel, text/comma-separated-values, text/xml, application/xml");
  pf.SetPreference("browser.helperApps.alwaysAsk.force", false);
  pf.SetPreference("browser.download.dir", @ "C:\TestDownloads\" + TestCode);
  pf.SetPreference("browser.download.folderList", 0); pf.SetPreference("browser.download.manager.showWhenStarting", false);
  return pf;
}

1 个答案:

答案 0 :(得分:0)

我有一个我们使用的解决方案:

它涉及使用Javascript和名为Dojo的第三方JavaScript库。

IJavaScriptExecutor exec = (IJavaScriptExecutor)Driver;
string content = ... //  <-- This needs to be the string content of the Dojo js library.
content = Convert.ToBase64String(Encoding.UTF8.GetBytes(content));
exec.ExecuteScript("var s=window.document.createElement('script');s.innerHTML=atob('" + content + "');window.document.head.appendChild(s);");

var target = ...   // <--  This is the IWebElement that maps to the file upload input dom object.

string targetId = target.GetAttribute("id");
// Add an id if the target doesn't have one
            if (targetId == null || string.IsNullOrEmpty(targetId))
            {
                targetId = "seleniumDragAndDropInput_target";
                exec.ExecuteScript("sId=function(e, i){e.id = i;};sId(arguments[0], arguments[1]);", target.InnerObject, targetId);
            }


exec.ExecuteScript(
                    "var f=dojo.create('form', {id: 'seleniumDragAndDropInput_form', style: {position: 'fixed', left: 0, top: 0, width:'100px', height: '100px'}}, dojo.body());"
                    + "dojo.create('input', { type: 'file', id: 'seleniumDragAndDropInput' }, f);");
            var input = new Textbox(By.Id("seleniumDragAndDropInput"));
            input.TypeText(filePath);  // < -- This is the path to your file on the system

            exec.ExecuteScript(
                    "var files=dojo.byId(\"seleniumDragAndDropInput\").files;"
                    + "var eve=document.createEvent(\"HTMLEvents\");"
                    + "eve.initEvent(\"drop\", true, true);"
                    + "eve.dataTransfer = {files:files};"
                    + "eve.type = \"drop\";document.getElementById('" + targetId + "').dispatchEvent(eve);");

            exec.ExecuteScript("dojo.destroy('seleniumDragAndDropInput_form');");
            if (targetId == "seleniumDragAndDropInput_target")
            {
                exec.ExecuteScript("document.getElementById('seleniumDragAndDropInput_target').id = null");
            }

我们将Dojo内容转换为base64,然后通过Javascript atob对其进行解密 - 这是为了解决字符串转义问题等问题。

此代码适用于Internet Explorer,FireFox和Chrome。 本质上 - FileUpload输入受到保护,不受Javascript交互的影响,以保证您的本地文件免受不道德网站的侵害。 如果您尝试使用Javascript与网站中的文件输入进行交互,它只会给您一条错误消息。 但是,有一个漂亮的解决方法。

您可以使用可写路径字段创建自己的文件输入控件(使用dojo)。 然后,您可以在控件上触发'drop'事件,但将'drop'事件路由到您要与之交互的真实文件输入。

结果是文件上传被触发,模仿某人将文件拖放到文件上传本身。

这种方法比大多数尝试使用Robot等与文件浏览对话框进行交互的方式更好 - 根据您的操作系统和浏览器,这些对话框可能会有所不同。 在我的测试中 - 它至少适用于IE,FireFox和Chrome。

我唯一警告你的是,这不适用于Selenium Grid。 由于C#代码不一定与浏览器在同一台机器上运行 - 在这种情况下,它将难以解析您希望上传的文件的文件路径 - 除非它在网络共享上都可以通过相同的路径访问