AngularJS: how to invoke event handlers and detect bindings in tests

时光总嘲笑我的痴心妄想 提交于 2019-12-08 02:20:23

问题


I want to write unit and e2e tests for various custom angularjs directives that add javascript event bindings to the elements they are attached to.

In tests, it's easy enough to simulate click and dblclick events using jQuery methods.

element("#id").click();

However, I am also binding mouseover, mouseout and contextmenu events, and haven't found a way to invoke these in e2e tests. The code below shows the approach I am taking.

it('should show a context menu when the user right clicks on a grid row', 
    function () {
    //not currently triggering the context menu
    var outerRow = element(".ngRow", "outer row");
    var row = element(".ngRow:first > div", "row");
    angular.element(row).triggerHandler("contextmenu");
    expect(outerRow.attr("class")).toContain("open");
});

How can I get the contextmenu event to fire in tests?

Similarly, in unit tests for the directives, I want to be able to detect if an event binding has been attached to an element.

How can I achieve this?


回答1:


Got to the bottom of this eventually. To trigger the events on elements selected using jQuery, jQuery obviously needs to be loaded. The problem is that, as explained here, the Angular runner runs the tests in an IFrame which doesn't have jQuery loaded.

However, you can extend the angular scenario dsl to execute code in the context of your e2e test where jQuery is loaded. The function below enables you execute any javascript method, or to fire any event:

//this function extends the Angular Scenario DSL to enable JQuery functions in e2e tests
angular.scenario.dsl('jqFunction', function () {
    return function (selector, functionName /*, args */) {
        var args = Array.prototype.slice.call(arguments, 2);
        return this.addFutureAction(functionName, function ($window, $document, done) {
            var $ = $window.$; // jQuery inside the iframe
            var elem = $(selector);
            if (!elem.length) {
                return done('Selector ' + selector + ' did not match any elements.');
            }
            done(null, elem[functionName].apply(elem, args));
        });
    };
}); 

The following code uses the above function to fire the contextmenu event in an e2e test:

it('should show a context menu when the user right clicks on a grid row', function () {
    var outerRow = element(".ngRow:first", "outer row");
    jqFunction(".ngRow:first > div", "contextmenu");
    expect(outerRow.attr("class")).toContain("open");
});


来源:https://stackoverflow.com/questions/17575768/angularjs-how-to-invoke-event-handlers-and-detect-bindings-in-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!