How do you open a zip file using watir-webdriver? - ruby

My test suite has a cucumber front end with a ruby backend, running the latest version of watir-webdriver and its dependencies atop the latest version of OSX. My cucumber environment is setup to execute in Firefox.
The export feature of our app creates a zip file but to test the import feature, I need the contents of the zip file.
My actual test needs to unpack that zip file and select the individual files in it for use in testing the import feature of our web application.
Can anyone point me to a reference that can help me figure out how to write that?

Based off my experience, you download this file the same way that a normal user might. So first off, you just click the download button or whatever and then can access the file wherever it is and check out its contents.
Assuming the downloads just go to your Downloads folder by default, there is some simple code you can use to select the most recently downloaded item:
fn = Dir.glob("~/Downloads/*.zip").max { |a,b| File.ctime(a) <=> File.ctime(b)}
Then just use the unzip shell command to unzip the file. No reason to add another gem into the mix when you can just use generic shell commands.
`unzip #{fn}`
Then, you'd use Dir.glob again to get the filenames of everything inside the unzipped files folder. Assuming the file was named "thing.zip", you do this:
files = Dir.glob("~/Downloads/thing/*")
If you want to files to be downloaded directly to your project folder, you can try this. This also prevents the popup from asking you if you really want to save the file which is handy. I think this still works but haven't used it in some time. The above stuff works for sure though.
profile = Selenium::WebDriver::Firefox::Profile.new
download_dir = Dir.pwd + "/test_downloads"
profile['browser.download.dir'] = download_dir
profile['browser.helperApps.neverAsk.saveToDisk'] = "application/zip"
b = Watir::Browser.new. :firefox, :profile => profile

I ended up adding the rubyzip gem at https://github.com/rubyzip/rubyzip
the solution is on that link but i modified mine a little bit. I added the following to my common.rb file. see below:
require 'Zip'
def unpack_zip
test_home='/Users/yournamegoeshere/SRC/watir_testing/project files'
sleep(5) #<--manually making time to hit the save download dialog
zip_file_paths = []
Find.find(test_home) do |path|
zip_file_paths << path if path =~ /.*\.zip$/
end
file_name=zip_file_paths[0]
Zip::File.open(file_name) do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
# Extract to file/directory/symlink
puts "Extracting #{entry.name}"
entry.extract(test_home + "/" + entry.name)
# Read into memory
content = entry.get_input_stream.read
end
# Find specific entry
entry = zip_file.glob('*.csv').first
puts entry.get_input_stream.read
end
end
This solution works great!

Related

how to reload external file every time?

I have a ruby script where my "config" is in an extra file. It's called ftp_config.rb. Then I have filetrack.rb that downloads files from a ftp server - what files/directories is specified in ftp_config.rb. And finally I got rufus_download.rb that is calling a function from filetrack.rb every day so I get all new files from the server.
Everything works fine just I want to know how to make it so when I edit ftp_config.rb the changes are picked up by the script without the need to restart rufus_download.rb.
currenly
rufus_download.rb contains require_relative 'filetrack'
filetrack.rb contains require_relative 'ftp_config'
Right now if I add new files to be downloaded to ftp_config.rb I need to restart rufus
require_relative returns false if the file you have requested is already loaded to your ruby script and returns true if you haven't
If you want changes to be loaded directly you need to load files
load 'path/to/ftp_config'
every time your script executes it will load / reload the script
EDIT:
you can load by expanding path of the current ruby script:
load ::File.expand_path('../ftp_config.rb', __FILE__)
Assuming that files are in the same folder
EDITEND
hope that helps
You need a gem that monitors filechanges like "sinatra/reloader" for Sinatra and eg filewatcher or listen for desktop apps. After detecting an update you load the script, not require, that only loads a script once.
Here an example of filewatcher.
STDOUT.sync = true
FileWatcher.new(['c:/test/scans']).watch() do |filename, event|
puts filename
if(event == :changed)
puts "File updated: " + filename
end
if(event == :delete)
puts "File deleted: " + filename
end
if(event == :new)
puts "Added file: " + filename
end
end

copy all files from ftp folder using Chef

