Testing javascript on subdomain with capybara, phantomjs and rails
capybara, phantomjs, ruby-on-rails, subdomain
Solution
Capybara already starts a server for you, to quote the docs:
Some Capybara drivers need to run against an actual HTTP server. Capybara takes care of this and starts one for you in the same process as your test, but on another thread. Selenium is one of those drivers, whereas RackTest is not.
Within your test you can use the `visit` method with a relative url, for example:
visit("/statistics")
Capybara will direct this request to the server it just started for this test.
When your want to use an absolute url within your test, you can, but you should also specify the port the server is running on. This port is being randomly chosen during the test. Some drivers have a method available to retrieve the port number.
For example when you use the Capybara-Webkit driver:
Capybara.current_session.driver.server_port
To `visit` an absolute url you can then use:
port_number = Capybara.current_session.driver.server_port
visit("http://127.0.0.1:#{port_number}/statistics")
Within the test specs probably a method `login_as` won't work. You have to log in with a few simple steps. For example:
before(:each) do
visit "/login"
fill_in "Email", :with => "my@email.com"
fill_in "Password", :with => "secret"
click_button "Login"
end
To test multiple subdomains you can set the `Capybara.app_host`. Take a look at this question for a detailed explanation.
UPDATE
Capybara 2 includes a nice feature called `always_include_port` which will automatically add the port number the server is running on.
Capybara.always_include_port = true
So instead of
visit("http://127.0.0.1:#{port_number}/statistics")
you can now use
visit("/statistics")
and it will automatically connect to `http://127.0.0.1:#{port_number}/statistics`.
If you want to test multiple subdomains with `Capybara.app_host`, you could use a domain name which always resolves to 127.0.0.1 for example `lvh.me`.
For example, if you specify `Capybara.app_host = "http://example.lvh.me"` it will run the tests using the `example` subdomain.
Problem
Solution This worked. The main essence is that I have to set the `Capybara.server_port` and `Capybara.app_host` and sign in manually in the sign in form. `Capybara.app_host` cannot be set with a dynamic subdomain unless its declared in a variable. All urls has to be hard coded. ``` require 'spec_helper' feature 'customer' do let(:user) {FactoryGirl.create(:user)} let(:firm) {user.firm} let(:customers) {"http://#{firm.subdomain}.lvh.me:31234/customers"} let(:root_url) {"http://#{firm.subdomain}.lvh.me:31234/"} before(:all) do Capybara.server_port = 31234 sub = firm.subdomain Capybara.app_host = root_url end def sign_in_on_js visit root_url fill_in "Email", :with => user.email fill_in "Password", :with => "password" click_button "Sign in" page.should have_content("Signed in successfully.") end scenario "make new", js: true do sign_in_on_js visit customers page.should have_content("Add new customer") find("#dialog_customer").click page.should have_content("Create new customer") end end ``` Original question I am making a multitenant app in rails. There is going to be a lot of javascript. But, I cant get the testing to work. When not running `:js = true` every thing works. The problem arises in specs like this one ``` let(:customers) {"http://#{firm.subdomain}.lvh.me:3003/customers"} scenario "Statistics select", :js => true do visit customers page.should have_content("Add new customer") end ``` The poltergeist web driver for capybara cannot find the url and returns a blank page ``` Failure/Error: page.should have_content("Add new customer") expected there to be text "Add new customer" in "" ``` I have this in my spec_helper.rb ``` require 'capybara/rspec' require 'capybara/poltergeist' Capybara.javascript_driver = :poltergeist Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app, :debug => true) end ``` Poltergeist and phantomjs try to deliver. I get this output ``` {"name"=>"set_debug", "args"=>[true]} {"response"=>true} {"name"=>"visit", "args"=>["http://subdomain2.lvh.me:3003/statistics"]} poltergeist [1362522132943] state default -> loading {"response"=>{"status"=>"fail"}} ``` Do I need to have a server running during testing to make this work? I've tried selenium and capybara-webkit, but phantomjs has gotten closest to success. I have also tried to change the hosts file in different ways( maybe not correct ) Any tips on setup are welcome! Update Starting to get desperate. I now start the rails server ``` rails s -e test -p 3001 ``` and then run my tests. Now I get redirected to the sign in page. I have this in the specs ``` before(:each) do login_as(user, :scope => :user) end ``` How can I sign in the test user on the rails test server without going trough the sign in process manually for every spec