diff --git a/common/frame_session.go b/common/frame_session.go index fa954b88d..5232b96fc 100644 --- a/common/frame_session.go +++ b/common/frame_session.go @@ -1084,3 +1084,16 @@ func (fs *FrameSession) updateViewport() error { return nil } + +func (fs *FrameSession) executionContextForID( //nolint:unused + executionContextID cdpruntime.ExecutionContextID, +) (*ExecutionContext, error) { + fs.contextIDToContextMu.Lock() + defer fs.contextIDToContextMu.Unlock() + + if exc, ok := fs.parent.contextIDToContext[executionContextID]; ok { + return exc, nil + } + + return nil, fmt.Errorf("no execution context found for id: %v", executionContextID) +} diff --git a/common/page.go b/common/page.go index 40df9f0d4..d1572f7c8 100644 --- a/common/page.go +++ b/common/page.go @@ -20,6 +20,7 @@ import ( "github.com/chromedp/cdproto/page" cdppage "github.com/chromedp/cdproto/page" "github.com/chromedp/cdproto/runtime" + cdpruntime "github.com/chromedp/cdproto/runtime" "github.com/chromedp/cdproto/target" "github.com/dop251/goja" ) @@ -70,11 +71,11 @@ type Page struct { backgroundPage bool mainFrameSession *FrameSession - // TODO: FrameSession changes by attachFrameSession (mutex?) - frameSessions map[cdp.FrameID]*FrameSession - workers map[target.SessionID]*Worker - routes []api.Route - vu k6modules.VU + frameSessions map[cdp.FrameID]*FrameSession + frameSessionsMu sync.RWMutex + workers map[target.SessionID]*Worker + routes []api.Route + vu k6modules.VU logger *log.Logger } @@ -129,7 +130,9 @@ func NewPage( return nil, err } + p.frameSessionsMu.Lock() p.frameSessions[cdp.FrameID(tid)] = p.mainFrameSession + p.frameSessionsMu.Unlock() p.Mouse = NewMouse(ctx, s, p.frameManager.MainFrame(), bctx.timeoutSettings, p.Keyboard) p.Touchscreen = NewTouchscreen(ctx, s, p.Keyboard) @@ -275,12 +278,15 @@ func (p *Page) getOwnerFrame(apiCtx context.Context, h *ElementHandle) cdp.Frame func (p *Page) attachFrameSession(fid cdp.FrameID, fs *FrameSession) { p.logger.Debugf("Page:attachFrameSession", "sid:%v fid=%v", p.session.ID(), fid) + p.frameSessionsMu.Lock() + defer p.frameSessionsMu.Unlock() fs.page.frameSessions[fid] = fs } func (p *Page) getFrameSession(frameID cdp.FrameID) *FrameSession { p.logger.Debugf("Page:getFrameSession", "sid:%v fid:%v", p.sessionID(), frameID) - + p.frameSessionsMu.RLock() + defer p.frameSessionsMu.RUnlock() return p.frameSessions[frameID] } @@ -320,6 +326,9 @@ func (p *Page) setViewportSize(viewportSize *Size) error { func (p *Page) updateExtraHTTPHeaders() { p.logger.Debugf("Page:updateExtraHTTPHeaders", "sid:%v", p.sessionID()) + p.frameSessionsMu.RLock() + defer p.frameSessionsMu.RUnlock() + for _, fs := range p.frameSessions { fs.updateExtraHTTPHeaders(false) } @@ -328,6 +337,9 @@ func (p *Page) updateExtraHTTPHeaders() { func (p *Page) updateGeolocation() error { p.logger.Debugf("Page:updateGeolocation", "sid:%v", p.sessionID()) + p.frameSessionsMu.RLock() + defer p.frameSessionsMu.RUnlock() + for _, fs := range p.frameSessions { p.logger.Debugf("Page:updateGeolocation:frameSession", "sid:%v tid:%v wid:%v", @@ -341,12 +353,16 @@ func (p *Page) updateGeolocation() error { return err } } + return nil } func (p *Page) updateOffline() { p.logger.Debugf("Page:updateOffline", "sid:%v", p.sessionID()) + p.frameSessionsMu.RLock() + defer p.frameSessionsMu.RUnlock() + for _, fs := range p.frameSessions { fs.updateOffline(false) } @@ -355,6 +371,9 @@ func (p *Page) updateOffline() { func (p *Page) updateHttpCredentials() { p.logger.Debugf("Page:updateHttpCredentials", "sid:%v", p.sessionID()) + p.frameSessionsMu.RLock() + defer p.frameSessionsMu.RUnlock() + for _, fs := range p.frameSessions { fs.updateHTTPCredentials(false) } @@ -503,11 +522,14 @@ func (p *Page) EmulateMedia(opts goja.Value) { p.colorScheme = parsedOpts.ColorScheme p.reducedMotion = parsedOpts.ReducedMotion + p.frameSessionsMu.RLock() for _, fs := range p.frameSessions { if err := fs.updateEmulateMedia(false); err != nil { + p.frameSessionsMu.RUnlock() k6ext.Panic(p.ctx, "emulating media: %w", err) } } + p.frameSessionsMu.RUnlock() applySlowMo(p.ctx) } @@ -1017,6 +1039,22 @@ func (p *Page) Workers() []api.Worker { return workers } +// executionContextForID returns the page ExecutionContext for the given ID. +func (p *Page) executionContextForID( //nolint:unused + executionContextID cdpruntime.ExecutionContextID, +) (*ExecutionContext, error) { + p.frameSessionsMu.RLock() + defer p.frameSessionsMu.RUnlock() + + for _, fs := range p.frameSessions { + if exc, err := fs.executionContextForID(executionContextID); err == nil { + return exc, nil + } + } + + return nil, fmt.Errorf("no execution context found for id: %v", executionContextID) +} + // sessionID returns the Page's session ID. // It should be used internally in the Page. func (p *Page) sessionID() (sid target.SessionID) {