7

当您的 Angular 应用程序在 DOM 上准备就绪时,Angular-scenario 运行良好。使用 requirejs 或其他 AMD 库时并非如此。如何在角度场景中添加对 AMD 的支持?

4

3 回答 3

9

您需要做的是覆盖默认的帧加载行为并在您的 amd 应用程序准备好时发出一个新事件。

第一件事是在您的 Angular 应用程序中添加以下行以及 angular.bootstrap 调用。角度场景需要此数据。

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'
    }, '*');
}

接下来,在您的 e2e 跑步者中,您必须包含这些行。如果是外部脚本,则必须在 angular-scenario 之后加载,并且必须在 DOM 准备好之前对其进行解析:

/**
 *  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;
        };
    }
})();

最后,要启用 amd 配置,您必须将属性 ng-useamd 添加到 angular-scenario 的 script 标签。

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

你现在准备好了

使用角度场景 v1.0.3 测试

于 2013-03-19T12:50:13.750 回答
4

上面的答案在我的场景中部分失败(Angular 1.1.4,fresh Karma)。在调试视图中它运行良好,在正常的概述页面中它失败了。我注意到一个额外的嵌套 .

我将代码更改为向测试应用程序的父 iframe 发送消息。

if (top !== window) {
    window.parent.postMessage({
        type: 'loadamd'
    }, '*');
}
于 2013-05-14T18:18:44.947 回答
1

接受的答案是绝对正确的,但很遗憾您必须将该代码放入您的页面中。

因此,如果有帮助,我为 karma 创建了一个预处理器,以将“修复”注入作为测试运行的一部分。

代码:https ://github.com/tapmantwo/karma-ng-bootstrap-fix-preprocessor npm:https ://www.npmjs.org/package/karma-ng-bootstrap-fix-preprocessor

请注意,这仅在您通过 karma 提供文件时才有效。如果您代理它们,它们不会经过预处理器。因此,作为替代方案,我有一个 ng-scenario 的分支,它执行类似的操作以允许手动引导的站点运行;

https://github.com/tapmantwo/karma-ng-scenario

这不是节点模块,因此您必须手动设置它,但最好(恕我直言)有这样的东西,而不是感染生产代码只是为了让测试通过。

于 2014-06-06T13:22:02.943 回答