在Selenium中测试自删除/动态Webelement

时间:2018-10-01 12:13:02

标签: javascript java unit-testing selenium

我在做什么

我一直在尝试Selenium,并编写了一个简单的程序来简化我的Selenium测试生活。其中一部分是测试网络元素,并弄清哪些方法(单击提交等)使它们重新加载页面,保持静态或变旧而无需重新加载页面。在这个问题中,我对第三种情况特别感兴趣,因为前两种已经由我实现了。

我遇到的问题

我遇到的问题是找到一个陈旧且不会导致页面重新加载的Webelement。我想不出一种搜索的好方法,我还没有HTML和javascript的技巧(无论如何),并且除非实际测试,否则我无法验证我的代码是否有效。

我已经做过/尝试过的

我想寻找的第一件事是弹出窗口,但实际上它们实际上并不是网页的一部分,并且它们也不可靠。我希望某些东西能够始终如一地运行,因为否则测试将无法进行。我认为动态Webelements(那些在作用时会更改其定位符的Webelements)将适合我的需求,但我没有找到它们的好方法。任何“自动删除webelement的示例” “ webelement变旧不会导致页面重新加载示例” 的google结果,只会给我这样的关于stackoverflow的问题而不是我想要的-具体示例。我正在运行的代码只是等待javascript中的staleReferenceExceptiononload事件。如果发生staleReferenceException但没有发生onload事件,那么我知道我发现了一个自我删除/动态网络元素(至少我认为这是检测此问题的正确方法)。这是我正在运行的代码:

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的{​​{1}}变量。从1开始的三个“情况”(0是代表程序流错误的起始值)代表此测试的三个(非错误)可能结果:

  1. 页面重新加载
  2. 页面保持静态,网页元素不变
  3. 页面保持静态,网络元素发生变化

我需要一个很好的例子来测试第三种情况。

我考虑过的解决方案

我已经完成了一些有关删除javascript中的webelements的基础研究,但IA:我什至不知道我是否可以像这样和B那样在Selenium中的页面上执行操作:我宁愿得到一个仅使用该网页的测试用例因为引入我的编辑使测试用例的有效性依赖于我的更多代码(这很糟糕!)。因此,我需要的是一种找到符合我的条件的web元素的好方法,而不必通过打开f12窗口来搜索互联网,希望找到一个可以满足我需要的按钮。

编辑1

我只是尝试更手动地进行此测试,在回答中建议我在适当的时间手动删除Webelement,然后以这种方式测试程序。我测试的是Google主页。我尝试使用google apps按钮,因为单击它不会导致整个页面重新加载。所以我的想法是,我将单击它,暂停程序执行,手动将其删除,运行其余代码,由于不会发生onload事件,因此我的程序将通过测试。令我惊讶的是,这没有发生。

我运行的确切代码如下。我在第一行停止了调试:

threadcase

应该发生的是,Stale网络元素导致程序在第4行停止等待,程序继续运行,在6-11行初始化Javascript回调,然后在第14行调用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 } 等待“ onload”事件,该事件仅在页面重新加载时发生。现在不这样做,否则我是盲目的。我一定会混淆程序流程,因为我99%确信在操作DOM删除要单击的webelement时没有页面重新加载。

这是我正在尝试的URL:

https://www.google.com/webhp?gws_rd=ssl

简单的google主页,我要删除的按钮是google apps按钮(右上角的黑色9格)

有关该元素的一些信息:

class =“ gb_8 gb_9c gb_R gb_g”

id =“ gbwa”

它是按钮本身的常规容器元素以及它创建的下拉菜单。当我的程序在第1行到达STOP时,我正在删除它。然后在调试器中浏览我的程序。注意(您可能不得不多次单击按钮上的检查元素以将其聚焦)。我将尝试删除较低级别的元素,而不是整个容器,以查看是否会发生任何变化,但这种行为仍然使我感到困惑。这里的目标是使程序流进入线程案例3,因为那是我们正在测试的线程。应该没有页面重新加载,但是在我手动删除它之后,webelement应该过时了。当我看不到页面重新加载时,我不知道为什么JavaScript回调正在运行。如果您需要有关我在Google主页上要删除的内容的更多信息,请告诉我,我将尝试发送图片(当然还有可选的手绘圈)。

1 个答案:

答案 0 :(得分:1)

我认为您可以通过测试进行调试,在合适的位置放置一个断点,然后使用浏览器开发工具手动更新HTML。

很明显,如果您希望这是一个可重复的过程,那不是一个选择,但是,如果您只是进行调查,那么手动干预可能是合适的