Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit aadc374

Browse files
authored
Merge pull request #169 from grafana/fix/49-cannot-find-context-with-specified-id
Fix/49 cannot find context with specified id
2 parents 176800f + bce2f54 commit aadc374

File tree

7 files changed

+190
-158
lines changed

7 files changed

+190
-158
lines changed

common/browser.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,16 @@ func (b *Browser) onAttachedToTarget(ev *target.EventAttachedToTarget) {
242242
b.sessionIDtoTargetID[ev.SessionID] = evti.TargetID
243243
b.sessionIDtoTargetIDMu.Unlock()
244244
case "page":
245-
var opener *Page = nil
245+
// Opener is nil for the initial page
246+
var opener *Page
246247
b.pagesMu.RLock()
247248
if t, ok := b.pages[evti.OpenerID]; ok {
248249
opener = t
249250
}
250-
b.logger.Debugf("Browser:onAttachedToTarget:page", "sid:%v tid:%v opener nil:%t", ev.SessionID, evti.TargetID, opener == nil)
251251
b.pagesMu.RUnlock()
252252

253+
b.logger.Debugf("Browser:onAttachedToTarget:page", "sid:%v tid:%v opener nil:%t", ev.SessionID, evti.TargetID, opener == nil)
254+
253255
p, err := NewPage(b.ctx, b.conn.getSession(ev.SessionID), browserCtx, evti.TargetID, opener, true, b.logger)
254256
if err != nil {
255257
isRunning := atomic.LoadInt64(&b.state) == BrowserStateOpen && b.IsConnected() //b.conn.isConnected()
@@ -279,6 +281,8 @@ func (b *Browser) onAttachedToTarget(ev *target.EventAttachedToTarget) {
279281
}
280282
}
281283

284+
// onDetachedFromTarget event can be issued multiple times per target if multiple
285+
// sessions have been attached to it. So we'll remove the page only once.
282286
func (b *Browser) onDetachedFromTarget(ev *target.EventDetachedFromTarget) {
283287
b.sessionIDtoTargetIDMu.RLock()
284288
targetID, ok := b.sessionIDtoTargetID[ev.SessionID]

common/connection.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ func (c *Connection) recvLoop() {
345345
}
346346
}
347347

348-
func (c *Connection) send(msg *cdproto.Message, recvCh chan *cdproto.Message, res easyjson.Unmarshaler) error {
348+
func (c *Connection) send(ctx context.Context, msg *cdproto.Message, recvCh chan *cdproto.Message, res easyjson.Unmarshaler) error {
349349
select {
350350
case c.sendCh <- msg:
351351
case err := <-c.errorCh:
@@ -358,9 +358,12 @@ func (c *Connection) send(msg *cdproto.Message, recvCh chan *cdproto.Message, re
358358
case <-c.done:
359359
c.logger.Debugf("Connection:send:<-c.done", "wsURL:%q sid:%v", c.wsURL, msg.SessionID)
360360
return nil
361+
case <-ctx.Done():
362+
c.logger.Errorf("Connection:send:<-ctx.Done()", "wsURL:%q sid:%v err:%v", c.wsURL, msg.SessionID, c.ctx.Err())
363+
return ctx.Err()
361364
case <-c.ctx.Done():
362365
c.logger.Errorf("Connection:send:<-c.ctx.Done()", "wsURL:%q sid:%v err:%v", c.wsURL, msg.SessionID, c.ctx.Err())
363-
return nil
366+
return ctx.Err()
364367
}
365368

366369
// Block waiting for response.
@@ -395,13 +398,12 @@ func (c *Connection) send(msg *cdproto.Message, recvCh chan *cdproto.Message, re
395398
return &websocket.CloseError{Code: code}
396399
case <-c.done:
397400
c.logger.Debugf("Connection:send:<-c.done #2", "sid:%v tid:%v wsURL:%q", msg.SessionID, tid, c.wsURL)
401+
case <-ctx.Done():
402+
c.logger.Debugf("Connection:send:<-ctx.Done()", "sid:%v tid:%v wsURL:%q err:%v", msg.SessionID, tid, c.wsURL, c.ctx.Err())
403+
return ctx.Err()
398404
case <-c.ctx.Done():
399405
c.logger.Debugf("Connection:send:<-c.ctx.Done()", "sid:%v tid:%v wsURL:%q err:%v", msg.SessionID, tid, c.wsURL, c.ctx.Err())
400-
// TODO: this brings many bugs to the surface
401406
return c.ctx.Err()
402-
// TODO: add a timeout?
403-
// case <-timeout:
404-
// return
405407
}
406408
return nil
407409
}
@@ -443,15 +445,13 @@ func (c *Connection) sendLoop() {
443445
case code := <-c.closeCh:
444446
c.logger.Debugf("Connection:sendLoop:<-c.closeCh", "wsURL:%q code:%d", c.wsURL, code)
445447
_ = c.closeConnection(code)
448+
return
446449
case <-c.done:
447450
c.logger.Debugf("Connection:sendLoop:<-c.done#2", "wsURL:%q", c.wsURL)
451+
return
448452
case <-c.ctx.Done():
449453
c.logger.Debugf("connection:sendLoop", "returning, ctx.Err: %q", c.ctx.Err())
450454
return
451-
// case <-time.After(time.Second * 10):
452-
// c.logger.Errorf("connection:sendLoop", "returning, timeout")
453-
// c.Close()
454-
// return
455455
}
456456
}
457457
}
@@ -513,5 +513,5 @@ func (c *Connection) Execute(ctx context.Context, method string, params easyjson
513513
Method: cdproto.MethodType(method),
514514
Params: buf,
515515
}
516-
return c.send(msg, ch, res)
516+
return c.send(c.ctx, msg, ch, res)
517517
}

