簡體   English   中英

Rails集成測試在啟用selenium-webdriver時失敗,在省略時通過

[英]Rails integration tests failing when selenium-webdriver enabled and passing when omitted

我有以下使用RSpec和Capybara編寫的集成測試,但js: true失敗js: true並且在忽略時通過。

當我手動測試應用程序時,它運行良好。 一旦Rails 4服務器從http://localhost:3000啟動,用戶就會從/重定向到/signin 使用devise gem對用戶進行了驗證。

gem依賴項有問題嗎? 我有什么想念的嗎?

寶石文件

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

login_spec.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'

原始網頁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看起來好像您正在使用bootstrap-switch(?)一樣,它確實隱藏了真實的復選框,因此,如果您只關心有一個復選框,則可以執行上述任一操作。 (可選)您可以檢查實時頁面上的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是否已運行,創建了包裝器並在其中隱藏了復選框。

我確實質疑您為什么使用ids / names / labels / placeholders查找這些元素並使它們更具可讀性時使用xpaths查找這些元素

現在,您已經添加了html-查看密碼字段,沒有實際的<label>元素-因此標簽文本已用完,但是以下任何一種方法都可以找到該元素

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

通常我會選擇第一個,因為它正在測試用戶應該看到的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM