Отладка ошибки "Элемент не активен в точке"
Я вижу это только в Chrome.
Полное сообщение об ошибке гласит:
"org.openqa.selenium.WebDriverException: Элемент не активен в точке (411, 675). Другой элемент получит щелчок: ..."
Элемент, который "получит щелчок", находится сбоку от рассматриваемого элемента, не сверху и не перекрывая его, не перемещаясь по странице.
Я попытался добавить смещение, но это тоже не работает. Элемент находится в отображаемом окне без необходимости прокрутки.
54 ответа
Это вызвано следующими 3 типами:
1. Элемент не виден для нажатия.
Используйте Actions или JavascriptExecutor, чтобы заставить его щелкнуть
По действиям:
WebElement element = driver.findElement(By("element_path"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().perform();
Автор JavascriptExecutor:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(250, 0)"); // if the element is on top.
jse.executeScript("scroll(0, 250)"); // if the element is on bottom.
или же
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Webelement);
Затем нажмите на элемент.
2. Страница обновляется до того, как щелкнет элемент.
Для этого заставьте страницу подождать несколько секунд.
3. Элемент кликабелен, но поверх него есть спиннер / оверлей
Приведенный ниже код будет ждать, пока наложение не исчезнет
By loadingImage = By.id("loading image ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));
Затем нажмите на элемент.
Вы также можете использовать JavaScript click, и тогда прокрутка не понадобится.
IJavaScriptExecutor ex = (IJavaScriptExecutor)Driver;
ex.ExecuteScript("arguments[0].click();", elementToClick);
Кажется, для этого есть ошибка в chromedriver (проблема в том, что он помечен как не исправленный) -> GitHub Link
(возможно, наградить спонсоров FreedomSponsors?)
В комментарии № 27 предлагается обходной путь. Может быть, это будет работать для вас.
У меня была та же самая проблема, перепробовал все предложенные решения, но они не работали для меня. в конце концов я использовал это:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("var evt = document.createEvent('MouseEvents');" + "evt.initMouseEvent('click',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" + "arguments[0].dispatchEvent(evt);", findElement(element));
Надеюсь это поможет
Вау, здесь много ответов и много хороших.
Я надеюсь, что добавлю что-то к этому из моего опыта.
Ну, ребята, в моем случае была накладка cookie, скрывающая элемент время от времени. Прокрутка до элемента также работает; но, по моему скромному мнению (для моего случая - не панацея для всех), самое простое решение - просто перейти на полный экран (я запускал свои сценарии на 3/4 окна)! Итак, поехали:
driver.manage().window().maximize();
Надеюсь, это поможет!
Вам нужно использовать фокус или прокрутку на этом элементе. Возможно, вам также придется использовать явное ожидание.
WebElement firstbutton= driver.findElement(By.xpath("Your Element"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();
ИЛИ
Элемент нельзя щелкнуть из-за наличия на нем счетчика / наложения:
By loadingImage = By.id("loading image ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));
ИЛИ
Point p= element.getLocation();
Actions actions = new Actions(driver);
actions.moveToElement(element).movebyoffset(p.x,p.y).click().perform();
ИЛИ
Если все еще не работает, используйте JavascriptExecutor
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", firstbutton);
Я видел это в ситуации, когда окно Chrome, управляемое селеном, было слишком маленьким. Элемент, на который нужно щелкнуть, был вне области просмотра, и поэтому он не работал.
Это звучит логично... реальный пользователь должен будет либо изменить размер окна, либо прокрутить, чтобы можно было увидеть элемент и фактически щелкнуть по нему.
После того, как я проинструктировал драйвер селена, чтобы правильно установить размер окна, эти проблемы исчезли для меня. API веб-драйвера описан здесь.
Получал эту ошибку при запуске тестов без головы с xvfb-run. Они работали безупречно на местном уровне. При использовании chrome версии webdriver / chromedriver / chrome / java и т. Д. Идентичны.
Ошибка "не исправить" в chromedriver - ссылка на GitHub, на которую указал Тони Лампада, подсказывает, что это может быть связано с тем, что отображается / не отображается на экране.
Справочное сообщение для xvfb-run показывает следующее:
-s ARGS --server-args=ARGS arguments (other than server number and
"-nolisten tcp") to pass to the Xvfb server
(default: "-screen 0 640x480x8")
Изменение разрешения для xvfb убрало ошибку:
xvfb-run -s "-screen 0 1280x1024x16" ...
Рубин / Watir-WebDriver/ хром
Я использую следующий трюк и похоже, что он работает:
#scroll to myelement
@browser.execute_script "window.scrollTo(#{myelement.element.wd.location[0]},#{myelement.element.wd.location[1]})"
# click myelement
myelement.when_present.fire_event("click")
Я тоже боролся с этой проблемой. Код отлично работает в FF, не работает в Chrome. То, что я пытался сделать, это щелкнуть по флажку - если его не было видно, я бы прокрутил его, а затем щелкнул. Даже просмотр в Chrome работает, только несколько нижних пикселей флажка не были видны, поэтому веб-драйвер отказывался нажимать на него.
Мой обходной путь заключается в следующем:
WebElement element = _sectorPopup.findElement(...);
((Locatable) element).getCoordinates().inViewPort();
try {
element.click();
} catch (Exception e) {
new Actions(getWebDriver()).sendKeys(Keys.PAGE_DOWN).perform();
element.click();
}
Chrome также имеет проблемы с sendKeys, иногда необходимо использовать действия. Очевидно, вам нужно знать, в каком направлении и сколько вам нужно пройти, чтобы ваш пробег мог варьироваться. Но я предпочитаю это взлому javascript, поэтому я публикую его здесь на тот случай, если кто-то найдет это полезным.
Я получил ту же проблему при запуске сценария селена в Python. Вот что я использовал для нажатия на элемент:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).click(element).perform()
Сначала попробуйте получить последнюю версию драйвера Chrome и проверьте, решает ли он проблему.
В моем случае это не решило проблему. Но следующее решение у меня сработало до сих пор. Ниже приведен код C#, но вы можете следовать той же логике на вашем конкретном языке. Что мы делаем здесь,
Шаг 1: Сфокусируйтесь на элементе, используя объект Selenium Actions,
Шаг 2: Затем нажмите на элемент
Шаг 3: Если есть исключение, то мы инициируем событие JavaScript "Click" для элемента, выполняя сценарий JavaScript с помощью метода "ExecuteScript" драйвера браузера Selenium.
Вы также можете пропустить шаги 1 и 2 и попробовать только шаг 3. Шаг 3 будет работать сам по себе, но я заметил странное поведение в одном сценарии, когда шаг 3, даже если он успешно щелкнул по элементу, вызвал неожиданное поведение в других частях моего кода после щелчка по элементу.
try
{
//Setup the driver and navigate to the web page...
var driver = new ChromeDriver("folder path to the Chrome driver");
driver.Navigate().GoToUrl("UrlToThePage");
//Find the element...
var element = driver.FindElement(By.Id("elementHtmlId"));
//Step 1
new Actions(driver).MoveToElement(element).Perform();
//Step 2
element.Click();
}
catch (Exception)
{
//Step 3
driver.ExecuteScript("document.getElementById('elementHtmlId').click();");
}
При использовании Protractor мне это помогло:
var elm = element(by.css('.your-css-class'));
browser.executeScript("arguments[0].scrollIntoView();", elm.getWebElement());
elm.click();
Я сделал этот метод на основе комментария от ответа Тони Лампады. Это работает очень хорошо.
def scroll_to(element)
page.execute_script("window.scrollTo(#{element.native.location.x}, #{element.native.location.y})")
end
Я столкнулся с подобной проблемой, когда мне приходилось ставить два флажка один за другим. Но я получал ту же ошибку, что и выше. Затем я добавил ожидание между своими шагами для проверки флажков... это работает нормально и замечательно. Вот шаги:-
When I visit /administrator/user_profiles
And I press xpath link "//*[@id='1']"
Then I should see "Please wait for a moment..."
When I wait for 5 seconds
And I press xpath link "//*[@id='2']"
Then I should see "Please wait for a moment..."
When I visit /administrator/user_profiles_updates
Сегодня у меня такая же проблема. Вы мне не поверите, если я скажу, как я решил проблему.
By maximizing the browser size
Да, это проблема с указателем, которая означает размер браузера. Для этого вам просто нужно увеличить размер окна вручную или с помощью кода.
Причина этой ошибки заключается в том, что элемент, на который вы пытаетесь щелкнуть, не находится в области просмотра (область, видимая пользователем) браузера. Таким образом, способ преодолеть это - сначала прокрутить до нужного элемента, а затем выполнить щелчок.
Javascript:
async scrollTo (webElement) {
await this.driver.executeScript('arguments[0].scrollIntoView(true)', webElement)
await this.driver.executeScript('window.scrollBy(0,-150)')
}
Джава:
public void scrollTo (WebElement e) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeAsyncScript('arguments[0].scrollIntoView(true)', e)
js.executeAsyncScript('window.scrollBy(0,-150)')
}
Объяснение сообщения об ошибке:
Сообщение об ошибке просто говорит, что элемент, на который вы хотите нажать, присутствует, но он не виден. Это может быть покрыто чем-то или временно не видно.
Может быть много причин, почему элемент не виден в момент теста. Пожалуйста, повторно проанализируйте свою страницу и найдите правильное решение для вашего случая.
Решение для конкретного случая:
В моем случае эта ошибка возникает, когда всплывающая подсказка к элементу экрана, на котором я только что щелкнул, всплывала над элементом, который я хотел щелкнуть следующим. Defocus был решением, которое мне было нужно.
- Быстрое решение, как расфокусировать, было бы щелкнуть по некоторому другому элементу в другой части экрана, который не делает ничего. ничего не происходит после действия щелчка.
- Правильным решением будет позвонить
element.blur()
на элементе, всплывающем во всплывающей подсказке, что заставит всплывающую подсказку исчезнуть.
По-видимому, это является результатом ошибки "Не исправить" в двоичном файле драйвера Chrome.
Одно решение, которое сработало для меня (наш пробег может меняться), можно найти в этом обсуждении в группе Google, комментарий № 3:
https://groups.google.com/forum/?fromgroups=
Соответствующая часть прямо здесь:
С тех пор я обошел проблему, перейдя непосредственно к разделу родительского якоря пролета.
. Driver.Navigate() GoToUrl(driver.FindElement(By.Id(embeddedSpanIdToClick)) FindElement(By.XPath("..")) GetAttribute(" HREF")..);
В моем случае я использую Python, поэтому, как только я получил нужный элемент, я просто использовал
driver.get(ViewElm.get_attribute('href'))
Однако я ожидаю, что это сработает только в том случае, если элемент, на который вы пытаетесь щелкнуть, является ссылкой...
Если у вас есть jQuery
загруженный на странице, вы можете выполнить следующую команду javascript:
"$('#" + element_id + "').click()"
Пример использования Python Executor:
driver.execute_script("$('#%s').click()" % element_id)
Ответ Тони Лампада, комментарий № 27, действительно решил эту проблему для меня, за исключением того, что он предоставил код Java, и мне нужен Python. Вот функция Python, которая прокручивает до позиции элемента и затем щелкает по нему.
def scroll_to_and_click(xpath):
element = TestUtil.driver.find_element_by_xpath(xpath)
TestUtil.driver.execute_script('window.scrollTo(0, ' + str(element.location['y']) + ');')
element.click()
Это решило проблему для меня в Chrome 34.0. Это не нанесло вреда в Firefox 28.0 и IE 11; эти браузеры не подвержены этой проблеме, но прокрутка до положения элемента до щелчка по нему все еще не плохая вещь.
Я столкнулся с той же проблемой с clj-webdriver (clojure port of Selenium). Я только что перевел предыдущее решение для удобства. Вы можете вызвать эту функцию, прежде чем делать щелчок или что-либо еще, чтобы избежать этой проблемы.
(defn scrollTo
"Scrolls to the position of the given css selector if found"
[q]
(if (exists? q)
(let [ loc (location-once-visible q) jscript (str "window.scrollTo(" (:x loc) "," (:y loc) ")") ]
(execute-script jscript))))
Я встретил это, потому что диалоговое окно загрузки на этот элемент. Я просто решаю это, добавив ожидание, прежде чем работать с этим элементом.
try {
Thread.sleep((int) (3000));
} catch (InterruptedException e) {
//
e.printStackTrace();
}
Надеюсь, это поможет!
Это может произойти, если элемент меняет положение, когда драйвер пытается щелкнуть по нему (я видел это и в IE). Драйвер сохраняет исходную позицию, но к тому времени, когда он фактически нажимает на нее, эта позиция больше не указывает на этот элемент. Кстати, у драйвера FireFox такой проблемы нет, очевидно, он "щелкает" по элементам программно.
В любом случае, это может произойти, когда вы используете анимацию или просто динамически меняете высоту элементов (например, $("#foo").height(500)
). Вам нужно убедиться, что вы нажимаете на элементы только после того, как их высота "установилась". Я закончил с кодом, который выглядит следующим образом (привязки C#):
if (!(driver is FirefoxDriver))
{
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(
d => d.FindElement(By.Id(someDynamicDiv)).Size.Height > initialSize);
}
В случае анимации или любого другого фактора, который вы не можете легко запросить, вы можете использовать "универсальный" метод, который ожидает, что элемент будет стационарным:
var prevLocation = new Point(Int32.MinValue, Int32.MinValue);
int stationaryCount = 0;
int desiredStationarySamples = 6; //3 seconds in total since the default interval is 500ms
return new WebDriverWait(driver, timeout).Until(d =>
{
var e = driver.FindElement(By.Id(someId));
if (e.Location == prevLocation)
{
stationaryCount++;
return stationaryCount == desiredStationarySamples;
}
prevLocation = e.Location;
stationaryCount = 0;
return false;
});
Я получал эту ошибку, потому что я тестировал зависание, а затем мне нужно было щелкнуть ссылку под всплывающей подсказкой. Решение было добавить page.find('.sp-logo').hover
до click_link
чтобы убрать всплывающую подсказку.
Попробуйте развернуть браузер, когда вы работаете с разрешением более 1024x768.
driver.manage().window().maximize();
Я делаю своего рода грубую силу кликов, и это работает для меня.
try:
elem.click()
except:
print "failed to click"
size = elem.size
mid_of_y = int(size["height"])/2
stepts_to_do_to_left = int(size["width"])
while stepts_to_do_to_left > 0:
try:
print stepts_to_do_to_left, mid_of_y
action = webdriver.common.action_chains.ActionChains(driver)
action.move_to_element_with_offset(elem, mid_of_y, stepts_to_do_to_left)
action.click()
action.perform()
print "DONE CLICK"
break
except:
pass
После тестирования всех упомянутых предложений ничего не сработало. Я сделал этот код. Это работает, но не красиво
public void click(WebElement element) {
//https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
while(true){
try{
element.click();
break;
}catch (Throwable e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
public void click(String css) {
//https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
while(true){
try{
driver.findElement(By.cssSelector(css)).click();
break;
}catch (Throwable e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
Забавно, все время, которое я проводил, глядя на различные ответы, никто не пробовал очевидного, чего, конечно, я тоже не делал. Если на вашей странице один и тот же идентификатор использовался несколько раз, как на моей ((newButton),), а нужный вам не первый найденный, то, по всей вероятности, вы получите эту ошибку. Самое простое, что можно сделать (C#):
var testIt = driver.FindElements(By.Id("newButton"));
Обратите внимание, что это FindElements, а не FindElement.
А затем проверьте, сколько результатов вернулось из поиска. Если это второй, вы можете использовать:
testit[1].Click();
Или получите те, кто повторно использовал идентификаторы, чтобы исправить их.
Я также застрял на два дня по одной и той же причине: на самом деле прокрутка заставит его работать, потому что, возможно, данные не могут быть загружены должным образом, что может вызывать одну и ту же ошибку снова и снова.
Я сделал случайную прокрутку вниз, один раз с помощью (0,-500), затем (0,400), затем (0.-600), и вы можете задать эти значения прокрутки в соответствии с вашим использованием. Просто прокрутите его там, где у вас есть содержимое, чтобы нажать.
driver.execute_script("scrollBy(0,-500);")
sleep(5)
driver.execute_script("scrollBy(0,400);")
sleep(5)
driver.execute_script("scrollBy(0,-600);")
sleep(5)
Это действительно сработало:)