【问题标题】:How do you test ActionCable with Capybara?您如何使用 Capybara 测试 ActionCable?
【发布时间】:2018-07-07 06:47:12
【问题描述】:

我尝试了这个解决方案https://gist.github.com/alexeyrazuvaev/98448c9935352fac5ee96e139bc3bd72,但它不适用于我的测试。尝试在浏览器中重现它,它按预期工作。我无法弄清楚我的测试有什么问题。

这是一个例子:

scenario 'they see their name and message in the chat box', js: true do
  find('textarea#message_content').send_keys(:enter)
  is_expected.to have_selector('p', text: /^#{current_user.name}|foobar$/)
end

其他信息:

cable.yml

redis: &default
  adapter: redis
  url: redis://localhost:6379/1

production: *default
development: *default
test: *default

spec/support/capybara.rb

Capybara.javascript_driver = :webkit
Capybara.server = :puma

Capybara::Webkit.configure do |config|
  config.allow_url("https://code.jquery.com/jquery-3.3.1.min.js")
end

测试日志

# ...
Started GET "/cable" for 127.0.0.1 at 2018-01-30 11:21:16 +0800
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-01-30 11:21:16 +0800
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Registered connection (Z2lkOi8vY2hhdHRlci9Vc2VyLzE)
ConversationChannel is transmitting the subscription confirmation
ConversationChannel is streaming from conversation_channel_1
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-01-30 11:21:18 +0800
ConversationChannel stopped streaming from conversation_channel_1
# ...

在浏览器上测试时的服务器日志

# ...
Started GET "/cable" for 127.0.0.1 at 2018-01-29 09:02:02 +0800
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-01-29 09:02:02 +0800
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  User Load (1.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Registered connection (Z2lkOi8vY2hhdHRlci9Vc2VyLzE)
ConversationChannel is transmitting the subscription confirmation
ConversationChannel is streaming from conversation_channel_11
ConversationChannel#send_message({"content"=>"foobar\n", "conversation_id"=>"11"})
   (0.2ms)  BEGIN
  Conversation Load (0.3ms)  SELECT  "conversations".* FROM "conversations" WHERE "conversations"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
   (0.6ms)  SELECT "users"."id" FROM "users" INNER JOIN "user_conversations" ON "users"."id" = "user_conversations"."user_id" WHERE "user_conversations"."conversation_id" = $1  [["conversation_id", 11]]
  SQL (12.5ms)  INSERT INTO "messages" ("content", "user_id", "conversation_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["content", "foobar\n"], ["user_id", 1], ["conversation_id", 11], ["created_at", "2018-01-29 01:02:18.272060"], ["updated_at", "2018-01-29 01:02:18.272060"]]
   (12.4ms)  COMMIT
  Rendered messages/_message.html.erb (0.8ms)
[ActionCable] Broadcasting to conversation_channel_11: {:message=>"<p>John Doe: foobar\n</p>\n"}
ConversationChannel transmitting {"message"=>"<p>John Doe: foobar\n</p>\n"} (via streamed from conversation_channel_11)

【问题讨论】:

  • 假设您已将 Capybara.server 设置为 puma,正在运行 actioncable 进程(异步适配器),并允许 actioncable 从您正在运行的测试的 IP/域建立连接工作。将您的 Capybara 和 actioncable 配置添加到您的问题中。还要检查您的 test.log 中是否存在与可操作连接相关的任何错误。
  • @ThomasWalpole 检查更新的问题
  • 尝试更改 cable.yml 以在测试模式下使用 async 适配器(默认 rails 配置)而不是 redis
  • 另外,可以尝试使用selenium 而不是capybara-webkit 运行它——我认为支持的Qt capybara-webkit 并不能真正与WebSockets 一起使用(尽管我可能错了,而且日志似乎显示它至少在进行连接)。要检查的另一件事是运行测试时puma 产生的输出。它是否显示它以“单一模式”或“集群模式”运行?另外,我假设is_expected 相当于expect(page) ?
  • @ThomasWalpole 你说得对,puma 处于单人模式,我将subject 设置为页面,所以is_expected 相当于expect(page)

标签: ruby-on-rails rspec capybara actioncable


【解决方案1】:

由于这适用于selenium 驱动程序而不是capybara-webkit,因此有两种可能性之一。

  1. capybara-webkit 不能与 websocket 一起正常工作。如果您使用 Qt 4.x 编译它,这将是正确的,但是我相信使用 Qt 5.x 构建它应该可以工作 - ActionCable not connecting during capybara-webkit feature spec - 并且日志似乎显示它至少是连接的。

  2. 您正在页面上的 JS 中使用 ES6+ 功能。 capybara-webkit 使用的 QtWebkit 已经过时了,基本上相当于 6-7 年前的 Safari 版本,这意味着它不支持 ES6+。因此,如果您在代码中使用了任何 ES6+ 方法/功能而没有进行 polyfill 和/或转译 capybara-webkit 将不会运行 JS。由于actioncable 确实似乎在连接日志,它至少在运行您的一些 JS,因此启用“raise_javascript_errors- https://github.com/thoughtbot/capybara-webkit#configuration - in yourcapybara-webkit”配置可能会显示您在按键处理程序中使用的某些方法的错误不支持。

【讨论】:

  • 感谢您的回答。补充一下,供参考,测试中用redis还是async没关系,都试过了,结果一样,其他复杂的测试我就不知道了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 2018-11-06
  • 2016-05-15
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
相关资源
最近更新 更多