2016-08-30 43 views
0

更新的代碼:@FindBy WebElements不是在PageFactory/Page對象框架被初始化

public class FlightBookingTest extends PageBase{ 

@Test(priority = 1) 
@Parameters({"from", "to"}) 
public void searchForAPackage(String from, String to) throws InterruptedException { 

    customerHomePage().selectDepartureAirport(from); 
    customerHomePage().selectDestinationAirport(to); 
    customerHomePage().selectStartDate(); 
    customerHomePage().submitSearchRequest(); 

    assertThat(searchResultsPage().checkPageTitle(), equalTo("Flight Results")); 
} 

頁面對象:

public class CustomerHomePage extends PageBase { 

@FindBy(how = How.XPATH, using = ".//* [@id='container']/div/div[3]/div/div[1]/div/h3") 
public WebElement searchResults; 
//loads more locators 

public CustomerHomePage(WebDriver driver) { 
    this.driver = driver; 
    driver.manage().window().maximize(); 
} 

public void visit(String url){ 
    driver.get(baseURL); 
} 

public void selectDepartureAirport(String departureAirport) { 
    click(whereFromDropdown); 
    selectOption(departureAirport); 
} 

public void selectDestinationAirport(String destination) { 
    click(destinationLocator); 
    type(destination, destinationLocator); 
    selectOption("(" + destination + ")"); 
} 

public void selectFromDate() { 
    type("15/07/2016", dateFromField); 
} 

public void submitSearchRequest() { 
    click(submitSearchButton); 
    waitForIsDisplayed(searchResults, 120); 
} 

public void selectStartDate() { 
    click(dateFromField); 
    click(nextMonthSelector); 
    click(dayOfMonth); 
} 

PageBase:

public class PageBase extends TestBase { 

public CustomerHomePage customerHomePage() 
{ 
    return PageFactory.initElements(driver, CustomerHomePage.class); 
} 

試驗基地:

public class TestBase implements Config { 

public WebDriver driver; 
//a bunch of methods to handle Driver instantiation and kill 

//a bunch of Webdriver utility methods including: 
public void click(WebElement element) { 
    waitForIsDisplayed(element, 120); 
    element.click(); 
} 
public Boolean waitForIsDisplayed(WebElement element, Integer... timeout) { 
    try { 
     waitFor(ExpectedConditions.visibilityOf(element), 
       (timeout.length > 0 ? timeout[0] : null)); 
    } catch (org.openqa.selenium.TimeoutException exception) { 
     return false; 
    } 
    return true; 
} 

private void waitFor(ExpectedCondition<WebElement> condition, Integer timeout) { 
    timeout = timeout != null ? timeout : 5; 
    WebDriverWait wait = new WebDriverWait(driver, timeout); 
    wait.until(condition); //java.lang.reflect.UndeclaredThrowableException HERE...Caused by NoSuchElementException 
} 

看起來框架不尊重等待期望條件 - 元素的可見性。我懷疑是與實施「visibilityOf(元素)」和@FindBy初始化元素異常

堆棧跟蹤的方式:

java.lang.reflect.UndeclaredThrowableException 
at com.sun.proxy.$Proxy7.findElement(Unknown Source) 
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.isDisplayed(Unknown Source) 
at org.openqa.selenium.support.ui.ExpectedConditions.elementIfVisible(ExpectedConditions.java:302) 
at org.openqa.selenium.support.ui.ExpectedConditions.access$100(ExpectedConditions.java:41) 
at org.openqa.selenium.support.ui.ExpectedConditions$10.apply(ExpectedConditions.java:288) 
at org.openqa.selenium.support.ui.ExpectedConditions$10.apply(ExpectedConditions.java:285) 
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:238) 
at com.multicom.fabrix.framework.TestBase.waitFor(TestBase.java:152) 
at com.multicom.fabrix.framework.TestBase.waitForIsDisplayed(TestBase.java:141) 
at com.multicom.fabrix.pageobjects.CustomerHomePage.waitForResults(CustomerHomePage.java:75) 
at com.multicom.fabrix.regressiontests.FlightBookingTest.searchForAPackage(FlightBookingTest.java:23) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86) 
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643) 
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820) 
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128) 
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129) 
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112) 
at org.testng.TestRunner.privateRun(TestRunner.java:782) 
at org.testng.TestRunner.run(TestRunner.java:632) 
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366) 
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361) 
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319) 
at org.testng.SuiteRunner.run(SuiteRunner.java:268) 
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) 
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) 
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244) 
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169) 
at org.testng.TestNG.run(TestNG.java:1064) 
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:74) 
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:121) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

Caused by: java.lang.reflect.InvocationTargetException 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.mycompany.mymodule.webdriver.WebDriverInvoker.invokeNormally(WebDriverInvoker.java:47) 
at com.mycompany.mymodule.webdriver.WebDriverInvoker.invoke(WebDriverInvoker.java:38) 
... 41 more 

產生的原因:org.openqa.selenium.NoSuchElementException :沒有這樣的元素:無法找到元素:{「method」:「xpath」,「selector」:「.//*[@ id ='container']/div/div [3]/div/div [1]/div/h3「}

回答

1

將您的PageBase類切換到下面。您之前正在初始化代理,但未返回該實例,只是一個新對象。否則,你可以使用'this'粘在CustomerHomePage的構造函數的initElements線代替'CustomerHomePage.class'

public class PageBase extends SeleniumBase { 

public CustomerHomePage customerHomePage() 
{ 
    return PageFactory.initElements(driver, CustomerHomePage.class); 
} 
+0

謝謝。作爲解釋 – Steerpike

+0

我在這個階段不明白的是爲什麼所有的方法現在使用FindBy的炸彈與NoSuchElementExceptions。當我用斷點進行調試時,測試運行良好。所以,FindBy的同步問題。在WebDriver驅動到相關頁面或頁面區域之前,initElements是否會嘗試查找定位符?根據測試,我引用了幾個不同的PageObjects,因此一些FindBy可能會在頁面加載之前嘗試初始化? – Steerpike

+0

由於PageFactory.initElements只爲使用@FindBy批註標記的WebElement字段提供代理,因此初始化PageObjects的位置並不重要。但是,當您訪問這些字段時,對於諸如sendkeys或click等方法,您必須確保瀏覽器位於正確的頁面上。您可以將當前URL與您想要的PageObject進行比較,或者查看LoadableComponent類。如果您獲取的NoSuchElementExceptions在調試模式下消失,則需要使用WebDriverWait和ExpectedConditions類進行正確同步。 – Grasshopper

0

變量名的你@FindBydrioDownLocator和一個你逝去的是dropDownContainer。在你的班級中是否還有WebElement類型的其他變量?