вторник, 2 июня 2009 г.

Выбор элемента из списка - просто, но не для Watij

"Выбор элемента из списка" - Казалось бы простая задача для любого инструмента, но и тут наш друг опенсорс Watij проявил свою несостоятельность.

Приведем пример:

* HTML код страницы

<select name="criteria" onchange="change(this.value)">
<option value="-2">Id</option>
<option value="-1">Application Number</option>
<option value="0" selected="selected">other</option>
</select>


* java код с выбором элемента (допускаем, что элемент есть всегда, по этой причине не проверяем ничего на наличие, а сразу выбираем элемент)

SelectList combobox = selectList(FinderFactory.name("criteria"));
combobox.option(FinderFactory.text("Id")).select();


* ошибка в результате выполнения

ERROR: 02/06/2009 14:30:10 [com.jniwrapper.util.c] - DomFactory.Proxy.invoke: target = Element <SELECT> id: >ms__id1, method = fireEvent, error = null
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.jniwrapper.win32.ie.dom.j.run(SourceFile:592)
at com.jniwrapper.win32.MessageLoopThread$ThreadSynchronizedAction.run(MessageLoopThread.java:566)
at com.jniwrapper.win32.MessageLoopThread$LoopThread.run(MessageLoopThread.java:508)
Caused by: com.jniwrapper.win32.com.ComException: COM object method returns error code: 0x80070057; E_INVALIDARG (The parameter is incorrect.)
at com.jniwrapper.win32.com.impl.IUnknownImpl.invokeStandardVirtualMethod(SourceFile:725)
at com.jniwrapper.win32.mshtml.impl.IHTMLElement3Impl.fireEvent(IHTMLElement3Impl.java:376)
at com.jniwrapper.win32.ie.dom.c.fireEvent(SourceFile:322)
at com.jniwrapper.win32.ie.dom.c.fireEvent(SourceFile:558)
... 7 more


При этом элемент выбирается, но событие onchange не отрабатывает.
Попробовал убрать onchange из описания SELECT, запустил тотже кусок java кода... В результате - та же самая ошибка.

Начал копаться в интернете, нашел пару братьев по несчастью, с той же проблемой. Думаю: "Что делать? Может обновить библиотеку jniwrapper?". В моей версии Watij она jniwrap-3.6.1.jar, в интернете нашел jniwrap-3.7.3.jar.
Скачал.
Запускаю - даже браузер не стартанул... Начал смотреть где беда, нашел быстро:
оказывается библиотека jniwrap платная... и при запуске проверяет лицензионный ключик :) (Интересная получается штука, бесплатный инструмент использует платную библиотеку) На сколько это правильно не знаю, но звучит очень не логично...

А теперь ВНИМАНИЕ вопрос:
Кто знает как победить проблему выбора элемента из списка?

Всем ответившим, заранее спасибо.

P.S. Но если вопрос окажется не решаемым, то можно ставить большой и жирный крест на таком "замечательном" инструменте, как Watij...

8 комментариев:

Unknown комментирует...

А версия IE какая? Я попробовал на 8-ке и у меня не возникло никакого исключения. И событие отрабатывает (проверил, изменив его на alert).

А.Б. комментирует...

Win XP, IE 6, java 1.6.0_10

Копаю дальше...

Анонимный комментирует...

import watij.elements.SelectList;
import watij.runtime.ie.IE;
import junit.framework.TestCase;
import static watij.finders.SymbolFactory.*;


public class WatijTest extends TestCase {
public void testProtestingSelect() throws Exception {
IE ie = new IE();
ie.start("http://www.protesting.ru/contact/contact.html");
SelectList sl = ie.selectList(name, "type");
sl.select("Консультация");
assertTrue(sl.getSelectedItems().contains("Консультация"));
}

}

работает на IE7 :)
что-то ты в Ватидже недокрутил...
[Вовка]

А.Б. комментирует...

Проблему с Exception победили... проблема была в собранном мной watij.jar.
Но а вот проблема с onchange осталась... не выполняется он и все...
смотрим дальше...

А.Б. комментирует...

Таак...
onchange завели, точнее он просто обязан отрабатывать, по логике вещей, но вот только не видно этой отработки в браузере.
Начинаем копать Javascript внутри onchange...

Удачи мне...

А.Б. комментирует...

И снова здравствуйте...

Убил не один час, пока нашел в чем же была беда...
Итак, по порядку.
В моем тестируемом приложении был SELECT вида:
<select name="type" onkeydown="testOnkeydownAlert();" onchange="testOnchangeAlert();" onblur="testOnblurAlert();" onfocus="testOnfocusAlert();">

Давайте разберемся, что же происходит, если вы сами кликаете мышкой на select и выбираете нужный элемент. События выполняются в следующем порядке:
- onblur
- onfocus
- onchange

WATIJ же при выборе элемента не кликает на него, а делает это, по всей видимости, через события клавиатуры, получается, что события отрабатывают в следующей очередности:
- onkeydown
- onchange

Тут то и таится бага:
По средствам javascript в событии
onfocus была скрыта кое какая логика. А как мы видим, выбор элемента WATIJ-ем не приводит к выполнению этого события.

Получается, что нам приходится извращаться следующим образом, чтобы заставить WATIJ выполнить все события, которые нам нужны:

SelectList combobox = ie.selectList(FinderFactory.name(name));
Option htmlOption = combobox.option(FinderFactory.text(option));
htmlOption.select();
combobox.focus();
ie.sendKeys("{ENTER}");

Ну не изврат? Возможно да, возможно нет... :)

Нас рассудит время...

Unknown комментирует...

Алексей, не боитесь писать такую хитрую логику, зависящую от порядка активации ивентов в JS? Это не стандартизировано и может в разных браузерах выполняться по разному.

А.Б. комментирует...

Алексей, честно говоря, тот кто писал ЭТО, видимо вообще ничего не боялся... Он уже 1.5 года как уволился, и после его ухода это приложение вообще никто правил, лишь скапливали написанные баги и все.
А тут от начальства пришел приказ, пофиксить самые критичные, это по цепочке пришло ко мне - написать автоматизированные регрессионные тесты. Вот и я копаю потихоньку.

Условия копирования публикаций:

Все публикации в данном блоге являются частной собственностью авторов. Любое копирование информации допускается только при условии указания имени автора и активной ссылки на источник.