如何处理硒中的NosuchwindowException
#html #网络开发人员 #测试 #selenium

在当今的数字景观中,网站充满了动态的内容,吸引了用户交互式体验的用户。一个值得注意的功能是通过用户采取的特定操作触发的新窗口和标签的经常出现。这些动态元素在增强用户参与度和提供无缝导航方面起着至关重要的作用。

作为自动化测试仪,遇到场景中需要在端到端流中处理多个窗口或选项卡是一个常见的情况。成功管理这种动态行为对于确保自动测试的准确性和可靠性至关重要。

但是,随着自动化测试往往会失败并使您的测试脚本降低可靠性,这变得极具挑战性。您的automation testing脚本应该能够管理许多窗口以更好地测试。在这种情况下,切换焦点以在必要的窗口或选项卡上执行任何操作成为无偿要求。

Selenium提供了与多个窗口一起使用的各种方法。但是,任何丝毫错误,例如使用无效的窗口句柄,切换到封闭的窗口等,都可以在自动化脚本中导致 nosuchwindowexception 。我们将在下一节中讨论有关这些的更多信息。

nosuchwindowexception 发生WebDriver试图与当时无法使用的窗口进行交互时。这可能是由于关闭的窗口或焦点中的窗口不同。

在此Selenium Java tutorial中,我们将讨论如何在硒中处理 nosuchwindowexception *。我们将讨论同样的最常见原因和处理它的最佳实践。使用Selenium Java对这些实践的实际实施将帮助您学习如何在自动化脚本中处理 *Nosuchwindowexception ,以使测试顺利且可靠地运行。

所以,让我们开始。

什么是窗口和窗口句柄?

在Selenium中,一个窗口是指使用web automation时,尤其是在使用图形用户界面(GUI)窗口或Web浏览器窗口/选项卡。当Selenium WebDriver启动Web浏览器时,它将打开一个新窗口,其中已加载网页。

每个窗口由一个唯一的ID表示,称为窗口句柄。它允许WebDriver与窗口及其元素进行交互。这些手柄也用于在不同的窗口之间切换,操纵窗口的大小和位置,并在窗口及其内容上执行其他操作。

如果您打开了多个浏览器窗口,则可以使用此方法检索一组所有窗口手柄。在此博客中,Selenium with Java语言已用于演示并提供代码样本。

driver.getWindowHandles()


    Returns a Set<String> containing handles of all the windows

获取当前的窗口句柄:

driver.getWindowHandle()



Returns the handle of the current window as a String

通过传递其手柄切换到特定窗口:

driver.switchTo().window("<random_window_handle>")

切换到主窗口返回:

    driver.switchTo().defaultContent()

要更好地理解这些方法,请考虑以下测试方案。

我们想到达Twitter页面,然后单击登录按钮。此按钮可在新窗口中加载的页面上可用。这个新窗口,窗口2是通过单击上一个/主窗口上的“关注”按钮1。

上加载的。

现在,如果我们希望测试方案通过,则必须将驱动程序焦点切换到Window 2后。如果您尝试在负载完成之前切换驱动器焦点,它将引起nosuchwindowexception。

到目前为止,哪个是2023年最想要的automation testing tools?让我们看看!

什么是硒中的NosuchwindowException?

nosuchwindowexception 是使用多个Windows/Tabs时最常遇到的exceptions in Selenium WebDriver。当Webdriver找不到所需的浏览器窗口或它需要与之交互的选项卡时,提高了 nosuchwindowexception

如果有多个开放式窗口,并且WebDriver正在寻找一个带有不正确的窗口手柄的窗口,则会发生此例外。另一个原因可能是所需的窗口已经关闭并且不再可用。

nosuchwindowexception 也可能发生浏览器本身问题,就像由于以前的动作而崩溃或已经变得无反应。

这里要注意的一个重要的事情是handling multiple frames in Seleniumhandling multiple windows in Selenium略有不同。至于帧,为切换提供的方法是不同的,同样,如果找不到框架,则提出的期望是 nosuchframeException 。。

在最强大的云基础架构上执行浏览器automation testing platform。利用lambdatest自动化测试,以在云上更快,可靠和可扩展的体验。

Selenium nosuchwindowexception的原因

使用多个窗口时,可能出于许多原因而发生此例外。一些最常见的是。

  • 窗口的关闭

  • 驱动程序专注于另一个窗口

  • 无效的窗口句柄

  • 窗口加载正时问题

示范:如何在硒中修复NosuchwindowException?

为了展示Selenium中 nosuchwindowexception 处理的最佳实践,我们将使用Selenium 4使用Maven和TestNG framework创建一个Java项目。

