etaoin 2024-04-26

I've query (e/query driver {:tag :a :fn/link "" :index 1})

how can I select the parent element of the above query?

Good question @raj.psgit! Here's me playing in my REPL:

(require '[etaoin.api :as e])

(def driver (e/firefox))

;; I'll amble over to a page we can both play with...
(e/go driver "")

;; And do a similar query to what you specified
(def elem (e/query driver {:tag :a :fn/link "" :index 1}))

;; Let's inspect a bit (looks good)
(e/get-element-tag-el driver elem)
;; => "a"
(e/get-element-inner-html-el driver elem)
;; => "ClojureScript Cheatsheet"

;; And this is counter-intuitive, I think, but it seems you can use the child fn to ask for the parent via XPath
(def parent-elem (e/child driver elem ".."))

;; This seems to work fine!
(e/get-element-tag-el driver parent-elem)
;; => "p"
(e/get-element-inner-html-el driver parent-elem)
;; => "<a href=\"\">ClojureScript Cheatsheet</a>"

(e/quit driver)
So, in my dabbling here, I've found I can use the child fn to get to its parent element. Lemme know if this helps, works for you, and answers your question.

sounds good @lee the answer is (e/child driver elem "..") which is from your snippet 🙂

yes you read it correctly

Hi I need help with etaoin for the following scenario

@raj.psgit you were close. Here's what I did below: 1. switched child to children to get all td tags. 2. turfed the parent-tr count is println, you were printing the length of the webdriver element id string 3. printed from the returned td-els 4. switched to doseq from for because for is lazy and won't be realized outside of a REPL Continuing from the REPL session I showed above:

(let [parent-tr (e/query driver {:css "tbody > tr:last-child"})
      td-els   (e/children driver parent-tr {:tag :td})]
  (println "tds count is " (count td-els))
  (doseq [td td-els]
    (println "td text" (e/get-element-text-el driver td))))
Here's what this outputs for me:
tds count is  5
td text Totals:
td text 
td text 84.65 %
td text 
td text 97.08 %

Awesome. Thanks @lee it works

👍 1

let say I have html attached here

I need to get the last <tr> element in the html inside the iframe, <#document> and again <html> and <body>

here is the screenshot of the inspect of the webpage

I wrote the code like this

I'm getting false response for (println (e/exists? driver :myframe))

yeap if you see my code above I've tried (e/switch-frame driver :myframe)

but it is not working

I think it is because iframe inturn contains html document

but also it is I'm not sure why (println (e/exists? driver :myframe)) returns false

I think maybe because you've switched inside the frame you can no longer see the frame element. Lemme try your HTML from here... just a sec.

I'm foggy on iframes in general... hold on another sec...

Oh... I think you were trying to convey in your HTML example that your iframe index.html is the content between the #document tags? Is that... your intent?

what I'm trying to do is to get all the <tr> tags elements

I'm trying your sample html and it seems incorrect. My question is related to that.

what you think is incorrect

if that is helpful

Ah you are working from the inspector only and not files?

That's why I can't simply try your HTML sample.

I took the screenshot if the html above is confusing

So @raj.psgit, you gave me some HTML. I assumed I could use this to replicate your problem, but you just pasted it from the inspector. Now that I understand this, I can can rework your example HTML to something I can use and help you more.

Oh no please. I'm good with what I have no need to paste more HTML!

when I did the file save as

Ok, I've saved your html and iframe HTML to separate files in my fiddle directory. fiddle/slack2024-04-26.html

<html xmlns="" xml:lang="en" lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html">
      <!-- CSS Tabs is licensed under Creative Commons Attribution 3.0 -  -->
   </head>
   <body onload="init('tab1');">
      <h1><a id="hudson_link" href="/job/Services/job/project-name/job/master/6121/">Back to #6121</a></h1>
      <h2><a id="zip_link" href="*zip*/Cloverage_20report.zip">Zip</a></h2>
      <ul id="tabnav">
         <li id="tab1" class="selected" onclick="updateBody('tab1')" value="index.html">Cloverage report</li>
         <script type="text/javascript">document.getElementById("hudson_link").innerHTML="Back to #6121";</script><script type="text/javascript">document.getElementById("hudson_link").href="/job/Services/job/project-name/job/master/6121/";</script><script type="text/javascript">document.getElementById("zip_link").href="*zip*/Cloverage_20report.zip";</script>
      </ul>
      <div>
         <iframe id="myframe" height="100%" width="100%" frameborder="0" src="slack2024-04-26-iframe.html" style="height: 26px;">
         </iframe>
      </div>
      </body>
</html>
And the iframe source fiddle/slack2024-04-26-iframe.html
<html>
               <head>
                  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                  <link rel="stylesheet" href="./coverage.css">
                  <title>Coverage Summary</title>
               </head>
               <body>
                  <table>
                     <thead>
                        <tr>
                           <td class="ns-name"> Namespace </td>
                           <td class="with-bar"> Forms </td>
                           <td class="with-number">Forms %</td>
                           <td class="with-bar"> Lines </td>
                           <td class="with-number">Lines %</td>
                           <td class="with-number">Total</td>
                           <td class="with-number">Blank</td>
                           <td class="with-number">Instrumented</td>
                        </tr>
                     </thead>
                     <tbody>
                        <tr>
                        <tr>
                           <td>Totals:</td>
                           <td class="with-bar"></td>
                           <td class="with-number">84.65 %</td>
                           <td class="with-bar"></td>
                           <td class="with-number">97.08 %</td>
                        </tr>
                     </tbody>
                  </table>
               </body>
               <html>

So working with this in my REPL let's fire up a firefox session and bring up the test page:

(require '[etaoin.api :as e]
         '[ :as io])

(def driver (e/firefox))

(e/go driver (-> "fiddle/slack2024-04-26.html" io/file .toURI str))
Now, notice that we can find the :myframe element before we switch to it:
(e/exists? driver :myframe)
;; => true
But after we switch inside the iframe we can no longer see the iframe element (because we are inside it):
(e/switch-frame driver :myframe)

(e/exists? driver :myframe)
;; => false
Now that we are inside the iframe, I'll search for the last tr in the tbody like so:
(def elem (e/query driver {:css "tbody > tr:last-child"}))
And let's see if we go what we expected:
(e/get-element-tag-el driver elem)
;; => "tr"

(e/get-element-text-el driver elem)
;; => "Totals: 84.65 % 97.08 %"
I think that looks good.

Does that help?

yes it helped 🙂

thank you so much

You are welcome, @raj.psgit; feel free to drop by if you get stuck again with Etaoin.

Hey @lee one more question

I want to return child <td> as vector

(let [parent-tr (e/query driver {:css "tbody > tr:last-child"})
      td-els   (e/child driver parent-tr {:tag :td})]
  (println "parent-tr count is " (count parent-tr))
  (println "row-els count is " (count td-els))
  (for [row parent-tr]
    (println (e/get-element-text-el driver row)))
  #_(clojure.pprint/pprint (map  #(e/get-element-text driver %) td-els)))

the final for is not printing anything any idea?