send Ctrl-S to browser in Capybara Webkit test - ruby

I have JavaScript in my application that submits a form when the user hits Ctrl-S or Cmd-S. I want to write an automated test for this using RSpec, Capybara, and Capybara Webkit. I don't think I can just have Capybara execute JavaScript to trigger Ctrl-S/Cmd-S because that's not normally allowed with JavaScript in Chrome as a security concern. I see with Selenium there are page.driver.browser.action.key_down/key_up methods available. Is there anything similar with Capybara Webkit? If not, how can I send Ctrl-S and Cmd-S to the browser in my test?
Edit: I also can't get this to work using the regular Selenium driver with Firefox:
describe 'edit a template and hit Ctrl-S', js: true do
render_views
it 'saves the template' do
visit my_path
page.execute_script("$('#hidden_textarea').val('Fabulous new content')")
builder = page.driver.browser.action
builder.key_down(:control).send_keys('s').key_up(:control).perform
expect(page).to have_text('Record was saved.')
expect(page).to have_text('Fabulous new content')
end
end
It looks like the builder.key_down(:control).send_keys('s').key_up(:control).perform isn't doing anything--the page loads in Firefox but just sits there. This is with Firefox 19 on OS X with selenium-webdriver 2.35.1.
Any suggestions on how to get this to work in either Firefox or Chrome, with either Selenium or Capybara Webkit?

I'm trying to do a similar thing in Chrome using Capybara and SitePrism. This actually works for me in Firefox though:
page.element.native.send_keys :command, 'a'
so I suggest trying this
builder.native.send_keys :control, 's'

Related

Why capybara codes don't work with selenium webdriver?

I am new to Capybara. I have a question about why my Capybara doesn't work when I use it together with Selenium Webdriver.
This is my sample code:
Given(/^I am on the Youtube homepage$/) do
# visit 'http://www.youtube.com'
driver = Selenium::WebDriver.for :firefox
driver.navigate.to('http://www.youtube.com')
end
When(/^I search for "([^"]*)"$/) do |search_term|
fill_in 'search_query', :with => search_term
click_on 'search-btn'
end
Then(/^videos of large rodents are returned$/) do
expect(page).to have_content 'Making Friends with a Capybara'
end
When I run it, it just open Firefox and go to Youtube homepage. But it gets error:
Capybara::ElementNotFound: Unable to find field "search_query".
Everything works with visit 'http://www.youtube.com' command.
You're creating a driver, telling it to navigate to a page and then it's going out of scope so it's getting deleted. the visit line works because it's using the current capybara driver which stays around between test steps. Rather than creating a driver manually you should be registering a driver with Capybara and then specifying which driver to use for the specific test. See drivers
Since capybara sets up a selenium driver by default for use with firefox you can just do
Capybara.default_driver = :selenium
somewhere before running your tests to make all your tests run using selenium with firefox, or since capybara registers selenium as the default javascript driver you can tag any scenarios you want to run in firefox with #javascript as shown here
#javascript
Scenario: do something something
Given ...

Selenium can't find fields with type number

I'm having a problem getting Cucumber to find fields with the HTML5 type="number". I'm not a big fan of the way they look in the browser, but I have a few fields that need the number keyboard on mobile, and this seems to be the easiest way to get it. I'm using SimpleForm to build forms and when I set :as => :text everything works, but if I set :as => :number, the fields don't get filled out. I don't get any error, the field just doesn't get filled.
To be specific, when I have a step like this:
And I fill in "application_form_age" with "52"
then this tag won't get filled in:
<input class=​"numeric integer required" id=​"application_form_age" min=​"0" name=​"application_form[age]​" size=​"50" step=​"1" type=​"number">​
but this one works:
<input class=​"string required" id=​"application_form_age" name=​"application_form[age]​" size=​"50" type=​"text">​
Also, it only happens in #javascript scenarios. In situations where #javascript isn't necessary and the scenario doesn't launch a browser, that works fine too.
Versions of things:
capybara (2.2.1)
cucumber (1.3.14)
selenium-webdriver (2.41.0)
simple_form (2.1.1)
webrat (0.7.3)
Firefox 29.0
I'm stumped. I tried yanking out a bunch of my application JS and CSS to see if something I'm doing is breaking it, but no luck with that. I'm just patching it out by forcing those fields not to have HTML5 type number in my test environment, but I don't want to live like that. Is anyone else seeing this? I haven't been able to find any references to it, which makes it seem like it's something I'm doing. But I haven't been able to figure it out.
Ok, I have found firefox has an option to disable number input field support: 'dom.forms.number'.
So if you add the following lines in your env.rb, number input gets disabled and tests work again.
Capybara.register_driver :selenium do |app|
profile = Selenium::WebDriver::Firefox::Profile.new
profile["dom.forms.number"] = false
Capybara::Selenium::Driver.new(app, :browser => :firefox, :profile => profile)
end
First off, I think you have some confusion regarding those frameworks. Cucumber is a BDD framework, which doesn't automate browsers in any way, so this question has nothing to do with it (This is why I removed it from your question title).
Looks like you are using Capybara, which is an ATDD framework. You might probably consider showing us the Capybara code you use in order diagnose your problem.
Under the hood, I assume you use Selenium WebDriver, I can confirm that Selenium works fine with <input type="number"> (Tested with Firefox 28, which is the one selenium-webdriver (2.41.0) supports to).
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
DEMO_PAGE = <<-eos
data:text/html,
<input class=​"numeric integer required" id=​"application_form_age" min=​"0" name=​"application_form[age]​" size=​"50" step=​"1" type=​"number">
eos
driver.get(DEMO_PAGE)
driver.find_element(:tag_name, 'input').send_keys('25')
So you might want to create a similar demo using Capybara to test this functionality.
If the demo works, then we need take a closer look at your application.
Othwewise, please raise a ticket for Capybara developers.

