Что не так с моим путем, чтобы выбрать следующее:
<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
Похоже, ваш процессор 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)]'
Я имею в виду Спецификация XPath, а не версию библиотеки ruby xpath
Могу ли я легко изменить спецификацию?
связанное обсуждение XPath matches
, которое также не поддерживается в версии 1.0: stackoverflow.com/a/35796197/2998271
У меня нет опыта работы с ruby, но на основе связанного обсуждения кажется, что процессор XPath реализует только XPath 1.0, поэтому у вас нет возможности использовать выражение XPath 2.0, следовательно, альтернативное выражение
Другой возможный 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 user2012677 Не видя HTML, невозможно дать наилучший подход - зависит от того, правильно ли метка связана с элементом и т. д. Если метка правильно связана с полем, то, если вы уже нашли поле, вы можете просто сделать find(:label, for: field)
- для родительской формы можно сделать field.ancestor('form')
Являются ли «find() и field.ancestor(), rspec, xpath или капибара? Могу ли я ожидать (рендеринг).find (: метка, для: поле) и ожидать (рендеринг). )?
@user2012677 user2012677 Это методы водосвинки, а не сопоставители rspec. Это выходит далеко за рамки вашего первоначального вопроса, и сложно дать полный ответ в комментариях. Задайте новый вопрос с образцом HTML и объясните, что именно вы пытаетесь сделать.
Разве caybara не работает с xpath v3?