You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java Selenium切换标签页时遇数组越界问题求助

问题分析与修复方案

核心问题

  1. 数组越界异常:代码中ArrayList<String> tabs3 = new ArrayList<>(driver.getWindowHandles());在创建新标签页前执行,后续新增标签页、重新初始化ChromeDriver后,tabs3未更新,仍保留旧窗口句柄集合,此时用tabs3.get(2)或tabs3.get(1)访问必然超出集合长度。
  2. 标签页无法聚焦:切换窗口时依赖过时的句柄集合,导致WebDriver定位不到目标标签页,无法完成聚焦操作。
  3. 冗余操作干扰流程:大量无意义的driver.navigate().forward()调用、固定时长的Thread.sleep会降低代码稳定性,干扰页面加载逻辑。

修复步骤

  • 动态获取窗口句柄:每次切换标签页前,重新获取当前所有窗口句柄,不依赖提前保存的旧集合。
  • 统一Driver实例:避免中途替换Driver对象,否则原Driver的窗口句柄会完全失效,用单个Driver完成全流程操作。
  • 替换固定等待为显式等待:用WebDriverWait等待元素可交互,替代不稳定的Thread.sleep。
  • 移除无效页面操作:删除无意义的forward()调用,仅在需要前进页面时使用。

修复后的代码示例

package Stripetesting;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.interactions.Actions;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class Plansinfirefox {
    public static void main(String[] args) throws InterruptedException, AWTException {
        // 统一使用ChromeDriver完成全流程
        System.setProperty("webdriver.chrome.driver", "/home/gt51022/Downloads/chromedriver_linux64/chromedriver");
        WebDriver driver = new ChromeDriver();
        WebDriverWait wait = new WebDriverWait(driver, 15);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(7, TimeUnit.SECONDS);

        // 主应用登录流程
        driver.get("https://app.ai/");
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"formBasicEmail\"]"))).sendKeys("wond@yopmail.com");
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("password"))).sendKeys("Qwerty@1");
        wait.until(ExpectedConditions.elementToBeClickable(By.className("checkmark"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"root\"]/div/div[2]/div/div/div[1]/div/div/form/button"))).click();

        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div/div[1]/ul/li[2]/a"))).click();
        // 选择团队
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div[2]/div[2]/div[3]/div/div/div[2]/div"))).click();
        // 添加新团队成员
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div/div[2]/div[2]/div[1]/div[2]/button"))).click();

        // 打开新标签页生成随机邮箱
        driver.switchTo().newWindow(WindowType.TAB);
        driver.get("http://www.yopmail.com");
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div[2]/main/div[3]/div/div[2]/div/a[1]/div[2]/h3"))).click();
        // 复制邮箱到剪贴板
        WebElement copyBtn = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//span[@class=\"notmobile\"])[2]")));
        Actions actions = new Actions(driver);
        actions.click(copyBtn).doubleClick().perform();

        // 切换回主应用标签页
        List<String> allTabs = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(allTabs.get(0));
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"formPlaintextEmail\"]"))).sendKeys(Keys.LEFT_CONTROL,"v");

        // 选择角色与权限
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[3]/div/div/form/div[2]/div[2]/div/div/div[1]/input[1]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[@id=\"basic-typeahead-multiple-item-16\"]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@id=\"teams\"]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[3]/div/div/form/div[2]/div[3]/div/div/div/div/div/span[1]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[3]/div/div/form/div[2]/div[3]/div/div/button"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class=\"btn btn-primary\"]"))).click();

        // 退出登录
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//img[@class=\"rounded-circle\"]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[@href=\"#\"]"))).click();

        // 切换到Yopmail标签页查看邀请邮件
        allTabs = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(allTabs.get(1));
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"login\"]"))).sendKeys(Keys.LEFT_CONTROL,"v");
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div[2]/main/div[3]/div/div[1]/div[2]/div/div/form/div/div/div[4]/button/i"))).click();

        driver.switchTo().frame("ifmail");
        wait.until(ExpectedConditions.elementToBeClickable(By.linkText("http://app.ambaram.ai/signup"))).click();

        // 切换到新打开的注册链接标签页
        allTabs = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(allTabs.get(2));
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("form-control"))).sendKeys("buyer");
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div/div/div[2]/div/div[1]/div/div/form/div[2]/input"))).sendKeys(Keys.LEFT_CONTROL,"v");
        wait.until(ExpectedConditions.elementToBeClickable(By.className("checkmark"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"root\"]/div/div[2]/div/div[1]/div/div/form/button"))).click();

        // 回到Yopmail标签页获取OTP
        allTabs = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(allTabs.get(1));
        driver.navigate().refresh();
        wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ifmail"));
        String strCode = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\"mail\"]/div/table/tbody/tr[3]/td/table/tbody/tr[1]/td/table/tbody/tr[5]/td/span"))).getText();
        System.out.println("----------------");
        System.out.println(strCode);
        System.out.println("----------------");

        // 切换到注册标签页输入OTP并完成注册
        allTabs = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(allTabs.get(2));
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("code1"))).sendKeys(strCode);
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class=\"otp btn btn-primary\"]"))).click();

        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@name=\"newPassword\"]"))).sendKeys("Qwert@1");
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@name=\"comfirmNewPass\"]"))).sendKeys("Qwert@1");
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class=\"otp btn btn-primary\"]"))).click();

        wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("email"))).sendKeys(Keys.LEFT_CONTROL,"v");
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("password"))).sendKeys("Qwert@1");
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[@class=\"checkmark\"]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class=\"btn btn-primary\"]"))).click();

        // 加入团队
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//span[@class=\"toggleHide\"])[2]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div/div[2]/div[2]/div[2]/span/div/button"))).click();

        // 修改头像
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//img[@class=\"rounded-circle\"]"))).click();
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/div[2]/div[2]/header/div/div[3]/div[3]/div/div/a[1]"))).click();
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("profilePicture"))).sendKeys("/home/gt51022/Downloads/ca-times.brightspotcdn.jpeg");
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class=\"activateBtn btn btn-primary\"]"))).click();

        // 返回仪表盘
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[@class=\"toggleHide\"]"))).click();

        driver.quit();
    }
}

内容的提问来源于stack exchange,提问作者Bug Hunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:41:45