Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Flash message not detected when root route is customized #753

Closed
davidmles opened this Issue · 8 comments

2 participants

@davidmles

Let's suppose we customize the root route to have a page param, like this:

get "(/page/:page)" => "main#index", as: "root"

When this route is set, and a flash message is displayed in the root page, Capybara will not detect it, unless we load the Chrome Selenium driver and use it.

I have built a simple example app to show the issue: https://github.com/idavemm/flash_root

It contains 2 integration tests, one checks the flash message with javascript and the other without javascript. To run it:

ruby -Itest test/integration/flash_message_test.rb
@jnicklas
Owner

I'm sorry, I don't have the time to wade through that example app. Please provide a simpler code sample.

@davidmles

Sure, although that app is the simpler case, as it needs to have 2 controllers, a redirection, and a custom route.

Basically, what's needed to replicate the issue is the following:

  • 3 routes: the normal root, a custom root, and one for the controller that generates the flash and redirects to the root. The custom root is the key to replicate the issue. In this case it has no use, but in my real application it is used to show a paginated list.
FlashRoot::Application.routes.draw do
  root to: "main#index"

  get "(/page/:page)" => "main#index", as: "root"

  get "/set_flash" => "flash#info"
end
  • One main controller, that's showed in the root. It is void, but its view only has a link to generate a flash message:
<h1>Main page</h1>

<%= link_to "Set flash", set_flash_path %>
  • One controller that simply generates the flash message and redirects to root:
class FlashController < ApplicationController
  def info
    flash[:info] = "This is a flash message"
    redirect_to root_path
  end
end

That's it. Now for the integration tests:

require 'test_helper'

class FlashMessageTest < ActionDispatch::IntegrationTest
  test "should show a success flash message with JS" do
    Capybara.current_driver = Capybara.javascript_driver

    visit root_path
    click_link "Set flash"

    assert page.has_content? "This is a flash message"
  end

  test "should show a success flash message without JS" do
    visit root_path
    click_link "Set flash"

    assert page.has_content? "This is a flash message"
  end
end

The test_helper.rb is configured as normal: https://github.com/idavemm/flash_root/blob/master/test/test_helper.rb

@jnicklas
Owner

There are too many things in a Rails app which could make this go wrong. I'd be extremely surprised if this was an issue with Capybara, you need to find the underlying cause of this, and this isn't getting anywhere near that. Try writing a Sinatra app, or something else simpler, which makes it more apparent what's going on. I'm sure you'll find that the issue is somewhere within your code.

@davidmles

The code is the most simple I can write to reproduce the issue. It's a new app initialized through "rails new flash_root", and I just created the two controllers and the code I posted above. There is nothing more than that, so the problem is now isolated.

If it has nothing to do with Capybara, I can post it in the Rails github issues page if you want.

@jnicklas
Owner

Look, I'm really not trying to be rude or anything, but consider the fact that Capybara has a massive test suite and is used by thousands of people. I've personally written dozens of applications which have used the RackTest driver along with Rails' flash. I find it extremely hard to believe that something so fundamentally simple would be broken. It just doesn't make any sense. I'm not saying it's impossible, just highly unlikely.

That's why I'm not going to spend my time going through your code, fixing what I'm 99% sure is your problem. I'm telling you that if you even want me to consider this as a legitimate issue, you need to give me something simpler, which explains the error more clearly. If you don't want to, or can't do that, then I'm afraid I can't help you.

@davidmles

Have you noticed the two routes that point to root? As I said, this is the key of the issue:

get "(/page/:page)" => "main#index", as: "root"

Without that line, it works well. But in my real application, a paginated list on root page is needed, so that route is needed, and its name is "root". I think that is a special case, and maybe it is not so extensively used.

I don't know what more I can do. I have uploaded a simple new app to github and explained here how to reproduce the issue. The code is simple enough.

I'm going to post this issue to the Rails devs and comment here back when it has some answer.

@jnicklas
Owner

Yeah, I don't think you should have a route named "root" which isn't actually the root route, that seems like a bad idea. You might want to not do that. Anyway, this isn't a Capybara issue as far as I can see. I'm closing this.

@jnicklas jnicklas closed this
@davidmles

Yes, but I'm forced to do that somehow.

Nonetheless it seems to be a bug of Rails' ActionDispatch::Routing::Mapper.normalize_path. It is already reported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.