remote_file block copies only one specific file.
Is there any possibility in Chef to copy all files from specific folder on ftp?
my current code is quite weird as for me:
require 'net/ftp'
ftp = Net::FTP::new("server")
ftp.login("user", "password")
ftp.chdir("/folder")
fileList = ftp.nlst('*.jar')
fileList.each do |file|
remote_file "C:\\Temp\\" + file do
source "ftp://user:password#server/folder/" + file
action :create_if_missing
end
end
ftp.close
If your solution works, why not wrap it in an LWRP? They are quite easy to create, and would tuck away the implementation in its own file. This is what I would do.
See: http://docs.opscode.com/chef/lwrps_custom.html
And for a real-life - easy to understand - example, see:
https://github.com/opscode-cookbooks/ssh_known_hosts/blob/master/providers/entry.rb
https://github.com/opscode-cookbooks/ssh_known_hosts/blob/master/resources/entry.rb

Error reading local file in Sinatra

I'm trying to write a Sinatra app that reads in a list from a file, and then spits back a random item from that list.
I'm having trouble figuring out the path to the file to read it, though. Sinatra says 'no such file or directory' when I try to load an item in my browser:
Errno::ENOENT at /wod
No such file or directory - http://localhost:4567/listing.txt
Here is the code:
require 'sinatra'
#list
get /item
puts read_list[rand(#list.size)]
end
def read_list
File.open('listing.txt', 'r').readlines
end
I have the file in /public, which the Sinatra README says is the default location for hosting static files. Furthermore, if I put it in /public I can navigate to localhost:4567/listing.txt and read the file in the browser.
A couple things I noticed:
get /item
isn't correct, it should be:
get '/item' do
If you start your code inside the same directory the Ruby code is in, the current working-directory will be ".", which is where Ruby will look when trying to:
File.open('listing.txt', 'r').readlines
Ruby will actually use './listing.txt' as the path. That's OK if you manually launch the code from the root directory of the application, but that doesn't work well if you try to launch it from anywhere else.
It's better to be explicit about the location of the file when you're actually trying to load something for use with a web server. Instead of relying on chance, there are a couple things you can do to help make it more bullet-proof. Consider this:
def read_list
running_dir = File.dirname(__FILE__)
running_dir = Dir.pwd if (running_dir == '.')
File.open(running_dir + '/public/listing.txt', 'r').readlines
end
File.dirname gets the path information from __FILE__, which is the absolute path and name of the current file running. If the application was started from the same directory as the file, that will be ., which isn't what we want. In that case, we want the absolute path of the current working-directory, which Dir.pwd returns. Then we can append that to the path of the file you want, from the root of the application.
You'll need to do File.read('public/listing.txt', 'r') to get what you want here.
File.open isn't part of Sinatra and doesn't know to look in a specific place for static files, so it just looks in the current working directory.

include file to ruby testScript

I have multiple ruby test cases for selenium-webdriver and all the files are sharing the same user name and password to login to my account. Is there a way to create a global file and include that file in these test cases instead of typing them over and over again, something like #include?
Here is the part of the code that needs to be shared between other test cases:
def setup
#driver = Selenium::WebDriver.for :firefox
#base_url = "http://localhost:3000/"
#driver.manage.timeouts.implicit_wait = 30
#verification_errors = []
#facebook_ID = "xxxxxxxxxx#xxx.xxx"
#facebook_password = "xxxxxxx"
#facebook_receiver_friend = "John Smith"
end
There are multiple ways to do it.
You could use
require 'setup'
where setup.rb is the common file that has all the setting up variables/functions.
You could also use a YAML file. More information here. Where all your config attributes can be defined.
Also put this is at the top of the file $:.unshift '.' . This is so that your test file can "discover" your setup.rb file which is routable from the home directory.
Note - Even though you will save the file as setup.rb you will require as only setup.
I got my answer:
eval File.open('setup.dat').read
This will insert what I have in setup.dat as a text wherever I need it.

ruby-inotify example?

I'm looking for a simple, concise example of using the inotify gem to detect a change to a directory.
It lacks examples.
There's an example in examples/watcher.rb.
That link is to aredridel's repo, since it looks like you linked to aredridel's docs, and aredridel is the one who wrote the example.
One of my projects I have used ruby-inotify for monitoring file creation under specific folder using following code
# frozen_string_literal: true
require 'rb-inotify'
# observe indicate folder, trigger event after
module ObserveFiles
def self.observe
watcher = INotify::Notifier.new
directory = CONFIG['xml_folder'] # folder that want to watch
watcher.watch(directory, :create) do |event|
# do your work where
# here, event.name is created file name
# event.absolute_name file absolute path
end
watcher.run
end
end
Use this code like
ObserveFiles.observe
Hope this will help someone.

Resources