Отладка ошибки "Элемент не активен в точке"

Я вижу это только в 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)

Это действительно сработало:)

Другие вопросы по тегам