Почему Selenium мерцает между поиском и отсутствием определенного элемента HTML?

Я использую Specflow/Selenium для автоматизации тестирования веб-приложения, над которым я работаю в среде ASP.Net. Большинство «нажатий кнопок» приводят к полной загрузке страницы. Я выполняю следующие строки кода для выполнения при нажатии такой кнопки, но это мерцающий фрагмент кода — иногда он находит элемент, а иногда терпит неудачу. Почему это?

public class CreateQuestionPOM : BasePOM
{
    //Flickering find!
    [FindsBy(How = How.XPath, Using = "//label[text()[contains(.,'True/False')]]")] 
    private IWebElement trueFalseOption;

    [FindsBy(How = How.XPath, Using = "//a[@ct='Button' and @title='Next']")]
    private IWebElement nextButton; 

    public CreateQuestionPOM(IWebDriver driver) : base(driver) { }

    public void CreateTrueFalseQuestion()
    {            
        trueFalseOption.Click();
        nextButton.Click();

        WebDriverWait wait = new WebDriverWait(GetDriver(), TimeSpan.FromSeconds(20));
        wait.Until(driver1 => ((IJavaScriptExecutor)GetDriver()).ExecuteScript("return document.readyState").Equals("complete"));
    }

}

Приведенная выше сигнатура метода аналогична всем нажатиям кнопок, происходящим на странице. Приведенный выше фрагмент кода вызывается после нажатия предыдущей кнопки. Метод очень похож на описанный выше — дождитесь, пока document.readystate станет complete. Но почему это мерцает так часто и какое рекомендуемое решение?


person PhD    schedule 01.10.2015    source источник
comment
Может быть, страница иногда загружается не полностью, когда страница очищается?   -  person JeffC    schedule 02.10.2015
comment
Я бы не подумал, что это так, учитывая оператор wait.Until.   -  person PhD    schedule 02.10.2015
comment
Щелчки происходят до ожидания.   -  person JeffC    schedule 03.10.2015
comment
Э... да. Загрузка страницы происходит после клика. Таким образом, щелчок происходит до ожидания. Не уверен, что понимаю...   -  person PhD    schedule 03.10.2015
comment
Единственные элементы, которые вы найдете в этом фрагменте кода, находятся перед ожиданием. Итак... если элементы не найдены, ожидание не поможет.   -  person JeffC    schedule 04.10.2015
comment
Вот поток: нажмите и ждите новой страницы. Каждый метод вызывает «ожидание» после щелчка, чтобы следующий метод мог найти элемент на новой выбранной странице. Вышеупомянутый метод вызывается после запуска другого аналогичного метода. Это как если бы ожидание возвращается на текущую страницу, а не ждет перед попыткой.   -  person PhD    schedule 04.10.2015


Ответы (1)


В вашем коде нет ожидания, есть wait.until(). Когда этот код выполняется, он выполняется немедленно, и проверяется условие until. Если условие until истинно, выполнение продолжается. Только если условие until ложно, будет ожидание. Если код выполняется достаточно быстро, браузер может не перейти на следующую страницу, пока не будет проверено условие until. Условие until будет выполнено, поскольку текущая страница (страница, на которой вы щелкнули элемент) уже загружена. Одна вещь, которую вы можете попробовать, — это выбрать элемент со страницы, по которой щелкнули, и подождать, пока он устареет. Элемент считается устаревшим, если его больше нет в DOM. Когда загружается следующая страница, элементы на предыдущей странице устаревают. Попробуйте приведенный ниже код и посмотрите, поможет ли он.

public void CreateTrueFalseQuestion()
{            
    trueFalseOption.Click();
    nextButton.Click();

    WebDriverWait wait = new WebDriverWait(GetDriver(), TimeSpan.FromSeconds(20));
    // when nextButton is stale you know the browser is transitioning...
    wait.until(ExpectedConditions.stalenessOf(nextButton));
    // ... then you wait for the new page to load
    wait.Until(driver1 => ((IJavaScriptExecutor)GetDriver()).ExecuteScript("return document.readyState").Equals("complete"));
}
person JeffC    schedule 04.10.2015