Selenium Java类外访问PageObject元素报空指针异常排查
问题定位
报错抛出空指针的位置是AllBotsPage.selectBot()方法内调用wd.findElement()的行,核心问题有3个:
- 页面对象实例化时机错误。测试代码里先创建了
AllBotsPage实例,之后才调用wLogin()方法。从代码结构看,BaseClass中的wd驱动实例是在wLogin()执行流程中才完成初始化、并跳转到对应业务页面的,创建albot对象时传入的wd本身就是null,调用其方法必然触发空指针。 @FindBy注入的页面元素错误使用了static修饰。PageFactory是针对类实例做元素代理初始化的,静态字段属于类本身,不会被代理注入,后续调用messageIcon、newTab这两个静态元素时同样会触发空指针。selectBot方法内XPath语法错误。谓词中嵌套的路径使用了//开头的绝对路径,不符合XPath语法规则,即使wd正常初始化,该路径也无法定位到目标元素。
修复方案
- 调整测试类中页面对象的实例化顺序,先完成登录、页面跳转,待wd初始化完成且导航到目标页面后,再实例化对应页面对象:
public class Whatsapp extends Baseclass { @Test public void Whtsapp() { // 先执行登录流程,完成驱动初始化、页面跳转 wLogin("Auto@test.com","Rak@1234"); // 进入对应页面后再初始化页面对象 AllBotsPage albot = new AllBotsPage(wd); WhatsAppPage whtsapp = new WhatsAppPage(md); albot.selectBot("Autobot"); albot.messageIcon.click(); albot.setAgentOnline(true); System.out.println("sending a message from whatsapp"); startApp("whtsapp"); whtsapp.searchButton.click(); whtsapp.searcTextbox.sendKeys("D360 26"); whtsapp.searchResult.click(); whtsapp.sendTextmsg.sendKeys("Hello Appium"); whtsapp.sendButton.click(); albot.newTab.click(); albot.searchUser.sendKeys("9535143660"); albot.startConversationButton.click(); albot.verifyMessage("Hello Appium"); albot.resolveChatOptions.click(); albot.resolveConversation.click(); albot.confirmResolveChat.click(); } }
- 移除页面对象类中WebElement字段的
static修饰符,所有@FindBy标注的元素都定义为实例字段:
// 移除static修饰 @FindBy(how = How.XPATH, using = "//*[@id='bui-8__anchor']") public WebElement messageIcon; @FindBy(xpath = "//button[contains(text(),'New')]") public WebElement newTab;
- 修正
selectBot方法中的XPath语法,把谓词内的绝对路径改为相对路径,同时恢复显式等待逻辑,避免页面未加载完成就触发元素查找:
public void selectBot( String name){ String a = "//*[@class='botcard__namewrapper' and .//span[contains(text(),'"+name+"')]]"; WebDriverWait wait = new WebDriverWait(wd,Duration.ofSeconds(10)); wait.until(ExpectedConditions.elementToBeClickable(By.xpath(a))).click(); }
- 额外修复
verifyMessage方法的逻辑bug:该方法if语句后多写了分号,无论是否找到目标元素都会固定返回true,修正后逻辑如下:
public boolean verifyMessage(String value){ WebElement targetMsg = new WebDriverWait(wd, Duration.ofSeconds(10)) .until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[normalize-space()='"+value+"'])[2]"))); return targetMsg.getText().contains(value); }
内容的提问来源于stack exchange,提问作者user3194257
相关产品推荐
相关产品推荐

