此刻,我变得越来越沮丧,希望能对stackexchange有所帮助。
第一件事:我不是一个经验丰富的Javascript开发人员,可能根本不是一个经验丰富的开发人员,但是我想我知道如何使用基本脚本编写-我对C#,Java和co。有所了解。当前的Web自动化脚本,我认为赶上并尝试用Javascript编写是一个好主意,但是现在我在某个时候,我考虑从头开始使用另一种不太混乱的语言。
请,有人能告诉我,到底如何让我的代码从上到下以同步方式执行?
经过大量时间的谷歌搜索,到目前为止,我已经尝试了以下方法:
#! /usr/bin/env node
开始第1行,然后使用./app.js
在终端中开始async
function()await
()但是即使现在,当我运行脚本时,它也会抛出很多UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'isDisplayed' of undefined
和类似的东西,让我猜测,该节点正在异步运行我的某些方法/函数。在浏览器窗口加载完毕之前,这些异常就会在控制台中弹出。
我正在使用: *硒webdriver 3.6.0 * Firefox 60.0.2 *节点8.10.0
我的代码基本上看起来像这样:
const {Builder, By, Key, until, manage} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');
const webdriver = require('selenium-webdriver');
const fs = require('fs');
//
// declaring lots of global variables, I need in my functions
//
async function init(){
let options = await new firefox.Options()
.setProfile('/home/ruphus/.mozilla/firefox/selenium_profile.backtesting');
let driver = await new webdriver.Builder()
.forBrowser('firefox')
.setFirefoxOptions(options)
.build();
await driver.get('https://www.someurl.com/')
.then(openStrategySettings())
.then(btnStrategySettings.click());
// ... defining webelements/locations to the previously created objects - using xpath
inputPeriod = await driver.findElement(By.xpath("//div[@id='header-toolbar-intervals']/div/div/div"));
}
async function openStrategySettings() {
if (!someWebelement.isDisplayed()){
await tabStrategyTester.click();
}
}
async function inputValue(element, value) {
await element.sendKeys(Key.BACK_SPACE + Key.BACK_SPACE + value.toString());
}
async function run(){
// this is the main function with a couple of for loops and array.forEach(function()... things
}
init();
run();
据我了解,我正在使用async init()
函数启动webdriver和firefox。在这里,我将所有这些方法都使用await。启动webdriver / firefox之后,我将Object变量定义到这些位置(我希望这种情况在浏览器启动和加载时发生)。
但是以某种方式,我不明白为什么,该脚本似乎运行了我的所有功能,并且在启动脚本后可以直接找到所有代码。实际上,它似乎在等待最后一次加载浏览器。在它最终加载之前,我得到了几个(8)UnhandledPromiseRejectionWarning
..
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'sendKeys' of undefined
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'click' of undefined
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'isDisplayed' of undefined
在此,我将非常感谢您的帮助。
答案 0 :(得分:0)
让async
/ await
函数完全同步运行的答案似乎是让它仅运行ONE函数。
我的意思是说,不能先init();
初始化浏览器,变量和内容,然后 后再调用run();
进行自动化本身。
应该构建一个小的函数main()来调用这两个函数:
async main(){
await init;
await run();
}
main();
这似乎可以解决异步运行的问题。尽管如此,我仍然在为await driver.sleep(1000);
困扰,该功能似乎无法按预期工作。
通过进一步的谷歌搜索,我还阅读了关于here的webdriver-sync。但这是关于该主题的相当老的评论。我不太确定 webdriver-sync 的最新信息。我可能会尝试一下。
如果有人对如何解决有进一步的信息,例如
中使用的无效await driver.sleep(1000);
方法
array.forEach(async function(entry){
for(){
for(){
await driver.sleep(1000);
}
}
}
我真的很高兴阅读。
答案 1 :(得分:0)
您对await
的使用几乎是正确的。但是.then
方法需要一个(或两个)函数作为参数。您在then()
内部进行函数调用,实际上是将该函数调用的结果传递给then()
而不是函数本身。
async function init(){
let options = await new firefox.Options()
.setProfile('/home/ruphus/.mozilla/firefox/selenium_profile.backtesting');
let driver = await new webdriver.Builder()
.forBrowser('firefox')
.setFirefoxOptions(options)
.build();
await driver.get('https://www.someurl.com/')
.then(openStrategySettings) // <-- XXX pass function
.then(() => btnStrategySettings.click()); // <-- XXX if the argument isn't a plain function name, arrow functions come handy
// ... defining webelements/locations to the previously created objects - using xpath
inputPeriod = await driver.findElement(By.xpath("//div[@id='header-toolbar-intervals']/div/div/div"));
}
async function openStrategySettings() {
if (! await someWebelement.isDisplayed()){ // <-- XXX isDisplayed() is async (returns Promise), await its settlement
return await tabStrategyTester.click(); // <-- XXX never ignore a Promise
}
}
async function inputValue(element, value) {
return await element.sendKeys(Key.BACK_SPACE + Key.BACK_SPACE + value.toString()); // <-- XXX never ignore a Promise
}
当return
在异步函数中使用异步函数的结果时,await
可以省略,因为Promise中的Promise会自动展开。因此,return element.sendKeys(
的工作原理相同,但是使用await
可能会减少混乱。
答案 2 :(得分:0)
async function surrounding_function(){
for(value of array){
for(){
for(){
await driver.sleep(1000);
}
}
}
}
driver.sleep()
返回一个Promise对象,该对象将在睡眠时间过去后实现。 await
停止执行,直到解决了诺言(履行或拒绝)。同时,解释器从任务队列执行其他任务。确定await语句的值是可以的,因为这仅会忽略Promise的值。不是承诺本身。异步函数返回一个Promise。 .forEach
方法将忽略您作为回调传递的函数的返回值,从而忽略Promise,并继续执行而无需等待Promise结算。调用异步函数首先将新任务推送到任务队列中。没有await
,这些任务将以意外的顺序执行。