使用casperJS测试jQuery Geocomplete插件(自动完成)

时间:2014-07-16 13:30:12

标签: javascript backbone.js autocomplete casperjs

我们现在已经用casperjs写了几个测试用例。与其他测试框架相比,它的功能就像魅力一样。但是我们的应用程序有一个关键部分,我们没有编写合适的测试用例。

在我们的应用中,我们集成了一种名为Geocomplete(http://ubilabs.github.io/geocomplete/)的自动完成插件,可以从Google Maps Api中获取地理数据。

有以下工作流程。在我们网站的起始页面上,有一个带有一个输入字段的表单,用于自动完成功能。用户可以在其中输入特定城市的名称,Google会返回数据。在后台,骨干模型填充了该数据。

以下是测试用例的代码:

    casper.test.begin('Test User Login Form', 4, function suite(test) {

        casper.options.verbose = true;
        casper.options.logLevel = 'debug';
        var url = 'http://localhost:8889/';
        var session;

        casper.start(url);

        casper.test.comment('Start Testing');

        casper.waitFor(function check() {
            return this.evaluate(function() {
                return document.getElementById('page-wrap');
            });
        }, function then() {
            casper.waitForSelector('#landingForm', function() {
                this.echo('waiting');
            });
        });

        // input is populated with a some letters
        casper.then(function() {
            casper.sendKeys('#landingForm input[name="location.name"]', 'Klag', {
                keepFocus: true
            });
        });

        // .pac-item container whill show the autocomplete suggestions
        casper.then(function() {
            casper.waitUntilVisible('.pac-item', function() {

                // we have tried several methods here like mouse_over + click etc.
                this.sendKeys('#landingForm input[name="location.name"]', casper.page.event.key.Down, {
                    keepFocus: true
                });
                this.sendKeys('#landingForm input[name="location.name"]', casper.page.event.key.Enter, {
                    keepFocus: true
                });
                // form is submitted
                this.click('#landingForm > div > div > div > span > button');
            });
        });

        casper.then(function() {
            // wait until next page is visible
            casper.waitUntilVisible('div.activity-pic', function() {
                // get backbone session model
                session = casper.evaluate(function() {
                    return require('model/session');
                });
                // test if model was populated correctly with the data from google
                test.assertEquals(session.filterModel.attributes.location.name, 'Klagenfurt', 'Name equals expected values.');
            });
        });

        casper.run(function() {
            casper.test.comment('Ending Testing');
            test.done();
        });

    });

测试

test.assertEquals(session.filterModel.attributes.location.name, 'Klagenfurt', 'Name equals expected values.');

总是失败并告诉我name-attribute未定义。输入字段与城市名称相关联。我们在其他测试用例中使用了evaluate-method来检查我们模型的值和属性,它有效。

有人有同样的问题吗?

1 个答案:

答案 0 :(得分:1)

有两种可能的方法。基于this comment,您可以通过evaluatewaitFor执行事件监听器(此处为可重用的casper函数):

casper.waitForGeocodeResult = function(){
    this.thenEvaluate(function(){
        // TODO: initialize $input
        $input.bind('geocode:result', function(event, result) {
            window._myGeocodeResultArrived = true;
        }
    });
    this.waitFor(function check(){
        return this.evaluate(function(){
            return "_myGeocodeResultArrived" in window && window._myGeocodeResultArrived;
        });
    });
    this.thenEvaluate(function(){
        window._myGeocodeResultArrived = false;
    });
};

您可以这样称呼:

casper.waitForGeocodeResult();
casper.then(function() {
    // get backbone session model
    session = casper.evaluate(function() {
        return require('model/session');
    });
    // test if model was populated correctly with the data from google
    test.assertEquals(session.filterModel.attributes.location.name, 'Klagenfurt', 'Name equals expected values.');
});

如果这不起作用,可以反复直接检查会话模型(再次作为可重用的casper函数):

casper.getBackboneModel = function(name, keyFunc){
    var oldRetry;
    this.then(function(){
        oldRetry = this.options.retryTimeout;
        // set retry timeout a little higher in case the require is a time intensive function
        this.options.retryTimeout = 500;
    });
    this.waitFor(function check(){
        var model = casper.evaluate(function(modelName){
            return require(modelName);
        }, name);
        return keyFunc(model);
    }, null, function onTimeout(){
        this.echo("warning: geocomplete was unsuccessful");
    });
    this.then(function(){
        // reset timeout
        this.options.retryTimeout = oldRetry;
    });
};

这样称呼:

casper.getBackboneModel(function(session){
    try {
        var temp = session.filterModel.attributes.location.name;
        return "name" in session.filterModel.attributes.location;
    } catch(e){
        return false;
    }
});
casper.then(function() {
    // get backbone session model
    session = casper.evaluate(function() {
        return require('model/session');
    });
    // test if model was populated correctly with the data from google
    test.assertEquals(session.filterModel.attributes.location.name, 'Klagenfurt', 'Name equals expected values.');
});