How to upload file in angularjs e2e protractor testing - angularjs

I want to test file uploading using an angularjs e2e test. How do you do this in e2e tests? I run my test script through grunt karma.

This is how I do it:
var path = require('path');
it('should upload a file', function() {
var fileToUpload = '../some/path/foo.txt',
absolutePath = path.resolve(__dirname, fileToUpload);
element(by.css('input[type="file"]')).sendKeys(absolutePath);
element(by.id('uploadButton')).click();
});
Use the path module to resolve the full path of the file that you want to upload.
Set the path to the input type="file" element.
Click on the upload button.
This will not work on firefox. Protractor will complain because the element is not visible. To upload in firefox you need to make the input visible. This is what I do:
browser.executeAsyncScript(function(callback) {
// You can use any other selector
document.querySelectorAll('#input-file-element')[0]
.style.display = 'inline';
callback();
});
// Now you can upload.
$('input[type="file"]').sendKeys(absolutePath);
$('#uploadButton').click();

You can't directly.
For security reason, you can not simulate a user that is choosing a file on the system within a functional testing suite like ngScenario.
With Protractor, since it is based on WebDriver, it should be possible to use this trick
Q: Does WebDriver support file uploads? A: Yes.
You can't interact with the native OS file browser dialog directly,
but we do some magic so that if you call
WebElement#sendKeys("/path/to/file") on a file upload element, it does
the right thing. Make sure you don't WebElement#click() the file
upload element, or the browser will probably hang.
This works just fine:
$('input[type="file"]').sendKeys("/file/path")

Here is a combo of Andres D and davidb583's advice that would have helped me as I worked through this...
I was trying to get protractor tests executed against the flowjs controls.
// requires an absolute path
var fileToUpload = './testPackages/' + packageName + '/' + fileName;
var absolutePath = path.resolve(__dirname, fileToUpload);
// Find the file input element
var fileElem = element(by.css('input[type="file"]'));
// Need to unhide flowjs's secret file uploader
browser.executeScript(
"arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1",
fileElem.getWebElement());
// Sending the keystrokes will ultimately submit the request. No need to simulate the click
fileElem.sendKeys(absolutePath);
// Not sure how to wait for the upload and response to return first
// I need this since I have a test that looks at the results after upload
// ... there is probably a better way to do this, but I punted
browser.sleep(1000);

var imagePath = 'http://placehold.it/120x120&text=image1';
element(by.id('fileUpload')).sendKeys(imagePath);
This is working for me.

This is what I do to upload file on firefox, this script make the element visible to set the path value:
browser.executeScript("$('input[type=\"file\"]').parent().css('visibility', 'visible').css('height', 1).css('width', 1).css('overflow', 'visible')");

If above solutions don't work, read this
First of all, in order to upload the file there should be an input element that takes the path to the file. Normally, it's immediately next to the 'Upload' button... BUT I've seen this, when the button doesn't have an input around the button which may seem to be confusing. Keep clam, the input has to be on the page! Try look for input element in the DOM, that has something like 'upload', or 'file', just keep in mind it can be anywhere.
When you located it, get it's selector, and type in a path to a file. Remember, it has to be absolute path, that starts from you root directory (/something/like/this for MAC users and C:/some/file in Windows)
await $('input[type="file"]').sendKeys("/file/path")
this may not work, if...
protractor's sendKeys can only type in an input that's visible. Often, the input will be hidden or have 0 pixels size. You can fix that too
let $input = $('input[type="file"]');
await browser.executeScript(
"arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1",
$input.getWebElement()
);

I realized that the file input in the web app I'm testing is only visible in Firefox when it is scrolled into view using JavaScript, so I added scrollIntoView() in Andres D's code to make it work for my app:
browser.executeAsyncScript(function (callback) {
document.querySelectorAll('input')[2]
.style = '';
document.querySelectorAll('input')[2].scrollIntoView();
callback();
});
(I also removed all of the styles for the file input element)

// To upload a file from C:\ Directory
{
var path = require('path');
var dirname = 'C:/';
var fileToUpload = '../filename.txt';
var absolutePath = path.resolve('C:\filename.txt');
var fileElem = ptor.element.all(protractor.By.css('input[type="file"]'));
fileElem.sendKeys(absolutePath);
cb();
};

If you want to select a file without opening the popup below is the answer :
var path = require('path');
var remote = require('../../node_modules/selenium-webdriver/remote');
browser.setFileDetector(new remote.FileDetector());
var fileToUpload = './resume.docx';
var absolutePath = path.resolve(process.cwd() + fileToUpload);
element(by.css('input[type="file"]')).sendKeys(absolutePath);

the current documented solutions would work only if users are loading jQuery. i all different situations users will get an error such:Failed: $ is not defined
i would suggest to document a solution using native angularjs code.
e.g. i would suggest instead of suggesting:
$('input[type="file"]') .....
to suggest:
angular.element(document.querySelector('input[type="file"]')) .....
the latter is more standard, atop of angular and more important not require jquery

Related

sendKeys method doesn't work with react page

