0
votes

Is there a way to access a directive's controller using the .controller() method inside a Protractor test? In unit tests I can do

var el = angular.element(...);
$compile(el)(scope);
var component = el.controller('nameOfDirective');

but I can't seem to figure out how to do that in a Protractor test.

Here is the code I'm trying to test...

//registration.route.js
(function () {
    'use strict';

    angular.module('app.account.registration').run(appRun);

    appRun.$inject = ['routerHelper'];
    /* @ngInject */
    function appRun(routerHelper) {
        routerHelper.configureStates(getStates());
    }

    function getStates() {
        return [
            {
                state: 'registration',
                config: {
                    url: '/registration',
                    template: '<registration layout="column" flex/>',
                    title: 'registration'
                }
            }
        ];
    }
})();

//registration.component.js
(function () {
    'use strict';

    angular.module('app.account.registration').component('registration', {
        templateUrl: 'app/account/registration/registration.html',
        controller: Controller
    });

    /* @ngInject */
    function Controller($state, UserService, SweetAlert) {
        var self = this;

        this.$onInit = function () {
            this.state = 'unverified';
            this.processing = false;
        };

        this.register = function (formData) {
            this.processing = true;

            UserService.register(formData.email).then(function (response) {
                self.state = 'verify';
                self.email = response.data.email;
                //response.data.token will only be returned on localhost for security reasons
                self.token = response.data.token;
                self.processing = false;
            }).catch(function (error) {
                if (error.status === 422) {
                    SweetAlert.error('Error!', formData.email + ' already exists. Please use a unique email.');
                }
                self.processing = false;
            });
        };
    }

})();
1
What are you trying to get out of the controller? - CShark
I'm end-to-end testing the registration page which sends an email to the user with a "confirm email" link. The link has a token which I use to complete the registration. I need the token to "fake" clicking the email. Is there a better way of testing this? EDIT: the token is returned in the response to Service.register(userEmail) which is called from within my directive. - exk0730
So you're saying you want Service.register(userEmail) to return some kind of fake token rather than its normal behavior? - CShark
Well I'd like to actually hit the server, which would mean Service.register would return a real token. Unless I shouldn't be hitting the real REST api? But then it doesn't really seem like an end to end test...it's debatable, I suppose. - exk0730
No, it can/should be hitting the real REST api. - CShark

1 Answers

1
votes

If anyone needs the answer for this, here it is:

browser.executeScript(function () {
    return window.angular.element(document.body)
                         .find('DIRECTIVE-TAG-NAME').controller('directiveName');
}).then(function (directiveControllerInstance) {
    console.log(directiveControllerInstance);
});

For example, if your directive name is "testDirective", you would do:

browser.executeScript(function () {
    return window.angular.element(document.body)
                         .find('test-directive').controller('testDirective');
}).then(function (directiveControllerInstance) {
    console.log(directiveControllerInstance);
});