Java+Selenium+TestNG实现Reddit弹窗登录按钮自动化测试问题
Reddit登录自动化:无法定位弹窗登录按钮问题解决
问题描述
使用Java/Selenium实现Reddit自动化登录,已完成访问网站、点击登录按钮、弹出登录框、填写用户名和密码步骤,但始终无法定位并点击弹窗中的登录按钮,即使添加1秒等待仍报noSuchElement错误。已知按钮在密码符合长度要求前处于禁用状态。
登录按钮截图:
现有代码
package org.example; import org.openqa.selenium.*; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.edge.EdgeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.Test; import java.util.Iterator; import java.util.Set; public class TestCases { String userName = "ThrowAwayTestingbot"; String password = "CEN4072!"; WebDriver create_driver( char browser){ if(browser == 'c'){ System.setProperty("webdriver.chrome.driver","C:\\Users\\pr0je\\Desktop\\Spring2024\\CEN4072 - Software Testing\\FinalGroupProject\\src\\main\\java\\org\\example\\chromedriver.exe"); return new ChromeDriver(); }else if(browser == 'f'){ System.setProperty("webdriver.gecko.driver","C:\\Users\\pr0je\\Desktop\\Spring2024\\CEN4072 - Software Testing\\FinalGroupProject\\src\\main\\java\\org\\example\\geckodriver.exe"); return new FirefoxDriver(); }else if(browser == 'e'){ System.setProperty("webdriver.chrome.driver","C:\\Users\\pr0je\\Desktop\\Spring2024\\CEN4072 - Software Testing\\FinalGroupProject\\src\\main\\java\\org\\example\\msedgedriver.exe"); return new EdgeDriver(); } else System.out.println("Sorry, we could not start a browser. Attempting to start Chrome."); return new ChromeDriver(); } WebDriver driver = create_driver('c'); @Test void test_sign_in() throws InterruptedException { // Visit Reddit.com driver.get("https://www.reddit.com"); driver.manage().window().maximize(); String mainWindow = driver.getWindowHandle(); String popUp = null; WebElement button = driver.findElement(By.id("login-button")); button.click(); Thread.sleep(2000); // Get PopUp Info Set<String> handles = driver.getWindowHandles(); Iterator<String> iterator = handles.iterator(); while(iterator.hasNext()){ popUp = iterator.next(); } driver.switchTo().window(popUp); driver.findElement(By.id("login-username")).sendKeys(userName); Thread.sleep(250); driver.findElement(By.id("login-password")).sendKeys(password); Thread.sleep(1000); } // End of Sign In Test } // END OF TestCases Class
已尝试的定位方式
// By Class(错误用法) button = driver.findElement(By.className("login w-100\n" + "button-large px-[var(--rem14)]\n" + "button-brand\n" + "\n" + "\n" + "\n" + "items-center justify-center\n" + "button inline-flex ")); button.click(); // By xPath(路径不准确) button = driver.findElement(By.xpath("//*[@id=\"login\"]/faceplate-tabpanel/auth-flow-modal[1]/div[2]/faceplate-tracker")); button.click(); // By Selector(语法错误+路径不准确) button = driver.findElement(By.cssSelector("login > faceplate-tabpanel > auth-flow-modal:nth-child(1) > div.w-100 > faceplate-tracker > button")); button.click();
问题分析与解决方案
1. 核心错误:错误切换窗口
Reddit的登录弹窗是当前页面内的模态框,并非新浏览器窗口。你代码中切换到新窗口的操作会导致上下文错误,无法定位原页面内的弹窗元素,直接移除窗口切换代码即可。
2. 定位方式的错误修正
- By.className不能传入多个类名:
By.className()仅支持单个类名,多类名需用CSS选择器(如.button-brand.button-large)。 - XPath/CSS选择器路径错误:Reddit登录按钮所在的弹窗包含自定义元素(如
faceplate-tabpanel),需用更稳定的属性定位,比如按钮的type="submit"或aria-label属性。
3. 替换Thread.sleep为显式等待
硬编码等待时间不稳定,改用Selenium的显式等待,等待按钮变为可点击状态,确保元素已加载完成且解除禁用。
修正后的完整代码
package org.example; import org.openqa.selenium.*; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.edge.EdgeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.Test; import java.time.Duration; public class TestCases { String userName = "ThrowAwayTestingbot"; String password = "CEN4072!"; WebDriver create_driver(char browser) { if (browser == 'c') { System.setProperty("webdriver.chrome.driver", "C:\\Users\\pr0je\\Desktop\\Spring2024\\CEN4072 - Software Testing\\FinalGroupProject\\src\\main\\java\\org\\example\\chromedriver.exe"); return new ChromeDriver(); } else if (browser == 'f') { System.setProperty("webdriver.gecko.driver", "C:\\Users\\pr0je\\Desktop\\Spring2024\\CEN4072 - Software Testing\\FinalGroupProject\\src\\main\\java\\org\\example\\geckodriver.exe"); return new FirefoxDriver(); } else if (browser == 'e') { System.setProperty("webdriver.edge.driver", "C:\\Users\\pr0je\\Desktop\\Spring2024\\CEN4072 - Software Testing\\FinalGroupProject\\src\\main\\java\\org\\example\\msedgedriver.exe"); return new EdgeDriver(); } else { System.out.println("Sorry, we could not start a browser. Attempting to start Chrome."); return new ChromeDriver(); } } WebDriver driver = create_driver('c'); @Test void test_sign_in() { // Visit Reddit.com driver.get("https://www.reddit.com"); driver.manage().window().maximize(); // 初始化显式等待,超时时间10秒 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); // 点击登录按钮,等待按钮可点击 WebElement loginBtn = wait.until(ExpectedConditions.elementToBeClickable(By.id("login-button"))); loginBtn.click(); // 等待用户名输入框可见并输入用户名 WebElement usernameInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login-username"))); usernameInput.sendKeys(userName); // 等待密码输入框可见并输入密码 WebElement passwordInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login-password"))); passwordInput.sendKeys(password); // 等待登录按钮可点击并点击(自动等待按钮解除禁用) WebElement submitBtn = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button[type='submit'].button-brand"))); submitBtn.click(); } // End of Sign In Test } // END OF TestCases Class
其他可选定位方式
如果上述CSS选择器失效,可尝试以下定位方式:
- 通过
aria-label定位:By.cssSelector("button[aria-label='Log In']") - 通过文本定位(需注意文本可能随语言变化):
By.xpath("//button[text()='Log In']")
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

