首页 > 其他分享 >软件测试学习笔记丨Seleium的BUG:页面元素文案重复空格处理

软件测试学习笔记丨Seleium的BUG:页面元素文案重复空格处理

时间:2024-02-04 16:32:53浏览次数:24  
标签:java String selenium Seleium driver org import BUG 软件测试

前言

  • 需求

做 WEB 的 UI 自动化练习,其需求为:

访问慕课网的实战页面,获取实战页面的课程列表信息,并逐个点击进入详情并且关闭详情,直到最后一个。

  • 环境
  • Java 8
  • Maven
  • Selenium 4.0
  • Junit 5

初步代码

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class imoocTest {
    private static WebDriver driver;

    @BeforeAll
    static void setUP() {
        // 获取当前文件下所在的目录
        String currentDirectory = System.getProperty("user.dir");
        // 设置chromeDriver
        System.setProperty("webdriver.chrome.driver", currentDirectory + "/src/test/resources/Driver/Chrome/chromedriver");
        ChromeOptions options = new ChromeOptions();
        //浏览器模拟手机模式
        options.addArguments("--disable-web-security");
        // 最大化窗口
        options.addArguments("--start-maximized");
        //解决报 403 问题
        options.addArguments("--remote-allow-origins=*");
        driver = new ChromeDriver(options);
        // 隐式调用
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
    }

    @AfterAll
    static void tearDown() {
        //关闭浏览器
        driver.quit();
    }

    @Test
    public void test() throws InterruptedException {
        // 打开慕课网实战的页面
        driver.get("https://coding.imooc.com/");
        // 获取当前页面的句柄
        String mainWindowHandle = driver.getWindowHandle();
        // 获取下一页按钮的元素
        WebElement nextPage = driver.findElement(By.xpath("//a[text()='下一页']"));
        // 判断下一页按钮是否存在
        while (nextPage != null) {
            // 获取当前页面的所有课程名称
            List<WebElement> courseNameList = driver.findElements(By.cssSelector(".title.ellipsis2"));
            for (int i = 0; i < courseNameList.size(); i++) {
                // 获取当前课程并且点击进入详情页面
                String courseName=courseNameList.get(i).getText();
                System.out.println(i + ":获取到的课程名称1:" + courseName);
                driver.findElement(By.xpath("//p[text()='" + courseName + "']")).click();
                Thread.sleep(2000);
                // 获取浏览器所有的窗口句柄
                Set<String> allWindowHandles = driver.getWindowHandles();
                for (String windowHandle : allWindowHandles) {
                    if (!windowHandle.equals(mainWindowHandle)) {
                        driver.switchTo().window(windowHandle);
                        break;
                    }
                }
                // 关闭详情页面
                driver.close();
                // 将句柄切换到主页面
                driver.switchTo().window(mainWindowHandle);
                Thread.sleep(2000);
            }
            // 点击下一页
            nextPage.click();
            Thread.sleep(1000);
            // 判断下一页元素是否存在,不存在则捕获异常并将下一页元素赋值为null
            try {
                nextPage = driver.findElement(By.xpath("//a[text()='下一页']"));
            } catch (Exception e) {
                nextPage = null;
                System.out.println("没有下一页了");
            }
        }
    }
}

问题现象

代码完成之后,执行代码。前 12 个元素执行均正常,但是执行到 13 个元素(从0到1落地微前端架构, MicroApp实战招聘网站)时,报NoSuchElementException 错误,即元素信息未找到。

软件测试学习笔记丨Seleium的BUG:页面元素文案重复空格处理_软件测试

问题分析

看到报错信息是NoSuchElementException,元素找不到。

