2016-07-22 18 views
2
  1. Ich versuche, auf eine Schaltfläche klicken, die auf einer Seite durch die Verwendung sichtbar ist WebDriver warten aber WebDriver nur in der Lage ist, auf der Schaltfläche klicken, sobald ich ein Thread.sleep, um den Code hinzuzufügen.WebDriver Wait ‚.bis (ExpectedConditions.elementToBeClickable‘ funktioniert nur, wenn i Thread.sleep (500) auf den Code hinzufügen?

  2. ich habe überprüft auch auf die Schaltfläche, um zu sehen, ob seine sichtbar (True), bevor ich meinen Code ausführen und es wiederum returns = true.

// Taste der Sichtbarkeit des Check:

List<WebElement> signOutList = driver.findElements(.xpath(".//*[starts-with(@id,'fulfillment-time-type-section-')]/div[2]//button")); 
Assert.assertTrue(signOutList.size() > 0); 

// Der folgende Code nicht klickt auf die Schaltfläche

By timeDropdownButton = By.xpath(".//*[starts-with(@id,'fulfillment-time-type-section-')]/div[2]//button"); 
WebElement myDynamicElement = (new WebDriverWait(driver, 10)) 
       .until(ExpectedConditions.elementToBeClickable(timeDropdownButton)); 
myDynamicElement.click(); 

// Der Code unten auf die Schaltfläche Ist klicken:

Thread.sleep(500); 
By timeDropdownButton = By.xpath(".//*[starts-with(@id,'fulfillment-time-type-section-')]/div[2]//button"); 
WebElement myDynamicElement = (new WebDriverWait(driver, 10)) 
       .until(ExpectedConditions.elementToBeClickable(timeDropdownButton)); 
myDynamicElement.click(); 


Bitte beachten Sie, dass ich auch versucht habe, mit JS-Code und WebDriver-Aktionen usw. auf die Schaltfläche zu klicken.

Ich weiß nicht, warum "Wait Clickable" nur funktioniert, wenn ich mit "Thread.sleep" kombiniere?

The button I'm trying to click

+0

haben Sie mit einer Erhöhung der Zeit von 10 Sekunden bis mehr versucht .. ??? –

+0

Hallo Saurabh, habe ich versucht, den folgenden Code, aber es immer noch nicht funktioniert hat (geändert 10-1000): \t \t \t \t WebElement myDynamicElement = (neu WebDriverWait (Fahrer, 1000)) – Gbru

+0

Versuchen Sie einmal mit 'ExpectedConditions.visibilityOfElementLocated'..and lass es mich wissen .. –

Antwort

0

Es ist wahrscheinlich immer noch aktiv Javascript auf der Seite ausgeführt wird. Im ersten Sekundenbruchteil könnte es so modifiziert werden, dass die ExpectedCondition nicht erkennen kann. Wenn ich Probleme mit unerwartetem Verhalten habe, finde ich, dass das Warten auf das Laden der Seite (JavaScript-Skripte eingeschlossen) normalerweise die meisten Probleme löst.

Um zu warten, dass die Seite geladen wird, können Sie Javascript aufrufen, um die readyState des Dokuments zu überprüfen. Versuchen Sie, auf das Laden der Seite zu warten, und warten Sie dann, bis das Element anklickbar ist.

Eine schnelle Suche gibt diese (code taken from here):

wait.until(new Predicate<WebDriver>() { 
      public boolean apply(WebDriver driver) { 
       return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete"); 
      } 
     } 
    ); 
+0

danke für Ihre Hilfe @ Parker, ich versuchte er oben Code, aber es hat immer noch nicht funktioniert :( Ich habe Thread Schlaf mit dem oben genannten und es scheint die erforderliche Aufgabe zu tun – Gbru

0

Nach Methode scheint richtig zu funktionieren:

public void waitForPageLoad() { 
    ExpectedCondition<Boolean> expectation = new 
      ExpectedCondition<Boolean>() { 
       public Boolean apply(WebDriver driver) { 
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete"); 
       } 
      }; 
    try { 
     Thread.sleep(1000); 
     WebDriverWait wait = new WebDriverWait(driver, 30); 
     wait.until(expectation); 
    } catch (Throwable error) { 
     Assert.fail("Timeout waiting for Page Load Request to complete."); 
    } 
} 
2

Sie wollen in der Regel Thread.sleep in Tests so weit wie möglich zu vermeiden. Es scheint nicht so wichtig mit nur ein paar Tests, aber es gibt eine Menge Probleme in ihrer Verwendung. Zunächst einmal, wenn Sie eine Reihe von Tests haben, kann die Laufzeit der Testsuite unkontrollierbar werden. Zweitens sind sie manchmal nicht genug. Zum Beispiel, warten 500 Millisekunden möglicherweise genug sein, mit Produktionsmaschinen im Allgemeinen, aber wenn der Webserver unter hoher Belastung oder in einer Testumgebung ist, kann es 750 Millisekunden dauern, um bereit zu sein. Dann handelt es sich um nicht-deterministische Fehler. Es ist am besten, Konstrukte wie zu verwenden und ihnen einen vernünftigen (aber allzu großzügigen) Maximalwert zu geben, so dass Sie nicht länger als nötig warten müssen, aber wenn es fehlschlägt, bedeutet das, dass etwas ernsthaft falsch mit der getesteten Umgebung war.

Auch die Pizza Hut Website verwendet hier stark asynchrone Java Script und schwebende Panels, etc.All dies erfordert etwas mehr Sorgfalt bei der Verwendung von Selenium, da Elemente bereit sein müssen, um mit ihnen zu interagieren, aber sie sind oft schon im DOM. Dies bedeutet, dass Selenium sie wahrscheinlich schnell finden wird, bevor das JavaScript abgeschlossen ist, und sie sind nicht wirklich in einem gebrauchsfertigen Zustand. Sie werden ExpectedConditions verwenden, wie Sie es bereits versucht haben. Die Schaltfläche, mit der Sie Probleme hatten, benötigt das Warten auf JavaScript, das bereits vorgeschlagen wurde, aber es muss nicht beim Laden der Seite sein, sondern direkt vor dem Klicken auf die Schaltfläche. Beispiel, das auf meiner Maschine arbeitete:

@Test 
public void foo() { 
    WebDriver driver = new FirefoxDriver(); 
    driver.manage() 
      .window() 
      .maximize(); 
    // Move through the page to the point you are interested in 
    driver.get("https://www.pizzahut.co.uk/"); 
    waitForElement(driver, By.cssSelector(".hidden-xs [title='Pizza']")).click(); 
    waitForElement(driver, By.cssSelector("form[action='/menu/startyourorder']")).submit(); 
    WebElement postElement = waitForElement(driver, By.id("ajax-postcode-txt")); 
    postElement.sendKeys("TS1 4AG" + Keys.ENTER); 
    // Wait for the java script to finish executing 
    waitForJavaScript(driver); 
    // Finally you should be able to click on the link 
    waitForElement(driver, By.partialLinkText("Start Your Order")).click(); 
    // continue on ... then quit the driver 
    driver.quit(); 
} 

private WebElement waitForElement(WebDriver driver, By locator) { 
    return new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(locator)); 
} 

private void waitForJavaScript(WebDriver driver) { 
    new WebDriverWait(driver, 10).until(new Predicate<WebDriver>() { 
              public boolean apply(WebDriver driver) { 
               return ((JavascriptExecutor) driver).executeScript("return document.readyState") 
                        .equals("complete"); 
              } 
             } 
    ); 
} 

In einem WebDriverWait das angegebene int Argument ist die Anzahl der Sekunden, um es halten wird die gegebene Überprüfung versuchen. Wenn es zu der eingestellten Menge kommt (10 Sekunden im obigen Beispiel), wirft es eine TimeoutException.

0

Versuchen Sie eine PageFactory-Implementierung, um zu sehen, ob das Selen-API das Problem für Sie löst.

public class OrderMyPizzaPage { 
     @FindBy(css="form[action='/menu/startyourorder']") 
     WebElement startMyOrder; 

     public void startOrder() { 
      startMyOrder.click(); 
     } 
    } 

Große, und jetzt, wenn wir davon ausgehen, dass alles, was erfolgreich geschehen ist, und wir sind zu dem Punkt, wo wir auf klicken können ‚starten Sie Ihre Bestellung‘

public void myExecutingMethod(WebDriver driver) { 
     //previous steps occur and we've just performed interactions which should cause the 'start your order' button to be on the dom 

     OrderMyPizzaPage orderPage = PageFactory.initElements(driver, OrderMyPizzaPage.class); 
     orderPage.startOrder(); 

     //And now maybe it worked? 
    } 

Wenn das doesn Arbeite nicht, probier ein bisschen mehr Brute-Force. Erstellen Sie ein benutzerdefiniertes Vergleichselement für Ihr WebDriverWait, das vor der Freigabe prüft, ob eine Post-Klick-Bedingung wahr ist. Wenn es nicht wahr ist, lassen Sie das Prädikat den Klick erneut ausführen!

Wegen der Zeitzone Fragen war ich nicht in der Lage den Nachschlag für einen erfolgreichen Post Klick Inhalt zu erhalten, so gibt es einen fehlenden Verweis im Schnipsel. Es ist, als gekennzeichnet FIXME

public void startOrder(WebDriver driver) { 
    WebDriverWait wait = new WebDriverWait(driver, 30); 
    //Throttle the polling! 
    wait.pollingEvery(1500, TimeUnit.MILLISECONDS); 
    wait.until(new Predicate<WebDriver>() { 
     public boolean apply(WebDriver input) { 
      boolean successfulClick = false; 
      //FIXME: Need to check for something that should occur after the click happens successfully 
      By lookupAfterClick = By.cssSelector(""); 
      WebElement nextElement = ExpectedConditions.visibilityOfElementLocated(lookupAfterClick).apply(input); 
      if (nextElement == null) { 
       System.out.println("Not there yet, Keep trying!"); 
       By startOrderLookup = By.cssSelector("form[action='/menu/startyourorder']"); 
       WebElement startOrder =ExpectedConditions.visibilityOfElementLocated(startOrderLookup).apply(input); 
       if (startOrder != null) { 
        System.out.println("Clicking Start Order!"); 
        startOrder.click();       
       } else { 
        System.out.println("Start Order isn't visible!"); 
       } 
      } else { 
       System.out.println("Hey, That worked!"); 
       successfulClick = true; 
      } 
      return successfulClick; 
     } 
    });   
} 
+0

Dank @ Jeremiah schätzen die Hilfe – Gbru