javascript - 在 Selenium 中测试一个自删除/动态 Webelement
问题描述
我在做什么
我一直在试验 Selenium 并制作了一个简单的程序来让我的 Selenium 测试生活更轻松。其中一部分是测试 webelements 并找出哪些方法(单击提交等)使它们重新加载页面、保持静态或在不重新加载页面的情况下变得陈旧。在这个问题中,我对第三种情况特别感兴趣,因为前两种情况我已经实现了。
我遇到的问题
我遇到的问题是找到一个过时且不会导致页面重新加载的 Web 元素。我想不出一种搜索的好方法,我没有 HTML 和 javascript 技能来制作一个(无论如何),除非我实际测试它,否则我无法验证我的代码是否有效。
我做过/尝试过的事
我想寻找的第一件事是弹出窗口,但它们实际上并不是网页的一部分,而且它们也很不可靠。我想要一些行为一致的东西,否则测试将无法正常工作。我认为动态Webelements,那些在采取行动时会改变定位器的元素将适合我的需求,但我没有找到它们的好方法。任何“自我删除 webelement 示例”或“Webelement 过时不会导致页面重新加载示例”或类似内容的谷歌结果,只会给我这样的关于 stackoverflow 的问题,而不是我想要的 - 具体示例。我正在运行的代码只是在 javascript 中等待一个staleReferenceException
和一个onload
事件。如果staleReferenceException
发生但onload
事件没有,那么我知道我找到了一个自删除/动态 web 元素(至少我认为这是检测这个的正确方法)。这是我正在运行的代码:
try {
//wait until the element goes stale
wait.until(ExpectedConditions.stalenessOf(webElement));
//init the async javascript callback script
String script = "var callback = arguments[arguments.length - 1];" +
"var classToCall = 'SeleniumTest.isPageReloaded';" +
"window.addEventListener('onload'," + "callback(classToCall));";
//execute the script and wait till it returns (unless timeout exceeded)
JavascriptExecutor js = (JavascriptExecutor) driver;
//execute the script and return the java classname to call
//if/when the callback function returns normally
String classToCall = (String) js.executeAsyncScript(script);
clazz = Class.forName(classToCall);
callbackMethod = clazz.getMethod("JavascriptWorking");
callbackMethod.invoke(null,null);
//page reloaded
threadcase = 1;
}
//waiting until webElement becomes stale exceeded timeoutSeconds
catch (TimeoutException e) {
//page was static
threadcase = 2;
}
//waiting until webElement Reloaded the page exceeded timeoutSeconds
catch (ScriptTimeoutException e) {
//the webElement became stale BUT didn't cause a page reload.
threadcase = 3;
正如您在上面所注意到的,此代码中int
命名了一个变量。threadcase
从 1 开始的三个“案例”(0 是表示程序流错误的起始值)代表了该测试的三个(非错误)可能结果:
- 页面重新加载
- 页面保持静态,webelement 不会改变
- 页面保持静态,webelement 发生变化
我需要一个很好的例子来测试第三种情况。
我考虑过的解决方案
我已经对删除 javascript 中的 webelements 进行了一些基础研究,但是 IA:我什至不知道我是否可以像那样在 Selenium 中的页面上采取行动和 B:我宁愿得到一个只使用网页的测试用例,因为引入我的编辑使我的测试用例的有效性依赖于我的更多代码(这很糟糕!)。因此,我需要一种找到符合我的标准的 web 元素的好方法,而无需在打开 f12 窗口的情况下搜索互联网,希望找到一个可以满足我需要的按钮。
编辑 1
我只是尝试更手动地进行此测试,在答案中建议我在正确的时间手动删除一个 web 元素,然后以这种方式测试我的程序。我测试的是谷歌主页。我尝试使用谷歌应用程序按钮,因为单击它不会导致整个页面重新加载。所以我的想法是,我会单击它,停止程序执行,手动删除它,运行我的其余代码,并且由于不会发生 onload 事件,我的程序将通过测试。令我惊讶的是,事实并非如此。
我运行的确切代码如下。我在第一行停止了调试:
1 Method callbackMethod = null;
2 try {
3 //wait until the element goes stale
4 wait.until(ExpectedConditions.stalenessOf(webElement));
5 //init the async javascript callback script
6 String script = "var callback = arguments[arguments.length - 1];" +
7 "var classToCall = 'SeleniumTest.isPageReloaded';" +
8 "window.addEventListener('onload', callback(classToCall));";
9 //execute the script and wait till it returns (unless timeout
10 //exceeded)
11 JavascriptExecutor js = (JavascriptExecutor) driver;
12 //execute the script and return the java classname to call if/when
13 //the callback function returns normally
14 String classToCall = (String) js.executeAsyncScript(script);
15 clazz = Class.forName(classToCall);
16 callbackMethod = clazz.getMethod("JavascriptWorking");
17 callbackMethod.invoke(null,null);
18 //page reloaded
19 threadcase = 1;
20 }
21 //waiting until webElement becomes stale exceeded timeoutSeconds
22 catch (TimeoutException e) {
23 //page was static
24 threadcase = 2;
25 }
26 //waiting until webElement Reloaded the page exceeded
27 //timeoutSeconds
28 catch (ScriptTimeoutException e) {
29 //the webElement became stale BUT didn't cause a page reload.
30 threadcase = 3;
31 //trying to get the class from javascript callback failed.
32 }
应该发生的事情是一个陈旧的 webelement 导致程序在第 4 行停止等待,程序继续进行,在第 6-11 行初始化 Javascript 回调,然后在第 14 行调用executeAsyncScript
应该等到“onload”事件只有在页面重新加载时才会发生。现在它不这样做,或者我是盲人。我一定是混淆了程序流程,因为我有 99% 的把握在我操纵 DOM 以删除我单击的 web 元素时不会发生页面重新加载。
这是我正在尝试的 URL:
https://www.google.com/webhp?gws_rd=ssl
简单的google主页,我要删除的按钮是google apps按钮(右上角的黑色9格)
关于该元素的一些信息:
类="gb_8 gb_9c gb_R gb_g"
id="gbwa"
它是按钮本身和它创建的下拉菜单的一般容器元素。当我的程序在第 1 行遇到 STOP 时,我将删除它。然后我在调试器中检查我的程序。注意(您可能必须多次单击按钮上的检查元素才能专注于它)。我将尝试删除较低级别的元素而不是整个容器,看看这是否会改变任何东西,但这种行为仍然让我感到困惑。这里的目标是让程序流到 threadcase 3,因为那是我们正在测试的那个。应该没有页面重新加载,但是在我手动删除它之后,webelement 应该变得陈旧。当我看不到页面重新加载时,我不知道为什么 javascript 回调正在运行。如果您需要有关我在谷歌主页上删除的确切内容的更多信息,请告诉我,我
解决方案
我认为您可以通过测试进行调试,在合适的点放置断点,然后使用浏览器开发工具手动更新 HTML。
显然,如果您希望这是一个可重复的过程,这不是一个选择,但如果您只是在调查,那么手动干预可能是合适的
推荐阅读
- python - Python3函数将列表映射到字典
- typescript - ionic 3 movefile函数的问题
- scala - sbt,编译编译桥
- javascript - Calculator Project for Uni - JavaScript Code not working
- navbar - Bootstrap 4 透明导航栏
- python - python ffmpeg子进程在heroku上不起作用
- python - 如何使用字典计算字符串中每个单词的字母?(Python)
- firebase - 使用唯一 ID 时,firebase 数据库检查数据是否在插入之前存在
- c# - 保持 TcpListerner 处于空闲状态 C#
- python - 在模式匹配后返回一个巨大文件的确切行,而不在 Python3 中使用 FOR