Selenium-Java版(frame切换/窗口切换)

frame切换/窗口切换

前言

切换到frame

原因

解决

切换回原来的主html

切换到新的窗口

问题

解决

回到原窗口

法一

法二

示例


前言

参考教程:Python + Selenium Web自动化 2024版 - 自动化测试 爬虫_哔哩哔哩_bilibili

上期文章:Selenium-Java版(css表达式)-CSDN博客

切换到frame

运行代码

java 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.time.Duration;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 创建WebDriver对象
        WebDriver wd = new EdgeDriver();
        wd.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

        // 访问目标网页
        wd.get("https://www.byhy.net/cdn2/files/selenium/sample2.html");

        // 根据class name选择元素,返回的是一个列表
        List<WebElement> elements = wd.findElements(By.className("plant"));

        // 遍历列表并打印每个元素的文本内容
        for (WebElement element : elements) {
            System.out.println(element.getText());
        }

        // 创建Scanner对象等待用户输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("等待回车键结束程序");
        scanner.next();

        // 关闭浏览器
        wd.quit();
    }

发现并没有打印元素的文本内容

原因

这些元素是在一个叫iframe的元素中的

frame元素或者iframe元素的内部会包含一个被嵌入的另一份html文档。使用selenium打开一个网页的操作范围并不包含被嵌入的html文档里面的内容。

解决

操作被嵌入的html文档中的元素,需要**切换操作范围**到被嵌入的文档中。

使用 WebDriver 对象的switchTo属性,三选一:

括号内填id

java 复制代码
wd.switchTo().frame("frame1");

括号内填class属性值

java 复制代码
wd.switchTo().frame("innerFrame");

括号内填frame对应的WebElement对象

java 复制代码
wd.switchTo().frame(wd.findElement(By.tagName("iframe")));

上面例子的正确代码

java 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.time.Duration;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 创建WebDriver对象
        WebDriver wd = new EdgeDriver();
        wd.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

        // 访问目标网页
        wd.get("https://www.byhy.net/cdn2/files/selenium/sample2.html");

        // 切换到名为 'frame1' 的 frame
        wd.switchTo().frame("frame1");

        // 根据class name选择元素,返回的是一个列表
        List<WebElement> elements = wd.findElements(By.className("plant"));

        // 遍历列表并打印每个元素的文本内容
        for (WebElement element : elements) {
            System.out.println(element.getText());
        }

        // 创建Scanner对象等待用户输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("等待回车键结束程序");
        scanner.next();

        // 关闭浏览器
        wd.quit();
    }
}

运行框打印出了内容

切换回原来的主html

java 复制代码
wd.switchTo().defaultContent();

假如操作完frame里面的元素后,需要点击主html里面的按钮

运行代码

java 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.time.Duration;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 创建WebDriver对象
        WebDriver wd = new EdgeDriver();
        wd.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

        // 访问目标网页
        wd.get("https://www.byhy.net/cdn2/files/selenium/sample2.html");

        // 根据name属性值 'innerFrame',切换到iframe中
        wd.switchTo().frame("innerFrame");

        // 根据 class name 选择元素,返回的是 一个列表
        List<WebElement> elements = wd.findElements(By.className("plant"));

        // 遍历列表并打印每个元素的文本内容
        for (WebElement element : elements) {
            System.out.println(element.getText());
        }

        // 切换回 最外部的 HTML 中
        wd.switchTo().defaultContent();

        // 然后再 选择操作 外部的 HTML 中 的元素
        wd.findElement(By.id("outerbutton")).click();

        // 创建Scanner对象等待用户输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("等待回车键结束程序");
        scanner.next();

        // 关闭浏览器
        wd.quit();
    }
}

查看自动打开的网站

切换到新的窗口

问题

运行代码

java 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.time.Duration;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 创建WebDriver对象
        WebDriver wd = new EdgeDriver();
        wd.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

        // 访问目标网页
        wd.get("https://www.byhy.net/cdn2/files/selenium/sample3.html");

        // 点击打开新窗口的链接
        WebElement link = wd.findElement(By.tagName("a"));
        link.click();

        // wd.getTitle()方法是当前窗口的标题栏文本
        System.out.println(wd.getTitle());

        // 创建Scanner对象等待用户输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("等待回车键结束程序");
        scanner.next();

        // 关闭浏览器
        wd.quit();
    }
}

