Nightwatch 脚本在浏览器打开之前运行代码
Nightwatch script runs code before browser opens
我有很多测试,其中脚本 运行 首先,在浏览器实际启动之前,这有时会使测试 运行 不正确。实际上给我带来问题的最新情况是 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
这里发生的是脚本 运行 立即启动断言,但在浏览器 window 实际启动之前。一旦启动,它就会开始执行添加到购物车的操作。所以在我看来,它实际上并没有 运行 在 try
中包含整个代码序列,这打破了首先使用 try/catch
的要点。
我该如何解决这种情况?有没有办法让脚本等待浏览器实际启动,或者有办法检查它是否启动?我觉得 Nightwatch 有一些特定的东西会产生这种异步行为,而我在编写测试时却遗漏了这一点。你能解释一下吗?
注意:/Edit 请注意,我在测试之前有一个 before
块,它意味着启动浏览器 first 并确保主体可见。但正如您在控制台结果中注意到的那样,这是在做出断言之后发生的,因此它没有任何影响。
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);
}
我得到了相同的结果,但没有成功。还是我做错了?
Selenium API 命令是异步的。要强制 nightwach 同步进行 运行 操作,您有 2 个选项:
JavaScript 方式: 创建承诺
nightwatch 方式: 调用 .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()
命令的工作原理)
我有很多测试,其中脚本 运行 首先,在浏览器实际启动之前,这有时会使测试 运行 不正确。实际上给我带来问题的最新情况是 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
这里发生的是脚本 运行 立即启动断言,但在浏览器 window 实际启动之前。一旦启动,它就会开始执行添加到购物车的操作。所以在我看来,它实际上并没有 运行 在 try
中包含整个代码序列,这打破了首先使用 try/catch
的要点。
我该如何解决这种情况?有没有办法让脚本等待浏览器实际启动,或者有办法检查它是否启动?我觉得 Nightwatch 有一些特定的东西会产生这种异步行为,而我在编写测试时却遗漏了这一点。你能解释一下吗?
注意:/Edit 请注意,我在测试之前有一个 before
块,它意味着启动浏览器 first 并确保主体可见。但正如您在控制台结果中注意到的那样,这是在做出断言之后发生的,因此它没有任何影响。
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);
}
我得到了相同的结果,但没有成功。还是我做错了?
Selenium API 命令是异步的。要强制 nightwach 同步进行 运行 操作,您有 2 个选项:
JavaScript 方式: 创建承诺
nightwatch 方式: 调用
.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()
命令的工作原理)