Ruby on rails 启用selenium webdriver时Rails集成测试失败,省略时通过

Ruby on rails 启用selenium webdriver时Rails集成测试失败,省略时通过,ruby-on-rails,selenium-webdriver,rspec,devise,capybara,Ruby On Rails,Selenium Webdriver,Rspec,Devise,Capybara,我使用RSpec和Capybara编写了以下集成测试,它在js:true中失败,当我忽略它时通过 当我手动测试应用程序时,它工作正常。一旦Rails 4服务器在http://localhost:3000。使用Desive gem对用户进行验证 gem依赖项是否存在一些问题?我遗漏了什么吗 Gemfile group :development, :test do gem 'sqlite3', '1.3.11' gem 'byebug', '3.4.0' gem 'sp

我使用RSpec和Capybara编写了以下集成测试,它在
js:true
中失败,当我忽略它时通过

当我手动测试应用程序时,它工作正常。一旦Rails 4服务器在
http://localhost:3000
。使用Desive gem对用户进行验证

gem依赖项是否存在一些问题?我遗漏了什么吗

Gemfile

group :development, :test do
  gem 'sqlite3',     '1.3.11'
  gem 'byebug',      '3.4.0'
  gem 'spring',      '1.1.3'
  gem 'i18n-tasks'
  gem 'rspec-rails'
end

group :test do
  gem 'capybara'
  gem 'selenium-webdriver'
end
登录规范rb

require 'rails_helper'
RSpec.feature "Login:", js: true do
  scenario "-display login page to the user" do
    visit "/"
    expect(page).to have_xpath("//input[@type='email']")
    expect(page).to have_xpath("//input[@type='password']")
    expect(page).to have_content("Login to Dashboard")
    expect(page).to have_xpath("//input[@type='checkbox']")
    expect(page).to have_content("Forgot your password?")
  end
end
运行规范的命令:

rspec -b spec/feature/login_spec.rb
    Failures:

      1) Login: -display login page to the user
         Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"

         ActionController::RoutingError:
           No route matches [HEAD] "/assets/login_header-117f87e381545e9f6d5a7accb7aa72188a0304644af6891c42e1cd57f38fad67@2x.jpg"
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/rack/logger.rb:38:in `call_app'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/rack/logger.rb:20:in `block in call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.2/lib/active_support/tagged_logging.rb:68:in `block in tagged'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.2/lib/active_support/tagged_logging.rb:26:in `tagged'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.2/lib/active_support/tagged_logging.rb:68:in `tagged'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/rack/logger.rb:20:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/request_store-1.3.0/lib/request_store/middleware.rb:9:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/request_id.rb:21:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/methodoverride.rb:22:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/runtime.rb:18:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/lock.rb:17:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/static.rb:113:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/sendfile.rb:113:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/engine.rb:518:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/application.rb:164:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:66:in `block in call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in `each'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/capybara-2.6.2/lib/capybara/server.rb:19:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:88:in `service'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'
         # ------------------
         # --- Caused by: ---
         # Capybara::ExpectationNotMet:
         #   expected to find xpath "//input[@type='checkbox']" but there were no matches. Also found "", which matched the selector but not all filters.
         #   C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/capybara-2.6.2/lib/capybara/node/matchers.rb:97:in `block in assert_selector'
错误日志:

rspec -b spec/feature/login_spec.rb
    Failures:

      1) Login: -display login page to the user
         Failure/Error: raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"

         ActionController::RoutingError:
           No route matches [HEAD] "/assets/login_header-117f87e381545e9f6d5a7accb7aa72188a0304644af6891c42e1cd57f38fad67@2x.jpg"
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/rack/logger.rb:38:in `call_app'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/rack/logger.rb:20:in `block in call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.2/lib/active_support/tagged_logging.rb:68:in `block in tagged'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.2/lib/active_support/tagged_logging.rb:26:in `tagged'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.2/lib/active_support/tagged_logging.rb:68:in `tagged'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/rack/logger.rb:20:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/request_store-1.3.0/lib/request_store/middleware.rb:9:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/request_id.rb:21:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/methodoverride.rb:22:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/runtime.rb:18:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/lock.rb:17:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.2/lib/action_dispatch/middleware/static.rb:113:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/sendfile.rb:113:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/engine.rb:518:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.2/lib/rails/application.rb:164:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:66:in `block in call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in `each'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/capybara-2.6.2/lib/capybara/server.rb:19:in `call'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:88:in `service'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'
         # C:/RailsInstaller/Ruby2.1.0/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'
         # ------------------
         # --- Caused by: ---
         # Capybara::ExpectationNotMet:
         #   expected to find xpath "//input[@type='checkbox']" but there were no matches. Also found "", which matched the selector but not all filters.
         #   C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/capybara-2.6.2/lib/capybara/node/matchers.rb:97:in `block in assert_selector'
