Skip to content

Commit

Permalink
add query-tree fn (#269)
Browse files Browse the repository at this point in the history
* add query-tree fn

* update
  • Loading branch information
Uunnamed authored Aug 7, 2020
1 parent 3647e93 commit 943d4a7
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 10 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,26 @@ Finally it is also possible to obtain the *nth* element directly by using
Note the use of `click-el` here, as `query-all` returns an element, not a
selector that can be passed to `click` directly.

#### Getting elements like in a tree

`query-tree` takes selectors and acts like a tree.
Every next selector queries elements from the previous ones.
The fist selector relies on find-elements, and the rest ones use find-elements-from

```clojure
(query-tree driver {:tag :div} {:tag :a})
```

means

```
{:tag :div} -> [div1 div2 div3]
div1 -> [a1 a2 a3]
div2 -> [a4 a5 a6]
div3 -> [a7 a8 a9]
```
so the result will be [a1 ... a9]

### Interacting with queried elements

To interact with elements found via a query you have to pass the query result to
Expand Down
34 changes: 33 additions & 1 deletion resources/html/test2.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="" lang="en">

<div>
<div>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</div>
<div>
<ul>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
</div>
<div>
<select id="select">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</div>
<div>
<a href="">link1</a>
</div>
<a href="">link2</a>
</div>
</html>
41 changes: 32 additions & 9 deletions src/etaoin/api.clj
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,29 @@
el (apply query driver q (butlast more))]
(find-elements-from* driver el loc term))))

(defn query-tree
"Takes selectors and acts like a tree.
Every next selector queries elements from the previous ones.
The fist selector relies on find-elements,
and the rest ones use find-elements-from
{:tag :div} {:tag :a}
means
{:tag :div} -> [div1 div2 div3]
div1 -> [a1 a2 a3]
div2 -> [a4 a5 a6]
div3 -> [a7 a8 a9]
so the result will be [a1 ... a9]
"
[driver q & qs]
(reduce (fn [elements q]
(let [[loc term] (query/expand driver q)]
(set (mapcat (fn [e]
(find-elements-from* driver e loc term))
elements))))
(let [[loc term] (query/expand driver q)]
(find-elements* driver loc term))
qs))

(defn child
"Finds a single element under given root element."
Expand Down Expand Up @@ -721,7 +744,7 @@
- does not work in Phantom.js since it does not have a virtual mouse API;
- does not work in Safari.
"
"
[driver q-from q-to]
(mouse-move-to driver q-from)
(with-mouse-btn driver
Expand Down Expand Up @@ -954,7 +977,7 @@
- `:y2`: bottom right `y` coordinate;
- `:width`: width as a difference b/w `:x2` and `:x1`;
- `:height`: height as a difference b/w `:y2` and `:y1`.
"
"
[driver q]
(let [el (query driver q)
{:keys [width height]} (get-element-size-el driver el)
Expand All @@ -978,7 +1001,7 @@
intersection.
Returns true or false.
"
"
[driver q1 q2]
(let [a (get-element-box driver q1)
b (get-element-box driver q2)]
Expand Down Expand Up @@ -1056,7 +1079,7 @@
(def driver (firefox))
(get-element-attr driver {:tag :a} :class)
>> \"link link__external link__button\" ;; see note above
"
"
[driver q name]
(get-element-attr-el driver (query driver q) name))

Expand Down Expand Up @@ -1104,7 +1127,7 @@
(def driver (firefox))
(get-element-css driver {:id :content} :background-color)
>> \"rgb(204, 204, 204)\" ;; or \"rgba(204, 204, 204, 1)\"
"
"
[driver q prop]
(get-element-css-el driver (query driver q) prop))

Expand Down Expand Up @@ -1146,7 +1169,7 @@
For element `el` in `<div id=\"el\"><p class=\"foo\">hello</p></div>` it will
be \"<p class=\"foo\">hello</p>\" string.
"
"
[driver q]
(get-element-inner-html-el driver (query driver q)))

Expand Down Expand Up @@ -1179,7 +1202,7 @@
"Returns inner element's text.
For `<p class=\"foo\">hello</p>` it will be \"hello\" string.
"
"
[driver q]
(get-element-text-el driver (query driver q)))

Expand Down Expand Up @@ -1250,7 +1273,7 @@
- `driver`: a driver instance,
- `cookie-name`: a string/keyword witn a cookie name.
"
"
[driver cookie-name]
(->> driver
get-cookies
Expand Down Expand Up @@ -2682,7 +2705,7 @@
- `driver`: driver instance,
- `file`: either a path to a file or a native `java.io.File` instance.
"
"
{:arglists '([driver file])}
dispatch-driver)

Expand Down
13 changes: 13 additions & 0 deletions test/etaoin/api_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,19 @@
(is (= (vec tag-names)
["div" "b" "p" "span"])))))

(deftest test-query-tree
(let [url (-> "html/test2.html" io/resource str)
_ (go *driver* url)
all-div (query-tree *driver* {:tag :div})
all-li (query-tree *driver* {:tag :li})
li-three-level (query-tree
*driver* {:tag :div} {:tag :div} {:tag :div} {:tag :li})
tag-a (query-tree *driver* {:tag :div} {:tag :div} {:tag :a})]
(is (= 6 (count all-div)))
(is (= 8 (count all-li)))
(is (= 5 (count li-three-level)))
(is (= 1 (count tag-a)))))

(deftest test-child
(let [parent-el (query *driver* {:css "#wc3-barks"})
child-el (child *driver* parent-el {:css ".crypt-lord"})
Expand Down

0 comments on commit 943d4a7

Please sign in to comment.