File upload with Selenium

Published on March 29, 2006 and tagged with selenium  testing  tip

In my Selenium tests I want to upload some files. However, due to security restrictions in the browser a JavaScript cannot fill in a path in the respective file input field by default. Fortunately, there exists a workaround (originally from http://lists.public.thoughtworks.org/pipermail/selenium-users/2005-March/000213.html).

In FireFox enter “about:config” in the address bar, and set the value of “signed.applets.codebase_principal_support” to “true”. This allows non-signed scripts to request higher privileges.

In Selenium we then have to request the privilege to upload local files by adding the following JavaScript snippet to the function “Selenium.prototype.doType” in the file “selenium-api.js”:

netscape.security.PrivilegeManager.enablePrivilege('UniversalFileRead');

Update 2009-01-04: Fixing links, fixing problem with quotes which got messed up by WordPress.

30 comments baked

  • alex April 25, 2006 at 12:44

    Would you be able to go into any detail about how to test uploading files(eg excel) into an on-line app using selenium and IE

  • alex April 25, 2006 at 13:31

    Me again – is there any way to place the address of the file you are uploading into the text field – i tried type but got aunknown command error

  • cakebaker April 25, 2006 at 14:44

    @alex: Sorry, I am not able to say anything about IE as I do not use IE. Maybe you will have more luck in the selenium forums: http://forums.openqa.org/index.jspa

    By default, it is not possible to place the address of the file you want to upload into the text field with “type” due to security restrictions, hence the workaround ;-) But I think this workaround is Mozilla-specific and does not work with IE…

  • Surajit Basumallick March 20, 2007 at 11:26

    Please help me about file upload section. I am trying to upload a file and store it into a folder not database.
    another how to use GD using cakephp? please help me.my all try in vain.

  • cakebaker March 20, 2007 at 19:24

    @Surajit: Have a look at http://php.net/manual/en/features.file-upload.php and my article about file uploads: http://cakebaker.42dh.com/2006/04/15/file-upload-with-cakephp/

    I don’t have experience with GD, but maybe someone in the google group (http://groups.google.com/group/cake-php) has experience with it.

  • Manisha June 07, 2007 at 13:21

    Hi ,
    I have a browse button in my html which uploads the pdf file. used the command type which dosen’t work.

    I also performed these steps:

    1)Added pref(”signed.applets.codebase_principal_support”, true); into all.js file under firefox folder
    C:\Program Files\Mozilla Firefox\greprefs.

    2)Added to Selenium.prototype.doType = function(locator, value) {
    netscape.security.PrivilegeManager.enablePrivilege(’UniversalFileRead’);

    Still it doesn’t work, please let me know what am I doing wrong?

    Thanks,

    With regards,

    Manisha

  • cakebaker June 07, 2007 at 17:57

    @Manisha: I am not sure if this hack still works as this article is quite old, and I have switched to the Selenium IDE in the meantime. With the Selenium IDE, file uploads work without problems.

    Hope that helps.

  • taylor November 14, 2007 at 00:46

    I know it’s an old thread, but I thought I’d weigh in because I was looking for a solution to this problem and found it here.

    In addition to the IDE, I was able to upload files with Selenium Core v0.8.2 by using the hack as instructed. The relevant section of selenium-api.js looks like this:

    Selenium.prototype.doType = function(locator, value) {
    /**
    * Sets the value of an input field, as though you typed it in.
    *
    * Can also be used to set the value of combo boxes, check boxes, etc. In these cases,
    * value should be the value of the option selected, not the visible text.
    *
    * @param locator an element locator
    * @param value the value to type
    */

    netscape.security.PrivilegeManager.enablePrivilege(“UniversalFileRead”);

    if (this.browserbot.controlKeyDown || this.browserbot.altKeyDown || this.browserbot.metaKeyDown) {
    throw new SeleniumError(“type not supported immediately after call to controlKeyDown() or altKeyDown() or metaKeyDown()”);
    }
    // TODO fail if it can’t be typed into.
    var element = this.browserbot.findElement(locator);
    if (this.browserbot.shiftKeyDown) {
    value = new String(value).toUpperCase();
    }
    this.browserbot.replaceText(element, value);
    };

    Taylor Dorris
    http://www.proace.com

  • cakebaker November 14, 2007 at 19:53

    @taylor: Thanks for this code snippet!

  • shik November 05, 2008 at 16:03

    Selenium don’t work with “netscape.security.PrivilegeManager.enablePrivilege(”UniversalFileRead”);” modofoed =(

  • cakebaker November 07, 2008 at 18:12

    @shik: Hm, did you set “signed.applets.codebase_principal_support” to “true” in Firefox?

  • tony December 10, 2008 at 18:45

    I don’t know, if you really want to set signed.applets.codebase_principal_support to true in your Firefox.
    I have found another way to make change the security settings only for the Firefox instance started by
    Selenium RC.

    You have to patch the Selenium server by adding as user.js like this

    user_pref("signed.applets.codebase_principal_support", true);
    
    user_pref("capability.principal.codebase.p0.granted", "UniversalFileRead");
    user_pref("capability.principal.codebase.p0.id", "http://YOUR_AUT_DOMAIN1");
    user_pref("capability.principal.codebase.p0.subjectName", "");
    
    user_pref("capability.principal.codebase.p1.granted", "UniversalFileRead");
    user_pref("capability.principal.codebase.p1.id", "http://YOUR_AUT_DOMAIN2");
    user_pref("capability.principal.codebase.p1.subjectName", "");

    to your selenium-server.jar in the directory customProfileDirCUSTFF.

    As you can see, you can “register” multiple domains for your different test machines.

    The effect is, that Selenium creates a custom Firefox profile in your temp directory
    using the customProfileDirCUSTFF folder. So the user.js will be injected
    to your Selenium Firefox instance and its configuration will extend or override the settings
    of all.js and prefs.js.

    Additionally this solutions should work with all Firefoxes started by the patched Selenium server.

  • cakebaker December 11, 2008 at 18:00

    @tony: Thanks for your explanations! Seems to be a good approach.

  • Jaya December 30, 2008 at 09:13

    Hi,

    I did both the steps as you said but then its just opening the browser and nothing else is happening after that. Not even a single command is exceuted after that.

    Any help??
    Am using FF3 and sel v0.9.2 [2006], with Core v0.8.3 [1879] and v1.0-beta-1 [2201], with Core v1.0-beta-1 [1994]

  • cakebaker January 04, 2009 at 11:47

    @Jaya: Thanks for your comment!

    I just tested it with FF 3.0.5 and Selenium Core 0.8.3, and it worked fine. However, if you copied the JavaScript snippet from this article, you have to replace the quotes with those quotes used by JavaScript (somehow the quotes got messed up by WordPress). It should be fixed now.

    Hope this helps!

  • Jaya January 05, 2009 at 07:41

    Hi cakebaker, thankx for the comment.
    But i actually did that and it worked :) .

    SO vats up with FF2, do we need to follow the above steps or just modifying the about:config should help?

  • cakebaker January 06, 2009 at 18:33

    @Jaya: You have to follow both steps.

  • Maruthiprasath January 20, 2009 at 19:21

    thanks for ur post.
    it was great .. after long struggle i got the answer..
    u rock man..
    but we need to follow both steps

  • cakebaker January 21, 2009 at 17:49

    @Maruthiprasath: You are welcome! And yes, you have to follow both steps.

  • Bogdan April 29, 2009 at 13:05

    Good browser independent solution can be found here:
    http://gusiev.com/?p=3 files with Selenium IDE

  • cakebaker May 01, 2009 at 08:33

    @Bogdan: Thanks for the link! However, if you use the Selenium IDE the file upload should work without any “hacks”.

  • Amit Vibhuti May 30, 2009 at 12:15
  • cakebaker June 01, 2009 at 10:29

    @Amit: Thanks for the link!

  • Levent December 09, 2009 at 21:46

    I use selenium with ruby and firefox 3.5
    I modified the user_pref of firefox as specified, but I don’t know how to deal with the step involving
    netscape.security.PrivilegeManager.enablePrivilege(”UniversalFileRead”);
    It seems this is only applicable for the selenium java client.
    Is there a way to do it from Ruby?

  • Levent December 09, 2009 at 23:07

    I found the relevant code in selenium-api.js in selenium-server.jar and put in netscape.security.PrivilegeManager.enablePrivilege(’UniversalFileRead’);
    but it seemed to have no effect. I still see no upload in firefox after it clicks the submit button. Has anyone tried it in firefox 3.5+?

  • Prabin March 16, 2010 at 02:59

    Hey Levent! Did you get this working in firefox 3.5+ ?? This is shame, it does not seem to work with 3.5 at all. I am using an older version of selenium core though – 0.8.
    I have done everything that cakebaker tells me to do. Am I missing something?

  • Priyanka March 16, 2010 at 13:36

    Hi How can I upload a file in selenium , as it gives a security error .
    I am using command
    Sel.selenium.type(“attachment_upload_data”,”file”);

    It gives error -Security error

    What can I Do ??

  • Levent March 16, 2010 at 19:17

    No, we could not get it working. For uploads, we either use IDE or some special JS code in the application.

  • Prakash March 17, 2010 at 16:10

    public bool TypeIntoFileUpload(string controlId, string filePath)
    {
    try
    {
    string newFilePath = filePath.Replace(‘\\’, ‘/’);
    _selObj.WindowFocus();
    _selObj.Focus(controlId);
    string jscript=”";
    jscript += “if(selenium.browserbot.getCurrentWindow().clipboardData){window.clipboardData.setData(‘Text’,'” + newFilePath + “‘);}”;
    _selObj.GetEval(jscript);
    byte VK_CONTROL = 0×11;
    byte VK_V = 0×56;
    _selObj.KeyDownNative(Convert.ToString(VK_CONTROL));
    _selObj.KeyPressNative(Convert.ToString(VK_V));
    _selObj.KeyUpNative(Convert.ToString(VK_CONTROL));

    return true;
    }
    catch (Exception exc)
    {
    return false;
    }
    }

  • Prakash March 17, 2010 at 16:11

    Uploading Files using Selenium RC in C#
    After googling all around to overcome the Selenium incapability of handling File Upload control finally I could write a simple function in C# which will do my job. In the function given below _selObj is the object of DefaultSelenium class.

    public bool TypeIntoFileUpload(string controlId, string filePath)
    {
    try
    {
    string newFilePath = filePath.Replace(‘\\’, ‘/’);
    _selObj.WindowFocus();
    _selObj.Focus(controlId);
    string jscript=”";
    jscript += “if(selenium.browserbot.getCurrentWindow().clipboardData){window.clipboardData.setData(‘Text’,'” + newFilePath + “‘);}”;
    _selObj.GetEval(jscript);
    byte VK_CONTROL = 0×11;
    byte VK_V = 0×56;
    _selObj.KeyDownNative(Convert.ToString(VK_CONTROL));
    _selObj.KeyPressNative(Convert.ToString(VK_V));
    _selObj.KeyUpNative(Convert.ToString(VK_CONTROL));

    return true;
    }
    catch (Exception exc)
    {
    return false;
    }
    }

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License