@@ -345,13 +345,7 @@ func (f *Frame) hasContext(world string) bool {
345
345
f .executionContextMu .RLock ()
346
346
defer f .executionContextMu .RUnlock ()
347
347
348
- switch world {
349
- case mainWorld :
350
- return f .mainExecutionContext != nil
351
- case utilityWorld :
352
- return f .utilityExecutionContext != nil
353
- }
354
- return false // Should never reach here!
348
+ return f .getExecCtx (world ) != nil
355
349
}
356
350
357
351
func (f * Frame ) hasLifecycleEventFired (event LifecycleEvent ) bool {
@@ -517,20 +511,18 @@ func (f *Frame) waitForFunction(apiCtx context.Context, world string, predicateF
517
511
"fid:%s furl:%q world:%s pt:%s timeout:%s" ,
518
512
f .ID (), f .URL (), world , polling , timeout )
519
513
520
- rt := k6common .GetRuntime (f .ctx )
521
514
f .waitForExecutionContext (world )
522
515
523
516
f .executionContextMu .RLock ()
524
517
defer f .executionContextMu .RUnlock ()
525
518
526
- execCtx := f .mainExecutionContext
527
- if world == utilityWorld {
528
- execCtx = f .utilityExecutionContext
529
- }
519
+ execCtx := f .getExecCtx (world )
530
520
injected , err := execCtx .getInjectedScript (apiCtx )
531
521
if err != nil {
532
522
return nil , err
533
523
}
524
+
525
+ rt := k6common .GetRuntime (f .ctx )
534
526
pageFn := rt .ToValue (`
535
527
(injected, predicate, polling, timeout, ...args) => {
536
528
return injected.waitForPredicateFunction(predicate, polling, timeout, ...args);
@@ -1241,7 +1233,12 @@ func (f *Frame) SetContent(html string, opts goja.Value) {
1241
1233
document.write(html);
1242
1234
document.close();
1243
1235
}`
1244
- f .waitForExecutionContext (utilityExecutionContext )
1236
+
1237
+ f .waitForExecutionContext (utilityWorld )
1238
+
1239
+ f .executionContextMu .RLock ()
1240
+ defer f .executionContextMu .RUnlock ()
1241
+
1245
1242
_ , err := f .utilityExecutionContext .evaluate (f .ctx , true , true , rt .ToValue (js ), rt .ToValue (html ))
1246
1243
if err != nil {
1247
1244
k6common .Throw (rt , err )
@@ -1377,6 +1374,9 @@ func (f *Frame) WaitForFunction(pageFunc goja.Value, opts goja.Value, args ...go
1377
1374
k6common .Throw (rt , fmt .Errorf ("failed parsing options: %w" , err ))
1378
1375
}
1379
1376
1377
+ f .executionContextMu .RLock ()
1378
+ defer f .executionContextMu .RUnlock ()
1379
+
1380
1380
handle , err := f .waitForFunction (f .ctx , utilityWorld , pageFunc , parsedOpts .Polling , parsedOpts .Interval , parsedOpts .Timeout , args ... )
1381
1381
if err != nil {
1382
1382
k6common .Throw (rt , err )
@@ -1445,6 +1445,32 @@ func (f *Frame) WaitForTimeout(timeout int64) {
1445
1445
}
1446
1446
}
1447
1447
1448
+ func (f * Frame ) adoptBackendNodeID (world string , id cdp.BackendNodeID ) (* ElementHandle , error ) {
1449
+ f .executionContextMu .RLock ()
1450
+ defer f .executionContextMu .RUnlock ()
1451
+
1452
+ ec := f .getExecCtx (world )
1453
+ return ec .adoptBackendNodeID (id )
1454
+ }
1455
+
1456
+ func (f * Frame ) evaluate (world string , apiCtx context.Context , forceCallable bool , returnByValue bool , pageFunc goja.Value , args ... goja.Value ) (res interface {}, err error ) {
1457
+ f .executionContextMu .RLock ()
1458
+ defer f .executionContextMu .RUnlock ()
1459
+
1460
+ ec := f .getExecCtx (world )
1461
+ return ec .evaluate (apiCtx , forceCallable , returnByValue , pageFunc , args ... )
1462
+ }
1463
+
1464
+ // getExecCtx returns an execution context using a given world name.
1465
+ // Unsafe to use concurrently.
1466
+ func (f * Frame ) getExecCtx (world string ) frameExecutionContext {
1467
+ ec := f .mainExecutionContext
1468
+ if world == utilityWorld {
1469
+ ec = f .utilityExecutionContext
1470
+ }
1471
+ return ec
1472
+ }
1473
+
1448
1474
// frameExecutionContext represents a JS execution context that belongs to Frame.
1449
1475
type frameExecutionContext interface {
1450
1476
// adoptBackendNodeID adopts specified backend node into this execution
0 commit comments