WebDriver выполняет странное поведение JavaScript - PullRequest
0 голосов
/ 19 июля 2011

Я использую Webdriver через дистрибутив JBehave-Web (3.3.4) для тестирования приложения и сталкиваюсь с чем-то довольно странным:

Я пытаюсь взаимодействовать с модальной панелью от Richfaces, которая доставила мне много проблем, потому что она выдает исключение ElementNotVisibleException. Я решил это с помощью JavaScript:

Это код в объекте моей страницы, который происходит от org.jbehave.web.selenium.WebDriverPage

protected void changeModalPanelInputText(String elementId, String textToEnter){
    makeNonLazy();
    JavascriptExecutor je = (JavascriptExecutor) webDriver();
    String script ="document.getElementById('" + elementId + "').value = '" + textToEnter + "';";
    je.executeScript(script);
}

Странное поведение в том, что если я обычно выполняю тест, он ничего не делает, но если я поставлю точку останова в последней строке (в Eclipse), выделю строку и выполню из Eclipse (Ctrl + U), я могу видеть изменения в браузере.

Я проверил классы JavascriptExecutor и WebDriver, чтобы увидеть, есть ли какая-либо буферизация, но я ничего не смог найти. Есть идеи?

EDIT Я обнаружил, что если положить нить в спящий режим на 1 секунду, это заставит его работать, так что это выглядит как состояние гонки, но не могу понять, почему ...

Вот как это "работает", но я не очень рад этому:

protected void changeModalPanelInputText(String elementId, String textToEnter){
    String script ="document.getElementById('" + elementId + "').value = '" + textToEnter + "';";
    executeJavascript(script);
}

    private void executeJavascript(String script){
    makeNonLazy();
    JavascriptExecutor je = (JavascriptExecutor) webDriver();
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    je.executeScript(script);       
}

Установка ожидания в любую другую позицию тоже не работает ...

1 Ответ

1 голос
/ 27 июля 2011

Первая идея:

Убедитесь, что целевой элемент инициализирован и перечислим. Посмотрите, вернется ли это null:

Object objValue = je.executeScript(
    "return document.getElementById('"+elementId+"');");

Поскольку вы используете makeNonLazy(), возможно, просто добавьте цель в качестве члена WebElement вашего объекта страницы (при условии тип фабрики страниц в JBehave).

Вторая идея:

Явно подождите, пока элемент будет доступен, прежде чем изменять:

/**
 * re-usable utility class
 */
public static class ElementAvailable implements Predicate<WebDriver> {

    private static String IS_NOT_UNDEFINED = 
        "return (typeof document.getElementById('%s') != 'undefined');";
    private final String elementId;

    private ElementAvailable(String elementId) {
        this.elementId = elementId;
    }

    @Override
    public boolean apply(WebDriver driver) {
        Object objValue = ((JavascriptExecutor)driver).executeScript(
                String.format(IS_NOT_UNDEFINED, elementId));
        return (objValue instanceof Boolean && ((Boolean)objValue));
    }
}

...

protected void changeModalPanelInputText(String elementId, String textToEnter){
    makeNonLazy();

    // wait at most 3 seconds before throwing an unchecked Exception
    long timeout = 3;
    (new WebDriverWait(webDriver(), timeout))
            .until(new ElementAvailable(elementId));

    // element definitely available now
    String script = String.format(
            "document.getElementById('%s').value = '%s';",
            elementId,
            textToEnter);
    ((JavascriptExecutor) webDriver()).executeScript(script);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...