Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use angular-scenario with requirejs

Angular-scenario works well when your angular app is ready on DOM ready. Is not the case when using requirejs or an other AMD lib. How to add support for AMD in angular-scenario?

like image 911
Francis Avatar asked Mar 19 '13 12:03

Francis


People also ask

Does angular use RequireJS?

AngularJS is defined as a shim and injects the angular object into the RequireJS module. The angular. module is defined in our application module, and injects that object into the RequireJS module. The conditionals ensure that we bootstrap AngularJS only when the page is ready for it, and only once.

What is RequireJS in AngularJS?

RequireJs website defines RequireJS as a JavaScript file and module loader. Using a modular script loader like RequireJS will improve the speed and quality of your code. The files will be loaded asynchrounously when needed, rather than loading all at once.

What is AMD in angular?

Asynchronous module definition (AMD) is a specification for the programming language JavaScript. It defines an application programming interface (API) that defines code modules and their dependencies, and loads them asynchronously if desired.


1 Answers

What you have to do is to override the default frame load behaviour and to emit a new event when you amd app is ready.

The first thing is to add the following lines in your angular application along with the angular.bootstrap call. This data is required by angular-scenario.

angular.bootstrap(document, ['app']);

var html = document.getElementsByTagName('html')[0];

html.setAttribute('ng-app', 'app');
html.dataset.ngApp = 'app';

if (top !== window) {
    top.postMessage({
        type: 'loadamd'
    }, '*');
}

Next, in your e2e runner, you have to include those lines. If it's an external script, it must be loaded after angular-scenario and it must be parsed before the DOM is ready :

/**
 *  Hack to support amd with angular-scenario
 */
(function() {
    var setUpAndRun = angular.scenario.setUpAndRun;

    angular.scenario.setUpAndRun = function(config) {
        if (config.useamd) {
            amdSupport();
        }
        return setUpAndRun.apply(this, arguments);
    };

    function amdSupport() {
        var getFrame_ = angular.scenario.Application.prototype.getFrame_;

        /**
         *  This function should be added to angular-scenario to support amd. It overrides the load behavior to wait from
         *  the inner amd frame to be ready.
         */
        angular.scenario.Application.prototype.getFrame_ = function() {
            var frame = getFrame_.apply(this, arguments);
            var load = frame.load;

            frame.load = function(fn) {
                if (typeof fn === 'function') {
                    angular.element(window).bind('message', function(e) {
                        if (e.data && e.source === frame.prop('contentWindow') && e.data.type === 'loadamd') {
                            fn.call(frame, e);
                        }
                    });
                    return this;
                }
                return load.apply(this, arguments);
            }

            return frame;
        };
    }
})();

Finally, to enable the amd configuration, you must add the attribute ng-useamd to angular-scenario's script tag.

<script type="text/javascript" src="lib/angular-1.0.3/angular-scenario.js" ng-autotest ng-useamd></script>

You're now ready to go

tested with angular-scenario v1.0.3

like image 198
Francis Avatar answered Oct 12 '22 20:10

Francis