Capybara-webkit tries to open example.com - ruby-on-rails-3

I'm using capybara, capybara-webkit, capybara-screenshot together with cucumber. (Ruby 1.9.3, Rails 3.1.3) and Capybara.javascript_driver = :webkit is also set env.rb
Unfortunately running a cucumber spec with #javascript will never succeed for some reason and the error screenshots just capture example.com.
The URL which I actually try to open is generated with a rails router result for one of my models e.g. with visit products_url
So how can I avoid that it ends up querying example.com?
Any input is very welcome.
Just because the comment is messed up - here's what I found was the solution:
Capybara.run_server = true
Capybara.server_port = 7787
Before '#javascript' do
Capybara.app_host = "http://127.0.0.1:#{Capybara.server_port}"
end

Try using visit products_path instead. They do not recommend using absolute URLs in "Gotchas" section of README.

For me, there was a much sneaker "gotcha" (and I was using Capybara with Rspec). Originally in a spec I had:
visit "foos/5"
This worked fine with Rack::Test but when I wanted to switch to the webkit driver to test js interactions, I got that exception (Unable to load URL: file:///products (Capybara::Driver::Webkit::WebkitInvalidResponseError)).
What I had to do was change the path I passed to visit, like so:
visit "/foos/5"
Succes!!

Here's another potential gotcha, posted for others that might have this issue. I was testing action caching, and the key Rails generates looks like "views/www.example.com/products". This happens even if you use products_path as the url. This can lead to the need to set your server name so you can know in advance what cache key to expect.

Related

codeception do not see field but the browser does (Chrome Driver)

I have a codeception test on angular 5 application. with HTML5 pretty url.
I am testing 2 steps forms.
url: /register/ fields: first_name,email,password
when success redirect to:
url: /personal-details/ fields: date_of_birth
First step goes perfectly fine. I test all the scenarios. when step one ends, the browser redirects with HTML5 redirection to /personal-details/ as expected.
The problem is that codeception does not see #date_of_birth even though it is existed.
To verify that, I puased the execution and in the console I run
document.getElementById('date_of_birth')
and the field was found. it is on the page.
I though that it is related to the redirection, so I have added a special redirect in order to cause the first form to have the same problem, and it is working fine.
this is the error:
Test fields second step
Test tests\acceptance\FirstCest.php:testFieldsSecondStep
Step See element "#date_of_birth"
Fail Failed asserting that an array is not empty.
Scenario Steps:
What could possibly go wrong?
Thanks
Maybe Codeception checks if element exists before the page is fully loaded.
Try to use waitForElement instead of seeElement
$I->waitForElement('#date_of_birth', 10);
I came across this post with a similar issue. For (in my opinion) no valid reason I got the message
"Failed asserting that an array is not empty."
when using $I->canSeeElement() or $I->canSeeElementInDom(). In my case, I was not dealing with elements that are loaded asynchronously, those elements were present.
This is what my code looked like:
$I->canSeeElementInDOM('//*[#id="MyId"]//input[#name="myCheckbox"][not(#checked)]');
Using the following syntax fixed the problem:
$I->canSeeElementInDOM('//*[#id="MyId"]//input[#name="myCheckbox" and not(#checked)]');
Hope this helps someone too.

delete cookies using capybara webkit

I recently started using capybara-webkit in order to speed up my acceptance tests. 90% of my tests run using the standard capybara DSL but some are slightly different.
One of the main ones that I am having trouble with is deleting cookies. Previously I used the following:
page.driver.browser.manage.delete_all_cookies
but this does not work with capybara-webkit. Receive this error:
undefined method `delete_cookie' for #<Selenium::WebDriver::Driver:0x007f86cb068b88> (NoMethodError)
Does anyone know how I can delete the cookies using capybara-webkit?
Thanks!
You can use clear_cookies method:
page.driver.browser.clear_cookies

How can I run a Controller Action from Rails Console, but setting the request.shot?

I'm working on a multi-tenant application, so pretty much everything throughout (starting with routing) expects to have a "request.host" that looks like "tenant_id.myapp.com".
I'm trying to run a controller action from the Rails console, but I haven't been able to figure this one out.
The easiest thing to do seems to be "app.get", but I can't figure out how to set the host.
I also saw an answer that mentions using "ActionController::TestProcess", which as far as I understand has been removed from Rails (or if not, I haven't found how to include it)
Any other options?
Thanks!
Daniel
I just verified it in my console(Pry)
# Send request with fake HTTP_HOST
>>app.get(app.root_path, nil, {"HTTP_HOST" => "123.myapp.com"})
>>#=>200
# Then check if it works
>>app.request.env
>>#...
>># "HTTP_HOST" : "123.myapp.com"

Raising route not found error

I'm writing a book on Rails 3 at the moment and past-me has written in Chapter 3 or so that when a specific feature is run that a routing error is generated. Now, it's unlike me to go writing things that aren't true, so I'm pretty sure this happened once in the past.
I haven't yet been able to duplicate the scenario myself, but I'm pretty confident it's one of the forgotten settings in the environment file.
To duplicate this issue:
Generate a new rails project
important: Remove the public/index.html file
Add cucumber-rails and capybara to the "test" group in your Gemfile
run bundle install
run rails g cucumber:skeleton
Generate a new feature, call it features/creating_projects.feature
Inside this feature put:
This:
Feature: Creating projects
In order to value
As a role
I want feature
Scenario: title
Given I am on the homepage
When you run this feature using bundle exec cucumber features/creating_projects.feature it should fail with a "No route matches /" error, because you didn't define the root route. However, what I and others are seeing is that it doesn't.
Now I've set a setting in test.rb that will get this exception page to show, but I would rather Rails did a hard-raise of the exception so that it showed up in Cucumber as a failing step, like I'm pretty sure it used to, rather than a passing step.
Does anybody know what could have changed since May-ish of last year for Rails to not do this? I'm pretty confident it's some setting in config/environments/test.rb, but for the life of me I cannot figure it out.
After I investigate the Rails source code, it seems like the ActionDispatch::ShowExceptions middleware that responsible of raising exception ActionController::RoutingError is missing in the test environment. Confirmed by running rake middleware and rake middleware RAILS_ENV=test.
You can see that in https://github.com/josh/rack-mount/blob/master/lib/rack/mount/route_set.rb#L152 it's returning X-Cascade => 'pass' header, and it's ActionDispatch::ShowExceptions's responsibility to pick it up (in https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L52)
So the reason you're seeing that your test case is passing because rack-mount is returning "Not Found" text, with status 404.
I'll git blame people and get it fix for you. It's this conditional here: https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb#L159. If the setting is true, the error got translated right but we got error page output. If it's false, then this middleware doesn't get loaded at all. Hold on ...
Update: To clearify the previous block, you're hitting the dead end here. If you're setting action_dispatch.show_exceptions to false, you'll not get that middleware loaded, resulted in the 404 error from rack-mount got rendered. Whereas if you're setting action_dispatch.show_exceptions to true, that middleware will got loaded but it will rescue the error and render a nice "exception" page for you.

Using environment vars in non-rails cucumber test

I created a simple smoketest for a portal running java/tomcat/jahia (cms) fronted by cache servers and big ip. Cucumber + Webrat + Mechanize is a good fit for a simple smoketest of this setup. (and it has been very easy to get started).
Right now I have hardcoded into /features/support/paths.rb the following lines:
module NavigationHelpers
#PATH="http://production-environment"
#PATH="http://staging-environment"
#PATH="http://test-environment"
PATH="http://localhost:8080"
#
def path_to(page_name)
case page_name
when /the homepage/
"#{PATH}/"
when [...]
...
end
end
end
World(NavigationHelpers)
Right now I manually switch the comments when I want to test different environments. The issue here is I'd love to get rid of the constant PATH and put a default value inside one of the support files. And i also want to be able to feed cucumber with this environment variable from the command line like so:
cucumber ENV=staging
How do you cope with this issue? Any suggestions? Links to code that deals with this? Snippets?
You can pass environment variables to Cucumber like you have done with ENV. Each environment vriable will then be available in Ruby's ENV constant. More details in the Wiki
(I just added this page - the feature has been around since 0.3.90 but was only ever mentioned in the History.txt file).