I am creating an app to using [chromedp][1]
How can I check for an element is present in the page?
I tried to use cdp.WaitVisible()
but it didn't give me what I wanted.
I need this so I can make dictions if the application will do one thing or the other.
For this example, suppose I need to know if the search input is present or not
How can I do that?
[1]: https://github.com/knq/chromedp
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"time"
cdp "github.com/knq/chromedp"
cdptypes "github.com/knq/chromedp/cdp"
)
func main() {
var err error
// create context
ctxt, cancel := context.WithCancel(context.Background())
defer cancel()
// create chrome instance
c, err := cdp.New(ctxt, cdp.WithLog(log.Printf))
if err != nil {
log.Fatal(err)
}
// run task list
var site, res string
err = c.Run(ctxt, googleSearch("site:brank.as", "Easy Money Management", &site, &res))
if err != nil {
log.Fatal(err)
}
// shutdown chrome
err = c.Shutdown(ctxt)
if err != nil {
log.Fatal(err)
}
// wait for chrome to finish
err = c.Wait()
if err != nil {
log.Fatal(err)
}
log.Printf("saved screenshot of #testimonials from search result listing `%s` (%s)", res, site)
}
func googleSearch(q, text string, site, res *string) cdp.Tasks {
var buf []byte
sel := fmt.Sprintf(`//a[text()[contains(., '%s')]]`, text)
return cdp.Tasks{
cdp.Navigate(`https://www.google.com`),
cdp.Sleep(2 * time.Second),
cdp.WaitVisible(`#hplogo`, cdp.ByID),
cdp.SendKeys(`#lst-ib`, q+"
", cdp.ByID),
cdp.WaitVisible(`#res`, cdp.ByID),
cdp.Text(sel, res),
cdp.Click(sel),
cdp.Sleep(2 * time.Second),
cdp.WaitVisible(`#footer`, cdp.ByQuery),
cdp.WaitNotVisible(`div.v-middle > div.la-ball-clip-rotate`, cdp.ByQuery),
cdp.Location(site),
cdp.Screenshot(`#testimonials`, &buf, cdp.ByID),
cdp.ActionFunc(func(context.Context, cdptypes.Handler) error {
return ioutil.WriteFile("testimonials.png", buf, 0644)
}),
}
}
Here is my answer. The web page is www.google.co.in
. The element used is lst-ib
, Text box present on the page.
Navigate the page.
Wait until the element is visible.
Read the value of the element. This is first time page is being loaded so obviously value will be ""
.
Assume, you have modified the value of the element by typing in the text box. Now, if we try to read the value of the same element lst-ib
then we should get the updated value.
My code is below,
package main
import (
"context"
"log"
cdp "github.com/knq/chromedp"
)
func main() {
var err error
// create context
ctxt, cancel := context.WithCancel(context.Background())
defer cancel()
// create chrome instance
c, err := cdp.New(ctxt)
if err != nil {
log.Fatal(err)
}
// run task list
var res, value, newValue string
err = c.Run(ctxt, text(&res, &value, &newValue))
if err != nil {
log.Fatal(err)
}
// shutdown chrome
err = c.Shutdown(ctxt)
if err != nil {
log.Fatal(err)
}
// wait for chrome to finish
err = c.Wait()
if err != nil {
log.Fatal(err)
}
if len(value) > 1 {
log.Println("Search Input is present.")
} else {
log.Println("Search Input is NOT present.")
}
log.Println("New updated value: ", newValue);
}
func text(res, value, newValue *string) cdp.Tasks {
return cdp.Tasks{
cdp.Navigate(`https://www.google.co.in`),
cdp.WaitVisible(`lst-ib`, cdp.ByID),
cdp.EvaluateAsDevTools("document.getElementById('lst-ib').value", value),
cdp.EvaluateAsDevTools("document.getElementById('lst-ib').value='Hello';document.getElementById('lst-ib').value", newValue),
}
}
To run code use go run <FileName>.go
I am getting following output which was expected:
$ go run main.go
2017/09/28 20:05:20 Search Input is NOT present.
2017/09/28 20:05:20 New updated value: Hello
NOTE:
First I checked with Google Chrome Developer Tools
to get exact Javascript
s for my need. It helps a lot. I have added the screenshot of the Javascript I tried on Chrome Developer Tools.
I hope it helps you. :)
I'm facing the same problem, not sure if it is the same case, here's my code:
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
var existingNodes []*cdp.Node
var nonExistingNodes []*cdp.Node
err := chromedp.Run(ctx,
chromedp.Navigate(`https://www.google.com`),
chromedp.WaitVisible("div.ctr-p"),
chromedp.Query("#fsl a", chromedp.AtLeast(0), chromedp.After(func(i context.Context, n ...*cdp.Node) error {
existingNodes = n
return nil
})),
chromedp.Query("#fsl div.nonexists", chromedp.AtLeast(0), chromedp.After(func(i context.Context, n ...*cdp.Node) error {
nonExistingNodes = n
return nil
})),
)
if err != nil {
panic(err)
}
fmt.Printf("existingNodes count: %d
", len(existingNodes))
fmt.Printf("nonExistingNodes count: %d
", len(nonExistingNodes))
the result is: existingNodes count: 3 nonExistingNodes count: 0