I am trying to upload a file by using sendKeys method and adding absolute path to file but the file does not get uploaded. I think sendKeys method doesn't work very well on react pages. Can someone please help and give a workaround of this problem? Below is the code snippet:
I do not see any error but the file doesn't get uploaded.
Below is the function I am using to upload file:
importFileButton: {
get: function() {
return this.findElement(this.by.xpath("//div[#id='upload-file']//button[#aria-label='Import file Browse ']"))
}
}
attachCommaFile: {
get: function () {
browser.setFileDetector(new remote.FileDetector());
var fileToUpload = './../../files/fileimport_Pipe.txt',
absolutePath = path.resolve(__dirname, fileToUpload);
return this.importFileButton.sendKeys(absolutePath);
}
}
file uploads work with input tags
You're trying to sendKeys to a wrong element - button
Most like the tag you're looking for will have the following css [type=file]
for more detailed info see this post https://stackoverflow.com/a/66110941/9150146

Why ajax works only for homepage?

I have baked new project. My simple ajax function inserted to ..\templates\Pages\home.php:
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "myTest.txt", true);
xhttp.send();
}
My myTest.txt is in ..\webroot\ location.
Why this works for homepage, but not for any other created site in project? For all sites except homepage cakePHP can not find my text file. I have tried various locations for this file.
You should use "/myTest.txt" for the URL to open. Without the / on the front, it is interpreted as a relative URL, so if you're at something like /page/2, then it will look for /page/myTest.txt, which doesn't exist.
Take HTTP_ROOT as constant in bootstrap.php holding the base url(site name without sub path).
define the <base href="<?= HTTP_ROOT;?>" /> on the layout->head section. this will help to hit the site without sub-path on ajax request.
you can take a further constant eg-"siteURL" in javascript inline code on the layout's <head> OR a hidden input holding the base path.
Use the constant if you need.
siteURL+(if any further dir under webroot)+'myTest.txt'

File upload with webdriverio v5 in msedge

I am running an automation test in sauceLabs using webdriverio v5. I want to run a test which is uploading a file to msedge. Below is the sample code for the same.
const path = require('path');
const filePath = path.join(__dirname, 'path/to/your/file');
const remoteFilePath = browser.uploadFile(filePath);
$('upload file input selector').setValue(remoteFilePath);
This code works fine with chrome and firefox but when i try to run the same in msedge is gives Error: The uploadFile command is not available in msedge.
Seems like browser.uploadFile only works for chrome. i have tried various other things but the solutions works mostly on local and not on remote server like sauceLabs.
Is there any alternative for browser.uploadFile or any workaround which can be used to upload the file in msedge browser?
Looks like for security reasons, browser.uploadFile is not available to use for IE and Edge browsers.
I suggest you try to make a test with the code sample below.
It first finds the file upload element and then it uses sendkeys() to set the path value in control.
// fetch the element
WebElement input = driver.findElement(By.XPath("//input[#type='file']"));
// send file path keys
input.sendKeys(path);
If the issue persists then you can try the below example.
// fetch the element
WebElement input = driver.findElement(By.XPath("//input[#type='file']"));
// run JS to reveal the element
JavascriptExecutor executor = (JavaScriptExecutor)driver;
executor.executeScript("arguments[0].style.display = 'block';", input);
// send file path keys
input.sendKeys(path);
Reference:
Selenium how to upload files to Microsoft Edge
Note: You may need to convert the above code into your developing language.

How to Embed the Blob Video file in Quill JS

I am trying to append the recorded video which is blob object into quill editor but the video which is appended in the editor is not playable.
Able to see only the blob object getting printed in the quill editor. If i try to open the contents in the browser it is working fine. Any suggestions?
enter image description here
well,according to this issue,
I think you maybe need to overwrite the video module's sanitize method to make it work,for image it can work like this:
var Image = Quill.import('formats/image')
Image.sanitize = function(url) {
return url
}
so as I guess, following things maybe useful:
var Video = Quill.import('formats/video')
Video.sanitize = function(url) {
return url
}
and you may need provide blob url to make it work

Why downloading tiff doesn't work in Firefox?

In my project i use AngularJS so a directive for downloading files was created. It contains the following:
scope.$on('downloaded', function(event, data) {
var hiddenLink = document.createElement('a');
$(hiddenLink).attr({
href: 'data:application/tiff;base64,' + data.Attachment,
download: data.AttachmentFileName
});
if (isIEorFirefox) {
$(hiddenLink).click(function(event){
event.preventDefault();
var byteString = atob(data.Attachment);
var buffer = new ArrayBuffer(byteString.length);
var intArray = new Uint8Array(buffer);
for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
var blob = new Blob([buffer],{type:'image/tiff'});
window.navigator.msSaveOrOpenBlob(blob, data.AttachmentFileName);
});
$(hiddenLink).trigger('click');
} else {
hiddenLink.click();
}
});
Previously there was an issue - download in IE simply didn't start - but for now as you can it has been eliminated. Though another issue remains - currently this code doesn't start download in Firefox. There is only one question - why?
UPDATE:
I've updated initial code because it didn't save file properly in IE. Now it does. Searching over the web i still cannot find a way to make file download in FF. Moreover FF still seems not to have any native way to save files according to this article https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/. I would be grateful if someone prove me wrong.
hiddenLink.click();
should perhaps be:
$(hiddenLink).click();
or same as other:
$(hiddenLink).trigger('click');
Assume you also need the event handler added as well...

Resources