AngularJS:在E2E测试中访问范围

时间:2013-04-12 20:24:12

标签: angularjs karma-runner

我试图在E2E测试中访问$ scope而没有成功......

作为测试,我试过这个:(我的网站不使用JQuery ..)

跑步者将我的网站放在嵌套的iframe中,所以我直接访问它,然后获取所有的ng-scopes并尝试使用.scope(),如this帖子和下面的代码...... / p>

var frameDocument = document.getElementById('test-frames').children[0].contentDocument;
var scopeElements = frameDocument.getElementsByClassName('ng-scope');
var scopes = [].map.call(scopeElements, function (e) {
return angular.element(e).scope();
});

上面的代码找到了正确的元素,但是对它们调用scope()会为每个元素返回undefined ....

有人可以确认或否认我们可以访问E2E中的范围吗?我认为有办法吗?

感谢您

2 个答案:

答案 0 :(得分:3)

根据之前的回答,这是我的诀窍。

您可以将其扩展到动态范围。主要部分是从addFutureAction获取对appWindow的引用。

//HTML CODE

<body id="main-controller" ng-controller="mainCtrl" ng-init="__init__()">


//Scenario helper.

/*
Run `callback` with scope from `selector`.
*/
angular.scenario.dsl('scope', function() {
    return function(selector, callback) {
        return this.addFutureAction(
            'Executing scope at ' + selector,
            function(appWindow, $document, done) {
                var body = appWindow.document.getElementById(selector)
                var scope = appWindow.angular.element(body).scope()
                callback(scope)
                scope.$apply()
                done(null, 'OK');
            })
    }
})

//Actual test.

it(
'When alerts are defined, they are displayed.',
function() {
    scope('main-controller', function(scope) {
        scope.alerts.push({'type': 'error', 'msg': 'Some error.'})
    })

    expect(element('#alerts').css('display')).toEqual('block')
})

答案 1 :(得分:2)

在E2E测试中,以这种方式访问​​范围不是一个好选择。相反,您可以使用element()等辅助函数在页面中选择元素,并使用expect()检查模型数据。

您可能需要的是单元测试。您可以轻松访问单元测试中的$scope

这里有一个非常好的指南:http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-testacular.html

这也可能是一个时间问题,我可以像这样在testacular runner中达到范围。它在iframe中运行测试。要使其正常工作,您需要在测试中添加sleep(3)。但这非常脆弱。

    setTimeout(function () {
        console.log('try to reach frames');
        var frame = window.frames[0].window.frames['senario_frame'];
        if (!frame) {
            console.log('too late');
        } else {

            var scopeElements = frame.document.getElementsByClassName('ng-scope');
            var scopes = [].map.call(scopeElements, function (e) {
                return frame.angular.element(e).scope();
            });
            console.log(scopes);
        }
    }, 2000);