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

Java+Selenium+TestNG实现Reddit弹窗登录按钮自动化测试问题

Reddit登录自动化:无法定位弹窗登录按钮问题解决

问题描述

使用Java/Selenium实现Reddit自动化登录,已完成访问网站、点击登录按钮、弹出登录框、填写用户名和密码步骤,但始终无法定位并点击弹窗中的登录按钮,即使添加1秒等待仍报noSuchElement错误。已知按钮在密码符合长度要求前处于禁用状态。

登录按钮截图:
Reddit登录按钮截图

现有代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:35:00