Работа с событиями в Selenium


(Sergey356) #1

Доброго времени суток!

Не так давно начал развивать свои навыки, как автоматизатора и столкнулся с одной и типичных проблем, а именно - реализация стандартных событий на Selenium. Я прошелся по многим форумам, но ответа на свою ситуацию, так и не нашел. Поясню на конкретном примере:

1. Имеется магазин товаров, допустим: http://shoptime.ru/categories/odezhda

2. При наведении указателя мышки на любой товар, появиться скрытая кнопка "Быстрый просмотр". По умолчанию кнопка скрыта, но в HTML она присутствует. При наведении мышки, JS стандартно устанавливает атррибут display в нужное положение.

3. При клике по данной кнопке - открывается popup окно с информацией.

Собственно проблема заключается, как раз в нажатии этой кнопки.

Кнопка имеет свой id, но если я напрямую кликну на нее:

driver.findElement(By.id("showProductPopup")).click(); - Exlipse поругается, что элемент не видим на странице.

Я нашел способ в имитации наведения мышки: 

 

WebElement myElement = driver.findElement(By.xpath("Путь к продукту"));
Actions builder = new Actions(driver);
builder.moveToElement(myElement).build().perform();
 
Как результат - указатель наводиться и тут же уходит с элемента и если вставить за этой конструкцией команду:
driver.findElement(By.xpath("Путь до кнопки этого продукта")).click();

Рузельтата не будет.

Мне необходимо каким то образом задержать "указатель мыши" на элементе, пока не будет совершен click(); и, как следствие, откроется Popup окно

 


(Сергей Блохин) #2

Как вариант, поставьте сами атррибут display в нужное положение и далее сделайте Click.

def set_file(id, file)
    @wait.until{@driver.find_element(:id, id)}
    @driver.execute_script("#{id}.removeAttribute('class')")
    set_text(id, file)
end

(Alexander Petrovich) #3

В python+selenium для этого есть замечательная вещь action chains. Поищите по форуму. Возможно и на джаве такая штука реализуема


(falke5) #4

в селениум ide есть такая штука как mouseOver и ваш xpath


(Alexander Petrovich) #5

 

Actions builder = new Actions(driver);
   builder.moveToElement(myElement)
       .click(myElement)
Action mouseoverAndClick = builder.build();
mouseoverAndClick.perform();

Вот пример живой. Предупреждаю ещё раз, я в Java ноль :) 

Взято и перепилено отсюда

 


(Mykhailo Poliarush) #6

так вы решили свою проблему или нет?


(Sergey356) #7

Да, проблема была решена способом, предложенным furious_duck.

 

Actions builder = new Actions(driver);
   builder.moveToElement("тут элемент на который наводим").click("тут элемент по которому кликаем")
Action mouseoverAndClick = builder.build();
mouseoverAndClick.perform();

Благодарю! :)


(Mykhailo Poliarush) #8

ну вот и отлично :)


(Sergey356) #9

Не прошло и месяца, как мне снова пришлось вернуться к этой теме. Казалось бы, тесты написанны и работают(запускал десятки раз в течении нескольких недель), как вдруг сегодня придя на рабочее место обнаружил, что код, который наводил мышку и делал клик упорно не желает работать! ElementNotVisibleException: Element is not currently visible and so may not be interacted with

Проведя серию мелких тестов, убедился, что selenium даже не подводит "условный курсор" к элементу, соответственно и нажимать нечего.

 Actions builder = new Actions(driver);

builder.moveToElement(driver.findElement(By.id(".b-product-card.progress:nth-of-type(1)"))).click(driver.findElement(By.id("popup")));
Action mouseoverAndClick = builder.build();
mouseoverAndClick.perform();
 
1. С чем это может быть связанно? 
2. Хотелсь бы попробовать способ предложенный TIT, удалить класс у объекта, чтобы элемент скрытый стал виден. Но я не смог найти информацию как выполнять JavaScript код в Selenium(на JAVA). Буду благодарен, за пример:)

(Alexander Petrovich) #10

Стектрейс в студию, пжлст.
По прямому выполнению js читать здесь

upd:

Если тестите ту же страницу, что в первом посте, то я не вижу элемента с таким айдишником


(Sergey356) #11

 

org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 9 milliseconds
Build info: version: '2.25.0', revision: '17482', time: '2012-07-18 21:08:56'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.6.0_31'
Driver info: driver.version: RemoteWebDriver
Session ID: 36d5df40-ecf0-48a6-8118-5f3c2ad50afb
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:188)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:498)
at org.openqa.selenium.remote.RemoteExecuteMethod.execute(RemoteExecuteMethod.java:34)
at org.openqa.selenium.remote.RemoteMouse.click(RemoteMouse.java:58)
at org.openqa.selenium.interactions.ClickAction.perform(ClickAction.java:34)
at org.openqa.selenium.interactions.CompositeAction.perform(CompositeAction.java:31)
at Catalog.getFirstItemExpress(Catalog.java:39)
at CreateOrderFromExpress.testCreatOrderFromExpress(CreateOrderFromExpress.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
 

(Sergey356) #12

Данный локатор надо смотреть по адресу http://www.kupivip.ru/shop/directory/?activityId=30915&filter=ALL

(нужна регистрация, иначе редирект на стартовую будет)


(Alexander Petrovich) #13

Он на клике или наведении матерится?


(Alexander Petrovich) #14

элемента с xpath .//*[@id='.b-product-card.progress:nth-of-type(1)'] нет по вашему урлу


(Mykhailo Poliarush) #15

1. когда вы обновлялись в последний раз? может быть что-то поменялось в вашем приложении?

2. на счет джаскрипта, вот примерный код, как запускать javascript

 

WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return document.title");

(Sergey356) #16

Это не xpath, Sizzle :)


(Sergey356) #17

Благодарю! Я уже нашел эту статью и выработал решение.

 

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("$('#popup').css(\"display\",\"block\");"); //popup - это сама скрытая кнопка. которую требовалось нажать
driver.findElement(By.id("popup")).click();
 
Ву-а-ля:)

(Alexander Petrovich) #18

Вы же ищете по id в вашем запросе. Значит локатор неверно указан. потому что ваше By.id равно моему By.xpath


(Sergey356) #19

Я искал по ".b-product-card.progress:nth-of-type(1)

by.id перед ним - это опечатка от старого кода, я потом поправил, но забыл изменить на форуме. Прошу меня извинить


(Sergey Korol) #20

Возможно клик осуществляется быстрей, чем запрос на display. Попробуйте прикрутить задержку - какой-нибудь кастомный слип для findElement.