diff --git a/browser/mapping.go b/browser/mapping.go index e5239eeb9..b8b8b1944 100644 --- a/browser/mapping.go +++ b/browser/mapping.go @@ -1007,6 +1007,11 @@ func mapBrowser(vu moduleVU) mapping { //nolint:funlen if err != nil { return nil, err //nolint:wrapcheck } + + if err := initBrowserContext(bctx, vu.testRunID); err != nil { + return nil, err + } + m := mapBrowserContext(vu, bctx) return rt.ToValue(m).ToObject(rt), nil }, @@ -1033,7 +1038,26 @@ func mapBrowser(vu moduleVU) mapping { //nolint:funlen if err != nil { return nil, err //nolint:wrapcheck } + + if err := initBrowserContext(b.Context(), vu.testRunID); err != nil { + return nil, err + } + return mapPage(vu, page), nil }, } } + +func initBrowserContext(bctx *common.BrowserContext, testRunID string) error { + // Setting a k6 object which will contain k6 specific metadata + // on the current test run. This allows external applications + // (such as Grafana Faro) to identify that the session is a k6 + // automated one and not one driven by a real person. + if err := bctx.AddInitScript( + fmt.Sprintf(`window.k6 = { testRunId: %q }`, testRunID), + ); err != nil { + return fmt.Errorf("adding k6 object to new browser context: %w", err) + } + + return nil +} diff --git a/common/browser_context.go b/common/browser_context.go index f736df525..d497a87ef 100644 --- a/common/browser_context.go +++ b/common/browser_context.go @@ -108,9 +108,6 @@ func NewBrowserContext( } } - if err := b.AddInitScript(js.K6ObjectScript); err != nil { - return nil, fmt.Errorf("adding k6 object to new browser context: %w", err) - } if err := b.AddInitScript(js.WebVitalIIFEScript); err != nil { return nil, fmt.Errorf("adding web vital script to new browser context: %w", err) } diff --git a/common/browser_context_test.go b/common/browser_context_test.go index 4c975e3a9..e5de230c7 100644 --- a/common/browser_context_test.go +++ b/common/browser_context_test.go @@ -31,23 +31,19 @@ func TestNewBrowserContext(t *testing.T) { webVitalIIFEScriptFound := false webVitalInitScriptFound := false - k6ObjScriptFound := false for _, script := range bc.evaluateOnNewDocumentSources { switch script { case js.WebVitalIIFEScript: webVitalIIFEScriptFound = true case js.WebVitalInitScript: webVitalInitScriptFound = true - case js.K6ObjectScript: - k6ObjScriptFound = true default: - assert.Fail(t, "script is neither WebVitalIIFEScript, WebVitalInitScript, nor k6ObjScript") + assert.Fail(t, "script is neither WebVitalIIFEScript, nor WebVitalInitScript") } } assert.True(t, webVitalIIFEScriptFound, "WebVitalIIFEScript was not initialized in the context") assert.True(t, webVitalInitScriptFound, "WebVitalInitScript was not initialized in the context") - assert.True(t, k6ObjScriptFound, "k6ObjScript was not initialized in the context") }) } diff --git a/common/js/embedded_scripts.go b/common/js/embedded_scripts.go index 66bf5fd6b..e31da9ac7 100644 --- a/common/js/embedded_scripts.go +++ b/common/js/embedded_scripts.go @@ -17,10 +17,3 @@ var WebVitalIIFEScript string // //go:embed web_vital_init.js var WebVitalInitScript string - -// K6ObjectScript is used to propagate -// information to other libraries about -// the current user session. -// -//go:embed k6_object.js -var K6ObjectScript string diff --git a/common/js/k6_object.js b/common/js/k6_object.js deleted file mode 100644 index fbf489b1f..000000000 --- a/common/js/k6_object.js +++ /dev/null @@ -1 +0,0 @@ -window.k6 = {}; diff --git a/tests/browser_context_test.go b/tests/browser_context_test.go index c59f8cf13..238b1cd26 100644 --- a/tests/browser_context_test.go +++ b/tests/browser_context_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/xk6-browser/common" + "github.com/grafana/xk6-browser/env" ) func TestBrowserContextAddCookies(t *testing.T) { @@ -627,22 +628,53 @@ func TestBrowserContextClearCookies(t *testing.T) { func TestK6Object(t *testing.T) { t.Parallel() - b := newTestBrowser(t, withFileServer()) - p := b.NewPage(nil) - - url := b.staticURL("empty.html") - opts := &common.FrameGotoOptions{ - Timeout: common.DefaultTimeout, + tests := []struct { + name string + testRunID string + want string + }{ + { + name: "empty_testRunId", + want: `{"testRunId":""}`, + }, + { + name: "with_testRunId", + testRunID: "123456", + want: `{"testRunId":"123456"}`, + }, } - r, err := p.Goto( - url, - opts, - ) - require.NoError(t, err) - require.NotNil(t, r) - k6Obj := p.Evaluate(`() => window.k6`) - assert.NotNil(t, k6Obj) + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + _, rt, _, cleanUp := startIteration(t, env.ConstLookup(env.K6TestRunID, tt.testRunID)) + defer cleanUp() + + // First test with browser.newPage + got, err := rt.RunString(` + const p = browser.newPage() + p.goto("about:blank") + const o = p.evaluate(() => window.k6) + JSON.stringify(o) + `) + require.NoError(t, err) + assert.Equal(t, tt.want, got.String()) + + // Now test with browser.newContext + got, err = rt.RunString(` + browser.closeContext() + const c = browser.newContext() + const p2 = c.newPage() + p2.goto("about:blank") + const o2 = p2.evaluate(() => window.k6) + JSON.stringify(o2) + `) + require.NoError(t, err) + assert.Equal(t, tt.want, got.String()) + }) + } } func TestBrowserContextTimeout(t *testing.T) { diff --git a/tests/page_test.go b/tests/page_test.go index 357d12fe5..d2997f6bb 100644 --- a/tests/page_test.go +++ b/tests/page_test.go @@ -822,10 +822,11 @@ func TestPageWaitForFunction(t *testing.T) { // (more importantly) set browser as the mapped browser instance which will // force all tests that work with this to go through the mapping layer. // This returns a cleanup function which should be deferred. -func startIteration(t *testing.T) (*k6test.VU, *goja.Runtime, *[]string, func()) { +// The opts are passed to k6test.NewVU as is without any modification. +func startIteration(t *testing.T, opts ...any) (*k6test.VU, *goja.Runtime, *[]string, func()) { t.Helper() - vu := k6test.NewVU(t) + vu := k6test.NewVU(t, opts...) rt := vu.Runtime() mod := browser.New().NewModuleInstance(vu)