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();
    }
}

运行框

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

相关推荐
释槐鸟~5 小时前
还不知道RIDE工具怎么装吗
测试工具·自动化
有技巧搬砖1 天前
为什么锂电池组的电池老化测试很重要?
测试工具·锂电池·电池老化
蒲公英内测分发1 天前
智能手表卖出去后,包装、说明书和官网里的 App 下载入口怎么统一?
前端·人工智能·测试工具·智能家居·智能硬件·智能手表
蒲公英内测分发1 天前
智能手环出海测试,海外合作方分散在不同国家,Android 测试包怎么持续分发和更新?
android·前端·人工智能·测试工具·智能手表
无语的小歪歪1 天前
ATF 智测 1.0
python·测试工具·集成测试
SHENGWEI胜为2 天前
交换机端口显示正常,终端却获取不到 IP 地址?从 DHCP 流程定位故障
服务器·网络·测试工具·缓存·通信工程
xie881018022 天前
长表格跨页重复表头:排版上的做法
测试工具
老孟说禅2 天前
测试工具示波器的使用
测试工具
步行cgn3 天前
为什么使用接口测试工具?
测试工具
P1Browser3 天前
Puppeteer 与 Selenium 技术对比:多账号自动化管理如何做环境隔离?
selenium·测试工具·自动化