How to ng-click directive A in PhantomJS test

An application created by Yeoman with an angular generator.

Directive

angular.module('psApp').directive('scrollTop', function () {
  return {
    restrict: 'A',
    scope: true,
    template: '<a href="#" ng-click="click()" class="scroll-top"><span class="glyphicon glyphicon-arrow-up"></span> Back to top</a>',
    controller: ['$scope', '$element', '$document', function ($scope, $element, $document) {
      $scope.click = function () {
        $document.scrollTop(0, 500);
      };
    }]
  };
});

Test:

describe('Directive: scrollTop', function () {

  // load the directive module
  beforeEach(module('psApp'));

  var scope, element;

  beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();
    element = $compile('<div scroll-top></div>')(scope);
    scope.$apply();
  }));

  it('should have "Back to top" as text', inject(function () {
    expect(element.html()).toBe('<a href="#" ng-click="click()" class="scroll-top"><span class="glyphicon glyphicon-arrow-up"></span> Back to top</a>');
    expect(element.text()).toBe(' Back to top');
    element.click();
  }));
});

Mistake:

PhantomJS 1.9.7 (Mac OS X) Directive: scrollTop must have "Back to top" as the text TypeError: 'undefined' is not a function (evaluating to 'element.click () ")

I can’t understand where the problem is. :( Please write the function code.

+2
source share
3 answers

For some reason, PhantomJS does not have a click () function in it. Here is a workaround:

//Need to create a cross browser click() function no .click() in PhantomJS
function click(el){
    var ev = document.createEvent('MouseEvent');
    ev.initMouseEvent(
        'click',
        true /* bubble */, true /* cancelable */,
        window, null,
        0, 0, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /*left*/, null
    );
    el.dispatchEvent(ev);
}

And here is how to use it:

it('Should set the month when the month is changed', function(){
    var obj = element[0].getElementsByClassName('month_opt')[1];
    click(obj);
    expect(scope.dt.getMonth()).toEqual(1);
});
+3
source

PhantomJS, jqLite, AngularJS. 'click' : https://docs.angularjs.org/api/ng/function/angular.element

.

  • jQuery . jQuery, jqLite jQuery, click(). , , , -, jQuery.
  • triggerGandler() jqLite . ; . triggerHandler. :

    element.triggerHandler('click');
    

    triggerHandler "" , .

+5

This is not the place to check the browser (in this case, click). In a UNIT test, you should check it for selection so that the test action simply clicks the action from the scope:

$scope.$$childHead.click(); // in test $$childHead is scope of your directive in application
...your assertions here

The thing you want to test, click on the browser, this is more of an integration test, since you test the click in the browser and the answer in the directive → it is more suitable for Selenium, for example.

-1
source

Source: https://habr.com/ru/post/1612281/


All Articles