为什么GhostDriver无法接收CometActor发送的客户端JavaScript函数调用?

为什么GhostDriver无法接收CometActor发送的客户端JavaScript函数调用?,javascript,selenium,comet,lift,ghostdriver,Javascript,Selenium,Comet,Lift,Ghostdriver,使用GhostDriver运行Selenium测试时遇到问题。我们有一个硒测试失败,它受我们选择的技术的影响。我们的堆栈是由AngularJS前端支持的提升后端。我们正在利用CometActors将数据推送到前端的两个不同AngularJS控制器 当用户访问该站点时,他们将首先看到controller one提供的主页。此控制器使用许多可导航元素呈现页面。第二个控制器通过主页上生成的链接(包含$routeParams)链接到 加载模型列表页面时,会出现测试失败。此页面包含主控制器,它将我们从Co

使用GhostDriver运行Selenium测试时遇到问题。我们有一个硒测试失败,它受我们选择的技术的影响。我们的堆栈是由AngularJS前端支持的提升后端。我们正在利用CometActors将数据推送到前端的两个不同AngularJS控制器

当用户访问该站点时,他们将首先看到controller one提供的主页。此控制器使用许多可导航元素呈现页面。第二个控制器通过主页上生成的链接(包含$routeParams)链接到

加载模型列表页面时,会出现测试失败。此页面包含主控制器,它将我们从Comet接收的数据绑定到模板。当项目在页面上可见时,我们可以单击它们以转换到第二个控制器。此控制器向我们的Lift后端发出一个新请求,这会导致CometActor将响应发送回前端。我们已经验证了,到目前为止,所有功能都与我们预期的一样,包括用于检索模型列表的初始Comet请求以及用于前端的相应响应

问题出现在这里。。。前端从不执行CometActor响应中提供的JavaScript命令。永远不会调用CometDispatch.sendModels函数,从而防止事件触发对ModelListController的更新。我们的Selenium测试失败,因为它找不到更新ModelListController时应创建的预期HTML元素。我们不确定Comet提供的JavaScript命令会发生什么情况,因为它似乎从未在前端执行过。通过将GhostDriver生成的页面源转储到控制台,我们验证了模型列表没有呈现

当使用Firefox驱动selenium测试通过时,这个问题给我们带来了很多困惑

斯卡拉学院 comet-dispatch.js app.js controllers.js services.js index.html

模型目录
make-list.html

model-list.html

{{model.name}
这一问题也将在中描述

class CarRegistry extends CometActor {
  implicit val formats = DefaultFormats
  private val adapter: ModelAdapter = new LiftActorModelAdapter

  override def lifespan = Full(5 minutes)

  def render: RenderOut = {
    adapter.handleMessage(ListMakesMessage(this))
    "#car-registry-uuid [value]" #> SHtml.jsonCall(Call("function(){}"), fetchModelsByMakeId _).guid
  }

  def fetchModelsByMakeId(requestJValue: JValue) = {
    requestJValue match {
      case JInt(makeId) => adapter.handleMessage(ListModelsMessage(this, makeId.toLong))
      case _ => ()
    }
    _Noop
  }

  override def lowPriority = {
    case s @ JObject(List(JField(key, JArray(_)))) if key =="make"  =>
      partialUpdate(Call("CometDispatch.sendMakes", s))
    case s @ JObject(List(JField(key, JArray(_)))) if key =="model" =>
      partialUpdate(Call("CometDispatch.sendModels", s))
    case _ => ()
  }
}
var CometDispatch = {
    sendMakes: function(makesJson) {
        $('body').trigger('makes-received', makesJson);
    },
    sendModels: function(modelsJson) {
        $('body').trigger('models-received', modelsJson);
    }
};
'use strict';

angular.module('myApp', [
  'ngRoute',
  'myApp.filters',
  'myApp.services',
  'myApp.directives',
  'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider, $routeScopeProvider) {
  $routeProvider.when('/', {templateUrl: 'static/pages/make-list.html', controller: 'MakeListController'});
  $routeProvider.when('/:makeId/list', {templateUrl: 'static/pages/model-list.html', controller: 'ModelListController'});
  $routeProvider.otherwise({redirectTo: '/'});
}]);
'use strict';

angular.module('myApp.controllers', []).
    controller('MakeListController', function($scope, DataStore) {

        $( 'body' ).on( 'makes-received', function( event, makesJsonObj ) {
            $scope.$apply(function() {
                DataStore.makes = makesJsonObj['makes'];
                $scope.makes = makesJsonObj['makes'];
            });
        });

        $scope.makes = $scope.makes || DataStore.makes;
    }).
    controller('ModelListController', function($scope, $routeParams, CometRequestService) {

        $( 'body' ).on( 'models-received', function( event, modelsJsonObj ) {
            $scope.$apply(function() {
                $scope.models = modelsJsonObj['models'];
            });
        });

        CometRequestService.getModelsFor($routeParams.makeId);
    });
'use strict';

angular.module('myApp.services', []).
  factory('DataStore', function() {
      return {
          makes: []
      };
  }).
  factory('CometRequestService', function() {
     return {
         getModelsFor: function(makeId) {
             liftAjax.lift_ajaxHandler($('#car-registry-uuid').val() + "=" + makeId, null, null, null);
         }
     }
  });
<div id="main" lift="surround?with=default;at=content">
   <h1>Model Directory</h1>

    <div lift="comet?type=CarRegistry&randomname=true">
        <input type="hidden" id="car-registry-uuid"/>
    </div>

    <div ng-view></div>
</div>
<div id="make-list">   
    <div ng-repeat="make in makes">
        <a ng-href="#/{{make.id}}/list/" data-dropdown="dd-{{make.id}}">
            {{make.name}}
        </a>
    </div>
</div>
<div id="model-list">
    <div ng-repeat="model in models">
        <div>
            {{model.name}}
        </div>
    </div>
</div>