#groovy #spock #geb
Вопрос:
У меня есть следующие строки в классе объектов страницы (для работы с Shadow DOM):
11 headerContent(wait:true) { $("content-header") }
12 shadowRoot0(wait:true) { js.exec("return arguments[0].shadowRoot", headerContent) }
Однако, когда вы запускаете его в тестах GebSpock, он постоянно терпит неудачу с приведенным ниже исключением:
| Caused by: java.lang.IllegalArgumentException: The last argument to the js function must be string-like
| at geb.js.JavascriptInterface.exec(JavascriptInterface.groovy:53)
| at test.ui.modules.RightHandHeader._clinit__closure1$_closure3(RightHandHeader.groovy:12)
...
Приведенные выше строки кода переводятся из нижеприведенных кодов с помощью JavascriptExecutor с WebElement, которые просто хорошо работают при выполнении:
WebElement shadowDomHost = driver.findElement(By.cssSelector("content-header"))
WebElement root0 = (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", shadowDomHost)
Должно быть, что-то не так при вызове js.exec в GebSpock.
У кого-нибудь есть какие-либо идеи по этому поводу ? Каков правильный синтаксис передачи параметров js.exec() ?
пс:
def exec(Object[] args) {
if (args.size() == 0) {
throw new IllegalArgumentException("there must be a least one argument")
}
def script
def jsArgs
if (args.size() == 1) {
script = args[0]
jsArgs = []
} else {
script = args.last()
jsArgs = args[0..(args.size() - 2)]
}
if (!(script instanceof CharSequence)) {
throw new IllegalArgumentException("The last argument to the js function must be string-like")
}
execjs(script.toString(), *jsArgs)
}
Комментарии:
1. В Geb строка 11 имеет тип объекта Navigator. Я попытался передать «headerContent.FirstElement()» в js.exec(). Однако все равно наблюдалось одно и то же исключение. Попробовал также преобразовать его в строковый тип, но он жаловался на символы «- amp;gt » в параметрах и т. Д. Не уверены, поддерживает ли Geb элементы shadow DOM?
Ответ №1:
Я полагаю, что вы поменяли порядок аргументов в js.exec()
вызове. На основе Книги Геба:
Объект js также имеет метод exec (), который можно использовать для запуска фрагментов JavaScript. Он идентичен методу JavascriptExecutor.executeScript (), за исключением того, что он принимает свои аргументы в другом порядке…
Пример: assert js.exec(1, 2, "return arguments[0] arguments[1];") == 3
Это должно означать, что это должно устранить вашу проблему:
shadowRoot0 (wait:true) {
js.exec(headerContent.singleElement(), "return arguments[0].shadowRoot")
}
Комментарии:
1. Привет, аспок, большое тебе спасибо за твою помощь ! Да, теперь это работает, когда передаете параметры в другом порядке. Функция js.exec() возвращает значение shadowRoot0 правильно. Однако возвращенный shadowRoot0 становится типом RemoteWebElement. В классе объектов страницы строка » Смена(ожидание:истина) { shadowRoot0.find(«сатурн-меню») } » перестает работать (вызвано: groovy.lang.missingmethod Исключение: Нет подписи метода: org.openqa.selenium.remote. RemoteWebElement.find() ). Есть ли способ перевести его в тип навигатора и продолжать использовать тот же синтаксис поиска Geb в объекте страницы ?
2. Вы можете создать a
Navigator
из aWebElement
, передав его$()
методу, доступному вcontent
блоках. Так что в вашем случае это было бы$(js.exec(headerContent.singleElement(), "return arguments[0].shadowRoot"))
3. @Guoping, я предлагаю вам принять правильный ответ здесь, чтобы закрыть вопрос. Он по-прежнему указан как открытый. Это тоже вопрос вежливости. Пожалуйста, нажмите на серую галочку, сделав ее зеленой. Спасибо.