From fac0e72ccb1cbb1a56669a6898c31e4fbb8b6bef Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Wed, 17 Jul 2024 13:53:35 -0500 Subject: [PATCH] Add :fn/index as alias for :index in map syntax (#603) --- CHANGELOG.adoc | 2 ++ doc/01-user-guide.adoc | 14 +++++++------- env/test/resources/static/test.html | 10 ++++++++++ src/etaoin/impl/xpath.clj | 8 ++++---- test/etaoin/api_test.clj | 7 +++++++ 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index b4ebd85f..5a98b6af 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,8 @@ A release with an intentional breaking changes is marked with: * https://github.com/clj-commons/etaoin/issues/566[#566]: Recognize `:driver-log-level` for Edge * https://github.com/clj-commons/etaoin/issues/604[#604]: Add support for shadow DOM (https://github.com/dgr[@dgr]) +* https://github.com/clj-commons/etaoin/issues/603[#603]: Add :fn/index as alias for :index in map syntax +(https://github.com/dgr[@dgr]) * bump all deps to current versions * tests ** https://github.com/clj-commons/etaoin/issues/572[#572]: stop using chrome `--no-sandbox` option, it has become problematic on Windows (and we did not need it anyway) diff --git a/doc/01-user-guide.adoc b/doc/01-user-guide.adoc index 539f356c..f448f4d5 100644 --- a/doc/01-user-guide.adoc +++ b/doc/01-user-guide.adoc @@ -564,14 +564,14 @@ The rules are: * A `:tag` key represents a tag's name. Defaults to `*`. -* An `:index` key expands into the trailing XPath `[x]` clause. -Useful when you need to select a third row from a table, for example. * Any non-special key represents an attribute and its value. * `:fn/` is a prefix followed by a supported query function. There are several query functions of the form `:fn/*`. Each query function takes a parameter which is the value associated with the query function keyword in the map. +* `:fn/index`: Takes an positive integer parameter. + This expands into a trailing XPath `[x]` clause and is useful when you need to select a specific row in a table, for example. * `:fn/text`: Takes a string parameter. Matches if the element has the exact text specified. * `:fn/has-text`: Takes a string parameter. Matches if the element includes the specified text. @@ -608,7 +608,7 @@ Here are some examples of the map syntax: + [source,clojure] ---- -(= (e/query driver {:tag :div :index 1}) +(= (e/query driver {:tag :div :fn/index 1}) ;; equivalent via xpath: (e/query driver ".//div[1]")) ;; => true @@ -645,7 +645,7 @@ Here are some examples of the map syntax: + [source,clojure] ---- -(e/get-element-text driver {:fn/has-text "blarg" :index 3}) +(e/get-element-text driver {:fn/has-text "blarg" :fn/index 3}) ;; => "blarg in a p" ;; equivalent in xpath: @@ -765,11 +765,11 @@ Maybe you want to click on the second link within: ---- -You can use the `:index` like so: +You can use the `:fn/index` like so: [source,clojure] ---- -(e/click driver [{:tag :li :class :search-result :index 2} {:tag :a}]) +(e/click driver [{:tag :li :class :search-result :fn/index 2} {:tag :a}]) ;; check click tracker from our sample page: (e/get-element-text driver :clicked) ;; => "b" @@ -1252,7 +1252,7 @@ The most important one, `scroll-query` jumps the the first element found with th ---- (e/go driver sample-page) ;; scroll to the 5th h2 heading -(e/scroll-query driver {:tag :h2} {:index 5}) +(e/scroll-query driver {:tag :h2} {:fn/index 5}) ;; and back up to first h1 (e/scroll-query driver {:tag :h1}) diff --git a/env/test/resources/static/test.html b/env/test/resources/static/test.html index 9071cef8..837d1a8e 100644 --- a/env/test/resources/static/test.html +++ b/env/test/resources/static/test.html @@ -208,6 +208,16 @@

Find multiple elements nested

+

Find elements with index

+ +
    +
  1. One
  2. +
  3. Two
  4. +
  5. Three
  6. +
  7. Four
  8. +
  9. Five
  10. +
+

Operate on multiple elements

diff --git a/src/etaoin/impl/xpath.clj b/src/etaoin/impl/xpath.clj index 9a7ea987..72b1a71b 100644 --- a/src/etaoin/impl/xpath.clj +++ b/src/etaoin/impl/xpath.clj @@ -81,7 +81,7 @@ [[_ bool]] (node-boolean "@enabled" bool)) -(defmethod clause :index +(defmethod clause :fn/index [[_ idx]] (if idx (node-index idx) @@ -99,7 +99,7 @@ [q] (let [[tag q] (pop-map q :tag) tag (or tag :*) - idx-key :index - [index q] (pop-map q idx-key) - nodes (concat (into [] q) {idx-key index})] + [fn-index q] (pop-map q :fn/index) + [index q] (pop-map q :index) + nodes (concat (into [] q) {:fn/index (or fn-index index)})] (node-join (concat [".//" (to-str tag)] (map clause nodes))))) diff --git a/test/etaoin/api_test.clj b/test/etaoin/api_test.clj index 802cd937..1847f93a 100644 --- a/test/etaoin/api_test.clj +++ b/test/etaoin/api_test.clj @@ -698,6 +698,13 @@ (is (= (count elements) 2)) (is (= texts ["1" "2"]))))) +(deftest test-fn-index + (testing ":fn/index" + (let [items (for [index (range 1 6)] + (->> (e/query *driver* {:class :indexed :fn/index index}) + (e/get-element-text-el *driver*)))] + (is (= items ["One" "Two" "Three" "Four" "Five"]))))) + (deftest test-multiple-elements (testing "tag names" (let [q {:xpath ".//div[@id='operate-multiple-elements']//*"}