在上一篇文章中,我们了解了 JavaScriptExecutor 的基本概念和原理。今天,让我们撸起袖子,通过两个完整的实战案例来深入体验这个强大工具的魅力。

实战演练:登录页面自动化

让我们通过一个接地气的例子来看看 JavaScriptExecutor 的威力。我们要在 LambdaTest 电子商务演练网站上实现以下测试场景:

  1. 导航到账户登录页面
  2. 输入登录凭据,并通过红色边框高亮显示字段(就像是给重要内容划重点
  3. 点击登录按钮
  4. 打印页面标题和域名
  5. 验证登录成功

环境准备

首先,我们需要搭建测试舞台

代码实现

创建测试类的骨架

public class TestJavaScriptExecutor {
    // 在类级别声明 WebDriver,因为需要在多个方法中使用
    private WebDriver driver;

    @BeforeTest
    public void setup() {
        // 启动 Chrome 浏览器,就像是打开工具箱
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        // 设置 30 秒隐式等待,让页面内容充分加载
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30));
    }

    @AfterTest
    public void tearDown() {
        // 优雅地关闭浏览器,就像是收拾工具箱
        driver.quit();
    }
}

核心测试方法实现:

@Test
public void testJavaScriptExecutorCommand() {
    // 导航到登录页面
    driver.get("https://***/index.php?route=account/login");

    // 创建 JavaScriptExecutor 实例,就像是拿起魔法棒
    JavascriptExecutor js = (JavascriptExecutor) driver;

    // 处理邮箱字段:定位 -> 高亮 -> 输入 -> 恢复
    WebElement emailAddressField = driver.findElement(By.id("input-email"));
    js.executeScript("arguments[0].style.border='3px solid red'", emailAddressField);
    emailAddressField.sendKeys("FunTester@demo.com");
    js.executeScript("arguments[0].style.border='2px solid #ced4da'", emailAddressField);

    // 处理密码字段:同样的套路
    WebElement passwordField = driver.findElement(By.id("input-password"));
    js.executeScript("arguments[0].style.border='3px solid red'", passwordField);
    passwordField.sendKeys("FunTester123");
    js.executeScript("arguments[0].style.border='2px solid #ced4da'", passwordField);

    // 处理登录按钮:高亮并点击
    WebElement loginBtn = driver.findElement(By.cssSelector("input.btn"));
    js.executeScript("arguments[0].style.border='3px solid red'", loginBtn);
    js.executeScript("arguments[0].click();", loginBtn);

    // 获取页面信息,就像是收集战利品
    String titleText = js.executeScript("return document.title;").toString();
    System.out.println("Page Title is: " + titleText);

    String domainName = js.executeScript("return document.domain;").toString();
    System.out.println("Domain is: " + domainName);

    // 验证登录成功
    String myAccountHeader = driver.findElement(By.cssSelector("#content h2")).getText();
    assertEquals(myAccountHeader, "My Account");
}

代码解析

这段代码的精妙之处在于:

1. 视觉反馈机制

使用红色边框高亮字段,让测试执行过程一目了然。这不仅有助于调试,还能让观看测试执行的人清楚地看到当前操作的元素:

js.executeScript("arguments[0].style.border='3px solid red'", emailAddressField);

2. JavaScript 点击的优势

通过 JavaScript 直接点击按钮,避免了可能的点击失效问题。相比传统的 element.click(),JavaScript 点击更加稳定可靠

js.executeScript("arguments[0].click();", loginBtn);

3. 页面信息获取

直接获取页面的 title 和 domain,比传统方法更直接高效

String titleText = js.executeScript("return document.title;").toString();
String domainName = js.executeScript("return document.domain;").toString();

异步操作实战:页面滚动

让我们再来看一个使用 executeAsyncScript() 的例子,实现以下测试场景:

  1. 导航到 LambdaTest 电子商务演练网站主页
  2. 滚动到页面底部
  3. 验证页面底部显示 FROM THE BLOG 文本
@Test
public void testExecuteAsyncScript() {
    driver.get("https://ecommerce-playground.lambdatest.io");
    JavascriptExecutor js = (JavascriptExecutor) driver;

    // 异步滚动到页面底部,就像是坐电梯到顶楼
    js.executeAsyncScript("var callback = arguments[arguments.length - 1];" + 
                         "window.scrollBy(0,document.body.scrollHeight);" + 
                         "callback();");

    // 验证滚动结果
    String fromTheBlogText = driver.findElement(By.cssSelector("#entry_217991 > h3")).getText();
    assertEquals(fromTheBlogText, "FROM THE BLOG");
}

异步操作详解

这里的关键是 callback() 函数,它就像是信号灯,告诉系统异步操作已经完成。在 executeAsyncScript() 方法中,执行的脚本必须通过显式调用提供的 callback() 方法来发出完成信号。

异步脚本的结构

var callback = arguments[arguments.length - 1];  // 获取回调函数
// 执行异步操作
window.scrollBy(0,document.body.scrollHeight);
callback();  // 通知操作完成

为什么使用异步方法

实战技巧总结

1. 元素高亮技巧

在测试执行过程中高亮元素,不仅有助于调试,还能提升测试的可视化效果:

// 高亮元素
js.executeScript("arguments[0].style.border='3px solid red'", element);
// 恢复原样
js.executeScript("arguments[0].style.border='2px solid #ced4da'", element);

2. 强制点击技巧

当元素被遮挡或不在视口中时,JavaScript 点击比常规点击更可靠

js.executeScript("arguments[0].click();", element);

3. 页面信息获取技巧

直接通过 JavaScript 获取页面信息,比 WebDriver API 更直接高效

String title = js.executeScript("return document.title;").toString();
String url = js.executeScript("return document.URL;").toString();
String domain = js.executeScript("return document.domain;").toString();

4. 滚动操作技巧

JavaScript 提供了更灵活的滚动控制:

// 滚动到元素位置
js.executeScript("arguments[0].scrollIntoView(true);", element);
// 滚动指定距离
js.executeScript("window.scrollBy(0, 500);");
// 滚动到页面底部
js.executeScript("window.scrollBy(0, document.body.scrollHeight);");

常见问题与解决方案

问题 1:元素点击失效

现象:使用 element.click() 无法点击元素
解决方案:使用 JavaScript 强制点击

js.executeScript("arguments[0].click();", element);

问题 2:页面滚动不到位

现象:元素不在视口中,无法操作
解决方案:先滚动到元素位置

js.executeScript("arguments[0].scrollIntoView(true);", element);

问题 3:异步操作时机不准确

现象:操作执行过早或过晚
解决方案:使用 executeAsyncScript() 精确控制时机

js.executeAsyncScript("var callback = arguments[arguments.length - 1]; /* 异步操作 */ callback();");

总结

通过这两个实战案例,我们深入体验了 JavaScriptExecutor 在实际项目中的应用。从同步操作到异步操作,从元素交互到页面信息获取,JavaScriptExecutor 展现了其强大的能力和灵活性。


FunTester 原创精华


↙↙↙阅读原文可查看相关链接,并与作者交流