如何使用Selenium点击Angular应用中无响应的Start new booking按钮
Selenium操作Angular站点按钮无法点击的解决方案
核心原因排查
- 定位规则错误:
By.className("mat-button-wrapper")是Angular Material组件库的通用子元素类,全站所有mat-button按钮都会包含该类名元素,Selenium默认匹配第一个DOM元素,大概率是页面内不可见的隐藏元素,无法触发有效点击 - 异步渲染等待缺失:仅在首次打开页面时调用了
ngWebDriver.waitForAngularRequestsToFinish(),登录跳转后Angular会重新发起异步请求、渲染页面,未等待渲染完成就执行点击操作,此时目标按钮还未挂载到DOM中 - 交互状态未就绪:Angular Material按钮存在加载过渡、懒加载逻辑,即使DOM节点已存在,也可能处于
disabled或事件未绑定完成的状态,常规点击无法触发Angular的(click)绑定事件
可行修复方案
代码修改要点
- 登录完成后先等待Angular异步请求全部结束
- 优先使用NgWebDriver提供的Angular专属定位方式,避免通用类名/绝对路径Xpath定位
- 增加显式等待判定按钮可交互,必要时使用JS强制点击兼容Angular事件机制
修改后示例代码
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.chrome.ChromeDriver; import com.paulhammant.ngwebdriver.ByAngular; import com.paulhammant.ngwebdriver.NgWebDriver; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; public class NewClass { public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.chrome.driver", "C:\\Users\\Hp\\Downloads\\chromedriver_win32\\chromedriver.exe"); ChromeDriver driver = new ChromeDriver(); NgWebDriver ngWebDriver = new NgWebDriver(driver); ngWebDriver.waitForAngularRequestsToFinish(); driver.get("https://visa.vfsglobal.com/gbr/en/mlt/login"); driver.manage().window().maximize(); WebDriverWait wait = new WebDriverWait(driver, 30); wait.until(ExpectedConditions.elementToBeClickable(By.id("onetrust-accept-btn-handler"))).click(); // 登录操作 driver.findElement(By.id("mat-input-0")).sendKeys("*****@gmail.com"); driver.findElement(By.id("mat-input-1")).sendKeys("password"); // 替换登录按钮的绝对Xpath为更稳定的定位方式,这里保留原有逻辑可自行优化 driver.findElement(By.xpath("/html/body/app-root/div/app-login/section/div/div/mat-card/form/button")).click(); // ========== 以下为新增/修改内容 ========== // 等待登录跳转后Angular渲染完成 ngWebDriver.waitForAngularRequestsToFinish(); // 使用Angular专属定位方式匹配按钮文本,稳定性远高于通用类名 WebElement startBookingBtn = wait.until(ExpectedConditions.elementToBeClickable( ByAngular.buttonText("Start new booking") )); // 优先用原生点击,失败则用JS强制触发点击 try { startBookingBtn.click(); } catch (Exception e) { JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].click();", startBookingBtn); } } }
如果按钮文本存在空格/大小写差异,也可以替换定位方式为By.xpath("//button[contains(normalize-space(text()),'Start new booking')]")即可兼容。
内容的提问来源于stack exchange,提问作者Anox Software technology
相关产品推荐
相关产品推荐

