Testing HTML5 File Upload with Capybara/Selenium Webdriver - Ruby - ruby-on-rails

I have a simple modal that appears in which the user is shown the browse button to add the file to upload. Due to an unknown issue, be it the fact its an HTML5 file input therefore the browser adds its own functions to it, this has become a pain to test.
On my page I have:
<input type="file" id="photo_upload">
Capybara offers a solution out of the box which is:
attach_file <<upload_file_id>>, <<file_path>>
This behind the scenes executes a send_keys command to push the file_path into the path container for this input, however this simply did not work with my setup. I am running Firefox 25.0.1 on Windows 8. I tried both a relative path and a full path to this file, with forward and backslash combinations.
When I mean it did not work, I mean when my ajax script executes from clicking the button 'upload' next to it, it does not send any file object in the params.
I even tried to use capybara to send the file path directly:
find_field(<<upload_file_id>>).native.send_keys(<<file_path>>)
Next up, was to attempt to use selenium to push it in using:
element = driver.find_element(:id, <<upload_file_id>>)
element.send_keys <<file_path>>
Then I tried executing script to ensure the element was visible, and then setting it:
element = page.execute_script(
"document.getElementById('#{<<upload_file_id>>}').style.visibility = 'visible';
document.getElementById('#{<<upload_file_id>>}').style.height = '20px';
document.getElementById('#{<<upload_file_id>>}').style.width = '60px';
document.getElementById('#{<<upload_file_id>>}').style.opacity = 1; return
document.getElementById('#{<<upload_file_id>>}')")
find_field(field_locator).native.send_keys(<<file_path>>)
This didn't work either. Now I am completely stuck. All the help on here and google points to using the above, but it just simply does not work for my setup.
My options as far as I can see it are to use a windows automation script and jump out of capybara, run the script, and then continue, or to directly call the upload url either from capybara using a post or calling the js ajax that currently does it.

So I have solved it, and its not too ugly. I used the automation route via AutoIT. The bundle you download with AutoIT includes a script to exe converter and using the below script (I can not take credit for the script) I created an exe:
Local Const $dialogTitle = $CmdLine[2]
Local Const $timeout = 5
Local $windowFound = WinWait($dialogTitle, "", $timeout)
$windowFound = WinWait($dialogTitle, "", $timeout)
Local $windowHandle
If $windowFound Then
$windowHandle = WinGetHandle("[LAST]")
WinActivate($windowHandle)
ControlSetText($windowHandle, "", "[CLASS:Edit; INSTANCE:1]", $CmdLine[1])
ControlClick($windowHandle, "", "[CLASS:Button; TEXT:&Open]")
Else
MsgBox(0, "", "Could not find window.")
Exit 1
EndIf
In my capybara script, I merely run:
find_field(<<upload_file_id>>).click
system("<<full_path>>\\file_upload.exe \"#{<<file_path>>}\" \"File Upload\"")
and it works perfectly! In fact, I think I prefer the fact it exactly mimics what a user would be doing.

Related

Electron-mksnapshot snapshotResult.setGlobals location?

I've created a script using electron-link. Within the links are basic requires needed for electron i.e:
function get_app() {
return app = app || require("./node_modules/electron/index.js").app;
}
when running the script through electron I get the below error:
"To use Node's require you need to call snapshotResult.setGlobals first!"
I've attempted to add this line to many areas without much affect. is there a correct area to place this?
Figured it out. I needed to wrap my main.js file in a function and export that function. then I can call the function after calling the .setGlobals function.

Encryption in RoR using gpgr package fails to write output file?

I have a script that's a plugin for redmine which enhances the application to send encrypted mail using gpg. At some point this stopped working. Unfortunately the one who wrote that script is not available anymore and I am an admin with only very limited knowledge of RoR.
The problem is, that obviously the script creates a file with the mail body, saves it to temp, encrypts it to an output file, reads this output and then sends the mail.
With an empty /tmp directory (such as after rebooting the whole server), the gpg.in file gets created when I try to send a test mail. But then I get an error that the gpg.out file was not available. Creating it using touch does cause an empty email being send so obviously the script does not write anything to that file.
File.open('/tmp/gpg.in', 'w') do |f1| #<--- Works, file is created
f1.puts(body)
end
list_of_keys = [ rec ]
Gpgr::Encrypt.file('/tmp/gpg.in', :to => '/tmp/gpg.out').encrypt_using(list_of_keys) #<- gpg.out wird nicht erzeugt.
text = ""
File.open('/tmp/gpg.out', 'r') do |f2| #<- throws file not found error, if file not there. When file was created empty using touch, it sends an empty mail
With my limited RoR knowledge, I can't figure out how to debug this. Permissions on /tmp are 777 so the script should be allowed to write there and obviously has because File.open('/tmp/gpg.in', 'w') works correctly all the time without an error. Hence I expect the problem in Gpgr::Encrypt.file not working correctly, but I also don't get any error from that function it fails silently.

"document" in mozilla extension js modules?

I am building Firefox extension, that creates single XMPP chat connection, that can be accessed from all tabs and windows, so I figured, that only way to to this, is to create connection in javascript module and include it on every browser window. Correct me if I am wrong...
EDIT: I am building traditional extension with xul overlays, not using sdk, and talking about those modules: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules
So I copied Strophe.js into js module. Strophe.js uses code like this:
/*_Private_ function that creates a dummy XML DOM document to serve as
* an element and text node generator.
*/
[---]
if (document.implementation.createDocument === undefined) {
doc = this._getIEXmlDom();
doc.appendChild(doc.createElement('strophe'));
} else {
doc = document.implementation
.createDocument('jabber:client', 'strophe', null);
}
and later uses doc.createElement() to create xml(or html?) nodes.
All worked fine, but in module I got error "Error: ReferenceError: document is not defined".
How to get around this?
(Larger piece of exact code: http://pastebin.com/R64gYiKC )
Use the hiddenDOMwindow
Cu.import("resource://gre/modules/Services.jsm");
var doc = Services.appShell.hiddenDOMWindow.document;
It sounds like you might not be correctly attaching your content script to the worker page. Make sure that you're using something like tabs.attach() to attach one or more content scripts to the worker page (see documentation here).
Otherwise you may need to wait for the DOM to load, waiting for the entire page to load
window.onload = function ()
{
Javascript code goes here
}
Should take at least diagnose that issue (even if the above isn't the best method to use in production). But if I had to wager, I'd say that you're not attaching the content script.

Ruby tool that pics a folder on the local drive?

Ok so i have a ruby script that currently prompts the user for a string location of a folder on the users harddrive ...this works well
puts "\nEnter the location of the files"
loop do
print "\nLocation: "
reply = ''
reply = STDIN.gets.strip
break if File.directory?(reply)
puts File.directory?(reply)
end
But i was wondering if there was another tool other then the STDIN (which currently makes the user enter a string of the path) that will popup a folder search that the user can navigate to ...if there is anything else I can provide for anyone to help you help me..
I can ever use rails if there is no other option but i have no idea whats available to me
There are a many Ruby GUI libraries; pick one--most will have a file dialog.
For simple dialogs, Zenity is fine.
This is a file selection dialog:
file = `zenity --file-selection --title="Select a file"`.chomp
Adding one parameter changes it to a directory selection dialog:
dir = `zenity --file-selection --directory --title="Select a directory"`.chomp

Developing a Firefox plugin/addon that invokes "Save As" from FF's own set of functions

I have a basic FF addon that polls for something in the DOM of the page in window.document. When it sees it, it is supposed to save the page. That's the hard part. I don't want to replicate the functionality of "save complete" I just want to call the pre-existing functionality from the plugin/addon at the right moment.
Is this an XPCom thing? Or is it pure JavaScript via the relevant APIs ?
iMacros for Firefox can invoke Save-as (without popping the associated dialog), but I can't see how.
Can anyone advise as to how to call deeper Firefox functions like this?
Thanks, - Paul
PS - I really love Mozilla Archive Format, with MHT and Faithful Save but I think it is replicating functionality again. My alternative is to invoke it's function, but that's as opaque to me as the firefox native one.
You can use nsIWebBrowserPersist.saveDocument() for this:
var persist = Cc["#mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(Ci.nsIWebBrowserPersist);
var localPath = Cc["#mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
localPath.initWithPath(pathToLocalDirectory);
var localFile = localPath.clone();
localFile.append("mylocalfile.html");
persist.saveDocument(document, localFile, localPath, null, 0, 0);
The key is the third parameter which specifies where the linked URIs should be stored. See http://mxr.mozilla.org/mozilla2.0/source/embedding/components/webbrowserpersist/public/nsIWebBrowserPersist.idl#256 for complete documentation.

Resources