Skip to content

Commit 3e8cb5f

Browse files
authored
chore: roll to Playwright v1.48.1 (#500)
1 parent e8c12f4 commit 3e8cb5f

27 files changed

+1215
-808
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
[![PkgGoDev](https://pkg.go.dev/badge/github.com/playwright-community/playwright-go)](https://pkg.go.dev/github.com/playwright-community/playwright-go)
66
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](http://opensource.org/licenses/MIT)
77
[![Go Report Card](https://goreportcard.com/badge/github.com/playwright-community/playwright-go)](https://goreportcard.com/report/github.com/playwright-community/playwright-go) ![Build Status](https://github.com/playwright-community/playwright-go/workflows/Go/badge.svg)
8-
[![Join Slack](https://img.shields.io/badge/join-slack-infomational)](https://aka.ms/playwright-slack) [![Coverage Status](https://coveralls.io/repos/github/playwright-community/playwright-go/badge.svg?branch=main)](https://coveralls.io/github/playwright-community/playwright-go?branch=main) <!-- GEN:chromium-version-badge -->[![Chromium version](https://img.shields.io/badge/chromium-129.0.6668.29-blue.svg?logo=google-chrome)](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[![Firefox version](https://img.shields.io/badge/firefox-130.0-blue.svg?logo=mozilla-firefox)](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[![WebKit version](https://img.shields.io/badge/webkit-18.0-blue.svg?logo=safari)](https://webkit.org/)<!-- GEN:stop -->
8+
[![Join Slack](https://img.shields.io/badge/join-slack-infomational)](https://aka.ms/playwright-slack) [![Coverage Status](https://coveralls.io/repos/github/playwright-community/playwright-go/badge.svg?branch=main)](https://coveralls.io/github/playwright-community/playwright-go?branch=main) <!-- GEN:chromium-version-badge -->[![Chromium version](https://img.shields.io/badge/chromium-130.0.6723.31-blue.svg?logo=google-chrome)](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[![Firefox version](https://img.shields.io/badge/firefox-131.0-blue.svg?logo=mozilla-firefox)](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[![WebKit version](https://img.shields.io/badge/webkit-18.0-blue.svg?logo=safari)](https://webkit.org/)<!-- GEN:stop -->
99

1010
[API reference](https://playwright.dev/docs/api/class-playwright) | [Example recipes](https://github.com/playwright-community/playwright-go/tree/main/examples)
1111

1212
Playwright is a Go library to automate [Chromium](https://www.chromium.org/Home), [Firefox](https://www.mozilla.org/en-US/firefox/new/) and [WebKit](https://webkit.org/) with a single API. Playwright is built to enable cross-browser web automation that is **ever-green**, **capable**, **reliable** and **fast**.
1313

1414
| | Linux | macOS | Windows |
1515
| :--- | :---: | :---: | :---: |
16-
| Chromium <!-- GEN:chromium-version -->129.0.6668.29<!-- GEN:stop --> ||||
16+
| Chromium <!-- GEN:chromium-version -->130.0.6723.31<!-- GEN:stop --> ||||
1717
| WebKit <!-- GEN:webkit-version -->18.0<!-- GEN:stop --> ||||
18-
| Firefox <!-- GEN:firefox-version -->130.0<!-- GEN:stop --> ||||
18+
| Firefox <!-- GEN:firefox-version -->131.0<!-- GEN:stop --> ||||
1919

2020
Headless execution is supported for all the browsers on all platforms.
2121

browser_context.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func (b *browserContextImpl) SetDefaultNavigationTimeout(timeout float64) {
4444

4545
func (b *browserContextImpl) setDefaultNavigationTimeoutImpl(timeout *float64) {
4646
b.timeoutSettings.SetDefaultNavigationTimeout(timeout)
47-
b.channel.SendNoReply("setDefaultNavigationTimeoutNoReply", map[string]interface{}{
47+
b.channel.SendNoReply("setDefaultNavigationTimeoutNoReply", true, map[string]interface{}{
4848
"timeout": timeout,
4949
})
5050
}
@@ -55,7 +55,7 @@ func (b *browserContextImpl) SetDefaultTimeout(timeout float64) {
5555

5656
func (b *browserContextImpl) setDefaultTimeoutImpl(timeout *float64) {
5757
b.timeoutSettings.SetDefaultTimeout(timeout)
58-
b.channel.SendNoReply("setDefaultTimeoutNoReply", map[string]interface{}{
58+
b.channel.SendNoReply("setDefaultTimeoutNoReply", true, map[string]interface{}{
5959
"timeout": timeout,
6060
})
6161
}

browser_type.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (b *browserTypeImpl) Connect(wsEndpoint string, options ...BrowserTypeConne
105105
if err != nil {
106106
return nil, err
107107
}
108-
jsonPipe := fromChannel(pipe.(map[string]interface{})["pipe"]).(*jsonPipe)
108+
jsonPipe := fromChannel(pipe["pipe"]).(*jsonPipe)
109109
connection := newConnection(jsonPipe, localUtils)
110110

111111
playwright, err := connection.Start()
@@ -146,9 +146,9 @@ func (b *browserTypeImpl) ConnectOverCDP(endpointURL string, options ...BrowserT
146146
if err != nil {
147147
return nil, err
148148
}
149-
browser := fromChannel(response.(map[string]interface{})["browser"]).(*browserImpl)
149+
browser := fromChannel(response["browser"]).(*browserImpl)
150150
b.didLaunchBrowser(browser)
151-
if defaultContext, ok := response.(map[string]interface{})["defaultContext"]; ok {
151+
if defaultContext, ok := response["defaultContext"]; ok {
152152
context := fromChannel(defaultContext).(*browserContextImpl)
153153
b.didCreateContext(context, nil, nil)
154154
}

channel.go

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,46 +18,27 @@ func (c *channel) MarshalJSON() ([]byte, error) {
1818

1919
func (c *channel) Send(method string, options ...interface{}) (interface{}, error) {
2020
return c.connection.WrapAPICall(func() (interface{}, error) {
21-
return c.innerSend(method, false, options...)
22-
}, false)
21+
return c.innerSend(method, options...).GetResultValue()
22+
}, c.owner.isInternalType)
2323
}
2424

25-
func (c *channel) SendReturnAsDict(method string, options ...interface{}) (interface{}, error) {
26-
return c.connection.WrapAPICall(func() (interface{}, error) {
27-
return c.innerSend(method, true, options...)
28-
}, true)
25+
func (c *channel) SendReturnAsDict(method string, options ...interface{}) (map[string]interface{}, error) {
26+
ret, err := c.connection.WrapAPICall(func() (interface{}, error) {
27+
return c.innerSend(method, options...).GetResult()
28+
}, c.owner.isInternalType)
29+
return ret.(map[string]interface{}), err
2930
}
3031

31-
func (c *channel) innerSend(method string, returnAsDict bool, options ...interface{}) (interface{}, error) {
32+
func (c *channel) innerSend(method string, options ...interface{}) *protocolCallback {
3233
params := transformOptions(options...)
33-
callback, err := c.connection.sendMessageToServer(c.owner, method, params, false)
34-
if err != nil {
35-
return nil, err
36-
}
37-
result, err := callback.GetResult()
38-
if err != nil {
39-
return nil, err
40-
}
41-
if result == nil {
42-
return nil, nil
43-
}
44-
if returnAsDict {
45-
return result, nil
46-
}
47-
if mapV, ok := result.(map[string]interface{}); ok && len(mapV) <= 1 {
48-
for key := range mapV {
49-
return mapV[key], nil
50-
}
51-
return nil, nil
52-
}
53-
return result, nil
34+
return c.connection.sendMessageToServer(c.owner, method, params, false)
5435
}
5536

56-
func (c *channel) SendNoReply(method string, options ...interface{}) {
37+
func (c *channel) SendNoReply(method string, isInternal bool, options ...interface{}) {
5738
params := transformOptions(options...)
5839
_, err := c.connection.WrapAPICall(func() (interface{}, error) {
59-
return c.connection.sendMessageToServer(c.owner, method, params, true)
60-
}, false)
40+
return c.connection.sendMessageToServer(c.owner, method, params, true).GetResult()
41+
}, isInternal)
6142
if err != nil {
6243
logger.Printf("SendNoReply failed: %v\n", err)
6344
}

channel_owner.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type channelOwner struct {
1616
initializer map[string]interface{}
1717
parent *channelOwner
1818
wasCollected bool
19+
isInternalType bool
1920
}
2021

2122
func (c *channelOwner) dispose(reason ...string) {
@@ -48,7 +49,7 @@ func (c *channelOwner) setEventSubscriptionMapping(mapping map[string]string) {
4849
func (c *channelOwner) updateSubscription(event string, enabled bool) {
4950
protocolEvent, ok := c.eventToSubscriptionMapping[event]
5051
if ok {
51-
c.channel.SendNoReply("updateSubscription", map[string]interface{}{
52+
c.channel.SendNoReply("updateSubscription", true, map[string]interface{}{
5253
"event": protocolEvent,
5354
"enabled": enabled,
5455
})
@@ -95,18 +96,22 @@ func (c *channelOwner) createChannelOwner(self interface{}, parent *channelOwner
9596
c.eventToSubscriptionMapping = map[string]string{}
9697
}
9798

99+
func (c *channelOwner) markAsInternalType() {
100+
c.isInternalType = true
101+
}
102+
98103
type rootChannelOwner struct {
99104
channelOwner
100105
}
101106

102107
func (r *rootChannelOwner) initialize() (*Playwright, error) {
103-
result, err := r.channel.Send("initialize", map[string]interface{}{
108+
ret, err := r.channel.SendReturnAsDict("initialize", map[string]interface{}{
104109
"sdkLanguage": "javascript",
105110
})
106111
if err != nil {
107112
return nil, err
108113
}
109-
return fromChannel(result).(*Playwright), nil
114+
return fromChannel(ret["playwright"]).(*Playwright), nil
110115
}
111116

112117
func newRootChannelOwner(connection *connection) *rootChannelOwner {

connection.go

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ var (
2020
apiNameTransform = regexp.MustCompile(`(?U)\(\*(.+)(Impl)?\)`)
2121
)
2222

23-
type result struct {
24-
Data interface{}
25-
Error error
26-
}
27-
2823
type connection struct {
2924
transport transport
3025
apiZone sync.Map
@@ -102,13 +97,9 @@ func (c *connection) Dispatch(msg *message) {
10297
return
10398
}
10499
if msg.Error != nil {
105-
cb.SetResult(result{
106-
Error: parseError(msg.Error.Error),
107-
})
100+
cb.SetError(parseError(msg.Error.Error))
108101
} else {
109-
cb.SetResult(result{
110-
Data: c.replaceGuidsWithChannels(msg.Result),
111-
})
102+
cb.SetResult(c.replaceGuidsWithChannels(msg.Result).(map[string]interface{}))
112103
}
113104
return
114105
}
@@ -191,16 +182,20 @@ func (c *connection) replaceGuidsWithChannels(payload interface{}) interface{} {
191182
return payload
192183
}
193184

194-
func (c *connection) sendMessageToServer(object *channelOwner, method string, params interface{}, noReply bool) (*protocolCallback, error) {
185+
func (c *connection) sendMessageToServer(object *channelOwner, method string, params interface{}, noReply bool) (cb *protocolCallback) {
186+
cb = newProtocolCallback(noReply, c.abort)
187+
195188
if err := c.closedError.Get(); err != nil {
196-
return nil, err
189+
cb.SetError(err)
190+
return
197191
}
198192
if object.wasCollected {
199-
return nil, errors.New("The object has been collected to prevent unbounded heap growth.")
193+
cb.SetError(errors.New("The object has been collected to prevent unbounded heap growth."))
194+
return
200195
}
201196

202197
id := c.lastID.Add(1)
203-
cb, _ := c.callbacks.LoadOrStore(id, newProtocolCallback(noReply, c.abort))
198+
c.callbacks.Store(id, cb)
204199
var (
205200
metadata = make(map[string]interface{}, 0)
206201
stack = make([]map[string]interface{}, 0)
@@ -225,10 +220,11 @@ func (c *connection) sendMessageToServer(object *channelOwner, method string, pa
225220
}
226221

227222
if err := c.transport.Send(message); err != nil {
228-
return nil, fmt.Errorf("could not send message: %w", err)
223+
cb.SetError(fmt.Errorf("could not send message: %w", err))
224+
return
229225
}
230226

231-
return cb, nil
227+
return
232228
}
233229

234230
func (c *connection) setInTracing(isTracing bool) {
@@ -327,41 +323,66 @@ func fromNullableChannel(v interface{}) interface{} {
327323
}
328324

329325
type protocolCallback struct {
330-
callback chan result
331-
noReply bool
332-
abort <-chan struct{}
326+
done chan struct{}
327+
noReply bool
328+
abort <-chan struct{}
329+
once sync.Once
330+
value map[string]interface{}
331+
err error
333332
}
334333

335-
func (pc *protocolCallback) SetResult(r result) {
334+
func (pc *protocolCallback) setResultOnce(result map[string]interface{}, err error) {
335+
pc.once.Do(func() {
336+
pc.value = result
337+
pc.err = err
338+
close(pc.done)
339+
})
340+
}
341+
342+
func (pc *protocolCallback) waitResult() {
336343
if pc.noReply {
337344
return
338345
}
339346
select {
347+
case <-pc.done: // wait for result
348+
return
340349
case <-pc.abort:
341350
select {
342-
case pc.callback <- r:
351+
case <-pc.done:
352+
return
343353
default:
354+
pc.err = errors.New("Connection closed")
355+
return
344356
}
345-
return
346-
case pc.callback <- r:
347357
}
348358
}
349359

350-
func (pc *protocolCallback) GetResult() (interface{}, error) {
351-
if pc.noReply {
352-
return nil, nil
360+
func (pc *protocolCallback) SetError(err error) {
361+
pc.setResultOnce(nil, err)
362+
}
363+
364+
func (pc *protocolCallback) SetResult(result map[string]interface{}) {
365+
pc.setResultOnce(result, nil)
366+
}
367+
368+
func (pc *protocolCallback) GetResult() (map[string]interface{}, error) {
369+
pc.waitResult()
370+
return pc.value, pc.err
371+
}
372+
373+
// GetResultValue returns value if the map has only one element
374+
func (pc *protocolCallback) GetResultValue() (interface{}, error) {
375+
pc.waitResult()
376+
if len(pc.value) == 0 { // empty map treated as nil
377+
return nil, pc.err
353378
}
354-
select {
355-
case result := <-pc.callback:
356-
return result.Data, result.Error
357-
case <-pc.abort:
358-
select {
359-
case result := <-pc.callback:
360-
return result.Data, result.Error
361-
default:
362-
return nil, errors.New("Connection closed")
379+
if len(pc.value) == 1 {
380+
for key := range pc.value {
381+
return pc.value[key], pc.err
363382
}
364383
}
384+
385+
return pc.value, pc.err
365386
}
366387

367388
func newProtocolCallback(noReply bool, abort <-chan struct{}) *protocolCallback {
@@ -372,7 +393,7 @@ func newProtocolCallback(noReply bool, abort <-chan struct{}) *protocolCallback
372393
}
373394
}
374395
return &protocolCallback{
375-
callback: make(chan result, 1),
376-
abort: abort,
396+
done: make(chan struct{}),
397+
abort: abort,
377398
}
378399
}

event_emitter.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type EventEmitter interface {
1313
On(name string, handler interface{})
1414
Once(name string, handler interface{})
1515
RemoveListener(name string, handler interface{})
16+
RemoveListeners(name string)
1617
}
1718

1819
type (
@@ -31,6 +32,10 @@ type (
3132
}
3233
)
3334

35+
func NewEventEmitter() EventEmitter {
36+
return &eventEmitter{}
37+
}
38+
3439
func (e *eventEmitter) Emit(name string, payload ...interface{}) (hasListener bool) {
3540
e.eventsMutex.Lock()
3641
e.init()
@@ -64,6 +69,13 @@ func (e *eventEmitter) RemoveListener(name string, handler interface{}) {
6469
}
6570
}
6671

72+
func (e *eventEmitter) RemoveListeners(name string) {
73+
e.eventsMutex.Lock()
74+
defer e.eventsMutex.Unlock()
75+
e.init()
76+
delete(e.events, name)
77+
}
78+
6779
// ListenerCount count the listeners by name, count all if name is empty
6880
func (e *eventEmitter) ListenerCount(name string) int {
6981
e.eventsMutex.Lock()

fetch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ func (r *apiResponseImpl) Body() ([]byte, error) {
334334
}
335335
return nil, err
336336
}
337-
body := result.(map[string]interface{})["binary"]
337+
body := result["binary"]
338338
if body == nil {
339339
return nil, errors.New("response has been disposed")
340340
}

0 commit comments

Comments
 (0)