Javascript 在Selenium中测试自删除/动态Webelement 我在做什么

Javascript 在Selenium中测试自删除/动态Webelement 我在做什么,javascript,java,unit-testing,selenium,Javascript,Java,Unit Testing,Selenium,我一直在试验硒,并制作了一个简单的程序,使我的硒测试生活更轻松。其中一部分是测试webelements,并找出哪些方法(单击提交ect)可以让它们在不重新加载页面的情况下重新加载页面、保持静态或变得陈旧。在这个问题上,我对第三种情况特别感兴趣,因为前两种情况已经由我实现了 我遇到的问题 我遇到的问题是找到一个过时且不会导致页面重新加载的Webelement。我想不出一个好的方法来搜索,我没有HTML和javascript技能来制作一个(但无论如何),除非我真的测试它,否则我无法验证我的代码是否有

我一直在试验硒,并制作了一个简单的程序,使我的硒测试生活更轻松。其中一部分是测试webelements,并找出哪些方法(单击提交ect)可以让它们在不重新加载页面的情况下重新加载页面、保持静态或变得陈旧。在这个问题上,我对第三种情况特别感兴趣,因为前两种情况已经由我实现了

我遇到的问题 我遇到的问题是找到一个过时且不会导致页面重新加载的Webelement。我想不出一个好的方法来搜索,我没有HTML和javascript技能来制作一个(但无论如何),除非我真的测试它,否则我无法验证我的代码是否有效

我所做的/尝试的 我想找的第一件事是弹出窗口,但它们实际上不是网页的一部分,而且它们也很不可靠。我想要的东西将表现一致,因为否则测试将无法工作。我认为动态Webelements,即那些在执行操作时更改其定位器的元素将适合我的需要,但我没有找到它们的好方法。任何关于“自删除webelement exmaple”或“webelement过时不会导致页面重新加载示例”或类似内容的google结果,都只会给我关于stackoverflow的问题,比如这一个,而不是我想要的——具体示例。我运行的代码只是等待javascript中的
staleReferenceException
onload
事件。如果出现了
staleReferenceException
,但没有发生
onload
事件,那么我知道我发现了一个自删除/动态webelement(至少我认为这是检测此问题的正确方法)。以下是我正在运行的代码:

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;
正如您在上面所注意到的,在这段代码中有一个名为
threadcase
int
变量。从1开始的三个“案例”(0是表示程序流错误的起始值)表示该测试的三个(非错误)可能结果:

  • 页面将重新加载
  • 页面保持静态,webelement不变
  • 页面保持静态,webelement更改
  • 我需要一个很好的例子来测试第三种情况

    我考虑过的解决方案 我已经做了一些基本的研究来删除javascript中的webelements,但是我A:甚至不知道我是否可以在Selenium中这样操作页面;B:我宁愿得到一个只使用网页的测试用例,因为引入我的编辑使我的测试用例的有效性依赖于我的更多代码(这很糟糕!)。因此,我需要的是一个很好的方法,找到一个符合我的标准的webelement,而不必在f12窗口打开的情况下搜索互联网,希望找到一个按钮来满足我的需要

    编辑1 我只是试着更手动地做这个测试,答案中建议我在正确的时间手动删除一个webelement,然后用这种方式测试我的程序。我测试的是谷歌主页。我尝试使用谷歌应用程序按钮,因为点击它不会导致整个页面重新加载。所以我的想法是,我将单击它,停止程序执行,手动删除它,运行其余的代码,因为不会发生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删除我正在单击的webelement时不会发生页面重新加载

    这是我正在尝试的URL:

    简单的谷歌主页,我要删除的按钮是谷歌应用程序按钮(右上角的黑色9格)

    有关该元素的一些信息:

    class=“gb\u 8 gb\u 9c gb\u R gb\u g”

    id=“gbwa”


    它是按钮本身及其创建的下拉列表的常规容器元素。当我的程序在第1行停下来时,我正在删除这个。然后我在调试器中检查我的程序。注意(您可能必须多次单击按钮上的“检查元素”才能将注意力集中到该元素上)。我将尝试删除较低级别的元素,而不是整个容器,看看这是否会改变什么,但这种行为仍然让我感到困惑。这里的目标是将程序流发送到threadcase 3,因为这就是我们要测试的。应该没有页面重新加载,但是在我手动删除webelement后,它应该会变得过时。当我看不到页面重新加载时,我不知道为什么javascript回调会运行。如果您需要有关我在google主页上删除的内容的更多信息,请告诉我,我将尝试发送一张图片(当然带有可选的手绘圆圈)。

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


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

    我会删除我在selenium中单击的按钮HTML吗?我从来没有真正开始编辑DOM,但我现在会尝试一下,看看它是否适合我的需要。您可以按照自己的意愿以任何方式编辑DOM。我以为这是你想要的第三个选择;元素保留但发生更改?我尝试过这样做,但由于某些原因,当支持executeAsyncScript时,我的代码并没有因为executeAsyncScript而停止。该代码应该暂停,直到发生onload事件,并且由于某种原因,它不这样做,异步定义不应该等待。但是当我读到这个问题时:我的印象是它在