Hi I need to automate a website using cucumberJS and webdriverIO. For that I need to Upload a file but the field is hidden. For Example :
<input type="file" id='uploadFile' style="display: none"'>
but webdriver is unable to identify the element on the UI.
Thanks in Advance...
In webdriverIO v5, files are uploaded to inputs of type="file" by calling .setValue() on them with the local file path as an argument. This doesn't seem to work for hidden inputs though, because .setValue() first calls .clearValue() which will throw Element could not be scrolled into view. To work around this, call .addValue() directly on the element:
input.addValue(filePath);
Relevant API docs: https://webdriver.io/docs/api/element/addValue.html
I got the solution for this Issue.Using webdriverIO we can execute javascript to change the style display from "none" to "block".
client.execute(function() {
document.getElementById("element_id").style.display="block";
},function(err) {
client.uploadFile(localPath[,callback])
if(err){
console.log("Error "+err);
}
});
then upload the file to the field and then change the display again to none.
Related
I'm trying to port the following code from Ruby with the selenium-webdriver gem to Node.js with WebdriverIO:
#webdriver.navigate.to "https://imgur.com/upload"
element = #webdriver.find_element(:id, 'global-files-button')
element.send_keys("C:\\test\\image.png")
As you can see the code is very simple: navigate to a url, find the input, set the file path and it works as expected selecting the file for upload.
This is my ported version:
describe('User can upload', () => {
it('select file', () => {
browser.url("https://imgur.com/upload");
browser.waitForExist('#global-files-button');
$('#global-files-button').keys("C : \\ t e s t \\ i m a g e . p n g".split(" "));
});
});
Unfortunately this test doesn't set the path and I haven't been able to find a working example of uploading a file like this with wdio and the documentation has left me guessing. Any suggestions much appreciated.
I'm aware of both chooseFile and uploadFile but I'm working with a cloud platform to run my wdio tests and they don't seem to work reliably.
I've had trouble with this. From what I've researched it is not an issue with WebdriverIO or it's chooseFile() or uploadFile() methods. The root of the issue I believe comes down to an error in Selenium Webdriver being unable to handle the 'multiple' <input type='file' multiple> upload elements.
I fought this for a solid maybe 3 days before stumbling across this github issue:
https://github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/2239
Long story short, because the HTML on imgur has the "multiple" property on it, your upload tests won't work correctly. WebdriverIO / Selenium just stops functioning from what I've noticed.
Note: I've been able to actually have my application upload a single file and add files to my system and application while testing an <input type='file' multiple>. The problem is however, that WebdriverIO and Selenium just stops. The tests end, without reporting any success or failure results.
If you go and test another <input type=file> element somewhere across the web that is NOT designated as a "multiple" upload input field you should be able to make the chooseFile() methods from WebdriverIO function correctly.
I hope this helps you and perhaps anyone else who's struggled with file uploads.
EDIT:
I've tried to make your example work, and I had success with "chooseFile()" and passing the "filepath" to it directly. Perhaps you're trying to send keyboard commands when you don't really have to? Do you have a direct file path to the image you're attempting to upload? Below is what i was able to use to successfully upload a file.
it('upload a file to imgur', function () {
browser.url("https://imgur.com/upload");
browser.waitForExist('#global-files-button');
browser.chooseFile('#global-files-button', '/insert/path/to/image.png')
})
// c:/test/image.png
var test1 = 'c:/test/image.png'
var path = test1.split('/').join('\\\\')
browser.addValue('[name="fileField"]', path )
or maybe this also work
// c:\test\image.png
var path = 'c:\\test\\image.png'
browser.addValue('[name="fileField"]', path )
or maybe this
// c:/test/image.png
var path = 'c:/test/image.png'
browser.addValue('[name="fileField"]', path )
I am working on the project which simply read the txt/csv files from the directory and store in the database.
The upload function works like a charm but the problem is that I want to display the progress - any notification that tells the users that the system is working on the files.
Here is my HTML markup
<div class="form">
<input type="file" id="uploadFile" />
<button id="submit" type="button">Upload</button>
</div>
<div class="terminal">
<! -------------------RESULT---------------------->
</div>
I have the div called terminal to display the progress of file uploading. The way I place text inside the div is to use the innerHTML function of javascript. Thus, my upload code is as follows
var files = fs.readdirSync(folder_path);
// Loop through files gathered from folder reading
for(i=0; i<files.length; i++) {
document.getElementbyId("terminal").innerHTML+=files[i]+"<br/>";
var fileData = fs.readfileSync(folder_path+'\'+files[i], 'utf8');
// Upload function below
}
The above markup is a part of my js file which serves as an uploader. I first read the folder with fs.readdirSync, then iterate through the array of files gathered from readdirSync function. I want to display the file name in each loop in real time.
But it just displays everything once the upload has finished. So I don't know how to make it display the progress in real time or in other word, just like the console which displays any information in real time.
You don't have to loop, you can easily port this to your frontend app:
Monitoring XHR Progress
https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress
I'm working with polymer and I'm testing all in my local environment and all is working as expected, but the problem is when I'll move it into production, where the url shouldn't be the same as in my local. In node.js I can set it via the config.json file and catch it with app.get('config') or something like that, but in polymer I cant get it, and the only chance I have is to create another endpoint with all the config.json config file, but, and here is the best part, I should hardcode this url in polymer!! (so annoying). There is some way or library or component or something that I'm missing ?
Thanks in advance guys! StackOverflow and the users helped my a lot!
UPDATE
The thing is that I'm using custom elements (because I had handlebars too and there is a little problem with the {{}}) so, in the custom elements that I created I have this (for example in the core-ajax call):
<core-ajax id="login" auto="false" method="POST" contentType="application/json" url="/app/middle/login" ....></core-ajax>
as you can see the url is a little bit hardcoded, I want to use something like this (this is what I have on the node.js endpoint application):
router.post(endpoint.login, function (req, res) {
and I want to got something like that over polymer
<core-ajax id="login" auto="false" method="POST" contentType="application/json" url="{{login}}" ... ></core-ajax>
<script>
Polymer('log-form', {
login: endpoint.login,
ready: function () {
....
})
});
</script>
I'ts more clear now? I'm not so strong on english language.
Thanks Guys, for all!
I am new to nodejs. I am basically using express, and I have to create a form to upload photos. So far I have created a file called upload.handlebars where I have written the following code:
<form enctype="multipart/form-data" action="uploads" method="post">
<input type="file", id = "image", name="image", accept="image/*">
<input type='submit' id='tags' value='Upload'>
I have another file called router.js where I have written the post function. One of the lines in the post function is:
fs.readFile(req.files.image.path, function (err, data) {
However, I get an error as follows:
TypeError: Cannot read property 'image' of undefined at Object.handle....
How should I specify the 'name' of the image file in my router.js?
Make sure you have multiparty middleware enabled.
https://github.com/andrewrk/connect-multiparty
Latest express doesn't come with it.
you can use express to solve this problem quickly. to know more read the folowing page express api reference
for now the following code may help you -
app.post('<your path>',express.bodyParser(),function(req,res){
console.log(req.files);//to get all the files uplaoded
});
make sure express version should 3.4
Multiple files are being posted to nodejs application using Express and bodyParser.
The number of files change in every request. It is required to get number of files posted at the server.
I have tried using
req.files.length
but it gives undefined. How can I know the number of files posted in a post request?
Also how to loop through each file?
Putting answer my self.
It should be iterated upon like this
for (x in files){
//code for handling each object in json.
}
You can get the length of and iterate a collection of files with the name of the <input>:
// example: <input type="file" name="images" multiple>
req.files.images.length;
req.files.images.forEach(function (file, i) {
// ...
});
You can find an example of this in the Connect repository: examples/upload.js