Skip to content

Commit 756d88a

Browse files
Add isWebdriver to metrics. (#11162)
## Describe your changes Check whether Streamlit is running inside an end-to-end test by adding `isWebdriver` to the metrics (reading from `navigator.webdriver`). ## GitHub Issue Link (if applicable) n/a ## Testing Plan - ~~Explanation of why no additional tests are needed~~ - Unit Tests (JS and/or Python) ✅ - E2E Tests: **TODO** - ~~Any manual testing needed?~~ --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license. --------- Co-authored-by: Ken McGrady <[email protected]>
1 parent 67efd58 commit 756d88a

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

e2e_playwright/basic_app_test.py

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@
2121
from e2e_playwright.conftest import wait_for_app_loaded
2222

2323

24+
def test_is_webdriver_set(app: Page):
25+
"""Test that verifies that the window.navigator.webdriver is set to True
26+
when running inside an end-to-end test.
27+
28+
This isn't great but it's the best way we came up with to double-check that
29+
MetricsManager.isWebdriver() does what we want it to. We basically just
30+
copy the contents of that function here for testing :( .
31+
"""
32+
content = app.evaluate("window.navigator.webdriver")
33+
assert content, "window.navigator.webdriver is set to False"
34+
35+
2436
def test_total_loaded_assets_size_under_threshold(page: Page, app_port: int):
2537
"""Test that verifies the total size of loaded web assets is under a
2638
configured threshold.

frontend/app/src/MetricsManager.test.ts

+32
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const getMetricsManager = (
4545
return mm
4646
}
4747

48+
const originalWebdriver = window.navigator.webdriver
49+
4850
// Mock fetch for our metrics config request
4951
global.fetch = vi.fn(() =>
5052
Promise.resolve({
@@ -120,6 +122,7 @@ const checkDefaultEventData = (
120122

121123
afterEach(() => {
122124
window.analytics = undefined
125+
window.navigator.webdriver = originalWebdriver
123126
window.localStorage.clear()
124127
setCookie("ajs_anonymous_id")
125128
})
@@ -412,3 +415,32 @@ test("tracks installation data", () => {
412415
expect(trackCall.machineIdV3).toEqual(sessionInfo.current.installationIdV3)
413416
expect(trackCall.machineIdV4).toEqual(sessionInfo.current.installationIdV4)
414417
})
418+
419+
test("tracks server/local debug data", () => {
420+
const sessionInfo = mockSessionInfo()
421+
const mm = getMetricsManager(sessionInfo)
422+
mm.initialize({ gatherUsageStats: true })
423+
mm.enqueue("ev1", { data1: 11 })
424+
425+
const trackCall = mm.track.mock.calls[0][0]
426+
expect(trackCall.serverOs).toEqual(sessionInfo.current.serverOS)
427+
expect(trackCall.hasDisplay).toEqual(sessionInfo.current.hasDisplay)
428+
429+
// This test runs outside a browser so isWebdriver should be false.
430+
expect(trackCall.isWebdriver).toEqual(false)
431+
})
432+
433+
test("tracks server/local debug data with mocked webdriver", () => {
434+
window.navigator.webdriver = true
435+
const sessionInfo = mockSessionInfo()
436+
const mm = getMetricsManager(sessionInfo)
437+
mm.initialize({ gatherUsageStats: true })
438+
mm.enqueue("ev1", { data1: 11 })
439+
440+
const trackCall = mm.track.mock.calls[0][0]
441+
expect(trackCall.serverOs).toEqual(sessionInfo.current.serverOS)
442+
expect(trackCall.hasDisplay).toEqual(sessionInfo.current.hasDisplay)
443+
444+
// This test runs outside a browser so isWebdriver should be false.
445+
expect(trackCall.isWebdriver).toEqual(true)
446+
})

frontend/app/src/MetricsManager.ts

+5
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ export class MetricsManager {
247247
pythonVersion: this.sessionInfo.current.pythonVersion,
248248
serverOs: this.sessionInfo.current.serverOS,
249249
hasDisplay: this.sessionInfo.current.hasDisplay,
250+
isWebdriver: isWebdriver(),
250251
...this.getContextData(),
251252
})
252253

@@ -341,3 +342,7 @@ export class MetricsManager {
341342
}
342343
}
343344
}
345+
346+
function isWebdriver(): boolean {
347+
return window.navigator?.webdriver ?? false
348+
}

proto/streamlit/proto/MetricsEvent.proto

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ message MetricsEvent {
3939
string python_version = 36;
4040
string server_os = 42;
4141
bool has_display = 43;
42+
bool is_webdriver = 44;
4243

4344
// Host tracking fields:
4445
string hosted_at = 9;
@@ -82,7 +83,7 @@ message MetricsEvent {
8283
int64 total_load_time = 39;
8384
BrowserInfo browser_info = 40;
8485

85-
// Next ID: 44
86+
// Next ID: 45
8687
}
8788

8889
message BrowserInfo {

0 commit comments

Comments
 (0)