-
Notifications
You must be signed in to change notification settings - Fork 781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support a way to listen for javascript events #184
Comments
To be more exact: I want to wait until the event fired |
also window.addHook gets oaded dynamicly but works like addEventListener |
Please provide a small HTML file with a small chromedp Go program to reproduce this issue. |
I'm also trying to listen and wait for events, specifically dom ready and window loaded. window.addEventListener('load', function() {
console.log('All assets are loaded')
})
document.addEventListener("DOMContentLoaded", function() {
console.log("done")
}); Maybe it's more of a request for help or new feature request than an issue. It's probably possible to use the Something like this would be nice: chromedp.WaitEvent('window.load', func(event chromedp.Event) {
fmt.Printf("%+v\n", event)
return nil
}),
chromedp.WaitEvent('document.DOMContentLoaded', func(event chromedp.Event) {
fmt.Printf("%+v\n", event)
return nil
}), |
@montanaflynn what you probably want to do is listen/wait for the devtools events instead. See https://godoc.org/github.com/chromedp/chromedp#example-ListenTarget--ConsoleLog, which you can use to listen for events like https://chromedevtools.github.io/devtools-protocol/tot/Page#event-loadEventFired. I guess a way to receive JS events would be useful, but it's not clear to me in what cases it would be useful. Happy to take a look if anyone provides a full example, or a way to make it work with https://chromedevtools.github.io/devtools-protocol/tot/. |
So this issue is really old and I am not activly working on the project anymore I had this issue with. I only roughly remember that I was working on a screenshot chat bot for https://intel.ingress.com/intel This is an google map which was heavily modified. The only way to know for sure that the map fully loaded at the position I looked at is to listen for the specific javascript events fired by the map. So thoose events I had are fired exactly by that map code (cant provide source as obviously that one is copyrighted by google and obfuscated anyway). But in general this issue basicly is the same for any regular javascript event no matter what fires it. Basicly what I wanted is to block until that event fired. Similiar to what is possible to wait on a DOM node in chromedp |
Thanks. I'm leaving the "needs info" label on, because I still don't know how this is possible with the devtools protocol. |
I'm also not aware of a clean way to do this with DTP, but I think you could probably hack together a solution with a breakpoint - maybe using |
If anyone figures out a way and wants to post about it here, that would be helpful. This issue is not at the top of my priority list for now. |
How does puppeteer handle this? |
I was able to code this POF on 0.3.0. Doesn't work on 0.1.2, which we still have a bunch of chromedp code for testing or UI I took this from some of the code shown here and other piecemeal stuff: https://godoc.org/github.com/chromedp/chromedp#ListenTarget And this seems to capture javascript errors in addition to the other chromedp tests we have. For the time being, this code will live in a separate repo since dep ensure we're locked on 0.1.2 with our old ChromeDP calls wrapped in GoConvey for BDD style testing. As a FYI, this works but crudely, but I could see further maturation - if it's a priority. Otherwise, I may try puppeteer too, but this actually works for some tests our director wanted recently, because we want to crawl our webpages and see what javascript errors are introduced with the latest checkins. And, of course private info has been replaced with public strings like username/pword, URLs package main import (
) var (
) func listenTargetWithStage() {
} func writeHTML(content string) http.Handler { func main() {
} |
This can be implemented with the |
With // github.com/chromedp/chromedp v0.7.1
package main
import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptest"
"time"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
// create a test server to serve the page
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprint(w, `
<html lang="en">
<head>
<script>
setTimeout(() => {
document.dispatchEvent(new Event('myCustomEvent'))
}, 3000)
</script>
</head>
<body>
</body>
</html>
`,
)
}))
defer ts.Close()
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ctx, cancel = context.WithTimeout(ctx, time.Minute)
defer cancel()
var timestamp int
err := chromedp.Run(ctx,
chromedp.ActionFunc(func(ctx context.Context) error {
_, err := page.AddScriptToEvaluateOnNewDocument("__fired__ = null; document.addEventListener('myCustomEvent', (e) => {__fired__ = Date.now();})").
Do(ctx)
return err
}),
chromedp.Navigate(ts.URL),
chromedp.Poll("__fired__", ×tamp, chromedp.WithPollingInterval(time.Second)),
)
if err != nil {
log.Fatal(err)
}
log.Print(timestamp)
} The key part is to subscribe to the event with javascript code, and when the event is fired, set the value of a javascript variable. Then use |
For anyone looking for something similar that doesn't involve polling, here's a staring point that does a limited version of the func ExposeFunc(name string, f func(string)) chromedp.Action {
return chromedp.Tasks{
chromedp.ActionFunc(func(ctx context.Context) error {
chromedp.ListenTarget(ctx, func(ev interface{}) {
if ev, ok := ev.(*cdruntime.EventBindingCalled); ok && ev.Name == name {
f(ev.Payload)
}
})
return nil
}),
cdruntime.AddBinding(name),
}
} The exposed function will be a global in every target and is available regardless of navigation. This is a one-way street which just accepts a single string argument. The Puppeteer version provides a fully transparent proxy with support for arguments and return values, which this does not. |
@daaku could you please extend your example to show how ExposeFunc() would be used to listen for a Javascript event? @kenshaw adding an example to chromedp/examples would be a welcome addition |
@porjo Please check the doc for Runtime.addBinding. And see pr #1222. |
Hi I have a event I listen to in JS via the following Code. How can I listen to the event via chromedp?
The text was updated successfully, but these errors were encountered: