Any thoughts on what I can do/use to run cucumber scenarios in parallel on Windows? So far, I've tried (with the follow findings):
WatirGrid
Have to use Ruby threads to actually run in "parallel".
This forces us to wrap the browser object in a thread, and therefore
un-reachable once the thread block closes. (Can't pass Browser object
to cucumber environment)
Hydra:
Need SSH (and public-key) access to remote boxes (ie. No Windows)
Selenium Grid:
Super heavy and can't find clear Cucumber testing path
TestJour:
Requires Bonjour (which isn't available for Windows)
Re Watirgrid ...
I've since added an iterate method which can be passed a block of watir code to execute against remote browser objects. So the browser objects become reusable between steps. An updated detailed cucumber example is here:
https://github.com/90kts/watirgrid/blob/master/examples/cucumber/step_definitions/example_steps.rb
Your cuke steps end up looking like this:
Given /^navigate to the portal$/ do
#grid.iterate {|browser| browser.goto "http://gridinit.com/examples/logon.html" }
end
When /^they enter their credentials$/ do
#grid.iterate do |browser|
browser.text_field(:name => "email").set "tim#mahenterprize.com"
browser.text_field(:name => "password").set "mahsecretz"
browser.button(:type => "submit").click
end
end
Then /^they should see their account settings$/ do
#grid.iterate do |browser|
browser.text.should =~ /Maybe I should get a real Gridinit account/
end
end
If you have any questions feel free to drop me a line. We also have a commercial implementation of watirgrid on EC2 available for beta at http://gridinit.com/public/examples so stay tuned for more updates with different test frameworks!
FYI the control / iterate helpers are in the latest version of watirgrid v1.1.2
Alternatively to do it in parallel with different scenarios on each of the providers, I would just have a support/env.rb that looks something like this:
require 'watirgrid'
require 'rspec/expectations';
ENV["GRID"] = 'true'
ENV["controller_uri"] = "druby://10.0.1.3:11235"
if ENV["GRID"] then
params = {}
params[:controller_uri] = ENV["controller_uri"]
params[:browser] = 'chrome' # type of webdriver browser to spawn
grid ||= Watir::Grid.new(params)
grid.start(:initiate => true, :quantity => 1, :take_all => true)
else
#browser ||= Watir::Browser.new :chrome
end
Before do |scenario|
#browser = grid.providers.first
end
at_exit do
grid.iterate do |browser|
browser.close
end
grid.release_tuples
end
Note I'm using :take_all => true to get exclusive access to a provider and releasing it back to the grid at_exit ... I would then call my scenarios from a separate test runner using the CLI, maybe wrapped in a bash or DOS script e.g.
cucumber features --name "Name of scenario 1"
cucumber features --name "Name of scenario 2"
cucumber features --name "Name of scenario 3"
...
etc
Related
I'd like to extend the default console application that is built as standard with bundle gem by applying some of the IRB config options.
Looking at the documentation, I can see that it should be possible for instance to change the prompt, and this works fine on an interactive session. For example I can play with the displayed prompt like this:
2.1.4 :001 > conf.prompt_mode=:SIMPLE
=> :SIMPLE
>>
?> conf.prompt_mode=:DEFAULT
=> :DEFAULT
irb(main):004:0>
However, I cannot find how to translate this into syntax for use in the console app. For example this script:
require 'irb'
IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.start
Just starts with the generic configured prompt:
2.1.4 :001 >
I have spent some time trying to find an example use of IRB for a custom repl without loading global defaults, but not found anything I can copy from.
I can see that the undocumented method IRB.setup has something to do with this, it is setting all the config somehow. Is my only option to write my own version of IRB.start that applies my desired config after calling IRB.setup, or is there support for what I want to do built-in but not documented in standard location?
E.g. the following works, but I feel it's a bit heavy handed extending IRB module this way (and also prone to failing if IRB internals change).
require 'irb'
def IRB.custom_start custom_conf = {}
STDOUT.sync = true
IRB.setup(nil)
custom_conf.each do |k,v|
IRB.conf[k] = v
end
if #CONF[:SCRIPT]
irb = IRB::Irb.new(nil, #CONF[:SCRIPT])
else
irb = IRB::Irb.new
end
#CONF[:IRB_RC].call(irb.context) if #CONF[:IRB_RC]
#CONF[:MAIN_CONTEXT] = irb.context
trap("SIGINT") do
irb.signal_handle
end
begin
catch(:IRB_EXIT) do
irb.eval_input
end
ensure
irb_at_exit
end
end
IRB.custom_start :PROMPT_MODE => :SIMPLE
You can apply custom configurations in two ways.
The first one is to use irbrc file. It may be tricky in building console application (calling IRB.start from the ruby file instead of irb from the console).
The second one is the approach that you have described in the post. You can write your own IRB::start method based on the original one. There are exactly the same potential issues as in using undocumented API - it can break in the future with newer versions of irb.
You should think if you really need to build a console application on the top of irb. For example you can solve this problem using Pry. It allows to define configuration before starting interactive session.
require 'irb'
IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.start
The approach above doesn't work because conf[:PROMPT_MODE] gets over-riden in a method called IRB.init_config here
When IRB.start is called, it calls IRB.setup which in turn calls the method IRB.init_config -- which over-rides conf[:PROMPT_MODE] setting.
Here is one approach which solves the problem (relies on internal knowledge of the implementation).
require 'irb'
module IRB
singleton_class.send(:alias_method, :old_setup, :setup)
def IRB.setup(ap_path)
IRB.old_setup(ap_path)
conf[:PROMPT_MODE] = :SIMPLE
end
end
IRB.start
I wrote this bit of code to be called in a script that runs on a cron job, knowing it has to be a headless browser to be ran in a cron job, i found Headless. It sounds like a wonderful gem to do exactly what i want it do to, the only problem is it still opens up FireFox when I run the code.
I thought the whole point of headless was to not have to access the display and run in the background, like :phantomjs. Am I missing something or did I mistake what the headless gem is supposed to accomplish? (P.S. at bottom about when i tried to use :phantomjs)
#encoding: utf-8
require 'watir-webdriver'
require 'headless'
#log into admin dashboard
headless = Headless.new
browser = Watir::Browser.start 'http://app.mycompany.com/admin'
browser.link(:xpath =>'/html/body/div/div/div/div/a').when_present.click
browser.text_field(:id => 'Email').when_present.set 'me#mycompany.com'
browser.button(:id => 'next').click
browser.text_field(:id => 'Passwd').when_present.set 'password'
browser.button(:id => 'signIn').click
browser.goto 'https://app.mycompany.com/admin/dashboard'
#browser is at dashboard to grab yesterday's numbers
code that grabs data
#closes browser after grabbing data
browser.close
headless.destroy
#send timestamp
current_time = Time.now
puts "Screen grabbed at " + current_time.inspect + "\n\n"
#puts all data into array then outputs array split on each metric's title
dailyreportdata = [my glorious array of data]
dailyreportdata.each_slice(2) { |x|
puts x.join
}
My script runs to completion, but the data doesnt appear so I am guessing that it fails over when it tries to load the browser, thus loading no data to grab and send to my file.
My script look like this:
#!/bin/sh
_now=$(date +"%m_%d_%Y")
ruby dailyreportscraper.rb > ~/dailyscrape_$_now.txt
if I run it outside of the cron job, it works just fine.
P.S. - I tried phantomjs but every time it got to the "Enter Email" field, it would time out on waiting for the element to appear - it is a google login so maybe there is something to do with that, I even tried using the xpath as well.
Thanks for the help!
Call headless.start after you do headless = Headless.new.
And make sure you are running Xvfb.
I'm pretty new to cucumber automated testing. When I first started, a co-worker had set up everything for me on my computer, and (now that he's gone) I've run into a problem that I can't seem to figure out.
I'm using cucumber to test a web application. In the past when I run the script, an internet explorer pops up, and I can see each line of the script being executed.
I recently had to reinstall cucumber, ruby, watir, etc., and that internet explorer screen no longer pops up.
I installed Ruby 1.9.3, cucumber (gem install cucumber), watir (gem install watir). Am I missing something? Is it an extra plug in? The script still runs. However, instead of taking say 1 min + to run a 320 step script, it now takes 1.5 seconds. There are no error messages. When run from the command window, it literally looked like it just scrolled through the script instead of going through each step.
What is the pop up screen called anyways? A scenario screen? Output screen?
It was really difficult for me to look it up on google because I had no idea how to refer to that screen.
Any help is appreciated. and I realize I might not have described the problem well enough. Just leave a comment, and I can try to clarify it more.
Feature:
'To go to a webpage'
Scenario:
# ----------
# GO TO PAGE
# ----------
Given that I have gone to the Login page at "url"
#
# ----------
# LOG IN
# ----------
When I add "username" to the Username
When I add "password" to the Password
And click the Login button
Then "Welcome" should be mentioned on the page
script definitions:
require "rubygems"
require "watir"
puts "Browser is running..."
END {
puts "Closing browser..."
}
BEGIN {
puts "Starting browser..."
}
Given /^that I have gone to the Login page at "(.*)"$/ do |item|
#browser = Watir::IE.start(item)
lnk_found = 0
#browser.links.each do |lnk|
if lnk.id.to_s.matches("overridelink")
lnk_found += 1
end
end
if lnk_found > 0
#browser.link(:id, "overridelink").click
end
# puts "Watir Version: #{Watir::IE::VERSION}"
#browser.maximize
end
#
#
#
When /^I add "(.*)" to the Username$/ do |item|
#browser.text_field(:name, "loginName").set(item)
end
#
#
When /^I add "(.*)" to the Password$/ do |item|
#browser.text_field(:name, "passwd").set(item)
end
#
#
#
Then /^"(.*)" should be mentioned on the page$/ do |item|
if #browser.text.include?(item)
# puts "TEST PASSED. FOUND >#{item}<"
else
puts "*** TEST FAILED ***. >#{item}< was not found."
end
end
Directory Structure
Cucumber
Testing
lib
login.rb
login.feature
I don't know what exactly fixed it but after taking suggestions and advices from different people I basically uninstalled and reinstalled watir several times.
I also updated the code, took out "require 'rubygems'" and replaced Watir::IE.start with Watir::Browser.start.
It seems like the problem was the existing scripts I worked with was based off of older versions of watir/cucumber/ruby, so when I had to reinstall everything, the scripts were no longer compatible with newer versions of everything.
I was given a sample sinatra project with a hello world for capybara testing in akephalos. I understand the concept by looking at the code, but how do i run it? If I run rackup config.ru, and then go to :9292 I just see a hello world. Great, what is that telling me? How do I run the test? The project is bare bones, but below is a file called example_spec.rb. How can I see it fail, for example by looking for "Hi world" and watching it fail? Hope this is enough info. Thought I would check here before I ask the dude that supplied me with the test, thanks!
# describe and context blocks are optional but help organize things
describe 'the index page' do
include x
# :js => true is used to run the test in Firefox. Otherwise it runs headless
# and without JS support
it 'can view the index page', :js => true do
visit '/'
# check to see if the page has the following text (ignoring tags)
page.should have_content('Hello, world!')
# visit https://github.com/jnicklas/capybara to see a complete list of
# assertions
end
You need to set Capybara.app = <your Sinatra class>. Perhaps something like this:
setup do
Capybara.app = Main
end
bundle exec rspec spec, This means run "bundle exec rspec" on the "spec" directory
I have a simple watir (web-driver) script which goes to google. But, I want to use option parser to set an argument in the cmd to select a browser. Below is my script:
require 'optparse'
require 'commandline/optionparser'
include CommandLine
require 'watir-webdriver'
describe 'Test google website' do
before :all do
options = {}
opts = OptionParser.new do |opts|
opts.on("--browser N",
"Browser to execute test scripts") do |n|
options[:browser] = n
$b = n.to_s
end
end
opts.parse! ARGV
p options
end
describe 'The test website should be displayed' do
it 'should go to google' do
$ie = Watir::Browser.new($b)
#go to test website
$ie.goto("www.google.com")
end
end
end
Executing rspec ietest.rb --browser firefox -f doc
just gives me invalid option, ietest is the name of my file. Any other intuitive ways of setting a browser through web driver, with out changing script code, would be welcome.
You cannot use rspec with OptionParser since the rspec executable itself parses its own options. You cannot "piggy back" your options on the rspec options.
If you must do something like this then use either a settings file (spec_config.yml or similar), or use an environment variable:
BROWSER=firefox spec test_something.rb
And then in your code you can use ENV['BROWSER'] to retrieve the setting.
Please, learn about RSpec because I am guessing you have no clue about it (just google it). There are no expectations and you are writing your functionality in it.
require 'optparse'
require 'commandline/optionparser'
include CommandLine
require 'watir-webdriver'
options = {}
opts = OptionParser.new do |opts|
opts.on("--browser N",
"Browser to execute test scripts") do |n|
options[:browser] = n
end
opts.parse! ARGV
p options
ie = Watir::Browser.new(options[:browser].to_s)
#go to test website
ie.goto("www.google.com")
That should work.
EDIT: If you want to test it do something like this:
def open_url_with_browser(url, browser = 'firefox')
nav = Watir::Browser.new(browser)
nav.goto(url)
end
Then you would test that method in a spec. Just stub new, and goto in different specs.
If you are still wondering why are you getting the invalid option is because you are passing --browser to rspec, not your script, as intended.