Node.js 使用selenium webdriver执行序列(用于节点JS)
我对SeleniumWebDriver命令的执行顺序有点困惑 以下示例的正确编码是什么。 我想:Node.js 使用selenium webdriver执行序列(用于节点JS),node.js,selenium-webdriver,mocha.js,Node.js,Selenium Webdriver,Mocha.js,我对SeleniumWebDriver命令的执行顺序有点困惑 以下示例的正确编码是什么。 我想: 首先,在文本框中输入文本 然后,单击按钮 以下代码是否保证了正确的顺序 // Enter the text driver.findElement(webdriver.By.id('txt')) .sendKeys('bla bla') .then( function() {}, function(err) {
// Enter the text
driver.findElement(webdriver.By.id('txt'))
.sendKeys('bla bla')
.then(
function() {},
function(err) {
console.log(err);
done(err);
}
);
// Press the button
driver.findElement(webdriver.By.id('btn'))
.click()
.then(
function() {
done();
},
function(err) {
console.log(err);
done(err);
}
);
还是我应该这样做
// Enter the pass
driver.findElement(webdriver.By.id('txt_pass'))
.sendKeys('sifra')
.then(
function() {
// Press the login button
driver.findElement(webdriver.By.id('btn_login'))
.click()
.then(
function() {
done();
},
function(err) {
console.log(err);
done(err);
}
);
},
function(err) {
console.log(err);
done(err);
}
);
如果第二种情况是正确的,那么当一行中需要两个以上的操作时,我应该如何编写代码?Iw将非常复杂,必须进行维护
更新:
假设现在我想清除第一个findElement中的元素“txt”,并在键入文本之前执行此操作。根据路易斯的回答,我怀疑应该是这样的:
// Clear the textbox
driver.findElement(webdriver.By.id('txt'))
.clear()
.then(
function() {},
function(err) {
console.log(err);
done(err);
}
);
// Enter the text
driver.findElement(webdriver.By.id('txt'))
.sendKeys('bla bla')
.then(
function() {},
function(err) {
console.log(err);
done(err);
}
);
// go on with the further sequence...
我觉得这不是很好,它太长太笨拙了,特别是如果在同一个元素上有更多操作的话。有没有一个通用的方法来缩短这个,使它更紧凑
类似于链接:
findElement('txt').clear().sendKeys('bla, bla'); // This does not work, as clear is a void
第一种方法是正确的。您似乎缺少的一条信息是,WebDriver的JavaScript实现使用“承诺管理器”为您的承诺排序。这在指南的一节中进行了解释。以下是一个例子:
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
// Do not implicitly wait for anything.
driver.manage().timeouts().implicitlyWait(0);
// Set the script wait timeout to 10 seconds.
driver.manage().timeouts().setScriptTimeout(10 * 1000);
driver.get('http://www.example.com');
function err() {
console.log("ERR", arguments);
}
var start = Date.now();
driver.executeAsyncScript(
"var done = arguments[0];" +
"setTimeout(function () { document.body.innerHTML = '<p id=\"foo\"></p>'; done() }, 5000)")
.then(function () {
console.log("created foo!", Date.now() - start);
},
err);
driver.findElement(webdriver.By.tagName("body")).then(function () {
console.log("here", Date.now() - start);
});
driver.findElement(webdriver.By.id("foo")).then(function () {
console.log("found foo!", Date.now() - start);
}, err);
数字会有所不同,但它们总是>5000,并且彼此之间的联系非常紧密(除非在过载或速度慢得可笑的系统上运行)。首先执行的executeAsyncScript
用于说明需要一段时间才能完成的操作是如何而不是允许同一驱动程序上的后续操作继续进行的。除了执行脚本而不是查找元素这一事实之外,它与findElement
没有任何区别:promise manager会等到操作完成后才能继续下一个操作,即使这两个操作没有使用.then()显式排序
如果promise manager没有依次对操作进行排序,那么.findElement(webdriver.By.tagName(“body”))
将在异步脚本完成之前执行,并且它将在控制台打印“created foo!”
之前打印,因为页面确实有body
元素
此外,如果承诺管理器没有依次对操作排序,则最后一个.findElement
将无法找到id
值为foo
的元素。在脚本的早期,我关闭了隐式等待,这样findElement
调用肯定不会等待foo
出现
有些情况下,您可能更想像在第二个代码片段中那样做,但您没有在问题中包含任何明确的理由
另外,如果没有Selenium的promise manager,那么您必须执行类似于第二个代码片段的操作,因为一般来说,没有任何东西可以为您排序承诺
关于如何排序清除
和发送键
,您可以执行以下操作:
driver.findElement(webdriver.By.id('txt')).then(function (el) {
el.clear();
el.sendKeys('bla bla');
});
此结构使用“控制流”功能的特性。有趣。这与承诺在其他任何情况下都是相反的,但它似乎是正确的。我收回我的回答。@AaronDufour事实上,除非有人阅读了我在回答中提到的文档部分,否则Selenium管理承诺并不明显。@Louis,我明白了。我添加了一些更新来概括这个主题,你能看一下吗?
driver.findElement(webdriver.By.id('txt')).then(function (el) {
el.clear();
el.sendKeys('bla bla');
});