Rails 6 with ActionCable Rspec 3.10 Capybara 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."
}
)
這將替換頁面上的每個計數 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()是不好的做法,那么我有什么選擇可以強制水豚等待幾秒鐘?
uj5u.com熱心網友回復:
只需告訴 Capybara 您希望它在頁面上找到什么以及等待它出現的最長時間。在您的問題中,您說您希望按鈕從“計數”更改為“編輯”,但隨后您的代碼正在檢查“松散計數”,因此我并不完全清楚您所期望的可見變化,但假設后者你可以做類似的事情
expect(page).to have_css("div#count_#{Count.first.id} a.count-btn", text: 'Loose Count', wait: 10)
此外,執行find后跟fill_in只是等待元素出現是沒有意義的,因為fill_in已經在等待元素出現,所以
find('input#count_unopened_boxes_count')
fill_in 'count_unopened_boxes_count', with: 5
實際上與只是做一樣
fill_in 'count_unopened_boxes_count', with: 5
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/370158.html
