【发布时间】:2022-01-06 13:39:59
【问题描述】:
带有 ActionCable 的 Rails 6 规格 3.10 水豚3.36
-
用户访问
edit_inventory_path @inventory并查看Counts 的集合。 -
单击计数会触发 AJAX 调用以使用计数
_form填充模式 -
填写表单并点击提交触发器:
CountsChannel.broadcast_to(
@inventory,
{
count_id: @count.id,
html_slug: render_to_string(partial: 'counts/count', collection: @inventory.counts.sort_by { |c| [c.sort_by_status, - c.item.name] }),
uncounted: "#{view_context.pluralize(@inventory.counts.uncounted.size, 'item')} uncounted."
}
)
这会替换页面上的每个 count div。新提交的计数排序到页面底部,按钮文字发生变化。
我的测试期望该按钮从“计数”变为“编辑”。
RSpec.describe 'Performing an inventory', type: :system do
...
context 'when submitting a count' do
...
it 'changes the count button text' do
# making sure page is loaded
expect(page).to have_content "Edit #{inventory.name}"
# clicking the button opens a modal.
# AJAX puts the count edit form in the modal before it open
find("div#count_#{Count.first.id} a.count-btn").click
# wait to make sure the modal is open
find('input#count_unopened_boxes_count')
fill_in 'count_unopened_boxes_count', with: 5
click_button('Submit')
Rails.logger.debug 'HEYA just hit the submit button.'
# clicking the button closes and clears the modal
# and AJAXs form data to CountsController#update
# which triggers the ActionCable broadcast
# HERE: find('the button', wait: 5) does nothing
# because the old div is still on the page
# so Capybara finds it right away
# wait is a maximum wait time, not an absolute
count_1_btn_text = find("div#count_#{Count.first.id} a.count-btn").text
Rails.logger.debug 'HEYA found the button.'
Rails.logger.debug 'HEYA hoping ActionCable is complete.'
expect(count_1_btn_text).to eq 'Loose Count'
# some time later, the button text actually changes
end
end
end
当我查看 test.log 时,我知道这是时间问题:
...
Started GET "/inventories/1/edit" for 127.0.0.1 at 2021-11-29 12:51:05 -0500
...
Processing by InventoriesController#edit as HTML
Parameters: {"id"=>"1"}
...
Rendering layout layouts/application.haml
Rendering inventories/edit.haml within layouts/application
...
Rendered collection of counts/_count.haml [11 times] (Duration: 53.0ms | Allocations: 26025)
...
Completed 200 OK in 10635ms (Views: 10574.2ms | ActiveRecord: 15.7ms | Allocations: 645565)
...
Started GET "/assets/channels/consumer-ddc23d99c3f3572746769fa1851baebf4ef5d005651f6ac89f0739c1682a80bc.js" for 127.0.0.1 at 2021-11-29 12:51:15 -0500
Started GET "/assets/channels/counts_channel-6e2c07931c38a8f979370ee55ad4ca4783da4a2def12996ad4efe6f213d4fb78.js" for 127.0.0.1 at 2021-11-29 12:51:16 -0500
Started GET "/cable" for 127.0.0.1 at 2021-11-29 12:51:16 -0500
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2021-11-29 12:51:16 -0500
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
[1m[36mUser Load (0.6ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1[0m
Registered connection (Z2lkOi8vYnVpbGQtcGxhbm5lci9Vc2VyLzE)
...
[1m[36mInventory Load (44.2ms)[0m [1m[34mSELECT "inventories".* FROM "inventories" WHERE "inventories"."id" = 1 LIMIT 1[0m
CountsChannel is transmitting the subscription confirmation
CountsChannel is streaming from counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ
...
...
Rendered counts/_edit.haml (Duration: 48.7ms | Allocations: 28122)
Rendered counts/edit.js.erb (Duration: 50.3ms | Allocations: 28697)
Completed 200 OK in 66ms (Views: 56.2ms | ActiveRecord: 3.4ms | Allocations: 34258)
HEYA just hit the submit button.
...
Started PATCH "/inventories/1/counts/1" for 127.0.0.1 at 2021-11-29 12:51:17 -0500
Processing by CountsController#update as JS
Parameters: {"count"=>{"loose_count"=>"0", "unopened_boxes_count"=>"5"}, "partial_box"=>"Submit Box Count", "inventory_id"=>"1", "id"=>"1"}
HEYA found the button.
HEYA hoping ActionCable is complete.
... 49 lines later ...
[ActionCable] Broadcasting to counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ: {:count_id=>1, :html_slug=>"...real long string...", :uncounted=>"11 items uncounted."}
Rendering counts/update.js.erb
CountsChannel transmitting {"count_id"=>1, "html_slug"=>"...really long string... (via streamed from counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ)
Rendered counts/update.js.erb (Duration: 41.1ms | Allocations: 674)
Completed 200 OK in 344ms (Views: 56.4ms | ActiveRecord: 123.9ms | Allocations: 30670)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2021-11-29 12:51:18 -0500
CountsChannel stopped streaming from counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ
有人告诉我,像sleep() 这样的做法是不好的做法,那么我有什么办法可以迫使 Capybara 等待几秒钟?
【问题讨论】:
-
当我在
click_button 'Submit'之后添加sleep(3)时,它可以工作,只是感觉很糟糕。
标签: ruby-on-rails rspec capybara