【问题标题】:Unable to initialise using @FindBy in selenium webdriver java无法在 selenium webdriver java 中使用 @FindBy 进行初始化
【发布时间】:2020-10-06 22:43:15
【问题描述】:

我正在尝试使用页面对象模式执行基本的 selenium 操作。但是,当我运行测试时,我看到浏览器与给定的 url 一起打开,但测试失败,因为抱怨它无法初始化声明的 web 元素。有人可以帮助我了解我在这里缺少什么。下面是我的基类、页面对象类和测试类。

基本页面

public class Basepage {

public static WebDriver driver;

public Basepage(){}

public Basepage(WebDriver driver){
    this.driver = driver;
    PageFactory.initElements(driver,this);
}

public void OpenBrowser(){
    System.setProperty("webdriver.chrome.driver", 
"C:\\SeleniumWork\\chromedriver_win32\\chromedriver.exe");
    driver = new ChromeDriver();
    driver.navigate().to("https://www.google.com");
}

页面对象类

public class SecurityMainPage extends Basepage{

public SecurityMainPage(WebDriver driver){
    this.driver = driver;
    PageFactory.initElements(driver,this);
}

@FindBy( xpath = "//a[text()='What We Do']")
WebElement dropdown;

public void selectOption(String option){
    Actions actions = new Actions(driver);
    actions.moveToElement(dropdown).click().build().perform();  //dropdown element is returning null 
}

测试类

public class SecurityMainPageTests extends Basepage {

protected static SecurityMainPage sec = new SecurityMainPage(driver);
public SecurityMainPageTests(){}

@BeforeTest
public void setup(){
    OpenBrowser();
}
@Test
public void selectOptionTest(){
    sec.selectOption("Networking");
}
@AfterTest
public void tearDown(){
    closeBrowser();
}

日志

org.openqa.selenium.json.JsonException: java.lang.reflect.InvocationTargetException
Build info: version: '3.13.0', revision: '2f0d292', time: '2018-06-25T15:24:21.231Z'
System info: host: 'LAPTOP-5J2KPMM3', ip: '192.168.0.36', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.7'
Driver info: driver.version: RemoteWebDriver

    at org.openqa.selenium.json.JsonOutput.convertUsingMethod(JsonOutput.java:302)
    at org.openqa.selenium.json.JsonOutput.lambda$new$13(JsonOutput.java:139)
    at org.openqa.selenium.json.JsonOutput$SafeBiConsumer.accept(JsonOutput.java:394)
    at org.openqa.selenium.json.JsonOutput.write(JsonOutput.java:248)
    at org.openqa.selenium.json.JsonOutput.lambda$null$18(JsonOutput.java:152)
    at java.base/java.lang.Iterable.forEach(Iterable.java:75)
    at org.openqa.selenium.json.JsonOutput.lambda$new$19(JsonOutput.java:152)
    at org.openqa.selenium.json.JsonOutput$SafeBiConsumer.accept(JsonOutput.java:394)
    at org.openqa.selenium.json.JsonOutput.write(JsonOutput.java:248)
    at org.openqa.selenium.json.JsonOutput.lambda$null$20(JsonOutput.java:161)
    at com.google.common.collect.SingletonImmutableBiMap.forEach(SingletonImmutableBiMap.java:65)
    at org.openqa.selenium.json.JsonOutput.lambda$new$21(JsonOutput.java:160)
    at org.openqa.selenium.json.JsonOutput$SafeBiConsumer.accept(JsonOutput.java:394)
    at org.openqa.selenium.json.JsonOutput.write(JsonOutput.java:248)
    at org.openqa.selenium.json.JsonOutput.write(JsonOutput.java:239)
    at org.openqa.selenium.json.Json.toJson(Json.java:42)
    at org.openqa.selenium.remote.http.AbstractHttpCommandCodec.encode(AbstractHttpCommandCodec.java:227)
    at org.openqa.selenium.remote.http.AbstractHttpCommandCodec.encode(AbstractHttpCommandCodec.java:117)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:152)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)
    at org.openqa.selenium.remote.RemoteWebDriver.perform(RemoteWebDriver.java:614)
    at org.openqa.selenium.interactions.Actions$BuiltAction.perform(Actions.java:638)
    at test.java.SecurityMainPage.selectOption(SecurityMainPage.java:37)
    at test.java.SecurityMainPageTests.selectOptionTest(SecurityMainPageTests.java:28)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:774)
    at org.testng.TestRunner.run(TestRunner.java:624)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
    at org.testng.SuiteRunner.run(SuiteRunner.java:261)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
    at org.testng.TestNG.run(TestNG.java:1024)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
    Suppressed: org.openqa.selenium.json.JsonException: Attempting to close incomplete json stream
