如何获取Selenium WebDriver最近执行的XPath?
问题
我有一个clickButton方法,里面包含多个try-catch代码块,每个块用不同的XPath定位元素并执行点击操作。原本想在每个try-catch里返回对应的XPath,但这样修改量太大、太耗时,所以想找不用大量改代码的办法,直接通过WebDriver获取最近执行的XPath,类似driver.getLastXpath()的功能(已知WebDriver本身没有这个方法)。
相关代码示例如下:
public void actions(String action, String param, Webdriver driver){ switch(action){ case "Click Button": clickButton(driver, param); } } public void clickButton(Webdriver driver, String param){ try{ if (param.equalsIgnoreCase("Search")) { WebElement waittext = driver.findElement(By.xpath("xpath for search button")); Actions actions = new Actions(driver); actions.moveToElement(waittext).build().perform(); waittext.click(); return; }catch(Exception e){ System.out.println(e); } try{ if (param.equalsIgnoreCase("Save")) { WebElement waittext = driver.findElement(By.xpath("xpath for save button")); Actions actions = new Actions(driver); actions.moveToElement(waittext).build().perform(); waittext.click(); return; }catch(Exception e){ System.out.println(e); } // 更多类似的try-catch块... }
我想要实现的效果类似下面的代码:
public void actions(String action, String param, Webdriver driver){ switch(action){ case "Click Button": clickButton(driver, param); String recentlyUsedXpath = driver.getLastXpath(); // 想要这样的功能 } }
方案1:自定义封装XPath定位器,自动记录最后使用的XPath
这个方案改动极小,只需要替换原代码里的By.xpath()调用即可,完全不用修改try-catch结构。
实现步骤
- 创建工具类
CustomBy,维护静态变量存储最后使用的XPath:
public class CustomBy { private static String lastUsedXpath; public static By xpath(String xpathExpression) { lastUsedXpath = xpathExpression; return By.xpath(xpathExpression); } public static String getLastUsedXpath() { return lastUsedXpath; } }
- 修改
clickButton方法里的定位方式:
// 替换原有的By.xpath为CustomBy.xpath WebElement waittext = driver.findElement(CustomBy.xpath("xpath for search button"));
- 在需要获取的地方调用工具类方法:
public void actions(String action, String param, Webdriver driver){ switch(action){ case "Click Button": clickButton(driver, param); String recentlyUsedXpath = CustomBy.getLastUsedXpath(); // 获取最近XPath } }
方案2:轻微修改clickButton方法,返回成功执行的XPath
虽然你担心修改量大,但实际只需要给方法增加返回值,在每个成功分支返回对应XPath即可,改动量远小于逐个修改try-catch:
修改后的代码
// 修改方法返回类型为String public String clickButton(Webdriver driver, String param){ try{ if (param.equalsIgnoreCase("Search")) { String xpath = "xpath for search button"; WebElement waittext = driver.findElement(By.xpath(xpath)); Actions actions = new Actions(driver); actions.moveToElement(waittext).build().perform(); waittext.click(); return xpath; // 返回成功使用的XPath }catch(Exception e){ System.out.println(e); } try{ if (param.equalsIgnoreCase("Save")) { String xpath = "xpath for save button"; WebElement waittext = driver.findElement(By.xpath(xpath)); Actions actions = new Actions(driver); actions.moveToElement(waittext).build().perform(); waittext.click(); return xpath; // 返回成功使用的XPath }catch(Exception e){ System.out.println(e); } // 更多分支同理 return null; // 无成功执行时返回null }
调用处接收返回值:
public void actions(String action, String param, Webdriver driver){ switch(action){ case "Click Button": String recentlyUsedXpath = clickButton(driver, param); // 使用获取到的XPath } }
方案3:使用WebDriver事件监听(进阶)
通过EventFiringWebDriver监听元素查找事件,完全不需要修改业务代码,只需配置监听器:
实现步骤
- 创建事件监听器,记录XPath:
public class XPathRecorder implements WebDriverEventListener { private String lastUsedXpath; @Override public void beforeFindBy(By by, WebElement element, WebDriver driver) { if (by instanceof By.ByXPath) { // 提取并存储XPath字符串 lastUsedXpath = ((By.ByXPath) by).toString().replace("By.xpath: ", ""); } } // 其他未使用的接口方法留空实现 @Override public void afterFindBy(By by, WebElement element, WebDriver driver) {} @Override public void beforeClickOn(WebElement element, WebDriver driver) {} @Override public void afterClickOn(WebElement element, WebDriver driver) {} // ... 剩余接口方法均留空或默认实现 public String getLastUsedXpath() { return lastUsedXpath; } }
- 初始化带监听的WebDriver:
WebDriver originalDriver = new ChromeDriver(); XPathRecorder recorder = new XPathRecorder(); EventFiringWebDriver driver = new EventFiringWebDriver(originalDriver); driver.register(recorder);
- 获取最近使用的XPath:
public void actions(String action, String param, WebDriver driver){ switch(action){ case "Click Button": clickButton(driver, param); String recentlyUsedXpath = recorder.getLastUsedXpath(); } }
内容的提问来源于stack exchange,提问作者Uday Pratap Singh
相关产品推荐
相关产品推荐

