XPath не находит элемент

Что не так с моим путем, чтобы выбрать следующее:

<label class = "form-control-label" for = "profile_form_state">State</label>

Xпуть:

xpath = '//label[ends-with(@for, "_state")]'

Я использую rspec и капибару

 expect(rendered).to have_xpath(xpath)

Ошибка:

   xmlXPathCompOpEval: function ends-with not found
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
120
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Похоже, ваш процессор XPath поддерживает только XPath 1.0, а ends-with определен в XPath 2.0 и выше. Но вы можете имитировать ends-with() в XPath 1.0, используя substring() и string-length() :

xpath = '//label["_state" = substring(@for, string-length(@for) - string-length("_state") +1)]'

Вы можете немного сократить выражение, заменив string-length("_state") +1 предварительно вычисленным значением 5 (длина слова _state минус единица):

xpath = '//label["_state" = substring(@for, string-length(@for) - 5)]'

Разве caybara не работает с xpath v3?

user2012677 28.05.2019 11:00

Я имею в виду Спецификация XPath, а не версию библиотеки ruby ​​xpath

har07 28.05.2019 11:15

Могу ли я легко изменить спецификацию?

user2012677 28.05.2019 11:16

связанное обсуждение XPath matches, которое также не поддерживается в версии 1.0: stackoverflow.com/a/35796197/2998271

har07 28.05.2019 11:17

У меня нет опыта работы с ruby, но на основе связанного обсуждения кажется, что процессор XPath реализует только XPath 1.0, поэтому у вас нет возможности использовать выражение XPath 2.0, следовательно, альтернативное выражение

har07 28.05.2019 11:21

Другой возможный Xpath

//label[contains(@for, '_state')]

или

//label[text()='State']

или

//label[contains(text(), 'State')]

Попробуйте следующий Xpath.

xpath = '//label[contains(., "State")]'
Ответ принят как подходящий

Как ответил @har07, XPath 1.0 (который реализуют браузеры) не имеет ends-with, но CSS предоставляет селектор атрибутов конца $=

expect(rendered).to have_css(‘label[for$=“_state”]’)

или вы можете использовать регулярное выражение со встроенным :label селектор Capybaras

expect(rendered).to have_selector(:label, for: /_state$/)

Если вы действительно хотите придерживаться XPath, а не CSS, вы можете использовать гем xpath, который Capybara использует внутри для создания своих собственных XPath, и написать

xpath = XPath.descendant(:label).where(XPath.attr(:for).ends_with('_start'))
expect(rendered).to have_xpath(xpath)

Хотелось бы просто использовать rspec, чтобы найти элемент css и его предыдущую родственную метку, а в другом случае — родительскую форму. Каков наилучший способ? В противном случае, каков ваш лучший рекомендуемый подход?

user2012677 28.05.2019 15:28

@user2012677 user2012677 Не видя HTML, невозможно дать наилучший подход - зависит от того, правильно ли метка связана с элементом и т. д. Если метка правильно связана с полем, то, если вы уже нашли поле, вы можете просто сделать find(:label, for: field) - для родительской формы можно сделать field.ancestor('form')

Thomas Walpole 28.05.2019 16:09

Являются ли «find() и field.ancestor(), rspec, xpath или капибара? Могу ли я ожидать (рендеринг).find (: метка, для: поле) и ожидать (рендеринг). )?

user2012677 28.05.2019 16:19

@user2012677 user2012677 Это методы водосвинки, а не сопоставители rspec. Это выходит далеко за рамки вашего первоначального вопроса, и сложно дать полный ответ в комментариях. Задайте новый вопрос с образцом HTML и объясните, что именно вы пытаетесь сделать.

Thomas Walpole 28.05.2019 18:11

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