Open scrawfor opened 8 years ago
I looked through the implementation in the WebDriverJS Bindings.
Based on that, I implemented a custom action in protocol.js which uploads the file and returns the remote path. But it does not provide the other piece of functionality ("Replacing local path with remote path automatically").
/**
* Uploads a file to the remote server, returning the path to the remote file.
*
* @param {[String]} file The path to the file.
* @param {Function} [callback] Optional callback function to be called when the command finishes.
* @return {[String]} The path to the file on the remote server.
*/
Actions.uploadFileToSeleniumServer = function( filePath, callback ) {
//TODO Validate the file.
var AdmZip = require('adm-zip');
var zip = new AdmZip();
zip.addLocalFile(filePath);
return postRequest( '/file', { file : zip.toBuffer().toString('base64') }, callback );
};
protractor implemented setFileDetector :(
@straris The custom action I posted seems to work pretty well. We are running a private forked version of nightwatch with this change and haven't had any failures.
Thank you @scrawfor How do you actually use your custom command? I am getting postRequest is not defined
You would need to fork the repository and add the command to protocol.js.
You could then use it like any standard nightwatch action. Personally I defined a custom command which looks something like this:
exports.command = function (localFilepath, callback) {
var browser = this;
// First upload the file to the selenium server. This allows our code to work with selenium grid.
browser.uploadFileToSeleniumServer(localFilepath, function (result) {
if (result.status === -1) {
console.error(result);
return;
}
// Extract the new remote path of the file
var remotePath = result.value || "";
// Now, begin uploading the file to the website being tested.
browser.setValue("#someInput", remotePath, function () {
// Upload started, continue code. Wait for upload complete if necessary.
callback();
});
});
return this; // allows the command to be chained.
};
I should create a PR for this but I haven't had the chance yet.
Thank you for that @scrawfor
Next error would be:
{ status: -1, value: { localizedMessage: 'invalid code lengths set', cause: null, suppressed: [], message: 'invalid code lengths set', hCode: 1876464331, class: 'java.util.zip.ZipException', screen: null }, errorStatus: 13, error: 'An unknown server-side error occurred while processing the command.' }
I don't think I have run into that issue. Seems like the zip file you are sending is corrupt in some way.
ok, this helped me out: https://github.com/SeleniumHQ/selenium/issues/640
It seems to be a problem with adm-zip, I replaced it with archiver and it worked
@scrawfor How would you send a file without compressing it?
As far as I know you have to zip the file since that is expected by the server. Is that causing issues for you?
@scrawfor problem is that the file is being uploaded as a zip and in my case the test fails because the website expects an image file, should the server unzip it?
Yeah the server should unzip it. My guess is the file isn't being properly zipped, or you've got some other issues going on. Maybe try running the job locally or on another server?
thank you for the explanation! will give it a try
@scrawfor thanks this works for me are these changes merged to the master?
+1 we are blocked on this.
+1 as well, would be great to have this.
I've had to fork nightwatch and pull in the the above protocal.js changes and usage example, but this is working for us as well.
I created a custom command that will perform the upload without having to clone the repo if anyone else is interested: https://gist.github.com/Bunk/6c384fbe15556f7702d32aa8aa7a7521
The custom command work great for running the tests on sauselabs, i only have a problem when i try to run the test using the safari browser ( both locally and via sauslabs).
I posted the error message below, any ideas on how i should go about fixing this ?
`Error processing the server response:
Problem accessing /wd/hub/session/undefined/file. Reason:
Server Error
org.openqa.selenium.injector.UnableToInstaniateInstanceException: Unable to find required matches for constructor of: class org.openqa.selenium.remote.server.commandhandler.UploadFile at org.openqa.selenium.injector.Injector.newInstance(Injector.java:81) at org.openqa.selenium.remote.server.AllHandlers.lambda$handler$3(AllHandlers.java:139) at org.openqa.selenium.remote.server.AllHandlers.lambda$match$0(AllHandlers.java:87) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958) at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) at org.openqa.selenium.remote.server.AllHandlers.match(AllHandlers.java:89) at org.openqa.selenium.remote.server.WebDriverServlet.handle(WebDriverServlet.java:210) at org.openqa.selenium.remote.server.WebDriverServlet.doPost(WebDriverServlet.java:169) at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) at org.openqa.selenium.remote.server.WebDriverServlet.service(WebDriverServlet.java:129) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.seleniumhq.jetty9.servlet.ServletHolder.handle(ServletHolder.java:860) at org.seleniumhq.jetty9.servlet.ServletHandler.doHandle(ServletHandler.java:535) at org.seleniumhq.jetty9.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.seleniumhq.jetty9.security.SecurityHandler.handle(SecurityHandler.java:548) at org.seleniumhq.jetty9.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) at org.seleniumhq.jetty9.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) at org.seleniumhq.jetty9.servlet.ServletHandler.doScope(ServletHandler.java:473) at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) at org.seleniumhq.jetty9.server.handler.ContextHandler.doScope(ContextHandler.java:1155) at org.seleniumhq.jetty9.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.seleniumhq.jetty9.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.seleniumhq.jetty9.server.Server.handle(Server.java:530) at org.seleniumhq.jetty9.server.HttpChannel.handle(HttpChannel.java:347) at org.seleniumhq.jetty9.server.HttpConnection.onFillable(HttpConnection.java:256) at org.seleniumhq.jetty9.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.seleniumhq.jetty9.io.FillInterest.fillable(FillInterest.java:102) at org.seleniumhq.jetty9.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247) at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140) at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.seleniumhq.jetty9.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382) at org.seleniumhq.jetty9.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:708) at org.seleniumhq.jetty9.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:626) at java.lang.Thread.run(Thread.java:748)
`
@ConnorStroomberg did you end up solving what caused this issue? I am having a similar problem
@ConnorStroomberg What version of Safari? I wonder if this is a problem with the new WebDriver implementation... Or the Older one, which didn't support remote file uploads at all.
@Bunk Do you have an updated version of that gist, it no longer seems to work.
Created a custom command for v1.4 https://github.com/RohanImmanuel/NightwatchJS-Remote-File-Upload
For anyone before V2 has this issue. Maybe this will help you to bypass the issue: https://www.browserstack.com/docs/automate/selenium/test-file-upload#uploading-pre-loaded-files
BTW, none of above custom commands work for me. I guess the API has changed.
Is it now possible to implement file uploading using LocalFileDetector?
After some quick googling I found this. But I'm not familiar enough with the selenium project to node if it has any true impact.
This issue provide a method for uploading files and it works locally, but fails when using selenium grid as the remote node is unaware of the local file.