簡體   English   中英

等待Websocket Rails事件在測試環境中完成

[英]Wait for Websocket Rails event to finish in test environment

我在Rails應用程序中使用Websocket Rails gem發送事件,該事件觸發頁面的刷新。 一切工作正常,但是在測試中(我正在使用Rspec + Capybara + Selenium),我似乎無法找到一種方法來等待頁面響應Websocket事件。 我正在通過以下方式觸發測試中的事件:

WebsocketRails[@michael.id].trigger "refresh_task", {task: @michaels_task, modified_by: @archer}

該事件綁定如下。 ajax調用返回一個實際上是另一個ajax調用的腳本。

channel.bind('refresh_task', function(task_user) {
        var task = task_user["task"];
        var modified_by = task_user["modified_by"];
        if ($('span[data-mahi-task-id="' + task.id +'"]').length > 0) {//if the task is currently visible
            if ($('span[data-mahi-task-id="' + task.id +'"] div.modal').length > 0 ) { //the edit is open, so prompt the user 
                refresh_task = confirm(modified_by.name + " has modified this task, do you want to re-load? (if you don't re-load you risk overwriting their changes)");
            } else {
                refresh_task = true;
            }
            if (refresh_task == true) {
                //hide the modal if it exists
                $('span[data-mahi-task-id="' + task.id +'"] div.modal').modal('hide');

                //grey out the task while we load => this will get removed in ready.js
                $('span[data-mahi-task-id="' + task.id +'"]').addClass('ajax-disabled');
                // fake a "cancel" button on the update user task which will trigger a re-load of the task
                $.ajax({
                  url: "/users/" + task.created_by_id + "/tasks/" + task.id,
                  data: {task: task, update_details_cancel_button: "", _method:'put'}, //need to teel rails this is a put - not all browsers support put
                  dataType: 'script', //what format we expect the response to be - i.e. we want to execupte the resulting script
                  complete : ajaxComplete(task,modified_by),
                  method: 'POST' //not all browsers support put so send a POST with the data _method:'put' as above
                });
            }
        }
    });

一旦ajax啟動,我就可以告訴它運行並等待它完成,但是我需要我的測試才能在觸發事件和以某種方式啟動ajax之間等待?

我通過編寫一個接受代碼塊的輔助方法解決了這一問題。 helper方法記錄當前時間,然后向ajax start事件添加一個函數,該事件在sessionStorage變量中記錄ajax啟動的時間。 然后,我可以運行傳遞給該方法的代碼塊,並等待直到ajax啟動,如下所示:

def wait_for_ajax_to_start
  start_time = Time.now.to_f * 1000 #number of milliseconds
  #attach a hander on ajaxstart to store the time ajax started in a sessionStorage variable called 'ajaxStarted'
  page.evaluate_script('$(document).ajaxStart(function() {sessionStorage.ajaxStarted = $.now()})')

  #run the code block passed to this method
  yield

  #wait until the ajax has started or timeout
  Timeout.timeout(Capybara.default_wait_time) do #timeout after the default wait time
    loop until (page.evaluate_script('sessionStorage.ajaxStarted') != nil) && (page.evaluate_script('sessionStorage.ajaxStarted').to_i >= start_time)
  end
end

我這樣調用輔助方法:

wait_for_ajax_to_start {
  WebsocketRails[@michael.id].trigger "refresh_task", {task: @michaels_task, modified_by: @archer}  
}

到目前為止,這似乎對我有用。

您的測試應等待刷新導致頁面上的可見更改

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM