我现在正尝试在 nodejs 中使用 webdriverio 学习自动化,诚然我对 HTML 中的 jquery 了解不多。我在这里:
我已经编写了一个脚本,到目前为止,它成功地让我登录到一个帐户并导航到我想要的页面。我的目标是进行预订 - 但是当我单击预订项目时,会出现一个弹出窗口,其中包含一些预加载的数据和“进行预订”按钮,单击该按钮会运行一个 javascript 函数。但是,我无法成功地重新创建实际的点击。
按钮的 HTML 如下所示:
<div class="inside">
<ul class="toolBtns">
<li id="ctl00_ctrl_MakeBookingTime_liCancelChanges" class="cancelChanges">
<a id="ctl00_ctrl_MakeBookingTime_lbCancelChanges" href="javascript:__doPostBack('ctl00$ctrl_MakeBookingTime$lbCancelChanges','')">Discard Changes</a></li>
<li id="ctl00_ctrl_MakeBookingTime_liBook" class="bookRes">
<a id="ctl00_ctrl_MakeBookingTime_lbBook" href="javascript:__doPostBack('ctl00$ctrl_MakeBookingTime$lbBook','')">Make Reservation</a></li>
</ul>
</div>
到目前为止,我已经尝试使用它来单击它(这是我的“客户”声明之后的代码)
.execute(executeFunction).then(function(resp){
console.log('execute function status:',resp.state) // should log true if element is there
})
.waitForExist('#ctl00_ctrl_MakeBookingTime_lbBook').then(function(exists){
console.log('button exists status:',exists.state) // should log true if element is there
})
.elements('#ctl00_ctrl_MakeBookingTime_lbBook').then(function(resp){
console.log('element found status: ',resp);
return; //wait for the popup to load before executing the click
}).click('=Make Reservation') //this is the line that doesn't seem to work
最后一行是行不通的。如您所见,我使用正则表达式作为查询元素,但我也按照建议直接尝试了项目 ID here .我还尝试在 HREF 链接中手动执行 javascript 函数,但这只是关闭窗口而没有实际进行预订:
.execute("javascript:__doPostBack('ctl00$ctrl_MakeBookingTime$lbBook")
我猜 _doPostBack 函数中有一些我不理解的参数。
任何建议或指向其他文章的链接都会非常有帮助。我已经搜索了几个小时,但无法完全弄明白。谢谢!
更新
: ChristianB 请求日志,它们在这里:
2:32:16.747 INFO - Done: [execute script: javascript:LaunchLockedReserver(this,event,'54','200','12/19/2015','9:15 AM','2');, []]
12:32:16.752 INFO - Executing: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:16.766 INFO - Done: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]]
12:32:17.023 INFO - Executing: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:17.038 INFO - Done: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]]
12:32:17.303 INFO - Executing: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:17.303 INFO - Executing: [find element: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]])
12:32:17.311 INFO - Done: [find elements: By.xpath: //*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]]
12:32:17.568 WARN - Exception thrown
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//*[contains(@id, "ctl00_ctrl_MakeBookingTime_lbBook") and contains(., "Make Reservation")]"}
似乎最后一 block 不工作。感谢您将我指向日志。奇怪的是,当我直接将正则表达式更改为 ID 时,它仍然会出现错误:
12:38:33.483 WARN - Exception thrown
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"ctl00_ctrl_MakeBookingTime_lbBook"}
我会继续尝试并检查日志
更新 #2
我为我运行的每个函数(参见上面更新的代码)登录了 .then 函数,而 .waitForExists 函数似乎从未运行过。运行函数后我的控制台输出如下所示:
execute function status: success
Error: element (#ctl00_ctrl_MakeBookingTime_lbBook) still not existing after 500ms
at elements("#ctl00_ctrl_MakeBookingTime_lbBook") - isExisting.js:43:17
at isExisting("#ctl00_ctrl_MakeBookingTime_lbBook") - waitForExist.js:31:21
基本上它似乎是从 .execute 直接转到 .elements 函数...
最佳答案
您可能使用了错误的 .waitForExist
。
来自 http://webdriver.io/api/utility/waitForExist.html .一旦 ms
已用完,它的 Future 将返回一个 bool 值,具体取决于它是否找到了选择器。
.waitForExist(选择器[,ms][,reverse]).then(回调);
ms
和 reverse
是可选的。您需要默认值,ms
是在您的 wdio 配置文件中设置的。
要验证是否找到该元素,您可以这样做,
waitForExist('#ctl00_ctrl_MakeBookingTime_lbBook').then(函数(存在){
console.log(exists)//如果元素存在,应该记录 true
})
您不需要尝试部分匹配“Make Reservation”,因为 id 选择器应该是唯一的。
更新:
Futures 是链式的,很难判断 Future 在哪里打断了链条。有时,当我无法确定出现问题的正面或反面时,我会在每个链式成员之间调用一些我知道会返回一些东西的东西,比如
.getTitle().then(function(title){
console.log(title);
});
exists.state
属性不可用。虽然它不在文档中,但我已经验证 waitForExists 解析为 true 或 false。如果不确定传入的参数,可以使用 console.log(arguments)
将参数作为数组获取。不要将其用于生产。尝试在您的 waitForExist.then() 回调中执行此操作以查看您有什么。
您不应该需要 elements
(即使这可能不是问题的根源)。如果您只想单击一个按钮.click(#ctl00_ctrl_MakeBookingTime_lbBook)
是应该做的。
你能详细描述一下下面的代码吗?它也可能影响 Future 链的其余部分。你可以输出 console.log(arguments)
并发布吗?
.execute(executeFunction).then(function(resp){
console.log('execute function status:',resp.state) // should log true if element is there
console.log(arguments);
})
关于javascript - 无法使用 webdriverio 单击网页按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34242620/