测试方案1(演示 nosuchwindowexception

  1. Navigate to https://www.lambdatest.com/selenium-playground/window-popup-modal-demo.

  2. 单击在Twitter上关注

  3. 获取所有窗口手柄的列表并在控制台上打印它们。

  4. 尝试使用无效的窗口句柄切换到新窗口。

  5. verify nosuchwindowexception

测试方案2(使用try-catch handle nosuchwindowexception

  1. Navigate to https://www.lambdatest.com/selenium-playground/window-popup-modal-demo

  2. 单击在Twitter上关注

  3. 获取所有窗口手柄的列表并在控制台上打印它们。

  4. 开始尝试块。

  5. 尝试使用无效的窗口句柄切换到新窗口。

  6. 验证 nosuchwindowexception 被抬起并捕获在渔获块中。

测试方案3(使用显式等待, nosuchwindowexception

  1. Navigate to https://www.lambdatest.com/selenium-playground/window-popup-modal-demo

  2. 单击在Twitter上关注

  3. 使用预期条件等待windows的数量为2。

  4. ,请添加明确的等待
  5. 获取所有窗口句柄的列表并将它们存储在变量中。

  6. 启动一个循环,使用一个窗口句柄一个一个一个一个窗口。

  7. 使用窗口句柄切换到新窗口。

  8. 通过验证其标题是否是所需的窗口。

  9. 如果是匹配,请打破循环。如果没有,请重复步骤6和7,直到找到所需的窗口。

  10. 单击新窗口上的登录按钮。

此博客使用Eclipse IDE进行演示目的,但可以随意使用您的偏好。在创建Maven项目之前,无论您选择哪种IDE,实施过程一直相同。

当我们使用Selenium Web Automation时,我们将首先添加硒依赖性和TestNG,testng将用于test execution将其用于该项目的pom.xml。

创建项目并添加依赖项后,最终的pom.xml就像以下一个。

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
       <groupId>NoSuchWindowException</groupId>
       <artifactId>NoSuchWindowException</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <build>
           <sourceDirectory>src</sourceDirectory>
           <plugins>
               <plugin>
                   <artifactId>maven-compiler-plugin</artifactId>
                   <version>3.8.1</version>
                   <configuration>
                       <release>19</release>
                   </configuration>
               </plugin>
           </plugins>
       </build>
       <dependencies>
           <dependency>
               <groupId>org.seleniumhq.selenium</groupId>
               <artifactId>selenium-java</artifactId>
               <version>4.8.3</version>
           </dependency>
           <dependency>
               <groupId>org.testng</groupId>
               <artifactId>testng</artifactId>
               <version>7.7.1</version>
               <scope>test</scope>
           </dependency>
       </dependencies>
    </project>

接下来,添加一个新的Java test文件 testnosuchwindowexception.java src.test 软件包。一旦添加了项目结构,就会像这样。

我们将把测试用例添加到此处,以查看如何预防 nosuchwindowexception 在我们的Selenium automation脚本中出现。

在此博客中,我们将利用像Lambdatest这样的硒云网格的力量来执行Selenium Java testing。 Lambdatest是一种数字体验测试云,通过在3000+台式机和移动环境的云上运行您的Java automation testing脚本,从而呈指数级增加browser coverage。

完整的Manual testing教程涵盖了手动测试的所有方面,包括策略和最佳实践。

添加所有WebDriver配置和测试案例示例以演示 nosuchwindowexception 的修复程序,完成的文件应如下:

 package test;


    import java.net.*;
    import java.time.Duration;
    import java.util.HashMap;
    import java.util.Set;


    import org.openqa.selenium.remote.RemoteWebDriver;
    import org.testng.annotations.*;
    import org.openqa.selenium.By;
    import org.openqa.selenium.NoSuchWindowException;
    import org.openqa.selenium.safari.`Options;
    import org.openqa.selenium.support.ui.*;


    public class TestNoSuchWindowException {


       public RemoteWebDriver driver = null;


       String username = System.getenv("LT_USERNAME") == null ? "<lambdatest_username>" : System.getenv("LT_USERNAME");
       String accessKey = System.getenv("LT_ACCESS_KEY") == null ? "<lambdatest_accesskey>" : System.getenv("LT_ACCESS_KEY");


       @BeforeTest
       public void setup()
       {
           try {
               SafariOptions safariOptions = new SafariOptions();
               safariOptions.setPlatformName("MacOS Big sur");
               safariOptions.setBrowserVersion("14.0");

               HashMap<String, Object> ltOptions = new HashMap<String, Object>();
               ltOptions.put("build", "NoSuchWindowException in Selenium");
               ltOptions.put("name", "Handling NoSuchWindowException");
               ltOptions.put("w3c", true);
               safariOptions.setCapability("LT:Options", ltOptions);

               driver = new RemoteWebDriver(
                       new URL("https://" + username + ":" + accessKey + "@hub.lambdatest.com/wd/hub"), safariOptions);
           } catch (MalformedURLException e) {
               e.printStackTrace();
           }
            driver.get("https://www.lambdatest.com/selenium-playground/window-popup-modal-demo");
       }


       @AfterTest
       public void tearDown() {
           driver.quit();
       }


       @Test
       public void testNoSuchWindowException()
       {  
           System.out.println("Clicking on Follow button");
           driver.findElement(By.xpath("//*[@title='Follow @Lambdatesting on Twitter']")).click();

           Set<String> handles = driver.getWindowHandles();
           for(String handle : handles)
           {
               System.out.println("Valid handle value : " + handle);
               //adding -updated to valid handle value to demonstrate exception
               //due to invalid handle value
               driver.switchTo().window(handle + "-updated");
           }
       }


       @Test
       public void testNoSuchWindowException_fix()
       {  
           System.out.println("Clicking on Follow button");
           driver.findElement(By.xpath("//*[@title='Follow @Lambdatesting on Twitter']")).click();

           WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
           wait.until(ExpectedConditions.numberOfWindowsToBe(2));
           System.out.println("Verified total windows are 2");

           System.out.println("Fetching window handles of all windows");
           Set<String> handles = driver.getWindowHandles();


           System.out.println("Switching to each window one by one to verify if it is required one");
           for(String handle : handles)
           {
               System.out.println("Switching to window with handle : " + handle);
               driver.switchTo().window(handle);
               //using window title to reach to required window
               if(driver.getTitle().equals("Profile / Twitter"))
               {
                   System.out.println("Reached required window");
                   break;
               }
           }
           driver.findElement(By.xpath("//*[@data-testid='login']")).click();
           System.out.println("Clicked Login button successfully");
       }

       @Test
       public void testNoSuchWindowException_fix_tryCatch()
       {
           System.out.println("Clicking on Follow button");
           driver.findElement(By.xpath("//*[@title='Follow @Lambdatesting on Twitter']")).click();
           try
           {
               Set<String> handles = driver.getWindowHandles();
               for(String handle : handles)
               {
                   System.out.println("Valid handle value : " + handle);
                   //adding -updated to valid handle value to get exception
                   //due to invalid handle value
                   System.out.println("Invalid handle value used : " + handle + "-updated");
                   driver.switchTo().window(handle + "-updated");
               }
           } catch (NoSuchWindowException ex) {
               System.out.println("We are inside catch block");
               System.out.println("NoSuchWindowException has been caught.");
           }
       }
    }

codewalkthrough

步骤1 。我们首先创建一个*RemoteWebDriver*的实例,因为我们将在云中执行代码。

步骤2 。在创建帐户以获取用户名和访问密钥后,导航到LambdaTest Profile部分。这些将用于与他们的云网格建立连接。

您还可以使用以下命令将用户名和访问密钥作为环境变量配置,并直接在代码中获取它们。

用于MacOS和Linux:

export LT_USERNAME=LT_USERNAME
    export LT_ACCESS_KEY=LT_ACCESS_KEY

Windows:

set LT_USERNAME=LT_USERNAME
    set LT_ACCESS_KEY=LT_ACCESS_KEY

我们还可以通过导航到其Automation Capabilities Generator来获取所需的浏览器功能来使用lambdatest平台。这有助于提供可用的浏览器功能可用于执行中的浏览器功能的现成代码。

步骤3 。创建基本方法并将其命名为 setup(),并用 @beforetest annotation in TestNG进行注释。此方法将用于驱动程序设置并在每个测试之前打开网页。

在此博客中,我们使用了支持 Safarioptions 类的硒4。在此功能中,创建一个对象来定义浏览器属性,例如浏览器版本,OS版本等。它还接受lambdatest执行所需的变量作为功能。

这些变量用于设置构建,名称或任何其他浏览器属性之类的值,这将有助于识别LambdaTest Dashboard上的运行或修改行为。

步骤4。最后,创建了一个 remotewebdriver 的实例,以使用 safarioptions 和您的lambdatest用户名连接到lambdatest cloud Grid 和访问密钥。

步骤5。最后,导航到正在测试的示例网站上,该网站将在单击按钮时打开一个新窗口。

步骤6。添加一种方法为拆卸()并用 @aftertest 注释进行注释。这将用于关闭每个测试案例后的会话。

需要在Windows上为Safari browser testing提供一个很好的解决方案吗?忘记模拟器或模拟器使用真实的在线浏览器。免费尝试lambdatest!

测试方案:硒中的诺舒温迪克斯感受

步骤1。添加第一个测试案例,并将其命名为 testNosuchwindowException()。在此测试中,我们尝试通过使用无效的窗口手柄模拟硒中的 nosuchwindowexception

步骤2。我们首先单击“关注”按钮,该按钮将打开一个新窗口。

为此,我们使用driver.findElement() method in Selenium并使用XPath作为网络元素定位器。

步骤3 。接下来,使用 driver.getWindowhandles()获取所有窗口手柄的列表,然后将它们存储在变量中。这将穿过窗口句柄列表并打印有效的句柄值。

步骤4。最后,我们切换到新打开的窗口的尝试涉及传递无效的窗口手柄。为此,操纵上一步的有效句柄值以证明例外。

步骤5。在执行此操作时,您可以观察到,当窗口句柄传递的窗口手柄是无效的,而selenium中的 nosuchwindowexception nosuchwindowexception 失败,而硒无法找到窗口使用相同。

在以下各节中,我们将看到一些最佳实践,以防止硒中这种 nosuchwindowexception 发生。

提升您的Mobile App Testing质量:在lambdatest云上充分利用您的移动应用程序测试和测试,以进行全面的测试,错误检测等。

使用try-catch在硒中固定NosuchwindowException

如“最佳实践”部分中所讨论的,这是硒中处理 nosuchwindowexception 最常用的方法之一。

步骤1。为此,将另一个测试用例添加到Java文件中,并将其命名 testnosuchwindowexception_fix_fix_frycatch()。。

步骤2。单击“关注按钮”,该按钮应打开一个新窗口。

步骤3。

唯一的区别是我们将此代码放置在Try块中。这将有助于捕获异常并防止自动化脚本中的突然行为。

步骤4。这是一个捕获块。如果发生并执行任何后续操作,这有助于捕获异常。它还有助于在这种情况下优雅地终止代码。

步骤5。执行上述代码,您将获得以下输出。在此,您可以看到 nosuchwindowexception 被抬起但在捕获块内部优雅处理。

,但是要注意,即使处理了异常,也无法在新窗口上执行任何操作。这是因为增加了例外,这意味着窗口句柄不正确或不存在窗口。

您随时可以在这种情况下添加重试,以再次尝试以前的操作,该操作应启动窗口或检查句柄是否正确并尝试再次切换。

在Lambdatest云网格上运行您的Selenium Testing脚本。测试3000多个桌面和移动环境。免费尝试!

使用窗口手柄在硒中固定NosuchwindowException并等待

步骤1。接下来,添加一个新的测试用例,并将其命名为testnosuchwindowexception_fix()。我们将使用它来说明如何正确使用等待和窗口处理有助于我们防止 nosuchwindowexception 发生。

第2步。我们首先单击该按钮,该按钮应打开一个新窗口。

步骤3。

要处理异常,我们使用explicit waits in Selenium等待窗口的数量等于2,然后随流量向前移动。

步骤4:为此,创建一个WebDriverWait类的对象,并传递驱动程序对象以及我们要等待最长时间的持续时间。

一起使用此对象,直到()函数,我们添加了一个预期的条件等待窗口的数量为2。驱动程序最多等待5个这种情况发生的秒。

如果窗口的数量已验证,我们向前迈进,否则驱动程序会出现错误以表明未满足条件。

步骤5。接下来,为所有打开的窗口获取窗户手柄。我们将将其存储在一组中。

步骤6。我们将穿过此手柄列表,然后一个一个一个切换到每个窗口,直到找到所需的窗口。

步骤7。要检查是否需要当前窗口,我们通过将所需窗口的标题与当前窗口匹配。如果是一场比赛,请打破循环并继续。如果不是,请使用手柄切换到下一个窗口并继续相同的流程。

步骤8。

执行上述测试案例,我们得到了下面的输出。

从输出屏幕截图中,您可以看到我们已经成功验证了使用等待的2个窗口。然后,我们将驱动程序焦点切换到所需的新窗口,并可以成功单击登录按钮而不会遇到异常。

处理硒中NosuchwindowException的最佳实践

在示范部分中,很明显,通过遵循一些最佳实践,可以在自动化脚本中轻松处理硒中的 nosuchwindowexception

让我们更详细地看一下这些。

  • 使用显式等待

  • 使用有效的窗口手柄

  • 切换到正确的窗口

  • 使用try-catch块

  • 跟踪窗口手柄

结论

总而言之, nosuchwindowexception 是硒中常见的例外,在使用多个窗口或选项卡时可能会发生。但是,有了正确的实践知识,我们可以使自动化测试顺利进行,可靠地进行。在此博客中,我们讨论了可以导致硒中 nosuchwindowexception 的常见原因。我们还学习了处理同样的最佳实践,并就如何将这些方法添加到您的自动化脚本中进行了一些动手实践。因此,现在您可以开始开始,并且要注意硒的力量,请在脚本中预防 nosuchwindowexception