【问题标题】:Capybara Selenium WebDriver does not see my test dataCapybara Selenium WebDriver 看不到我的测试数据
【发布时间】:2016-10-21 13:30:42
【问题描述】:

Capybara Selenium WebDriver 无法查看我的测试数据库对象。是否有人发现我的设置存在问题或我可能缺少什么?

rails_helper.rb

...
RSpec.configure do |config|

  config.use_transactional_fixtures = false
  ... 
end

database_clearner.rb

RSpec.configure do |config|

  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

 config.before(:all) do
   DatabaseCleaner.start
 end

 config.before(:each, type: :feature) do
   # :rack_test driver's Rack app under test shares database connection
   # with the specs, so continue to use transaction strategy for speed.
  driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test

  if !driver_shares_db_connection_with_specs
    # Driver is probably for an external browser with an app
    # under test that does *not* share a database connection with the
    # specs, so use truncation strategy.
    DatabaseCleaner.strategy = :truncation
  end
end

config.before(:each, :js => true) do
  DatabaseCleaner.strategy = :truncation
end

config.before(:each) do
  DatabaseCleaner.start
end

config.append_after(:each) do
  DatabaseCleaner.clean
end

config.after(:all) do
  DatabaseCleaner.clean
end

end

external_user_viewing_resources_sel_spec.rb

require 'rails_helper'
require 'support/selenium_helper'

RSpec.feature "External user " do

before(:all) do
  get_driver
  login_user(:external_user)
end

after(:all) do
  #@driver.find_element(:id, "logout").click()
  #quit_driver
end

scenario "can view and click resources (helpful links)", js: true do
  @d1_inst_resource = create(:d1_inst_resource)
  puts @d1_inst_resource.inspect
  @driver.find_element(:id, 'helpful_links_panel')
  @driver.find_element(:id, "#{@d1_inst_resource.id}").click();
end
end

selenium_helper.rb

require 'selenium-webdriver'

def get_driver
  Capybara.current_driver = Selenium::WebDriver.for :firefox  #:chrome
  @driver = Capybara.current_driver
end

def quit_driver
  @driver.quit
  Capybara.use_default_driver
end

def login_user(user)
  @user = build_stubbed(user)
  @driver.get "http://localhost:3000"
  @driver.find_element(:id, "username").send_keys("#{@user.email}")
  @driver.find_element(:id, "password").send_keys("#{@user.password}")
  @driver.find_element(:css, "button[type='submit']").click()
end

错误

..............#<Resource id: 10534, text: "Text1", url: "MyText", position: 1, d1: true, d2: false, d3: false, conference: false, institution: true, start_date: "2016-10-06", end_date: "2020-10-06", created_at: "2016-10-21 13:28:15", updated_at: "2016-10-21 13:28:15">
F...*

Failures:

1) External user  can view and click resources (helpful links)
 Failure/Error: @driver.find_element(:id, "#{@d1_inst_resource.id}").click();

 Selenium::WebDriver::Error::NoSuchElementError:
   Unable to locate element: {"method":"id","selector":"10534"}

我看过其他文章,但它们并没有解决我的问题。我知道它们在不同的线程中运行,但我觉得上面的配置已经解决了这个问题......

Capybara with :js => true causes test to fail

*****更新的代码*****

selenium_helper.rb

def login_user(user)
  @user = build_stubbed(user)
  page.visit "/"
  page.fill_in "username", with: @user.email
  page.fill_in "password", with: @user.password
  page.find("button[type='submit']").click()

结束

external_user_viewing_resources_sel_spec.rb

require 'rails_helper'
require 'support/selenium_helper'

RSpec.feature "External user " do

before(:each) do
  Capybara.current_driver = :selenium
  @d1_inst_resource = create(:d1_inst_resource)
  puts Resource.count
  login_user(:external_user)
  puts 'test script count'
  puts Resource.get_resource_by_member_type_and_division(@user).count
end

scenario "can view and click resources (helpful links)", js: true do
  puts page.first('.userName').text
  expect(page.first('.userName').text).to eq("#{@user.first_name.upcase} #{@user.last_name.upcase}")
  page.find(:id, "#{@d1_inst_resource.id}")
  page.find(:id, "#{@d1_inst_resource.id}").click()
end
end

ma​​in_controller.rb

def index
  @resources = Resource.get_resource_by_member_type_and_division(@user)
  puts 'index query count'
  puts @resources.count
  @resources
