func TestWebView_URI(t *testing.T) { setup() defer teardown() mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {}) wantURI := server.URL + "/" var gotURI string webView.Connect("notify::uri", func() { glib.IdleAdd(func() bool { gotURI = webView.URI() if gotURI != "" { gtk.MainQuit() } return false }) }) glib.IdleAdd(func() bool { webView.LoadURI(server.URL) return false }) gtk.Main() if wantURI != gotURI { t.Errorf("want URI %q, got %q", wantURI, gotURI) } }
func TestWebView_Title(t *testing.T) { webView := NewWebView() defer webView.Destroy() wantTitle := "foo" var gotTitle string webView.Connect("notify::title", func() { glib.IdleAdd(func() bool { gotTitle = webView.Title() if gotTitle != "" { gtk.MainQuit() } return false }) }) glib.IdleAdd(func() bool { webView.LoadHTML("<html><head><title>"+wantTitle+"</title></head><body></body></html>", "") return false }) gtk.Main() if wantTitle != gotTitle { t.Errorf("want title %q, got %q", wantTitle, gotTitle) } }
func main() { gtk.Init(nil) win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) if err != nil { log.Fatal("Unable to create window:", err) } win.Connect("destroy", func() { gtk.MainQuit() }) win.Add(windowWidget()) // Native GTK is not thread safe, and thus, gotk3's GTK bindings may not // be used from other goroutines. Instead, glib.IdleAdd() must be used // to add a function to run in the GTK main loop when it is in an idle // state. // // Two examples of using glib.IdleAdd() are shown below. The first runs // a user created function, LabelSetTextIdle, and passes it two // arguments for a label and the text to set it with. The second calls // (*gtk.Label).SetText directly, passing in only the text as an // argument. // // If the function passed to glib.IdleAdd() returns one argument, and // that argument is a bool, this return value will be used in the same // manner as a native g_idle_add() call. If this return value is false, // the function will be removed from executing in the GTK main loop's // idle state. If the return value is true, the function will continue // to execute when the GTK main loop is in this state. go func() { for { time.Sleep(time.Second) s := fmt.Sprintf("Set a label %d time(s)!", nSets) _, err := glib.IdleAdd(LabelSetTextIdle, topLabel, s) if err != nil { log.Fatal("IdleAdd() failed:", err) } nSets++ s = fmt.Sprintf("Set a label %d time(s)!", nSets) _, err = glib.IdleAdd(bottomLabel.SetText, s) if err != nil { log.Fatal("IdleAdd() failed:", err) } nSets++ } }() win.ShowAll() gtk.Main() }
func TestWebView_LoadURI_load_failed(t *testing.T) { webView := NewWebView() defer webView.Destroy() loadFailed := false loadFinished := false webView.Connect("load-failed", func() { loadFailed = true }) webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := LoadEvent(event) switch loadEvent { case LoadFinished: loadFinished = true gtk.MainQuit() } }) glib.IdleAdd(func() bool { // Load a bad URL to trigger load failure. webView.LoadURI("http://127.0.0.1:99999") return false }) gtk.Main() if !loadFailed { t.Error("!loadFailed") } if !loadFinished { t.Error("!loadFinished") } }
func TestWebView_GetSnapshot(t *testing.T) { webView := NewWebView() defer webView.Destroy() webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := LoadEvent(event) switch loadEvent { case LoadFinished: webView.GetSnapshot(func(img *image.RGBA, err error) { if err != nil { t.Errorf("GetSnapshot error: %q", err) } if img.Pix == nil { t.Error("!img.Pix") } if img.Stride == 0 || img.Rect.Max.X == 0 || img.Rect.Max.Y == 0 { t.Error("!img.Stride or !img.Rect.Max.X or !img.Rect.Max.Y") } gtk.MainQuit() }) } }) glib.IdleAdd(func() bool { webView.LoadHTML(`<p id=foo>abc</p>`, "") return false }) gtk.Main() }
func TestWebView_RunJavaScript_exception(t *testing.T) { webView := NewWebView() defer webView.Destroy() wantErr := errors.New("An exception was raised in JavaScript") webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := LoadEvent(event) switch loadEvent { case LoadFinished: webView.RunJavaScript(`throw new Error("foo")`, func(result *gojs.Value, err error) { if result != nil { ctx := webView.JavaScriptGlobalContext() t.Errorf("want result == nil, got %q", ctx.ToStringOrDie(result)) } if !reflect.DeepEqual(wantErr, err) { t.Errorf("want error %q, got %q", wantErr, err) } gtk.MainQuit() }) } }) glib.IdleAdd(func() bool { webView.LoadHTML(`<p></p>`, "") return false }) gtk.Main() }
func TestWebView_RunJavaScript(t *testing.T) { webView := NewWebView() defer webView.Destroy() wantResultString := "abc" webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := LoadEvent(event) switch loadEvent { case LoadFinished: webView.RunJavaScript(`document.getElementById("foo").innerHTML`, func(result *gojs.Value, err error) { if err != nil { t.Errorf("RunJavaScript error: %s", err) } resultString := webView.JavaScriptGlobalContext().ToStringOrDie(result) if wantResultString != resultString { t.Errorf("want result string %q, got %q", wantResultString, resultString) } gtk.MainQuit() }) } }) glib.IdleAdd(func() bool { webView.LoadHTML(`<p id=foo>abc</p>`, "") return false }) gtk.Main() }
func TestWebView_LoadHTML(t *testing.T) { webView := NewWebView() defer webView.Destroy() loadOk := false webView.Connect("load-failed", func() { t.Errorf("load failed") }) webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := LoadEvent(event) switch loadEvent { case LoadFinished: loadOk = true gtk.MainQuit() } }) glib.IdleAdd(func() bool { webView.LoadHTML("<p>hello</p>", "") return false }) gtk.Main() if !loadOk { t.Error("!loadOk") } }
func Example() { runtime.LockOSThread() gtk.Init(nil) webView := webkit2.NewWebView() defer webView.Destroy() webView.Connect("load-failed", func() { fmt.Println("Load failed.") }) webView.Connect("load-changed", func(_ *glib.Object, i int) { loadEvent := webkit2.LoadEvent(i) switch loadEvent { case webkit2.LoadFinished: fmt.Println("Load finished.") fmt.Printf("Title: %q\n", webView.Title()) fmt.Printf("URI: %s\n", webView.URI()) webView.RunJavaScript("window.location.hostname", func(val *gojs.Value, err error) { if err != nil { fmt.Println("JavaScript error.") } else { fmt.Printf("Hostname (from JavaScript): %q\n", val) } gtk.MainQuit() }) } }) glib.IdleAdd(func() bool { webView.LoadURI("https://www.google.com/") return false }) gtk.Main() // output: // Load finished. // Title: "Google" // URI: https://www.google.com/ // Hostname (from JavaScript): "www.google.com" }
// TestConnectNotifySignal ensures that property notification signals (those // whose name begins with "notify::") are queried by the name "notify" (with the // "::" and the property name omitted). This is because the signal is "notify" // and the characters after the "::" are not recognized by the signal system. // // See // https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GObject-notify // for background, and // https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-new // for the specification of valid signal names. func TestConnectNotifySignal(t *testing.T) { runtime.LockOSThread() // Create any GObject that has defined properties. spacing := 0 box, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, spacing) // Connect to a "notify::" signal to listen on property changes. box.Connect("notify::spacing", func() { gtk.MainQuit() }) glib.IdleAdd(func(s string) bool { t.Log(s) spacing++ box.SetSpacing(spacing) return true }, "IdleAdd executed") gtk.Main() }
func TestWebView_LoadURI(t *testing.T) { setup() defer teardown() responseOk := false mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { w.Write([]byte("abc")) responseOk = true }) loadFinished := false webView.Connect("load-failed", func() { t.Errorf("load failed") }) webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := LoadEvent(event) switch loadEvent { case LoadFinished: loadFinished = true gtk.MainQuit() } }) glib.IdleAdd(func() bool { webView.LoadURI(server.URL) return false }) gtk.Main() if !responseOk { t.Error("!responseOk") } if !loadFinished { t.Error("!loadFinished") } }
func main() { flag.Usage = func() { fmt.Fprintln(os.Stderr) fmt.Fprintf(os.Stderr, "webkit-eval-js evaluates a JavaScript expression in the context of a web page\n") fmt.Fprintf(os.Stderr, "running in a headless instance of the WebKit browser.\n\n") fmt.Fprintf(os.Stderr, "Usage:\n\n") fmt.Fprintf(os.Stderr, "\twebkit-eval-js url script-file\n\n") fmt.Fprintf(os.Stderr, "url is the web page to execute the script in, and script-file is a local file\n") fmt.Fprintf(os.Stderr, "with the JavaScript you want to evaluate. The result is printed to stdout as JSON.\n\n") fmt.Fprintln(os.Stderr) fmt.Fprintf(os.Stderr, "Example usage:\n\n") fmt.Fprintf(os.Stderr, "\tTo return the value of `document.title` on https://google.com:\n") fmt.Fprintf(os.Stderr, "\t $ echo document.title | webkit-eval-js https://google.com /dev/stdin\n") fmt.Fprintf(os.Stderr, "\tPrints:\n") fmt.Fprintf(os.Stderr, "\t \"Google\"\n\n") fmt.Fprintf(os.Stderr, "Notes:\n\n") fmt.Fprintf(os.Stderr, "\tBecause a headless WebKit instance is used, your $DISPLAY must be set. Use\n") fmt.Fprintf(os.Stderr, "\tXvfb if you are running on a machine without an existing X server. See\n") fmt.Fprintf(os.Stderr, "\thttps://sourcegraph.com/github.com/sourcegraph/go-webkit2/readme for more info.\n") fmt.Fprintln(os.Stderr) os.Exit(1) } flag.Parse() if flag.NArg() != 2 { flag.Usage() os.Exit(1) } log := log.New(os.Stderr, "", 0) pageURL := flag.Arg(0) scriptFile := flag.Arg(1) if _, err := url.Parse(pageURL); err != nil { log.Fatalf("Failed to parse URL %q: %s", pageURL, err) } script, err := ioutil.ReadFile(scriptFile) if err != nil { log.Fatalf("Failed to open script file %q: %s", scriptFile, err) } runtime.LockOSThread() gtk.Init(nil) webView := webkit2.NewWebView() defer webView.Destroy() webView.Connect("load-failed", func() { fmt.Println("Load failed.") }) webView.Connect("load-changed", func(_ *glib.Object, event int) { loadEvent := webkit2.LoadEvent(event) switch loadEvent { case webkit2.LoadFinished: webView.RunJavaScript(string(script), func(val *gojs.Value, err error) { if err != nil { log.Fatalf("JavaScript error: %s", err) } else { json, err := val.JSON() if err != nil { log.Fatal("JavaScript serialization error: %s", err) } fmt.Println(string(json)) } gtk.MainQuit() }) } }) glib.IdleAdd(func() bool { webView.LoadURI(pageURL) return false }) gtk.Main() }