Как заставить xpath работать с Selenium при загрузке filepicker.io

После реализации filepicker.io некоторые из наших регрессионных тестов Selenium начали давать сбои. Сбои (периодические, но чаще всего в некоторых обстоятельствах) заключаются в том, что щелчки игнорируются на WebElements, найденных с помощью запросов XPath. например

driver.findElement(By.xpath("//a[text()='Demo data']")).click();

Добавление Sleep(2000) между findElement() и click() обычно решает проблему. (Я говорю в целом, потому что Sleep(1000) в основном было достаточно, пока этого не произошло, поэтому я сделал его Sleep(2000)...)

Проверка element.isDisplayed() не помогла. Проблема исчезнет, ​​если мы перестанем включать файл JavaScript filepicker.io.

Это как-то связано с тем, что filepicker.io представляет IFRAME? Мы также заметили, что функция JQuery document.ready() теперь вызывается дважды.


person Oliver Bock    schedule 06.06.2013    source источник
comment
Работает ли это, когда вы используете CSS для ссылки на элемент?   -  person Yoshi    schedule 07.06.2013
comment
CSS работает нормально.   -  person Oliver Bock    schedule 07.06.2013
comment
На самом деле мы видим это и с CSS, и кажется, что это происходит сразу после загрузки страницы. Возможно, динамическая вставка iframe что-то сбивает с толку.   -  person Oliver Bock    schedule 11.06.2013


Ответы (2)


Как обычно с такими проблемами, вы пытаетесь найти элемент, который еще не доступен на странице из-за запроса AJAX, который все еще загружает/обрабатывает его. Вам нужно дождаться появления элемента на странице.

Есть три способа сделать это:

  1. Использование sleep(). Это несмелыйпуть. Вы не должны использовать жестко запрограммированные спящие режимы, потому что вы либо будете ждать слишком долго (что делает тесты излишне медленными), либо слишком короткими (сбой теста).
  2. Используйте неявное ожидание. Это всегда будет ждать элемента, если он не найден.

    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    
  3. Используйте явное ожидание. Это позволяет вам явно ждать, пока один элемент (исчезнет) появится/станет доступным/что угодно.

    WebDriverWait wait = new WebDriverWait(driver, 10);
    WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Demo data")));
    
person Petr Janeček    schedule 11.06.2013
comment
Я не думаю, что это все. findElement() возвращает элемент без исключения (поэтому он находится в DOM), а click() не генерирует исключение (поэтому он виден). Это не элемент ввода, поэтому я понимаю, что включено не имеет значения. - person Oliver Bock; 12.06.2013
comment
@OliverBock Ох. Я, должно быть, неправильно понял вопрос, мой плохой, извините. Были баги с Firefox и iframes - иногда щелкает по неправильным координатам. Попробуйте с другим браузером, попытайтесь определить, где он на самом деле щелкает. Попробуйте executeScript("arguments[0].click()", theElementToClick); в качестве обходного пути. - person Petr Janeček; 12.06.2013

Теперь мы запускаем этот код первым после открытия любой страницы, содержащей filepicker.js:

while (FindElementsMaybeNone(By.cssSelector("#filepicker_comm_iframe")).size() == 0)
    Sleep(50);
while (driver.switchTo().frame("filepicker_comm_iframe") == null)
    Sleep(50);
driver.switchTo().defaultContent();

Мы предполагаем, что динамическая вставка IFRAME сборщиком файлов сбивает с толку Firefox или Selenium. Я не помечаю это как ответ, потому что не знаю, почему это работает.

person Oliver Bock    schedule 13.06.2013