Tak Wystąpił ten problem wiele razy podczas korzystania z Selenium. Są dwa sposoby na obejście tego problemu. Po pierwsze możesz zmienić domyślny czas oczekiwania. Na przykład biorąc pod uwagę ten kawałek kodu:
Actions builder = new Actions(driver);
builder.click(driver.findElement(By.className("lala"))).perform();
Ten kod wygeneruje wyjątek, jeśli w tym momencie to się nazywa nie ma żadnych elementów, które mogłyby zostać uznane dopasować klasę „lala”. Możesz zmienić ten domyślny czas oczekiwania na:
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
To sprawia, że kierowca odpytuje przez 5 sekund, zamiast od razu nie reagować. Jeśli element nadal nie może być zlokalizowany po 5 sekundach, akcja zakończy się niepowodzeniem. Oczywiście możesz zmienić to ustawienie. Odkryłem, że ta metoda działa dobrze przez większość czasu. Przez większość czasu nie przejmujesz się ładowaniem całej strony, tylko pewną częścią.
Pisałem również inną funkcję, która jest GetElementByClassAndText który zrobi to samo jako niejawny czekać na elemencie oprócz tego, że również sprawdza zawierający tekst, jak również w celu umożliwienia drobniejsze detale, co chcesz:
public static void waitAndClick(WebDriver driver, By by, String text) {
WebDriverWait wait = new WebDriverWait(driver, 10000);
Function<WebDriver, Boolean> waitForElement = new waitForElement(by);
wait.until(waitForElement);
for(WebElement e : driver.findElements(by)) {
if(e.getText().equals(text)) {
Actions builder = new Actions(driver);
builder.click(e).perform();
return;
}
}
}
a odpowiednia funkcja używa:
public class waitForElement implements Function<WebDriver, Boolean> {
private final By by;
private String text = null;
public waitForElement(By by) {
this.by = by;
}
public waitForElement(By by, String text) {
this.by = by;
this.text = text;
}
@Override
public Boolean apply(WebDriver from) {
if(this.text != null) {
for(WebElement e : from.findElements(this.by)) {
if(e.getText().equals(this.text)) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
} else {
try {
from.findElement(this.by);
} catch(Exception e) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
}
Zdaję sobie sprawę, że używasz selenu w Ruby, ale mam nadzieję, że niektóre z moich kodu (przynajmniej koncepcyjnie) jest zbywalne i pomocny dla Ciebie.
Czy mógłbyś bardziej szczegółowo opisać, w jaki sposób monitorujesz wartość? – emery
Czy możesz to rozwinąć –