undefined method select_list using ruby with watir 2.0 & selenium web driver

I'm new to using ruby and watir and learning it as i go.
I'm trying to select an entry in a selection box using the select_list method but keep getting
'undefined method 'select_list' for #selenium::webdriver. <NoMethodError>
the line of code I'm using to make the selection is
browser.select_list(:name, "linkType").set("Content Page")
and I've also tried
browser.select_list(:name, "linkType").select("Content Page")
The site code i'm looking to call from is
<select name="linkType" size="4">
<option value="Content Page">Content Page</option>
<option value="Preset Page">Preset Page</option>
<option value="Form">Form</option>
</select>
I'm probably missing something simple, but this is my first time working with ruby/watir/selenium.So any help would be greatly appreciated.
I can think of two possible reasons for the exception.
Browser is the wrong type
Based on the exception, it is saying that browser is a Selenium::Webdriver object. To use the select_list method you need a Watir::Browser (or Watir::Element) object.
I am guessing that somewhere you have the line:
browser = Selenium::WebDriver.for :firefox
This is creating a Selenium browser/driver instead of a Watir browser. You want to do:
browser = Watir::Browser.new :firefox
Using incorrect version of Watir
Based on the title of the question, you are trying to use Watir 2.0 and Selenium-Webdriver. These are not compatible with each other. Watir 2.0, which is now Watir-Classic, does not use Selenium-Webdriver at all.
If you want to use Selenium-Webdriver with a Watir API (ie methods like select_list), you need to use the Watir-Webdriver gem.
In other words, the top of your script would have:
require 'watir-webdriver'
browser = Watir::Browser.new :ff
Or, if you have the Watir meta gem installed, using any browser other than IE would cause the Watir-Webdriver gem to load:
require 'watir'
browser = Watir::Browser.new :ff

Capybara with selenium, send_key doesn't work

I'm using Cucumber to test a comment form that doesn't have a submit button. I found that selenium has a method called send_key, which in theory should allow me to do this:
find_field('my-field').native.send_key(:enter)
But when I run my test, I get:
undefined method `send_key' for #<Nokogiri::XML::Element:0x007f874b361828> (NoMethodError)
Not a clue what I'm doing wrong. Any ideas?
You have to use the Selenium driver and not the :rack_test driver in Capybara to access the send_keys method:
Install the gem selenium-webdriver and add it to your gem file if you are using bundler.
Mark your test using :js => true so that it runs with the Selenium driver.
You get an error because by default, Capybara uses the :rack_test driver. Calling native on an element access the driver specific methods. :rack_test driver elements are implemented natively as Nokogiri::XML::Element, therefore the send_keys methods do not exists and you get this error.
Try with xpath
within(:xpath, "//form[#id='the_form']") do
locate(:xpath, "//input[#name='the_input']").set(value)
locate(:xpath, "//input[#name='the_input']").node.send_keys(:return)
end
You could also have a hidden button. Capybara can see it and click it.
<%= form.submit "OK", style: "display: none;" %>
Then in your test:
Capybara.ignore_hidden_elements = false
click_on "OK"

Automating browser without actual browser window?

I need to do an automated script that fills two text fields and clicks a button on a web page, and stores all resulting text to a string variable.
I know how to do this with Watir, but the problem is that this script will be running on a Windows server (with no physical monitor attached).
So this needs some kind of "emulated browser" without actual browser window... I have never before done anything like this, but after google search I think that Ruby gems "mechanize" or "capybara" might be able to do the trick.
But because I don't have any experience with either capybara or mehcanize, I'm asking a little help here...
Here is what I'm trying to do, written in Watir code. I would really appreciate it if someone could tell me how to do the same thing with either "mechanize" or "capybara". Or, if there is some other way to do this, all suggestion are welcomed:
require "watir"
ie = Watir::Browser.new
ie.goto "http://www.vero.fi/vere/Tarkistus/VeronumeronTarkistus.aspx/"
ie.text_field(:id, "tbNimi").set "John Smith"
ie.text_field(:id, "tbVerotunnus").set "123456789012"
ie.button(:id, "btnHae").click
info = ie.text
You could also use Celerity. It drives headless browser using Watir API.
Can Selenium Help With with Selenium Server Running and Firefox Running in headless state
I have basically wrote an article in this over here
Hope this help
I use PhantomJS for this (with the Capybara driver poltergeist). It runs a headless WebKit (Safari and Chrome's browser engine) and Capybara tells it what to do. It's the simplest-to-setup implementation of this concept that I've found.
The code would look something like:
visit "http://www.vero.fi/vere/Tarkistus/VeronumeronTarkistus.aspx/"
fill_in "tbNimi", :with => "John Smith"
fill_in "tbVerotunnus", :with => "123456789012"
click_on "btnHae"
info = page.html

Resources