forked from go-rod/rod
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdev_helpers.go
127 lines (104 loc) · 2.92 KB
/
dev_helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// This file defines the helpers to develop automation.
// Such as when running automation we can use trace to visually
// see where the mouse going to click.
package rod
import (
"fmt"
"html"
"net/http"
"strings"
"time"
"github.com/ysmood/kit"
"github.com/ysmood/rod/lib/assets"
"github.com/ysmood/rod/lib/proto"
)
// check method and sleep if needed
func (b *Browser) trySlowmotion() {
if b.slowmotion == 0 {
return
}
time.Sleep(b.slowmotion)
}
func (el *Element) tryTrace(htmlMessage string) func() {
if !el.page.browser.trace {
return func() {}
}
return el.Trace(htmlMessage)
}
// ServeMonitor starts the monitor server
// The reason why not to use "chrome://inspect/#devices" is one target cannot be driven by multiple controllers.
func (b *Browser) ServeMonitor(host string) *kit.ServerContext {
if host == "" {
return nil
}
srv := kit.MustServer(host)
srv.Engine.GET("/", func(ctx kit.GinContext) {
res, err := proto.TargetGetTargets{}.Call(b)
kit.E(err)
ginHTML(ctx, kit.S(assets.Monitor, "list", res.TargetInfos))
})
srv.Engine.GET("/page/:id", func(ctx kit.GinContext) {
ginHTML(ctx, kit.S(
assets.MonitorPage,
"id", ctx.Param("id"),
))
})
srv.Engine.GET("/api/page/:id", func(ctx kit.GinContext) {
info, err := proto.TargetGetTargetInfo{
TargetID: proto.TargetTargetID(ctx.Param("id")),
}.Call(b)
kit.E(err)
ctx.PureJSON(http.StatusOK, info.TargetInfo)
})
srv.Engine.GET("/screenshot/:id", func(ctx kit.GinContext) {
id := proto.TargetTargetID(ctx.Param("id"))
p := b.PageFromTargetID(id)
ctx.Header("Content-Type", "image/png;")
_, _ = ctx.Writer.Write(p.Screenshot())
})
go func() { _ = srv.Do() }()
go func() {
<-b.ctx.Done()
_ = srv.Listener.Close()
}()
url := "http://" + srv.Listener.Addr().String()
kit.Log("[rod] monitor server on", url, "(open it with your browser)")
return srv
}
// Overlay a rectangle on the main frame with specified message
func (p *Page) Overlay(left, top, width, height float64, msg string) (remove func()) {
root := p.Root()
id := "rod-" + kit.RandString(8)
_, err := root.EvalE(true, "", root.jsFn("overlay"), Array{
id,
left,
top,
width,
height,
msg,
})
CancelPanic(err)
remove = func() {
_, _ = root.EvalE(true, "", root.jsFn("removeOverlay"), Array{id})
}
return
}
// Trace with an overlay on the element
func (el *Element) Trace(htmlMessage string) (removeOverlay func()) {
id := "rod-" + kit.RandString(8)
_, err := el.EvalE(true, el.page.jsFn("elementOverlay"), Array{
id,
htmlMessage,
})
CancelPanic(err)
removeOverlay = func() {
_, _ = el.EvalE(true, el.page.jsFn("removeOverlay"), Array{id})
}
return
}
func (p *Page) traceFn(js string, params Array) func() {
fnName := strings.Replace(js, p.jsFnPrefix(), "rod.", 1)
paramsStr := html.EscapeString(strings.Trim(kit.MustToJSON(params), "[]"))
msg := fmt.Sprintf("retry <code>%s(%s)</code>", fnName, paramsStr)
return p.Overlay(0, 0, 500, 0, msg)
}