2015-06-04 41 views
0

我在Rails应用程序中使用Websocket Rails gem来发送触发刷新页面部分的事件。所有工作都很好,但在我的测试中(我正在使用Rspec + Capybara + Selenium)我似乎无法找到一种方法来等待页面响应Websocket事件。我与触发在我的测试事件:等待Websocket Rails事件在测试环境中完成

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: "https://stackoverflow.com/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之间的等待?

回答

0

我通过编写一个接受一段代码的帮助器方法解决了这个问题。辅助方法记录当前时间,然后向ajax start事件添加一个函数,该函数记录ajax在sessionStorage变量中启动的时间。然后我可以运行传递给方法的代码块,等到阿贾克斯开始如下:

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} 
} 

这似乎为我工作至今...

0

您的测试应该等待刷新引起的页面上的可见更改