Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protractor File upload failing with ng upload version 3.3.4 #710

Closed
prabhu-telsiz opened this issue May 1, 2015 · 38 comments
Closed

Protractor File upload failing with ng upload version 3.3.4 #710

prabhu-telsiz opened this issue May 1, 2015 · 38 comments

Comments

@prabhu-telsiz
Copy link

I have been using the usual file upload in the protractor to upload the files .

element(by.id('upload_button')).sendKeys('file path');

It was working fine until our application's 'ng upload' upgraded to version 3.3.4.

We are using protractor Version 1.4.0.

Is this a known issue ?? Does anyone know a workaround for this

@danialfarid
Copy link
Owner

Does it work with the latest version?

@prabhu-telsiz
Copy link
Author

I dont know. I have not tried with the latest version.

@danialfarid
Copy link
Owner

Try it then it might have alraedy been fixed.

@prabhu-telsiz
Copy link
Author

Its not working with protractor latest version too. I used version 2.0

@tzclucian
Copy link

I encountered this as well.

It worked with protractor 1.6.1 and ng-file-upload 3.0.7

Then after we upgraded to ng-file-upload to 4.1.0 it stopped working with both Protractor 1.6.1 and Protractor 2.0.

Weird thing is that it works on Internet Explorer 11 😵

PS: I added more details about this here: angular/protractor#2101

@prabhu-telsiz
Copy link
Author

Im using something like this.

HTML:
input type="file" name="vedgeImage" class="pull-left" data-ng-model="fileVedge" multiple="false" accept=".bz2" data-ng-file-select data-ng-click="vedgeFileSelect()" id="vedge_file_select"

Protractor:

  1. element(by.id("vedge_file_select")).sendKeys(filepath);
    (This line of code works properly fine.It browses for file from the path given)

  2. When i click upload button "required error" message is thrown. It thinks that no file is selected
    element(by.id("Upload")).Click();

These are the same lines of code I used before upgrading ng-upload to version 3.3.4. It was working fine.
After upgrading ng-upload to version 3.3.4, the same lines of protractor code doesnt work.

NOTE : BUT IF I DO THIS MANUALLY-( BROWSE AND UPLOAD OPERATION) IS TOTALLY FINE. IT SEEMS TO BE BROKEN WHEN PERFORMNG THE SAME OPERATION WITH PROTRACTOR.

@snehacharkha
Copy link

@danialfarid i am facing the same issue . Any update on this ?

@tzclucian
Copy link

@danialfarid Any updates or atleast workarounds for this issue?

@danialfarid
Copy link
Owner

Try
element(by.id("vedge_file_select")).Click()
and then
sendKeys(filepath);
or something like this, the change listeners are registered after the input is clicked on.

@prabhu-telsiz
Copy link
Author

@tzclucian : Did u try ?

I dont know how to click and then sendkeys as @danialfarid mentioned.

@tzclucian
Copy link

@danialfarid thanks, it works.

@prabhu-telsiz Yes, I tried it and it works. You have to manually open the file selector dialog then do the send keys.

@sirkkalap
Copy link

@danialfarid I tried clicking the upload button and sending keys to the file input, but the file requester seems to stay open and block any further operations.

Is there any way to prevent the automatic opening of the file requester?

On a second run the dialog was left open and browser continued running other tests. Weird.

I have "ng-file-upload": "~4.2.1" and Firefox 22 :).

@danialfarid
Copy link
Owner

You can probably click on dialog cancel button and continue the test by sendKey

@sirkkalap
Copy link

The problem is that file requesters are not implemented by browser as they are operating system specific. Therefore Selenium has no control over them. So manually clicking is ok, if you run the tests on your local machine and have the patience to click them, but on our automated build servers there are no people to click them so the tests hang on those servers.

@danialfarid
Copy link
Owner

Try adding

        elem.bind('change', changeFn);

To this line: https://github.com/danialfarid/ng-file-upload/blob/master/dist/ng-file-upload.js#L231

That should solve the problem, I would add it to the next version if this does the trick for you.

@prabhu-telsiz
Copy link
Author

@tzclucian : Thanks.

@sirkkalap : Im also facing the same issues.

@sirkkalap
Copy link

@danialfarid Sorry for the delay. We had to work around this and ended up doing the upload request directly from test-code into the backend bypassing the file requester. Maybe later. Thanks for your help.

@daveboling
Copy link

@danialfarid Adding that elem.bind worked for what I had to do with my tests. It would be really nice to have this as soon as possible.

What I had to do to get this to work is not pretty, but it was better than modifying front-end code just to get tests to pass. Since I'm using labels as the my file select, I can click those with the WebDriver, but can't send_keys to it. At least, it wouldn't work for me that way. So I had to replace my labels with inputs and re-bind them back to scope. Again, It's nasty, but it works.

Note 1: Inside of my controller for this page, I've assigned a variable scope.compile = compile. This is the only way I could use the $compile service at all. If anyone knows a better way, please share.

Note 2: This will only work if you add elem.bind('change', changeFn); to the line that @danialfarid recommended at this link: https://github.com/danialfarid/ng-file-upload/blob/master/dist/ng-file-upload.js#L231

Python

for index in range(7):
    selector = '#upload_{}'.format(index)

    #target input field with jQuery and replace with real input
    input_field = '$("#upload_{}").replaceWith(angular.element("[ng-app=yourApp]").find(".controller-class").scope().compile(\'<input id="upload_{}" type="file" accept="image/*" ngf-select ng-model="r.file" ngf-change="imgPreview($files, $event, {})">\')(angular.element("[ng-app=yourApp]").find(".controller-class").scope()));'.format(index, index, index)

    #execute script
    self.browser.execute_script(input_field)

    file_input = self.browser.find_element_by_css_selector(selector)
    file_input.send_keys(FILE_PATH)