运行框

虽然打开了新窗口,但输出的不是新窗口标题,而是老窗口的标题

解决

点击链接和输出标题的中间加入如下代码

java 复制代码
        // 获取所有窗口句柄
        Set<String> windowHandles = wd.getWindowHandles();

        // 遍历所有窗口句柄
        for (String handle : windowHandles) {
            // 先切换到该窗口
            wd.switchTo().window(handle);
            // 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
            if (wd.getTitle().contains("Microsoft")) {
                // 如果是,那么这时候WebDriver对象就是对应的该窗口,正好,跳出循环
                break;
            }
        }

运行框

回到原窗口

法一

和切换新窗口用同样的方法,只需换一行代码

java 复制代码
wd.getTitle().contains("白月黑羽")

法二

遍历窗口句柄之前,提前保存当前窗口句柄

java 复制代码
        // mainWindow变量保存当前窗口的句柄
        String mainWindow = wd.getWindowHandle();

新窗口操作完后,将driver对应的对象返回到原来的窗口

java 复制代码
        // 通过前面保存的老窗口的句柄,自己切换到老窗口
        wd.switchTo().window(mainWindow);

示例

运行代码

java 复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.time.Duration;
import java.util.Scanner;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        // 创建WebDriver对象
        WebDriver wd = new EdgeDriver();
        wd.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

        // 访问目标网页
        wd.get("https://www.byhy.net/cdn2/files/selenium/sample3.html");

        // mainWindow变量保存当前窗口的句柄
        String mainWindow = wd.getWindowHandle();

        // 点击打开新窗口的链接
        WebElement link = wd.findElement(By.tagName("a"));
        link.click();

        // 获取所有窗口句柄
        Set<String> windowHandles = wd.getWindowHandles();

        // 遍历所有窗口句柄
        for (String handle : windowHandles) {
            // 先切换到该窗口
            wd.switchTo().window(handle);
            // 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
            if (wd.getTitle().contains("Microsoft")) {
                // 如果是,那么这时候WebDriver对象就是对应的该窗口,正好,跳出循环
                break;
            }
        }

        // 打印当前窗口的标题栏文本
        System.out.println(wd.getTitle());

        // 通过前面保存的老窗口的句柄,自己切换到老窗口
        wd.switchTo().window(mainWindow);

        // 打印切换回老窗口后的标题栏文本
        System.out.println(wd.getTitle());

        // 创建Scanner对象等待用户输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("等待回车键结束程序");
        scanner.next();

        // 关闭浏览器
        wd.quit();
    }
}

运行框

不仅仅适用于最初的老窗口,操作期间打开的其他窗口都可以保留其窗口句柄

相关推荐
水水不水啊2 天前
告别杂乱的调试窗口:我用 Python + WebView 写了一个现代化串口助手
python·测试工具·嵌入式·嵌入式开发·串口调试·串口助手
把头塞进显示器8 天前
电商平台-测试报告
python·selenium·pytest
霍格沃兹测试学院-小舟畅学9 天前
UI 测试的语义断言:Midscene aiAssert 比像素比对稳在哪、又会骗在哪
人工智能·测试工具
zuozewei9 天前
附录 A:主流工具对比选型表
人工智能·测试工具
我的xiaodoujiao9 天前
Django 基础知识详细图文教程 10-Django 模板引擎 3
后端·python·测试工具·django
霍格沃兹测试学院-小舟畅学9 天前
Google 开源 ARTEMIS:AI Agent 如何接管 Android 真机测试?
人工智能·测试工具
Liaiyang669 天前
# 自研 AST 容错初筛工具:横向评测 Django、PyTorch、TensorFlow 三大开源 Python 框架异常收容风险
python·测试工具·自动化·开源软件·代码规范·devops·代码复审
霍格沃兹测试学院-小舟畅学9 天前
我用 AI 把 Swagger 变成 500 条 pytest 用例,回归从 3 天到 3 小时
人工智能·测试工具
奔跑中的小象10 天前
GuideLLM 压测实战指南:给大模型推理服务做一次完整 SLA 评估
测试工具·guidellm
cpolar技术支持10 天前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright