【问题标题】:Nightwatch script runs code before browser opensNightwatch 脚本在浏览器打开之前运行代码
【发布时间】:2016-07-17 06:43:03
【问题描述】:

我有很多测试是在浏览器实际启动之前首先运行脚本,这有时会导致测试运行不正确。实际上给我带来问题的最新情况是try/catch 表达式,它并没有真正捕捉到某些元素不存在的事实(尽管预计不存在)。

在我的测试中,我试图遍历 5 个产品的列表,尝试将它们添加到购物车并检查按钮。对于某些产品,我知道“添加到购物车”按钮必须存在,在某些情况下我知道它不会存在,所以我尝试捕捉错误并移至下一个。 (我知道这不是最聪明的方法,但我正在一点一点地尝试学习和提高我的 javascript 编程技能)。

所以我的测试包含这个作为主要功能,除了从文件中读取测试数据和一些变量声明:

var myFunction = function (x) {
      var productID = data[x][0];
      var quantity = data[x][1];
      browser.url(homepage + 'p/' + productID);


      try {
            pageObject.addToCart(quantity);
            pageObject.click('@continueShopping');
            browser.pause(500);
            browser.assert.ok(true);
          }
      catch (err) {
            console.log('This error is expected');
            browser.asset.ok(true, 'but the product is not addable to cart');
         };
    }


for (var i = 0; i < data.length; i++) {
       myfunction(i);
    }

我明白了:

[Add To Cart Different Products] Test Suite
==================================================================

Running:  Add to cart different types of products
 ? Passed [ok]: true ok
 ? Passed [ok]: true ok
 ? Passed [ok]: true ok
 ? Passed [ok]: true ok
 ? Passed [ok]: true ok // this means is ran through whole list of 5 products already and just afterwards it starts trying to actually add them to cart (run the code)
 ? Element <body> was visible after 360 milliseconds.
 ERROR: Unable to locate element: "#addToCartButton" using: css selector
 ERROR: Unable to locate element: ".continueShopping" using: css selector

这里发生的情况是脚本在启动后立即运行断言,但在实际启动浏览器窗口之前。一旦它启动,它就会开始执行添加到购物车的操作。所以在我看来,它实际上并没有在try 中运行整个代码序列,这首先打破了使用try/catch 的意义。

我该如何解决这种情况?有没有办法让脚本等待浏览器实际启动,或者检查它是否启动?我觉得 Nightwatch 有一些特定的东西会产生这种异步行为,而我在编写测试时会丢失。你能解释一下吗?

注意:/编辑请注意,在我的测试之前我有一个before 块,它意味着首先启动浏览器并确保主体可见。但正如您在控制台结果中看到的那样,这发生在做出断言之后,因此没有效果。

 before : function (browser) {
        browser.url(homepage)
        .waitForElementVisible('body', 5000);
 },

更新:根据某人的建议,这应该通过在该函数上使用回调来实现,我已经尝试过。当我这样使用它时:

var myFunction = function (x) {
        console.log("on line" + x);
        return x;
    };

    var callback = function (y) {
        //var declaration etc
        try { //the code here }
        catch (err) { //the code here }            
    };

    for(var lineNr = 0; lineNr < data.length; lineNr++) {
        myFunction(lineNr, function (){
            console.log(lineNr);
            callback(lineNr);
        });
    }

或者像这样:

var myFunction = function (x,callback) {
        console.log("on line" + x);
        callback(x);
    };

    var callback = function (y) {
        // variables declaration
        try { //code here}
        catch (err) { //code here }
    };
    for(var lineNr = 0; lineNr < data.length; lineNr++) {
        myFunction(lineNr);
    }

我得到了相同的结果,但没有成功。还是我做错了?

【问题讨论】:

    标签: javascript asynchronous nightwatch.js


    【解决方案1】:

    Selenium API 命令是异步的。要强制 nightwach 同步运行操作,您有 2 个选项:

    • JavaScript 方式: 创建承诺

    • 守夜人方式:调用.perform()方法并将您的操作放入回调参数中:

    this.perform(function() {
      try {
          pageObject.addToCart(quantity);
          pageObject.click('@continueShopping');
          browser.pause(500);
          browser.assert.ok(true);
        }
      catch (err) {
          console.log('This error is expected');
          browser.asset.ok(true, 'but the product is not addable to cart');
       };
    });
    

    nightwatch 文档:Understanding the Command Queue(描述命令队列以及 perform() 命令的工作原理)

    【讨论】:

    • 对,我们信守承诺,尽管它需要更高级的编码技能。谢谢你的回答,我认为这是正确的方法,是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多