Build info: version: '3.13.0', revision: '2f0d292', time: '2018-06-25T15:24:21.231Z'

Driver info: driver.version: RemoteWebDriver
        at org.openqa.selenium.json.JsonOutput.close(JsonOutput.java:263)
        at org.openqa.selenium.json.Json.toJson(Json.java:44)
        ... 32 more
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.openqa.selenium.json.JsonOutput.convertUsingMethod(JsonOutput.java:298)
    ... 47 more
Caused by: java.lang.NullPointerException
    at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
    at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
    at com.sun.proxy.$Proxy9.getWrappedElement(Unknown Source)
    at org.openqa.selenium.interactions.PointerInput$Origin.asArg(PointerInput.java:203)
    at org.openqa.selenium.interactions.PointerInput$Move.encode(PointerInput.java:154)
    at org.openqa.selenium.interactions.Sequence.encode(Sequence.java:75)
    at org.openqa.selenium.interactions.Sequence.toJson(Sequence.java:84)
    ... 52 more

【问题讨论】:

  • 请添加完整的异常堆栈跟踪。
  • 我认为问题出在protected static SecurityMainPage sec = new SecurityMainPage(driver);。您正在将一个名为 driver 的未启动参数传递给 SecurityMainPage 构造函数。
  • @kaweesha 我已经添加了完整的日志详细信息。另外,我在调试模式下运行测试,驱动程序在您提到的行显示 null 。任何克服这个问题的建议都会有所帮助。

标签: java selenium-webdriver pageobjects


【解决方案1】:

为了便于理解,我将驱动程序启动和导航到 url 拆分为 Basepage 中的两个方法。而且你还没有声明closeBrowser() 方法。

基类

public class Basepage {

    public static WebDriver driver;

    public Basepage(){}
 
    public Basepage(WebDriver driver){
        this.driver = driver;
        PageFactory.initElements(driver,this);
    }

    public WebDriver initiateDriver(){
        System.setProperty("webdriver.chrome.driver", 
        "C:\\SeleniumWork\\chromedriver_win32\\chromedriver.exe");
        driver = new ChromeDriver();
        return driver;
    }

    public void openBrowser(String url){
        driver.navigate().to(url);
    }
}

测试类

public class SecurityMainPageTests extends Basepage {

    WebDriver driver = null;
    protected static SecurityMainPage sec = null;
    String url = "https://www.google.com";

    public SecurityMainPageTests(){}

    @BeforeTest
    public void setup(){
        driver = initiateDriver();
        openBrowser(String url);
        sec = new SecurityMainPage(driver);
    }

    @Test
    public void selectOptionTest(){
        sec.selectOption("Networking");
    }

    @AfterTest
    public void tearDown(){
        closeBrowser();
    }
}

【讨论】:

  • 感谢您的解释。根据您的建议,我将页面对象代码的初始化移到 @BeforeTest 中,从而修复了测试。有什么方法可以在 @BeforeTest 之外初始化页面对象?
  • 你可以使用@BeforeSuite并写一个方法。在该方法中,您可以初始化页面对象。您不需要在页面工厂模型中的@BeforeTest 之外启动页面对象。参考这个tutorial
  • 感谢您的评论。我能够在 C# 页面对象模式中初始化 @BeforeTest@BeforeSuite 之外的页面对象。但是,我试图在 Java 中实现相同的目标。看起来我必须在用套件或测试注释的方法中初始化它们。
猜你喜欢
  • 1970-01-01
  • 2022-12-13
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多