common/context.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,14 @@ func GetProcessID(ctx context.Context) int {
6464
v, _ := ctx.Value(ctxKeyPid).(int)
6565
return v // it will return zero on error
6666
}
67+
68+
// contextWithDoneChan returns a new context that is canceled when the done channel
69+
// is closed. The context will leak if the done channel is never closed.
70+
func contextWithDoneChan(ctx context.Context, done chan struct{}) context.Context {
71+
ctx, cancel := context.WithCancel(ctx)
72+
go func() {
73+
<-done
74+
cancel()
75+
}()
76+
return ctx
77+
}

common/frame.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ func (f *Frame) waitForFunction(
542542
rt.ToValue(polling),
543543
}, args...)...)
544544
if err != nil {
545-
return nil, err
545+
return nil, fmt.Errorf("frame cannot wait for function: %w", err)
546546
}
547547
return result, nil
548548
}
@@ -569,14 +569,14 @@ func (f *Frame) waitForSelector(selector string, opts *FrameWaitForSelectorOptio
569569

570570
ec := f.executionContexts[mainWorld]
571571
if ec == nil {
572-
return nil, fmt.Errorf("cannot find execution context: %q", mainWorld)
572+
return nil, fmt.Errorf("wait for selector cannot find execution context: %q", mainWorld)
573573
}
574574
// an element should belong to the current execution context.
575575
// otherwise, we should adopt it to this execution context.
576576
if ec != handle.execCtx {
577577
defer handle.Dispose()
578578
if handle, err = ec.adoptElementHandle(handle); err != nil {
579-
return nil, err
579+
return nil, fmt.Errorf("wait for selector cannot adopt element handle: %w", err)
580580
}
581581
}
582582

@@ -1481,7 +1481,11 @@ func (f *Frame) evaluate(
14811481
if ec == nil {
14821482
return nil, fmt.Errorf("cannot find execution context: %q", world)
14831483
}
1484-
return ec.evaluate(apiCtx, opts, pageFunc, args...)
1484+
eh, err := ec.evaluate(apiCtx, opts, pageFunc, args...)
1485+
if err != nil {
1486+
return nil, fmt.Errorf("frame cannot evaluate: %w", err)
1487+
}
1488+
return eh, nil
14851489
}
14861490

14871491
// frameExecutionContext represents a JS execution context that belongs to Frame.

0 commit comments

Comments
 (0)