В наших тестах на селен мы используем драйвер Google Chrome (язык Clojure).
(-> driver
(try
(.findElement (By/id "my-text-input"))
(catch Exception ex
(log/errorf ex " error caught!!"))))
Однако я получил ошибку
java.lang.IllegalArgumentException: No matching field found: findElement for class org.openqa.selenium.By$ById
at clojure.lang.Reflector.getInstanceField(Reflector.java:271)
at clojure.lang.Reflector.invokeNoArgInstanceMember(Reflector.java:315)
at com.my.company$connect$fn__15343.invoke(selenium.clj:50)
at com.my.company.selenium$connect.invokeStatic(selenium.clj:49)
at com.my.company.selenium$connect.invoke(selenium.clj:29)
Обратите внимание, что, насколько мне известно, эта проблема возникает только на чипах Mac, потому что мои товарищи по команде, у которых есть процессор Intel, не видят ошибки.
Код не имеет особого смысла.
Макросу потоковой обработки ->
не важно, какое содержимое будет в следующей форме — он просто помещает свои аргументы друг в друга, один за другим. Поэтому его не волнует, что вы используете (try (...))
и хотите поместить его driver
внутрь этих (...)
— он все равно поместит его на вторую позицию, чтобы он стал (try driver (...))
.
Это означает, что вы в конечном итоге вызываете (.findElement ...)
непосредственно по результату (By/id ...)
, и именно поэтому вы видите эту ошибку.
Вам нужно изменить код, чтобы он стал (.findElement driver ...)
.
Я ничего не знаю о Selenium или M1, но Clojure выглядит явно неправильно. У вас есть вложенность ->
и try
наоборот. Макросформа ->
разворачивается до
(try
driver
(.findElement (By/id "my-text-input"))
(catch ...))
то есть вы оцениваете driver
на предмет побочных эффектов (которых у него не может быть, поскольку это всего лишь переменная), а затем выбрасываете его. Затем вы вызываете .findElement
по результату By/id
, вообще не используя драйвер. Конечно, вместо этого вы хотели
(try
(.findElement driver (By/id "my-text-input"))
(catch ...))
то есть вызов метода .findElement
драйвера и передача ему результата By/id
. Конечно, вы можете просто написать это напрямую, но если вы предпочитаете стиль ->
(я тоже), просто поместите это внутри try
обычно:
(try
(-> driver
(.findElement ...))
(catch ...))
Или, если вы маньяк, вы можете настоять на использовании ->
вместо try
, но вам придется писать в довольно странном порядке (не делайте этого):
(-> driver
(.findElement ...)
(try (catch ...)))
Все эти три опции макрорасширяются до одного и того же.