首先查看报错的行数,第 68 行,即:driver.findElement(By.xpath(“//p[text()='” + courseName + “']”)).click();

由于这个是第 13 个元素信息,前 12 个元素信息均正常执行,无报错。则说明代码上没有问题。

那重点就关注到courseName(课程名字)这个参数。

通过打印信息,代码中获取到 courseName 文案为: 从0到1落地微前端架构, MicroApp实战招聘网站

通过网站的开发者工具,获取到页面中的 courseName 文案为:从0到1落地微前端架构, MicroApp实战招聘网站

通过对比,发现两者的区别在于在 MicroApp 前面,代码中获取到文案只有 1 个空格,而开发者工具获取到的文案有两个空格。

故导致后续的元素定位失败。

问题解决

通过百度等搜索,发现在2022 年 6 月的时候 Selenium 的 github 上就一个这样的 issues:getText() returns inconsistent result across browsers when element text contains redundant whitespaces

此 issues 上遇到的问题,即和我遇到的问题一样,在元素信息中有两个或者两个以上的空格,但是通过 getText()方法获取到的文案,只有一个空格。

软件测试学习笔记丨Seleium的BUG:页面元素文案重复空格处理_软件测试_02

看到该issues 在 2022 年 10 月显示关闭,第一想法就是更新下selenium-java的版本。于是将 pom 文件的selenium-java版本从 4.0.0-rc-2 升级到 4.15.0 版本。

PS:

selenium-java 在 4.8.0 版本开始 Java 的版本需要再 Java 11 及其以上版本

Java8 版本是无法运行selenium-java 的 4.8.0 以及以上版本的。

如执行,则会报如下错误:

软件测试学习笔记丨Seleium的BUG:页面元素文案重复空格处理_java_03

升级到 4.15.0 版本之后,再次执行代码。发现错误依旧,即issues 关闭了,但是 pr 还没提成功,那没有办法只能尝试其他办法了。

在升级selenium-java版本无效之后,只有尝试万能的 JS 大法。通过 Js 获取到页面元素的文案信息。

即:

String text = (String)js.executeScript(“return arguments[0].innerHTML”, element);

String text = (String)js.executeScript(“return arguments[0].textContent”, element);

代码调整`

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class imoocTest {
    private static WebDriver driver;

    @BeforeAll
    static void setUP() {
        // 获取当前文件下所在的目录
        String currentDirectory = System.getProperty("user.dir");
        // 设置chromeDriver
        System.setProperty("webdriver.chrome.driver", currentDirectory + "/src/test/resources/Driver/Chrome/chromedriver");
        ChromeOptions options = new ChromeOptions();
        //浏览器模拟手机模式
        options.addArguments("--disable-web-security");
        // 最大化窗口
        options.addArguments("--start-maximized");
        //解决报 403 问题
        options.addArguments("--remote-allow-origins=*");
        driver = new ChromeDriver(options);
        // 隐式调用
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
    }

    @AfterAll
    static void tearDown() {
        //关闭浏览器
        driver.quit();
    }

    @Test
    public void test() throws InterruptedException {
        // 打开慕课网实战的页面
        driver.get("https://coding.imooc.com/");
        // 获取当前页面的句柄
        String mainWindowHandle = driver.getWindowHandle();
        // 将driver转换为JavascriptExecutor以便执行JavaScript代码
        JavascriptExecutor js = (JavascriptExecutor) driver;
        // 获取下一页按钮的元素
        WebElement nextPage = driver.findElement(By.xpath("//a[text()='下一页']"));
        // 判断下一页按钮是否存在
        while (nextPage != null) {
            // 获取当前页面的所有课程名称
            List<WebElement> courseNameList = driver.findElements(By.cssSelector(".title.ellipsis2"));
            for (int i = 0; i < courseNameList.size(); i++) {
                // 获取当前课程并且点击进入详情页面
                String courseName =(String)js.executeScript("return arguments[0].textContent", courseNameList.get(i));
                System.out.println(i + ":获取到的课程名称1:" + courseName);
                driver.findElement(By.xpath("//p[text()='" + courseName + "']")).click();
                Thread.sleep(2000);
                // 获取浏览器所有的窗口句柄
                Set<String> allWindowHandles = driver.getWindowHandles();
                for (String windowHandle : allWindowHandles) {
                    if (!windowHandle.equals(mainWindowHandle)) {
                        driver.switchTo().window(windowHandle);
                        break;
                    }
                }
                driver.close();
                driver.switchTo().window(mainWindowHandle);
                Thread.sleep(2000);
            }
            nextPage.click();
            Thread.sleep(1000);
            try {
                nextPage = driver.findElement(By.xpath("//a[text()='下一页']"));
            } catch (Exception e) {
                nextPage = null;
                System.out.println("没有下一页了");
            }
        }
    }
}

脚本执行成功,无异常报错。执行结果如下:

软件测试学习笔记丨Seleium的BUG:页面元素文案重复空格处理_java_04


标签:java,String,selenium,Seleium,driver,org,import,BUG,软件测试
From: https://blog.51cto.com/u_16547786/9587251

相关文章

  • 软件测试学习笔记丨App自动化基础
    查看设备IDadbdevices查看设备的Android系统版本adbshellgetpropro.build.version.r-elease查看想要启动app的包名adbshellpmlistpackages查看想要启动app的启动页面adbshellmonkey-p${package.name}-vvv1获取app的启动页面adblogcat|grep-idisplayedadb......
  • 软件测试|人工智能:测试开发的新宠儿
    测试管理班是专门面向测试与质量管理人员的一门课程,通过提升从业人员的团队管理、项目管理、绩效管理、沟通管理等方面的能力,使测试管理人员可以更好的带领团队、项目以及公司获得更快的成长。提供1v1私教指导,BAT级别的测试管理大咖量身打造职业规划。测试是发现问题的艺术,而人......
  • mit6.824lab2D-Debug记录
    1.死锁要提交快照的时候由于没有人取走applyCh通道里面的东西,导致死锁。具体解释:2D的测试代码中在日志达到一定大小时会调用snapshot,该函数需要申请rf.mu这个互斥锁。而在提交普通的日志条目时,错误地没有先释放锁,导致snapshot无法进行下去,相关的进程卡在rf.mu这个锁上,无法完成......
  • 软件测试的常用指标和度量方法总结,如何进行测试效果评估和质量度量?
    前言大家好,我是chowley,我总结了一些测试的常用指标和度量方法,今天总结成博客发出来和大家一起探讨!软件测试是确保软件质量的关键步骤之一。为了全面评估测试的效果和软件的质量,我们需要依赖一系列的指标和度量方法。常用指标和度量方法1.代码覆盖率(CodeCoverage)代码覆盖率度......
  • Qt Access violation - code c0000005 debug write access violation
    WhentryingtodebugmyQtapplication,theappthrowaexceptionas"Exceptionat0x77da2073,code:0xc0000005:writeaccessviolationat:0x1,flags=0x0"IamusingQtcreatorandvs2005compileranddebugger. Iloadtheprojectonvs2005a......
  • 如何用Python调试 debug
    什么是调试,为什么我们需要调试这里借用南京大学蒋炎岩老师的ppt在计算机中,我们将机器看作状态机,同时我们遵循计算机不会犯错的原则,因此,当你设计的程序产生了与你意料相悖的结果,那就可以认为你的程序产生了bug。调试理论中的状态机我们将程序可以看成一个状态机,程序的不断......
  • PHPYUN人才招聘系统V7.0_VIP版更新包(20240101)中若干bug的修复解析及上架小程序过程
    没想到这么大的一个php开发者会遇到若干小bug问题,以前正常运行的程序升级到7.0后出现莫名奇妙的问题,比如模板消息不能使用了,完全收不到消息,后来才知道因为改版代码里出现了Bug,在比如网络招聘申请环节没反应,也是bug可能这次更新较大没注意把还好我自己解决了把解决过程分享出来!......
  • 软件测试/测试管理|项目启动:成功开启新征程的关键一步
    测试管理班是专门面向测试与质量管理人员的一门课程,通过提升从业人员的团队管理、项目管理、绩效管理、沟通管理等方面的能力,使测试管理人员可以更好的带领团队、项目以及公司获得更快的成长。提供1v1私教指导,BAT级别的测试管理大咖量身打造职业规划。在项目管理中,项目启动......
  • 软件测试/测试管理|需求管理:与产品经理沟通与解决不规范、不清晰和频繁变更的方法
    测试管理班是专门面向测试与质量管理人员的一门课程,通过提升从业人员的团队管理、项目管理、绩效管理、沟通管理等方面的能力,使测试管理人员可以更好的带领团队、项目以及公司获得更快的成长。提供1v1私教指导,BAT级别的测试管理大咖量身打造职业规划。在测试管理的角色中,与......
  • 软件测试/测试开发/全日制|Pytest allure如何添加测试用例步骤
    前言在编写自动化测试用例的时候经常会遇到需要编写流程性测试用例的场景,一般流程性的测试用例的测试步骤比较多,我们在测试用例中添加详细的步骤会提高测试用例的可阅读性。在allure提供给我们的众多装饰器中,就有一个非常符合我们的需求,它就是allure.step(),它可以帮助我们在测试用......