2016-08-30 1 views
0

code mis à jour:WebElements @FindBy ne sont pas initialisés dans un PageFactory/Page objet cadre

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")); 
} 

page Objet:

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); 
} 

Base de test:

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 
} 

On dirait que le framework ne respecte pas l'attente des conditions attendues - visibilité de l'élément. Je soupçonne que quelque chose à voir avec la mise en œuvre de « La visibilité des (élément) » et la façon dont les éléments @FindBy initialisés

de trace de la pile d'exception:

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 

causés par: org.openqa.selenium.NoSuchElementException : aucun élément de ce type: Impossible de localiser l'élément: {"méthode": "xpath", "sélecteur": ".//*[@id =" conteneur "]/div/div [3]/div/div [1]/div/h3 "}

Répondre

1

Bascule votre classe PageBase à ci-dessous. Vous avez initialisé les proxys plus tôt, mais vous n'avez pas renvoyé cette instance, juste un nouvel objet. Sinon vous pouvez coller la ligne initElements dans le constructeur de CustomerHomePage à l'aide 'this' au lieu du 'CustomerHomePage.class'

public class PageBase extends SeleniumBase { 

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

Merci. Fonctionne comme expliqué – Steerpike

+0

ce que je ne comprends pas vraiment à ce stade est pourquoi toutes les méthodes qui utilisent maintenant la bombe de FindBy avec NoSuchElementExceptions. Quand je débogue avec des points d'arrêt, le test fonctionne bien. Donc, il y a un problème de synchronisation avec FindBy. Est-ce que le initElements essaie de trouver les locators avant que le WebDriver ne conduise à la page ou à la zone de page concernée? Selon le test, je référence plusieurs objets PageObjects différents de sorte que certains FindBy peuvent essayer d'initialiser avant que la page ait été chargée? – Steerpike

+0

Peu importe où vous initialisez les objets PageObjects car PageFactory.initElements fournit uniquement des proxys pour les champs WebElement marqués avec l'annotation @FindBy. Mais lorsque vous accédez à ces champs, pour des méthodes telles que sendkeys ou click, vous devez vous assurer que le navigateur est sur la bonne page. Vous pouvez comparer l'URL actuelle avec ce que vous voulez pour l'objet PageObject ou regarder la classe LoadableComponent. Si vous obtenez NoSuchElementExceptions qui disparaissent en mode débogage, vous devez utiliser la classe WebDriverWait et ExpectedConditions pour synchroniser correctement. – Grasshopper

0

Nom de la variable dans votre @FindBy est drioDownLocator et que vous passez est dropDownContainer. Y at-il une autre variable avec le type WebElement dans votre classe?