Skip to content

Commit 5dcd175

Browse files
committed
feat: add support for flattened sessions
Chrome is deprecating non-flattened sessions (crbug.com/991325) where commands are wrapped via Target.SendMessageToTarget. Flattened mode includes the sessionId directly in the JSON-RPC message instead. Add rpcc.NewSession for creating session-scoped connections that share the parent's websocket I/O. WithSessionClose allows registering a cleanup callback for detachment. session.Manager now uses flattened mode by default, requiring Chrome 77+. WithNoFlatten opts into legacy mode for older versions. Closes #109
1 parent 3b1f600 commit 5dcd175

File tree

13 files changed

+1057
-198
lines changed

13 files changed

+1057
-198
lines changed

cdp_client.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/cdpgen/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,16 +330,23 @@ func (g *Generator) CdpClient(domains []proto.Domain) {
330330
// invoke methods or listen to events in every CDP domain. The Client consumes
331331
// a rpcc connection, used to invoke the methods.
332332
type Client struct {
333+
conn *rpcc.Conn
333334
%s
334335
}
335336
336337
// NewClient returns a new Client that uses conn
337338
// for communication with the debugging target.
338339
func NewClient(conn *rpcc.Conn) *Client {
339340
return &Client{
341+
conn: conn,
340342
%s
341343
}
342344
}
345+
346+
// Conn returns the underlying rpcc.Conn used by this Client.
347+
func (c *Client) Conn() *rpcc.Conn {
348+
return c.conn
349+
}
343350
`, fields.buf.Bytes(), newFields.buf.Bytes())
344351
}
345352

internal/testutil/testutil.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package testutil
22

33
import (
44
"context"
5+
"encoding/json"
6+
"io"
57
"testing"
68
"time"
79

@@ -11,6 +13,41 @@ import (
1113
"github.com/mafredri/cdp/rpcc"
1214
)
1315

16+
// logCodec wraps an rpcc.Codec and logs all requests and responses.
17+
type logCodec struct {
18+
t *testing.T
19+
enc *json.Encoder
20+
dec *json.Decoder
21+
}
22+
23+
func (c *logCodec) WriteRequest(r *rpcc.Request) error {
24+
c.t.Helper()
25+
data, _ := json.Marshal(r)
26+
c.t.Logf("SEND: %s", data)
27+
return c.enc.Encode(r)
28+
}
29+
30+
func (c *logCodec) ReadResponse(r *rpcc.Response) error {
31+
c.t.Helper()
32+
if err := c.dec.Decode(r); err != nil {
33+
return err
34+
}
35+
data, _ := json.Marshal(r)
36+
c.t.Logf("RECV: %s", data)
37+
return nil
38+
}
39+
40+
// NewLogCodec returns a new rpcc codec that logs all requests and responses.
41+
func NewLogCodec(t *testing.T) rpcc.DialOption {
42+
return rpcc.WithCodec(func(conn io.ReadWriter) rpcc.Codec {
43+
return &logCodec{
44+
t: t,
45+
enc: json.NewEncoder(conn),
46+
dec: json.NewDecoder(conn),
47+
}
48+
})
49+
}
50+
1451
// Client represents a test client.
1552
type Client struct {
1653
t *testing.T
@@ -32,7 +69,13 @@ func NewClient(ctx context.Context, t *testing.T) *Client {
3269
if err != nil {
3370
t.Fatal(err)
3471
}
35-
conn, err := rpcc.DialContext(ctx, v.WebSocketDebuggerURL)
72+
73+
var opts []rpcc.DialOption
74+
if testing.Verbose() {
75+
opts = append(opts, NewLogCodec(t))
76+
}
77+
78+
conn, err := rpcc.DialContext(ctx, v.WebSocketDebuggerURL, opts...)
3679
if err != nil {
3780
t.Fatal(err)
3881
}

0 commit comments

Comments
 (0)