原始页面Html

<!-- Login Block -->
  <div class="block push-bit">
    <!-- Login Form -->
    <form class="form-horizontal form-bordered form-control-borderless" id="new_user" action="/signin" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="56u6N33zmqwC3dEO3Nh7aZZqOIRgtphs/hoRXKXP3QRKZ2OfgZ6FpGPpFb6FiMc95DfWD/oOWvZVoepqbivjzw==" />

                <div class="alert
    alert-danger
     alert-dismissible" role="alert" id="alert">
  <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  <span id="alert-msg">You need to sign in or sign up before continuing.</span>
</div>

        <div class="form-group">
          <div class="col-xs-12">
            <div class="input-group">
              <span class="input-group-addon"><i class="gi gi-envelope"></i></span>
              <input label="Email:" wrapper="{:class=&gt;&quot;required&quot;}" id="login-email" class="form-control input-lg" placeholder="Email" type="email" name="user[email]" />
            </div>
          </div>
        </div>

        <div class="form-group">
          <div class="col-xs-12">
            <div class="input-group">
              <span class="input-group-addon"><i class="gi gi-asterisk"></i></span>
              <input label="Password:" wrapper="{:class=&gt;&quot;required&quot;}" id="login-password" class="form-control input-lg" placeholder="Password" type="password" name="user[password]" />
            </div>
          </div>
        </div>

        <div class="form-group form-actions">
          <div class="col-xs-4">

                <label class="switch switch-primary" data-toggle="tooltip" title="Remember Me?">
                  <input name="login-remember-me" type="hidden" value="0" /><input id="login-remember-me" name="login-remember-me" type="checkbox" value="1" />
                  <span></span>
                </label>
          </div>
          <div class="col-xs-8 text-right">
            <button name="button" type="submit" class="btn btn-sm btn-primary" id="login">
                <i class="fa fa-angle-right"></i> Login to Dashboard
</button>          </div>
        </div>

        <div class="form-group">
          <div class="col-xs-12 text-center">

    <a id="link-reminder-login" href="/users/password/new">Forgot your password?</a><br />

          </div>
        </div>
</form>    <!-- END Login Form -->


  </div>
  <!-- END Login Block -->

&时代;接近
继续之前,您需要登录或注册。
登录到仪表板


第一个猜测是,您正在通过CSS隐藏页面上的复选框(然后设置标签样式以显示已选中)。默认的框架测试驱动程序不会处理大多数CSS,因此它仍然会找到复选框,但是当您使用js:true时,您使用的是一个真正的浏览器,它会处理CSS。您可以尝试将测试更改为

expect(page).to have_xpath("//input[@type='checkbox']" , visible: :all)
看看这是否是问题所在。现在看到你的html,看起来你正在使用引导开关(?),它确实隐藏了真正的复选框,所以你可以在上面做,如果你关心的只是有一个复选框的话。或者,您可以检查live页面上的html,查看库向页面添加了什么html,并检查其中的一些内容。中间位置可能是检查隐藏的复选框,但检查它是否在交换机包装器中-类似于

expect(page).to have_css('.boostrap-switch-container input[type="checkbox"]', visible: :hidden) # adjust class as necessary for the wrapper produced by the library
这将验证交换机的JS是否已运行、是否已创建其包装器以及是否已将复选框隐藏在其中

我确实怀疑为什么要使用XPath来查找这些元素,而您可以使用ID/名称/标签/占位符来查找它们并使内容更具可读性

现在您已经添加了html——查看password字段,没有实际的元素——因此标签文本已被删除,但是以下任何一项都应该可以找到该元素

expect(page).to have_field("Password", type: 'password')  # placeholder
expect(page).to have_field("login-password", type: 'password')  # id
expect(page).to have_field("user[password]", type: 'password') # name

通常我会选择第一个,因为它正在测试用户应该看到的内容。

我做了上面建议的两个更改,但现在出现了以下异常
Capybara::ExpectationNotMet:#期望找到类型为“password”的字段“password”,但没有匹配项
,这是编写测试的示例。第一个字符串需要与密码字段的id/名称/占位符或标签文本相匹配-如果您想要准确的答案,请发布您的html我应该用一个新问题发布html,还是应该修改现有问题?通过添加实际的html代码编辑原始问题。@user2325154已更新以匹配您的html