Selenium: after file upload can not get file size - selenium

I use Selenium to test web app behaviour on file upload page.
The goal of test is to check application validations on file selection.
I use webDriver.SendKeys (C#) on file input to simulate file upload, file is selected successfully, but fileInput.files[0].size (js) is always 0 (or undefined?) and app shows error "Do not upload empty files". File size is correct on manual testing.
Any suggestions, on how to solve the problem?
UPDATE Code details:
HTML
<input id="file-path" type="file" data-bind="attr: { accept: mimeTypes }, event: { change: onFileSelect }" />
<small id="file-path-error" class="field-validation-error" data-bind="validationMessage: file"></small>
JS (file edit model uses knockout)
this.file = ko.observable().extend({
validation: [
{
validator: function(file) {
// valid if no file or file size < 5Mb
return !file || file.size < 5242880;
},
message: 'File size should be less than 5Mb'
}, {
validator: function(file) {
// valid if no file or file size > 0
return !file || file.size > 0;
},
message: 'Do not upload empty files'
}
]
});
this.onFileSelect = function(model, event) {
var fileInput;
fileInput = event.target;
if ((fileInput.files != null) && fileInput.files.length > 0) {
_this.file(fileInput.files[0]);
} else {
_this.file(null);
}
};
C#
webDriver.FindElement(By.Id("file-path")).SendKeys("C:\testFile.txt");
Assert.AreEqual(webDriver.FindElement(By.Id("file-path-error").Text,"");
Assertion always fails because file-path-error contains "Do not upload empty files" - that is the problem.

I was misleaded by answers on How to automate file upload in Internet Explorer using Selenium?
Discusstion on How to set a value to a file input in HTML? says that actually we can not upload files programmatically.
So there was no sence in expecting decent behaviour for such test.

Related

Angular 7 correctly upload doc/docx file

I'm having troubles uploading doc and docx files, because I can't get the right type of file when converting it to base64. This is my input:
<input
accept=".pdf,.txt,.doc,.docx"
type="file"
(change)="onNativeInputFileSelect($event)"
#inputFile
hidden
/>
In my method I do this:
onNativeInputFileSelect(event) {
if (event.target.value) {
const file: File = event.target.files[0];
this.changeFile(file).then((base64: string): any => {
this.attachment.content= base64;
this.uploadFile(this.attachment);
});
}
}
then in "uploadFile" I send the file to server as base 64 string.
The changeFile methods is this:
changeFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
This works fine for pdf or txt files, but when I upload .doc or .docx files I get this base64 string:
data:application/octet-stream;base64,0M8R4KGxGuEAA[...]
while for pdf I correctly have:
data:application/pdf;base64,JVBERi0xLjQKJeLjz9MKMS
This means that when I try to download the file I don't get the correct type, because I have application/octet-stream, and so I can't put the right extension to the file.
I've tried by passing to the accept property of input component this:
application/msword,application/pdf,text/plain,application/vnd.openxmlformats-officedocument.wordprocessingml.document
But nothing changed and the Window's file chooser suggested me only .pdf and .txt files
EDIT
This is a working stackblitz
I get "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,UEsDBB[...]" for docx and "data:application/msword;base64,0M8R4KGxGuv[...]" for doc file.

testCafe slowing the tests down after fileUpload

I am automating a data capture form.
The first element of this form is an image file upload control & I'm uploading a 5KB image.
But after this step, the test executes the next step which is writing a text into a textbox & then it halts for nearly 30 seconds.
How to reduce this un-necessary wait?
test('Test 1', async t => {
await listingPage.uploadImage();
await listingPage.listAnItem();
..
Upload image code
async uploadImage() {
await t.setFilesToUpload(this.imageInput, ['../../uploads/photo02.jpg']);
}
** Data entry code block **
async listAnItem() {
await t
.typeText(Selector('#description'), this.DESCRIPTION) /* --> Application is slowing after this step */
.click(this.categorySelect)
.click(Selector('#react-select-2-option-0-0'))
.testcaferc.json file
{
"browsers": [ "chrome", "safari" ],
"remoteChromeVersion": "80",
"src": "specs",
"reporter": [
{
"name": "spec"
}
],
"speed": 1,
"debugOnFail": false,
"skipJsErrors": true,
"selectorTimeout": 20000,
"assertionTimeout": 20000,
"pageLoadTimeout": 8000
}
DOM Snippet of file-upload
<input aria-describedby="error__images" aria-label="Upload an image" tabindex="0" type="file" multiple="" accept="image/jpeg, image/png" data-testid="imageInput" class="ImageInputstyles__Input-sc-2l692w-7 aosWu">
The issue itself was not due to the Upload files control.
Issue was occuring, due to a drop-box, (after uploading file), which was dynamically updating another drop-box that had values populated dynamically based on the value selected in the first drop-down.
Rewriting the drop-down operation something like below resolved the issue:
async fillSubCategoryFields(catType = 'CAT_NAME') {
await t
.click(this.categorySelect, { timeout: 50 })
.click(Selector('.listingSelect__option').withText(catType));
}

How to upload a photo in my Form and into my Vuex store?

I'm practicing building a Hybrid Mobile app with Quasar, Vue and Vuex.
I've successfully added my form input fields to my Vuex store but I don't know how to upload a file, in this case a photo, within my Form.
Here is my q-file input from my form, with the data.
<q-file
v-model="mealToSubmit.photo"
label="Upload File"
outlined
>
Data:
data () {
return {
mealToSubmit: {
name: '',
description: '',
photo: null,
grams: '',
calories: '',
visible: false
}
}
}
After I fill in the Form and click Save, all of the data appears on the page except for the photo I selected. In the console I get a 404 error:
404  http://localhost:8080/img/null 404 (Not Found)
I can see the problem here is that it's displaying null, instead of the name of the photo I upload, which is why I'm getting a 404 error.
Here are two screenshots, one of me filling in the Form and second is the data being displayed properly except for the photo, with the error message in the console.
NOTE:
Just to add to this, I've uploaded files before using Vue js and Bootstrap-Vue. I add an #change event on the File input with a v-model like this:
<b-form-group label="Upload Profile Photo (optional)" label-for="photo_id">
<b-form-file
v-model="profileData.photo_id"
id="photo_id"
placeholder="Choose a file..."
#change="attachImage"
accept=".jpg, .jpeg, .png"
></b-form-file>
</b-form-group>
Than in the Methods{}:
methods: {
attachImage(evt) {
const file = evt.target.files[0];
let reader = new FileReader();
reader.addEventListener('load', function() {
}.bind(this), false);
reader.readAsDataURL(file);
},
}
And then I bind the data using FormData(); and send it to the backend. This approach isn't working with the Quasar file upload input and the code that I have above.
I got it now:
<q-file
#input="getFile"
label="Upload file"
/>
methods: {
getFile(file) {
// file is in the file variable
this.mealToSubmit.photo = file
}
}

Safari file upload not accepting MKV video files

I have a file input element with an accept attribute which should allow various video formats. The only one I cannot select is MKV.
<input id="fileOne" type="file" accept="video/mp4,.mp4,video/avi,.avi,video/mpeg,.mpeg,.mpg,video/3gpp,.3gp,.divx,video/x-flv,.flv,video/x-matroska,.mkv,video/quicktime,.mov,audio/ogg,.ogg,video/webm,.webm,video/x-ms-wmv,.wmv">
It is set to accept the following:
video/mp4,.mp4,
video/avi,.avi,
video/mpeg,.mpeg,.mpg,
video/3gpp,.3gp,.divx,
video/x-flv,.flv,
video/x-matroska,.mkv,
video/quicktime,.mov,
audio/ogg,.ogg,
video/webm,.webm,
video/x-ms-wmv,.wmv
I cannot select MKV files in Safari when opening the file upload dialog. (The filename is greyed out). Should I be doing something different?
I have tagged PLUpload as I am generating the file upload element using PLUpload with the following filters:
filters: {
mime_types: [
{ title: "Video Files", extensions: "mp4,avi,mpeg,mpg,3gp,divx,flv,mkv,mov,ogg,webm,wmv" }
]
}

Jquery trigger when PDF file downloaded

I am using wicked_pdf plug-in for generating pdf. I am showing message and spinner when user click on pdf link and i want to hide that when pdf is generated and pushed to browser for download/show. I have added jquery code on body onload which will not execute. Is there any other way to trigger jquery function when pdf file pushed to browser?
This is a rather complicated issue, but can be solved nicely if you are willing to use jQuery plugins. http://jqueryfiledownload.apphb.com/ is a plugin that can do exactly what you need if I understood you correctly.
My frontend code looks like this
$.fileDownload('/Content/Print', {
successCallback: function (url) {
$("#PrintingMessage").dialog('close');
},
failCallback: function (responseHtml, url) {
$("#PrintingMessage").dialog('close');
if (responseHtml.indexOf('Error403') != -1) {
$("#PrintingFailedMessage").html("Error 403.");
} else if (responseHtml.indexOf('Error500') != -1) {
$("#PrintingFailedMessage").html("Error 500.");
}
$("#PrintingFailedMessage").dialog({ modal: true });
},
httpMethod: "POST",
data: $('#PublishForm').serialize()
});
And my backend does this at the end of the process. You'll have to translate that yourself :)
Response.SetCookie(new System.Web.HttpCookie("fileDownload", "true") { Path = "/" });
return File(file, System.Net.Mime.MediaTypeNames.Application.Octet, filename);