【问题标题】:DOM traversal in Capybara testingCapybara 测试中的 DOM 遍历
【发布时间】:2015-07-20 17:44:15
【问题描述】:

快速总结:为什么水豚找不到 .admin-edit 类?

所以,我建立了一个网站,其中有已发布和未发布的文章,访客只能看到已发布的文章,而管理员可以看到所有内容。登录是通过设计处理的,一个简单的 erb 表达式确定文章是显示还是“发布”。

我在我的文章控制器的 index 操作上列出文章并渲染部分以显示文章。

<% if article.published %>
  <dl class="individual-article">
    <dt><%= article.title %> 
      <% if current_user.try(:admin) %>
        | <span class="admin-edit"><%= link_to 'Edit', edit_article_path(article) %></span>
    <% end %><br> 
    <span class="article-tags">
        <%= raw article.tags.map(&:name).map { |t| link_to t, tag_path(t) }.join(', ') %></span>
    </dt>
    <dd><%= truncate(article.body.html_safe, length: 200) %>
        <%= link_to 'more', article_path(article) %>
    </dd>
  </dl>
<% end %>

这按预期工作,但我无法正确测试它。特别是,如果用户是管理员,它会在期望找到“编辑”时返回 false。

这是我的登录规范:

require 'rails_helper'

RSpec.describe "SignIns", type: :request do

describe "the sign in path" do
  let(:user)        { FactoryGirl.create(:user)      }
  let(:admin)       { FactoryGirl.create(:admin)     }
  let(:article)     { FactoryGirl.create(:article)   }
  let(:published)   { FactoryGirl.create(:published) }

  it "lets a valid user login and redirects to main page" do
    visit '/users/sign_in' 
    fill_in 'user_email',    :with => admin.email
    fill_in 'user_password', :with => admin.password 
    click_button 'Log in'
    expect(current_path).to eq '/'
    expect(page).to have_css('span.admin-edit')
  end
end  

这是我的文章工厂:

FactoryGirl.define do
  factory :article do
    title 'Title'
    body  'Content'

  factory :published do 
    published true 
  end
end 

这是我的用户工厂:

FactoryGirl.define do 

  factory :user do 
    email 'user@gmail.com'
    password 'password'

    factory :admin do 
      admin true 
    end
  end
end

这里是错误:

1) SignIns the sign in path lets a valid user login and redirects to main page
 Failure/Error: expect(page).to have_css('span.admin-edit')
   expected #has_css?("span.admin-edit") to return true, got false
 # ./spec/requests/sign_ins_spec.rb:18:in `block (3 levels) in <top (required)>'

我尝试了以下方法:

  1. 如果 rspec 对多个类有问题,则删除额外的文章
  2. 将 have_css 更改为 have_selector 并选择锚标记
  3. 从 html 正文中画出整个 DOM 根...
  4. 通过以具有管理员权限的用户身份手动登录来检查它是否在规范之外工作 -> 确实如此。
  5. 尝试删除未发表文章与已发表文章的区别,但仍然失败。
  6. 尝试移除 erb 条件以检查文章是否在视图中发布,但仍然失败。
  7. 尝试确保它不是通过 ajax 加载(在 will_paginate 中有备份)但失败了。

我做错了什么?

编辑

如果我避免使用 FactoryGirl 导入,它现在可以工作:

@article = Article.create(title: 'Title', body: 'body', published: true)

代替

let(:published) { FactoryGirl.create(:published) }

不知道为什么。

【问题讨论】:

  • 你在click_button登录后试过save_and_open_page吗?看到跨度了吗?
  • 是的,它不显示。很奇怪。
  • 我唯一能想到的是,这可能与两个用户使用相同的电子邮件有关,也许它会默默地失败,因此它不会重定向到主页,因此不能找到跨度。
  • 可能是。我建议使用faker gem 并使用Faker::Internet.email 在您的工厂生成电子邮件。
  • 是的,我向我的工厂添加了伪造者调用,我用它来为数据库播种,但它仍然失败。

标签: ruby-on-rails rspec devise capybara


【解决方案1】:

RSpec 懒惰地分配let 变量,因此在您显示页面时,已发布或未发布的文章都不存在。您需要使用 let!before 或以其他方式确保在显示您的页面之前创建对象。

【讨论】:

  • 它有效!不知道是懒惰分配的。谢谢:)
猜你喜欢
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多