@danialfarid
Copy link
Owner

@kadowki could you verify if this is fixed in version 4.2.2? I made some changes to make sure change listener is registered in both cases.

@daveboling
Copy link

@danialfarid Negative. It seems like ngf-change doesn't pick up an actual change on input fields when send_keys is used from Selenium. Also, whenever I try simulate a click event on ngf-select element, it doesn't find anything to send to which is why I had to change it to an input field.

@daveboling
Copy link

@danialfarid Something that is related and may be helpful in know: The old way of doing file upload using custom file select boxes and doing would allow user to click a styled label tag and open a . Now that we've moved to using ng-file-upload, we noticed that the same thing currently would not work due to no change detection being present in the element. With your directive, this isn't necessary anyways. If there was a way to simulate click and then send the file, that would be ideal. Else, it must be an input in order for that to happen.

danialfarid pushed a commit that referenced this issue Jun 4, 2015
@danialfarid
Copy link
Owner

since version 5.0.0 you can set ngf-reset-on-click to false for testing

@prabhu-telsiz
Copy link
Author

I updated my ng-upload to version 5.0.0
I still see the issue.

If i upload manually by selecting a file, upload operation is fine.
If i upload using protractor, File upload fails.
Error with POST call : ERR_FILE_NOT FOUND.

When I upload manually, the file parameters are proper. Screenshot attached.
screen shot 2015-06-08 at 12 08 42 pm

I find that file size is 0 when I upload using protractor. And someother file parameters is also not same.
screen shot 2015-06-05 at 1 59 53 pm

PROTRACTOR CODE:
element(by.id('maintenance_repository_vmanage_file_select')).sendKeys(path_to_vmanage);

Im not sure why im seeing this issue.

@danialfarid
Copy link
Owner

you need to set ngf-reset-on-click to false

@prabhu-telsiz
Copy link
Author

@danialfarid :

I set have set ngf-reset-on-click to false and tried.
Still I see the same issue as mentioned above.
Error with POST call : ERR_FILE_NOT FOUND.

This is the HTML where i set the "ngf-reset-on-click" is false

<'''input type="file" name="vedgeImage" class="pull-left ng-pristine ng-valid ng-touched" data-ng-model="fileVedge" data-ngf-multiple="false" accept=".bz2" data-ngf-select="" data-ngf-change="vedgeFileSelect()" data-ngf-reset-on-click="false" id="maintenance_repository_vedge_file_select"'''>

Do i need to make changes any where else?

And I cant do file upload manually after setting ngf-reset-on-click to false.
All the button's (Choose File, Upload,Cancel) got disabled. I cant do any clicks manually.

@rgurgul
Copy link

rgurgul commented Jun 11, 2015

setting ngf-reset-on-click to false isn't convinient way because I must set it every time when I run test ;(
And there isn't any way to set attr only for testing in protracor

@sirkkalap
Copy link

@rgurgul can't you set the nfg-reset-on-click in test setup method?

@rgurgul
Copy link

rgurgul commented Jun 24, 2015

@sirkkalap i need it for e2e test

@sirkkalap
Copy link

@rgurgul I generally execute javascript inside e2e tests when I need to toggle such things. Of course this depends on e2e-test implementation tech.

@danialfarid
Copy link
Owner

Since version 7 there won't be a new element created on each click so that would make the e2e testing easier.

@rgurgul
Copy link

rgurgul commented Aug 22, 2015

nice to hear it

@vsathyak
Copy link

@danialfarid :: our dev team updated ng-file-upload to 9.x. and after the update my protractor e2e script for file upload is failing. I mean the same old script works fine if the file is of extension .txt but unable to upload .csv file. Please see my script and html and let me know your thoughts..

Script used in e2e testing

this.uploadfile = function (uploadFile) {
    var fileToUpload = uploadFile;
    var absolutePath = path.resolve(__dirname, fileToUpload);
    $('input[type="file"]').sendKeys(absolutePath);
    element(bulkUploadModalUploadBtn).click();
};

This is working if the file is of extension .txt but not working for .csv

HTML
snip20151110_1
snip20151110_4

Hope you would be able to help me with some work around. Thanks in advance..

@danialfarid
Copy link
Owner

Is there any validation on the input file?

@vsathyak
Copy link

@danialfarid
Yup. We actually debugged the code and realized that while uploading a .csv file using protractor, the mime type returned is blank. Since the expected mime type is [allowed-mime="text/csv,text/plain"], blank value results in triggering validation that block the upload of file.. Any though about why the mime type is blank??

@danialfarid
Copy link
Owner

That is browser's specific implementation, probably a browser's bug if the file actually have the type info in your OS.

@vsathyak
Copy link

@danialfarid
I think the allowed extension and mime type is added by our dev guys for blocking other extensions. But if we upload a file manually, we are able to see the mime type and it works fine. Anyways thanks for the quick response. And please let me know if you are able to find a work around for this.

@icxDave
Copy link

icxDave commented Dec 20, 2015

Yeah, running into the same issue as prabhu-telsiz, file size is 0. Everything else is read - and I'm triggering the click, and using sendkeys. Works fine aside from protractor tests. I've also tried ngf-reset-on-click = false but no luck there either. My file however is uploading but it is corrupt.

@roshanhadal
Copy link

@vsathyak did you find a solution for mimetype issue? I am facing the same. File uploaded using protractor test (sample code below) has mimetype application/octet-stream whereas if I upload manually using the browser, it uploads fine with application/vnd.ms-excel.

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

element.all(by.css('input[type=file]')).get(0).sendKeys(absolutePath);
element(by.id('upload-btn')).click();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants