【问题标题】:How to handle the "unexpected alert open"?如何处理“意外警报打开”?
【发布时间】:2013-10-10 23:28:22
【问题描述】:

由于弹出窗口,我遇到了 Selenium 抛出 timeout exception 的问题

  unexpected alert open
  not provide any stacktrace information)
  Command duration or timeout: 5 milliseconds

警报有OKCANCEL 按钮。我知道两种处理方法


第一种方法是重新打开一个新会话

driver.quit();
driver = new ChromeDriver();

第二种方法是使用机器人类

Robot r = new Robot();
r.keyPress(KeyEvent.VK_ENTER);
r.keyRelease(KeyEvent.VK_ENTER);

但是,这种方法的时间效率不高。有没有更好的办法?

【问题讨论】:

    标签: java selenium


    【解决方案1】:

    这也可以通过 Java 来实现。创建 Java 类并实现 InvocationHandler 接口。覆盖调用方法,在此方法中,您的逻辑可以处理警报/弹出窗口或您要处理的任何事件。然后用你的 Webelement 包装这个类实例,这样每当它对每个 webelement 执行任何操作时,它都会调用这个包装器方法。

    希望这会有所帮助 - 这是实现的链接https://www.vinsguru.com/selenium-webdriver-how-to-handle-annoying-random-popup-alerts/

    【讨论】:

      【解决方案2】:

      在 Selenium 中处理警报的方法

      1. 单独决定

      如果您需要单独对测试中的每个警报采取措施,驱动程序会为您提供切换到警报的选项,并决定接受或关闭它。

      driver.switchTo().alert().accept();
      

      1. 默认设置处理

      如果您希望以相同的方式处理所有警报,您可以在测试执行开始时将全局 capability 设置为 ACCEPTINGORE 或 DISMISS 警报出现时默认

      capabilities.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
      

      1. 使用机器人类

      或者,您可以使用 Robot 类发送一个 Enter 键事件,该事件将接受警报。

      Robot r = new Robot();
       
      r.keyPress(KeyEvent.VK_ENTER);
      r.keyRelease(KeyEvent.VK_ENTER);
      

      【讨论】:

        【解决方案3】:
        ChromeOptions options = new ChromeOptions();
        options.setUnhandledPromptBehaviour(ACCEPT);
        WebDriver driver = new ChromeDriver(options);
        

        你可以通过 ACCEPT 而不是 以下枚举常量ACCEPTACCEPT_AND_NOTIFYDISMISSDISMISS_AND_NOTIFYIGNORE 根据您的要求。

        【讨论】:

          【解决方案4】:

          配置 DesiredCapabilities 以接受意外的更改行为。

          final DesiredCapabilities chromeCapabilities = DesiredCapabilities.chrome();
          chromeCapabilities.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
          final ChromeOptions chromeOptions = new ChromeOptions();
          /*
           * Other options...
           */
          chromeCapabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
          ChromDrvier driver = new ChromeDriver(chromeCapabilities);
          

          【讨论】:

            【解决方案5】:

            这个问题更经常令人烦恼,因为它出现在被测系统中不可预测的地方。现在,我认为没有办法通过 webdriver 中的配置来自动处理所有这些不确定性。我的一般建议是将 webDriver 包装在 Proxy 中,并使用某种动态代理来包装所有 webdriver 方法。通过这种方式,您可以对不可预测的警报进行单点控制,进行日志记录或评估方法性能,处理随机无法访问的浏览器异常,处理随机 StaleElementException 等。我发现这对于各种情况都非常有用,但性能损失很小.

                    Class WebDriverProxy implements InvocationHandler{
                   WebDriverWrapperImpl impl = new WebDriverWrapperImpl();
            
                    public String clickByXPath(String xpath)  {
                        return (String)handleInvocation(impl,"clickByXPath", new Object[]{xpath});
                        //  return impl.clickByXPath( xpath) ;
                    }
            
            
                /**All fail fast strategies could be centralized here., no need of any assertion errors in libraries,
                     * However it makes sense to wrap webdriver exceptions as either recoverable or nonrecoverable
                     * recoverable ones are like unexpected hangs on the browser, which could be handled at the test runner level, wherein the 
                     * whole test can be retried.
                     * irrecoverable ones are also mostly handled at the test runner level, but capable of being caught at the test script level *  
                     **/
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
                    {
                        Object o = null;
                        Throwable target = null;
                        try{
                            o = method.invoke(proxy, args);
                        }       
                        catch(InvocationTargetException ee){            
                            target = ee.getTargetException();
                            throw target;
                        }
                        return o;
                    }
            
                    public Object handleInvocation(Object proxy, String method, Object[] args){     
            
                        Object toReturn = null;
                        Method m = null;
                        Class[] classes = new Class[args.length];
                        for(int i = 0;i<args.length;i++){
                            classes[i]=String.class;
                        }
                        for(Object x:args){
                        logBuffer.append(x.toString()+","); 
                        }
                        log.trace("WebDriverProxy. "+method+"("+logBuffer.toString()+")");
                        logBuffer = new StringBuffer();
                        try{
                             m = proxy.getClass().getMethod(method,classes);
            
                            toReturn = invoke(proxy,m, args);
            
                        }catch(NoSuchMethodException e){    
                            e.printStackTrace();
            
                        }catch( StaleElementReferenceException e){
                            log.debug("Exception was of tye "+e.getClass().getCanonicalName());
            
            
            
            
            
            
                        }
                        catch(UnreachableBrowserException | NoSuchElementException e){
                            log.debug("Exception was of tye "+e.getClass().getCanonicalName());
                            //If the NoSuchelement is due to suspect Alerts being present, switchToAlert() and alert.accept() here.
                        }
            
            
            
                        return toReturn;
                    }
            
            
            
                    }
            
            
            class WebDriverWrapperImpl {
             WebDriver driver = new ChromeDriver();
              public String clickByXPath(String xpath)  throws Exception{
                        driver.findElement(By.Xpath(xpath)).click();
                        return driver.getTitle();
                    }
            
            }
            

            【讨论】:

              【解决方案6】:

              试试这个,

              public boolean isAlertPresent() {
              
                  boolean presentFlag = false;
              
                  try {
              
                      // Check the presence of alert
                      Alert alert = driver.switchTo().alert();
                      // Alert present; set the flag
                      presentFlag = true;
                      // if present consume the alert
                      alert.accept();
                      //( Now, click on ok or cancel button )
              
                  } catch (NoAlertPresentException ex) {
                      // Alert not present
                      ex.printStackTrace();
                  }
              
                  return presentFlag;
              }
              

              希望对你有所帮助。

              【讨论】:

              • 这是一个意外警报,它可以出现在任何地方。所以你认为在每一行代码之后我都会调用这个布尔函数isAlertPresent(),如果你的答案是否定的,那么请编辑并解释如何最佳地调用这个函数,而不是每次都重复/调用。
              • @paul,您应该根据需要进行更改。我写的是整体而不是针对特定部分。
              • 如果确定弹出窗口,则只使用 try catch 代码,无需检查弹出窗口是否打开或仅使用 driver.switchTo().alert();。但有时情况就像弹出窗口是否会打开,即不确定每次弹出窗口是否打开。我的申请中有这样的情况,所以我按照上面的方法处理。在我的情况下,虽然我从下拉列表中选择了特定值,但弹出窗口是打开的。这不适用于下拉的所有值。如果您有任何更好的技术,欢迎随时欢迎。
              【解决方案7】:

              如果您正在使用像 TestNG 这样的任何框架,您可以使用像 ITestListener 等这样的监听器,您必须覆盖一些方法,如 BeforeCommand 和 afterCommand。所以在 BeforeCommand 中,实现 alert 的代码来解除和检查美观。当 selenium 命令被执行时,这个 beforeCommand 方法将自动调用并检查 alert 是否存在。如果是,它将关闭并执行您的命令。希望能解决你的问题

              【讨论】:

              • 我在 TestNG 侦听器中没有找到类似 beforeCommand 的东西,但在 this 中找到了答案,通过实现 WebDriverEventListener 可以实现您的建议。
              【解决方案8】:

              这应该可以解决问题:

              driver.switchTo().alert().accept();
              

              【讨论】:

              • 我得到了这个:“NoSuchAlertError: no alert open”...不一致,有时测试通过,有时当我尝试接受警报时它给我那个错误...知道为什么或者如何解决?
              • 如果 WebDriver 中的某些内容并非始终如一地失败,则有 95% 的可能性是时间问题。您可以使用new WebDriverWait(driver).until(ExpectedConditions.alertIsPresent()) 等待它。
              • 我使用的是Nodejs Selenium,你能提供一个更详细的例子吗?非常感谢
              • 没关系,我只是在接受它之前睡觉(1000),无论如何谢谢:D
              • Nodejs 代码:driver.wait(webdriver.until.alertIsPresent()).then(()=> { driver.switchTo().alert().accept(); });跨度>
              猜你喜欢
              • 2021-11-01
              • 2015-01-02
              • 2017-07-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-09-29
              相关资源
              最近更新 更多