0

In app I use gem "I18n" for internationalization. All worck ok, but in aceptance tests, I receive an error:

    Failure/Error: expect(current_path).to eq profile_path
     expected: "/profile"
     got: "/en/profile"
   (compared using ==)

Test:

  describe 'User go to profile' do
    before do
      page.driver.header 'Accept-Language', locale
      I18n.locale = locale

      sign_in (user)
    end

    context 'locale EN' do
      let(:locale) { :en }

      scenario 'and view see profile page' do
        visit profile_path

        expect(current_path).to eq profile_path
      end
    end
  end

On site all work good. How can I fix it?

alexin
  • 243
  • 1
  • 15

2 Answers2

0

When using JS capable drivers (which capybara-webkit is) with Capybara actions occur asynchronously. This means the call to visit may return before the URL of the browser has actually changed, and why most capybara actions have waiting behavior built-in. In this case its probably you're getting the current_path before the browser has changed from the old path to the new. There are a couple of solutions

  1. If using Capybara 2.5+ change to using the have_current_path matcher which has waiting behavior built-in

    expect(page).to have_current_path(profile_path)

  2. Add a content check for something that should on the page - will trigger the waiting behavior and make sure the page is loaded before getting current_path

  3. add a sleep of a second or two after visit, which will give the browser time to change to the new path

Obviously #1 is the better solution unless you have some reason you can't be on Capybara 2.5+

Thomas Walpole
  • 48,548
  • 5
  • 64
  • 78
  • Thanks for the answer. Unfortunately nothing worked. 1. I use capybara (2.6.2) and capybara-webkit (1.8.0). `Failure/Error: expect(page).to have_current_path(profile_path) expected "/ru/profile" to equal "/profile"` 2. Add `expect(page).to have_content user.name` and `expect(page).to have_content user.mail` 3. Add `seep 5` before path test – alexin Feb 15 '16 at 21:06
  • then it sounds like your app is really redirecting to /ru/profile after authenticating - check your routes and settings for whatever authentication library you're using – Thomas Walpole Feb 15 '16 at 21:08
  • 1
    yes and each of your environments has different settings, so check the settings for the routes and auth library to see if you have any environment dependent settings, and then check your test.rb/development.rb/production.rb settings for default_url_options -- also look at why you're setting I18n.locale and also setting the header -- shouldn't the header be enough alone? – Thomas Walpole Feb 15 '16 at 21:23
0

Since you're saying that the problems are only in the RSpec tests and the app is working fine, then I assume you're expecting the URLs to be in the form of /:locale/profile(.:format). So, if you have something like the following route scope in your app...

config/routes.rb

scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
  get 'profile',  to: 'users#profile'

  # other routes
end

...and you have something like the following in your controller (probably ApplicationController) that automatically injects the locale into the url options...

def url_options
  { locale: I18n.locale }.merge(super)
end

(The above could also be an override of default_url_options as Tom Walpole mentioned)

...then, you'll need to pass that locale in as a parameter to your paths in the spec as well:

  describe 'User go to profile' do
    before do
      page.driver.header 'Accept-Language', locale
      I18n.locale = locale

      sign_in (user)
    end

    context 'locale EN' do
      let(:locale) { :en }

      scenario 'and view see profile page' do
        visit profile_path

        expect(current_path).to eq profile_path(locale: locale)
      end
    end
  end

Assuming the above is correct, you could even test this in a rails console and (probably) get output similar to the following:

irb> app.profile_path
ActionController::UrlGenerationError: No route matches {:action=>"profile", :controller=>"users"} missing required keys: [:locale]
irb> app.profile_path(locale: :en)
"/en/profile"
Community
  • 1
  • 1
Paul Fioravanti
  • 16,423
  • 7
  • 71
  • 122
  • Thanks for the help, man. `expect(current_path).to eq adverts_path(locale: locale)` It works as it should. – alexin Feb 20 '16 at 20:02