Fork me on GitHub
#etaoin
<
2024-04-26
>
RAJKUMAR21:04:49

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

RAJKUMAR21:04:09

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

lread23:04:47

Good question @U02PR896TMG! 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.

RAJKUMAR23:04:07

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

lread00:04:46

yes you read it correctly

RAJKUMAR23:04:51

Hi I need help with etaoin for the following scenario

RAJKUMAR23:04:23

let say I have html attached here

RAJKUMAR23:04:47

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

RAJKUMAR23:04:01

here is the screenshot of the inspect of the webpage

RAJKUMAR23:04:25

I wrote the code like this

RAJKUMAR23:04:51

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

RAJKUMAR23:04:28

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

RAJKUMAR23:04:49

but it is not working

RAJKUMAR23:04:05

I think it is because iframe inturn contains html document

RAJKUMAR23:04:41

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

lread23:04:42

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.

lread00:04:13

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

lread00:04:11

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?

RAJKUMAR00:04:51

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

lread00:04:29

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

RAJKUMAR00:04:06

what you think is incorrect

RAJKUMAR00:04:35

if that is helpful

lread00:04:32

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

lread00:04:54

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

RAJKUMAR00:04:57

I took the screenshot if the html above is confusing

lread00:04:36

So @U02PR896TMG, 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.

lread00:04:38

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

RAJKUMAR00:04:39

when I did the file save as

lread00:04:25

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>

lread00:04:50

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.

lread00:04:36

Does that help?

RAJKUMAR00:04:54

yes it helped 🙂

RAJKUMAR00:04:00

thank you so much

lread00:04:17

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

RAJKUMAR05:04:10

Hey @UE21H2HHD one more question

RAJKUMAR05:04:29

I want to return child <td> as vector

RAJKUMAR05:04:42

(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)))

RAJKUMAR05:04:11

the final for is not printing anything any idea?

lread14:04:11

@U02PR896TMG 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 %

RAJKUMAR04:04:17

Awesome. Thanks @UE21H2HHD it works

👍 1