Почему капибара говорит, что узел устарел и как его решить? - PullRequest
0 голосов
/ 23 октября 2019

У меня есть тест spec / capybara, который ищет элемент, а затем пытается запустить JS-скрипт для прокрутки элемента в поле зрения. Однако Capybara утверждает, что узел устарел к тому времени, когда он пытается запустить JS. Спорные строки являются последовательными. Вот они:

element = page.find(selector, visible: false)
Capybara.current_session.driver.browser.execute_script(script, element.native)

Я уже отладил немало. При размещении отладчика между строками find и execute_script вызов element действительно возвращает устаревший узел Obsolete #<Capybara::Node::Element>.

Выполнение page.find(selector, visible: false) в отладчике не возвращает устаревший узел, а скореенормальный активный узел, который вы ожидаете #<Capybara::Node::Element tag="div" path="/HTML/BODY[1]/DIV[6]/DIV[2]/DIV[1]/DIV[1]/DIV[54]">

Кроме того, при удалении двух строк и их запуске вручную в отладчике капибара правильно находит элемент DOM, правильно запускает JS и спецификация передает

Соответствующий код:

  def scroll_to(selector, align = true)
    if align
      script = <<-JS
        arguments[0].scrollIntoView(true);
      JS
    else
      script = <<-JS
        arguments[0].scrollIntoView(false);
      JS
    end

    element = page.find(selector, visible: false)

    Capybara.current_session.driver.browser.execute_script(script, element.native)
  end

  scroll_to(".xdsoft_time[data-hour='13'][data-minute='15']")

1 Ответ

1 голос
/ 23 октября 2019

Не зная, что происходит на вашей странице, невозможно точно сказать, почему вы получаете ошибку «устаревший узел», но эта ошибка указывает на то, что первоначально найденный узел больше не находится на странице. Это может произойти, если вы посещаете новую страницу, если часть страницы, содержащая этот узел, заменяется на JS и т. Д.

Передача visible: false, а затем попытка прокрутить этот элемент на странице не приводит ксмысл в том, что если элемент не виден, то вы никогда не сможете прокрутить его в поле зрения (visible означает, что нарисовано на странице, это не значит «в окне просмотра»).

Другие проблемы с вашим кодом:

  1. вы не должны вызывать драйвер execute_script, а просто использовать сеанс Capybara execute_script (как правило, если вывы используете Capybara.current_session.driver.browser вы делаете что-то не так).

    page.execute_script(script, element)
    
  2. Capybara уже предоставляет scroll_to, поэтому используйте его вместо того, чтобы писать собственный

      page.scroll_to(page.find(selector)) # Defaults to scrolling to the top
    

    Если вам нужен контроль над выравниванием элемента, просто передайте опцию: align

      page.scroll_to(page.find(selector), align: :center) # :top, :bottom, :center
    
...