end

错误

1
index query count
0
test script count
1
REVDIST TUSER1 
F

Failures:  

1) External user  can view and click resources (helpful links)
 Failure/Error: page.find(:id, "#{@d1_inst_resource.id}")

 Capybara::ElementNotFound:
   Unable to find id "11060"
 # /Users/meffinger1/.rvm/gems/ruby-2.2.5/gems/capybara-2.9.1/lib/capybara/node/finders.rb:44:in `block in find'
 # /Users/meffinger1/.rvm/gems/ruby-2.2.5/gems/capybara-2.9.1/lib/capybara/node/base.rb:85:in `synchronize'
 # /Users/meffinger1/.rvm/gems/ruby-2.2.5/gems/capybara-2.9.1/lib/capybara/node/finders.rb:33:in `find'
 # /Users/meffinger1/.rvm/gems/ruby-2.2.5/gems/capybara-2.9.1/lib/capybara/session.rb:735:in `block (2 levels) in <class:Session>'
 # ./spec/features/selenium/external_user_viewing_resources_sel_spec.rb:28:in `block (2 levels) in <top (required)>'

在 56.01 秒内完成(文件加载需要 6.33 秒) 1 个示例,1 个失败

【问题讨论】:

  • 页面上元素的id实际上是10534吗?而不是 resource_10534 之类的东西?
  • 好问题,这是查看代码

标签: selenium-webdriver rspec capybara


【解决方案1】:

您看不到该资源,因为它是在页面加载后才创建的,但是您在示例中也没有真正使用 Capybara,因为您完全绕过它并直接使用 selenium 实例.

get_driver 中,您将 Capybara.current_driver 设置为 Selenium::WebDriver 的一个实例,因为它需要一个与 Capybara 注册的驱动程序之一匹配的符号。在“login_user”中,您正在创建一个存根对象(即不是真实的/保存到数据库中),然后使用它来登录,因为数据库中没有用户可以加载应用程序线程,所以这将不起作用。我可能不完全理解您要做什么,但我希望您的文件看起来更像

external_user_viewing_resources_sel_spec.rb

require 'rails_helper'
require 'support/selenium_helper'

RSpec.feature "External user " do

before(:each) do
  login_user(:external_user)
end

scenario "can view and click resources (helpful links)", js: true do
  @d1_inst_resource = create(:d1_inst_resource)
  page.visit("whatever page should should show the record")
  page.find(:id, @d1_inst_resource.id").click();
  # some check for what should happen based on the click
end
end

selenium_helper.rb

def login_user(user)
  @user = create(user)
  page.visit "http://localhost:3000" #Is this meant to be a different system than the app under test? if not it should just be page.visit '/'
  page.fill_in("username", with: @user.email)
  page.fill_in("password", with: @user.password)
  page.find(:css, "button[type='submit']").click()
  #some check for whatever happens on the page to show the user has logge in
end

【讨论】:

  • 您的回复消除了很多 Capybara Selenium 的困惑,谢谢。我清理了代码并发布了更新。我正在使用 subbed 用户 b/c 该表位于不同的架构中,并且该用户实际上已经存在。
  • 但是,我仍然没有看到资源。我看到它在测试中创建(在放置“测试脚本计数”之后),但在浏览器启动时它在 index 方法中不可见。我仍然认为我在配置方面遗漏了一些东西。
  • 按照我在 login_user 末尾的回答中的说明在页面上添加检查以确保用户实际登录,并检查您的 test.log 以确认登录正在发生。此外,每个场景都是独立的,因此您的 login_user 需要在 before(:each) 而不是 before(:all) 中 - 还有为什么您将 js: true 元数据从场景中移除?
  • 如果您希望为功能中的每个场景创建资源,也应该在 before(:each) 中创建资源
  • 谢谢,我已经更新了代码。上面的测试表明用户已经登录了。
【解决方案2】:

将我的 database_cleaner.rb 文件更改为此修复了问题,它们不再在两个不同的线程中运行。

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.before :each do
    if Capybara.current_driver == :rack_test
      DatabaseCleaner.strategy = :transaction
    else
      DatabaseCleaner.strategy = :truncation
    end
    DatabaseCleaner.start
  end

  config.after do
    DatabaseCleaner.clean
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 2012-12-21
    相关资源
    最近更新 更多