使用Java Selenium切换标签页时遇数组越界问题求助
问题分析与修复方案
核心问题
- 数组越界异常:代码中
ArrayList<String> tabs3 = new ArrayList<>(driver.getWindowHandles());在创建新标签页前执行,后续新增标签页、重新初始化ChromeDriver后,tabs3未更新,仍保留旧窗口句柄集合,此时用tabs3.get(2)或tabs3.get(1)访问必然超出集合长度。 - 标签页无法聚焦:切换窗口时依赖过时的句柄集合,导致WebDriver定位不到目标标签页,无法完成聚焦操作。
- 冗余操作干扰流程:大量无意义的
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
相关产品推荐
相关产品推荐

