18

I'd like to reopen the question posed here and here about testing file uploading within Nightwatch.js which uses selenium.

Both links have the recommended solution of setting the value of the file input element as the url. In my use case, I've been unable to get this to work. Even setting the value tag manually, outside of nightwatch, of the input where type="file", does not change the url. I've tried this on Chrome, Firefox, and IE10, within the dev tools.

An alternative solution I've looked at was trying to emulate the entire file upload process keystrokes. This would follow the path of clicking the file upload button, typing the path, and typing enter. This would be done through the .click and .key methods. However, you lose focus of the actual file upload window, which delays the keystrokes until that window is closed. Other developers have seemed to be able to fix this solution directly in selenium using the .findElement and .sendKeys methods in java, but I could not figure out how to do this within javascript and nightwatch itself.

Any ideas?

// My test
      module.exports = {
      "Standard File Upload" : function (browser) {
        browser
          .url("http://localhost:3000")
          .waitForElementVisible('body', 1000)
          .waitForElementVisible('input[type="file"]', 1000)
          .setValue('input[type="file"]','http://localhost:3000/testfile.txt')
          .click('#submit')
          .pause(1000)
          .assert.containsText('h3', 'File Uploaded Successfully')
          .end();
      }
    };

// http://localhost:3000/testfile.txt was tested manually in the file upload window and worked successfully

<!-- My input tag --> 
<input id="fileUpload" type="file" name="textfile"/>
Community
  • 1
  • 1
timaw
  • 583
  • 1
  • 4
  • 12

3 Answers3

25

There were two seperate issues with my setValue() method implementation.

  1. Using the --verbose tag in the nightwatch command led me to an issue where it was not actually finding the input tag during the setValue(), however it was during the waitForElementVisible(). Changing input[type="file"] to input#fileUpload solved this issue.

  2. Secondly, the following ways of describing the path were not working...

    • 'textfile.txt'
    • 'http://localhost:3000/testfile.txt' (Will work if typed manually into file upload window)


    What did work was using require('path').resolve(__dirname + '/testfile.txt')


Take a look here to see the discussion that led to the fix. Thanks goes out to richard-flosi.

The working code:

module.exports = {
  "Standard File Upload" : function (browser) {
    browser
      .url("http://localhost:3000")
      .waitForElementVisible('body', 1000)
      .waitForElementVisible('input#fileUpload', 1000)
      .pause(1000)
      .setValue('input#fileUpload', require('path').resolve(__dirname + '/testfile.txt')) // Works
//      .setValue('input#fileUpload', "testfile.txt") // Will not work
//      .setValue('input#fileUpload', "http://localhost:3000/testfile.txt") // Will not work
//      .setValue('input[type="file"]', require('path').resolve(__dirname + '/testfile.txt')) // Will not work
      .click('#submit')
      .pause(1000)
      .assert.containsText('h3', 'File Uploaded Successfully')
      .end();
  }
};
timaw
  • 583
  • 1
  • 4
  • 12
  • I see that this answer was published a long time ago, but maybe you could help me with the file, that was published to s3. I need to handle the case when file path is like ``https://..../file.zip``. But how to type this path into file upload window? – MisterMe Dec 28 '16 at 11:26
1

I'm not sure why you're having these issues, maybe check to see if you are using the latest version of selenium server and nightwatch. This code works for me 100% in Chrome, Safari, Firefox, IE7/8/9/10/11 (not tested in IE6 but assume it as well).

driver.setValue('input#fileUpload', __dirname + '\\testfile.txt')
lacy
  • 428
  • 3
  • 11
1

In my case, I had an additional problem because the file I was trying to upload was too high up in my directory structure.

As soon as I moved the file to the same level (or in a subdirectory of) the actual test files, things worked.

From a script living in my page-objects folder:

// No dice:
var fullPath = require('path').resolve(__dirname + '/../../somefile.pdf');

// Works:
var fullPath = require('path').resolve(__dirname + '/../somefile.pdf');

this.setValue('input#fileUpload', fullPath);
Dale Anderson
  • 1,591
  • 18
  • 19