7

I am clicking on a upload button which opens up a windows file selector. I am not able to write the path to a file in that File Selector dialog using protractor.

I tried copying the text to the clipboard and pasting the same to File Upload by passing ctrl+v keypress in protractor. Able to copy the text but paste is not working.

Now I am planning to use robotjs or some other tool to achieve this.
Any idea how can we do this in protractor?

Praveen
  • 1,378
  • 2
  • 15
  • 26
  • Ideally there would be an input field you could post the directory path to and avoid the file browser altogether since robotjs renders your desktop useless while its running tests because if you move the mouse when it needs to type the path out it will type it there (e.g. your text editor). I was able to get this to work however and can post a code sample when i get home later. – sonhu May 12 '16 at 15:39

2 Answers2

11

Did you try this?

// set file detector
var remote = require('../../node_modules/protractor/node_modules/selenium-webdriver/remote');
browser.setFileDetector(new remote.FileDetector());


var fileToUpload = '../sample.txt';
var absolutePath = path.resolve(__dirname, fileToUpload);

var fileElem = element(by.css('input[type="file"]'));

// Unhide file input
browser.executeScript("arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px';  arguments[0].style.opacity = 1", fileElem.getWebElement());

fileElem.sendKeys(absolutePath);

// take a breath 
browser.driver.sleep(100);

// click upload button
element(by.css('button[data-ng-click="uploadFile(file)"]')).click(); // does post request

Please check this and this to more information.

Hope this helps. :)

Manuli
  • 1,203
  • 4
  • 20
  • 43
4

Assuming there is no possible way to make the input[type="file] element visible (see Quality Product's answer) due to layers upon layers of javascript it is possible to upload a file through the file browser using robotjs.

You will need to change to below code snippets around to fit your specific circumstances but this is how I was able to get robotjs to work (utilizing page object design pattern)

Page Object

var robot = require("robotjs");
var path = require("path");

var MediaPO = function() { 
   ...
   ...
   ...       

   this.clickBrowseFileLink = function() {
        return browseFileLink.click(); //returns a promise
   };

    this.uploadFile = function(filename) {
       robot.moveMouse(648, 264) //May need to change based on desktop size
       var uploadPath = path.resolve(__dirname,'../PATH/TO/UPLOAD/', filename); //change to your upload file's path
       robot.setKeyboardDelay(1000);
       console.log(uploadPath); //for debugging
       robot.typeString(uploadPath);
       robot.keyTap("enter");
       browser.sleep(3000);
    };
    ...
    ...
    ...

Spec

 //Note: all code but uploadFile should be replaced with the code from your project
 // this is just an example

it("should upload .png files successfully", function() {
   ...
   ...
   ...

   //your page object function for opening the file explorer
   //must return a promise otherwise the string will be typed too early

   mediaPO.clickBrowseFileLink().then(function() { 
       mediaPO.uploadFile("teddy.png");
       mediaPO.clickUploadNowButton(); //replace with your method of confirming upload.
       expect(mediaPO.pngFileExists()).toBeTruthy();
   });
};
sonhu
  • 961
  • 10
  • 19
  • Thank you Sonhu. I was using robotjs module only as my workaround to upload a file. This is a good piece of code. – Praveen May 13 '16 at 10:57