WaitForElementPresent
#1
Отправлено 09 октября 2008 - 09:17
В Selenium IDE есть функция waitForElementPresent, ее очень удобно использовать, чтобы тест не валился из-за того, что не успевает найти какую-нибудь линку или кнопку на форме.
В RC такой функции не нашла, есть только isElementPresent, возвращает булевское значение есть ли элемент. И чтобы дождаться появления элемента на форме, приходится писать такую конструкцию:
while (!browser.isElementPresent("AnyButton"))
browser.setTimeout("10000");
Есть ли возможность делать проще?
#2
Отправлено 09 октября 2008 - 09:57
сдается мне, что данная конструкция работает не так как вы ожидаете =) setTimeout ни как не влияет на функцию isElementPresent.while (!browser.isElementPresent("AnyButton"))
browser.setTimeout("10000");
Есть ли возможность делать проще?
кстати, если элемент так и не появится, то у вас будет бесконечный цикл
PS: 1) лучше напишите свой класс унаследованный от DefaultSelenium, и дополните его своими функциям
2) для клиентских либ есть документация
#3
Отправлено 09 октября 2008 - 10:53
#4
Отправлено 09 октября 2008 - 10:59
То, что setTimeout не влияет на появление элемента понятно и так) просто таким образом вставляется некая временная задержка, необходимая для появления элемента на форме. Вопрос в том, есть ли встроенная функция для этих целей?
public boolean waitForElementPresent(String elementToWaitForLocator) { boolean resultFlag = false; for (int second = 0; second <= Integer.parseInt(Constants.WaitFor_DELAY); second++) { if (selenium.isElementPresent(elementToWaitForLocator)) { resultFlag = true; break; } else { resultFlag = false; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } return resultFlag; }
Сообщение отредактировал NLord: 13 октября 2008 - 09:54
#5
Отправлено 09 октября 2008 - 11:03
setTimeout - не вставляет задержку на N-ое количество миллисекунд, у вас постояно долбиться browser.isElementPresent("AnyButton") без какой-либо задержки, до самого появления элементаТо, что setTimeout не влияет на появление элемента понятно и так) просто таким образом вставляется некая временная задержка, необходимая для появления элемента на форме. Вопрос в том, есть ли встроенная функция для этих целей?
встроенной функции нет, по крайней мере в либе для c#, с другими языками не работал. Мб они и содержат какие-нить дополнительные функции
#6
Отправлено 09 октября 2008 - 11:06
ну таким макаром человек точно не научится документацию читатьpublic boolean waitForElementPresent(String elementToWaitFor)
#7
Отправлено 13 октября 2008 - 08:44
Что интересно - в доках говорят о классе Wait (http://release.openq...0.9.2/doc/java/).
Пока что-то не разобралась, но видимо это еще один вариант решения.
#8
Отправлено 13 октября 2008 - 18:39
Спасибо за ответ. Указанный код работает, что неудивительно.
Что интересно - в доках говорят о классе Wait (http://release.openq...0.9.2/doc/java/).
Пока что-то не разобралась, но видимо это еще один вариант решения.
Очень не рекомендую использовать в данном случае класс Wait... да и вообще мало где его можно применить в тестах на Selenium.
Тебе необходимо расширить DefaultSelenium и добавить следующий код:
/** * Waiting for element to appear/disappear on page for specified time (means not element visibility but really * present/not present like in {@link com.thoughtworks.selenium.Selenium#isElementPresent(String)} method). * * @param locator an element locator. * @param timeout time to wait in milliseconds after which {@link TimeoutException} will be thrown. * @param present true - wait until element appear, false - wait until element disappear. * @since Selenium RC 0.9.2. */ public void waitForElement(String locator, String timeout, boolean present) { String logMessage = "Waiting for element '" + locator + "' to " + (present ? "" : "dis") + "appear for " + timeout + " milliseconds... Element "; try { waitForCondition("var element;" + "try{" + " element = selenium.browserbot.findElement('" + locator.replaceAll("'", "\\\\'") + "');" + "} catch(e){" + " element = null;" + "}" + "element" + (present ? "!=" : "==") + "null;", timeout); logMessage += (present ? "" : "dis") + "appear."; } catch (SeleniumException e) { logMessage += "didn't " + (present ? "" : "dis") + "appear as expected!"; throw new RunTimeException(logMessage, e); } finally { LOG.trace(logMessage); } } /** * Waiting for element to appear on page for specified time. It's the same as {@link #waitForElement(String, String, * boolean)} when the third parameter is true. * * @param locator an element locator. * @param timeout time to wait in milliseconds after which {@link TimeoutException} will be thrown. * @since SeleniumRC 0.9.2. */ public void waitForElementAppear(String locator, String timeout) { waitForElement(locator, timeout, true); } /** * Waiting for element to disappear on page for specified time. It's the same as {@link #waitForElement(String, * String, boolean)} when the third parameter is false. * * @param locator an element locator. * @param timeout time to wait in milliseconds after which {@link TimeoutException} will be thrown. * @since SeleniumRC 0.9.2. */ public void waitForElementDisappear(String locator, String timeout) { waitForElement(locator, timeout, false); }
Теперь должно быть понятно почему использование класса Wait плохо.
PS: приведённый в 4-м посте код страдает теми же проблемами, что и решение с Wait.
#9
Отправлено 14 октября 2008 - 06:22
Спасибо за ответ. Указанный код работает, что неудивительно.
Что интересно - в доках говорят о классе Wait (http://release.openq...0.9.2/doc/java/).
Пока что-то не разобралась, но видимо это еще один вариант решения.
Очень не рекомендую использовать в данном случае класс Wait... да и вообще мало где его можно применить в тестах на Selenium.
...
Теперь должно быть понятно почему использование класса Wait плохо.
PS: приведённый в 4-м посте код страдает теми же проблемами, что и решение с Wait.
Не понятно :). Объясните, по возможности, в чём принципиальная порочность подхода? Ибо вездесущие "не рекомендуется" убеждают слабо, а работающий код чуть сильнее. Хотя, с Вашего разрешения, возьму Ваш код на вооружение :).
#10
Отправлено 14 октября 2008 - 09:53
При использовании класса Wait и т.п. мы файтически в цикле вызываем методНе понятно :). Объясните, по возможности, в чём принципиальная порочность подхода? Ибо вездесущие "не рекомендуется" убеждают слабо, а работающий код чуть сильнее. Хотя, с Вашего разрешения, возьму Ваш код на вооружение :).
DefaultSelenium#isElementPresent(String)
Этот вызов приводит к обращению драйвера к SeleniumRC по HTTP-протоколу, вызову команды JS через SeleniumCore самим RC и возврату результата обратно в драйвер. Само собой дело это не быстрое, а когда у нас цикл, то таких цепочек у нас может быть достаточно много, соответственно временное разрешение у нас очень маленькое (количество проверок в единицу времени). Кроме того что это расточительно, у нас может быть достаточно динамичное приложение и элемент мог не только появиться, но и уже исчезнуть, причём несколько раз.
При использовании метода
DefaultSelenium#waitForCondition(String, String)Происходит единственный запрос от драйвера к SeleniumRC и дальше цикл проверки на появление/исчезновение элемента выполняется только на стороне браузера JavaScript'ом. В этом случае мы имеем временное разрешение примерно того же порядка, что и скорость работы самого тестируемого Web-приложения.
Немного сумбурно, но думаю понятно :)
#11
Отправлено 14 октября 2008 - 11:21
...
При использовании методаDefaultSelenium#waitForCondition(String, String)Происходит единственный запрос от драйвера к SeleniumRC и дальше цикл проверки на появление/исчезновение элемента выполняется только на стороне браузера JavaScript'ом. В этом случае мы имеем временное разрешение примерно того же порядка, что и скорость работы самого тестируемого Web-приложения.
Немного сумбурно, но думаю понятно :)
Спасибо, Вы первый, кто мне смог это внятно объяснить :).
#12
Отправлено 11 ноября 2008 - 09:12
LOG.trace(logMessage);
#13
Отправлено 12 ноября 2008 - 10:34
Скажите пожалуйста, что за объект LOG в этом примере?
LOG.trace(logMessage);
Скорее всего используется log4j.
#14
Отправлено 12 ноября 2008 - 16:29
#15
Отправлено 17 ноября 2008 - 06:03
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (selenium.isElementPresent("Anybutton")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
#17
Отправлено 18 ноября 2008 - 15:47
selenium.waitForCondition("selenium.isElementPresent(\"" + locator + "\")", "10000");
или ждем, что элемент исчезнет:
selenium.waitForCondition("!selenium.isElementPresent(\"" + locator + "\")", "10000");
При этом "selenium." в условии - эт ключевое слово, дальше должно быть название команды из DefaultSelenium. То есть если вы этот класс расширили, нифига wait for condition новое не возьмет, только стандартные. Нужно конеш еще в код заглянуть, и убедиться что все работает именно так :)
#18
Отправлено 19 ноября 2008 - 09:31
По поводу того, что команда должна быть из DefaultSelenium, видимо, не совсем так, команда должна быть одной из допустимых в SeleniumCore, так?
#19
Отправлено 19 ноября 2008 - 09:59
private mySelenium selenium;
public void setUp() {
selenium = new mySelenium("localhost",
4444, "*firefox", "http://demo.soft.com...lder/page.aspx");
selenium.start();
}
...
selenium.waitForCondition("selenium.isElementPresent(\""+ "LoginTextBox" +"\")", "10000");
...
Вот только селениум должен называться selenium (private mySelenium selenium), а не как-то иначе типа (private mySelenium myBrowser)
Спасибо))
#20
Отправлено 19 ноября 2008 - 10:14
У меня указанный код работает и для переопределенного селениума:
Переопределённый он или нет - не важно, имелось ввиду, что работают только методы из DefaultSelenium, а если были добавлены новые, то эти новые естественно работать в waitForCondition не будут. Я думаю, что и DefaultSelenium здесь ни при чём, а методы могут быть использованы любые, которые позволяет именно Selenium Core.
Вот в этом сильно сомневаюсь, Selenium RC, а уж тем более Selenium Core знать ничего не знают про переменные теста и ему это должно быть совершенно безразлично. Т.е. ссылка на объект, соответствующий интерфейсу Selenium может называться как угодно, но в waitForCondition всегда надо писать "selenium".Вот только селениум должен называться selenium (private mySelenium selenium), а не как-то иначе типа (private mySelenium myBrowser)
Количество пользователей, читающих эту тему: 0
0 пользователей, 0 гостей, 0 анонимных