Skip to content

Commit 280ee88

Browse files
authored
Add support for BrowserStack Load Testing Service (LTS) (#54)
Adds an env-var-gated mode that lets the plugin emit per-test rows correctly when the user's suite is running on BrowserStack's load- testing infrastructure (where the test runs against a local Selenium hub rather than the Automate hub). src/utils/helper.js - isLoadTestingSession() + getLtsSessionId() helpers, driven by the BROWSERSTACK_LTS_SESSION_ID env var (or BROWSERSTACK_LTS=true|1 for local testing). - getCloudProvider() returns 'browserstack' under LTS so events flow through the integrations.browserstack.* path. - getIntegrationsObject() overrides session_id with the LTS env id and forces product='loadTesting' under LTS. src/testObservability.js - getProductMapForBuildStartCall() sets automate=false + lts=true under LTS so build.source aligns with the LTS contract. All LTS code paths are gated on helper.isLoadTestingSession(). Non-LTS Nightwatch runs see zero behavior change.
1 parent 99c7cb4 commit 280ee88

2 files changed

Lines changed: 51 additions & 4 deletions

File tree

src/testObservability.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,14 +897,21 @@ class TestObservability {
897897

898898
getProductMapForBuildStartCall(settings) {
899899
const product = helper.getObservabilityLinkedProductName(settings.desiredCapabilities, settings?.selenium?.host);
900+
// LTS runs explicitly disable Automate (browserstackAutomation: false)
901+
// and route to the LTS internal hub instead of the Automate cloud hub.
902+
// Keeping automate=true here causes builds to land in TestHub with
903+
// source=TO,AUT,LTS instead of the expected TO,LTS that production
904+
// (binary-CLI-managed) LTS builds carry. Mirror of py-sdk ea53d914.
905+
const lts = helper.isLoadTestingSession();
900906

901907
const buildProductMap = {
902-
automate: product === 'automate',
908+
automate: lts ? false : product === 'automate',
903909
app_automate: product === 'app-automate',
904910
observability: helper.isTestObservabilitySession(),
905911
accessibility: helper.isAccessibilityEnabled(settings),
906912
turboscale: product === 'turboscale',
907-
percy: false
913+
percy: false,
914+
lts
908915
};
909916

910917
return buildProductMap;

src/utils/helper.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ exports.debug = (text) => {
4242
}
4343
};
4444

45+
// Load Testing Service (LTS) gating helpers — mirror of bstack_utils/helper.py
46+
// is_load_testing_session() / get_lts_session_id() in browserstack-python-sdk
47+
// (branch LTS-tra-python-support). LTS pod-iterations export
48+
// BROWSERSTACK_LTS_SESSION_ID before invoking the test runner; presence of
49+
// that env var is the single source of truth for "this run is an LTS pod
50+
// iteration". Optional BROWSERSTACK_LTS=true|1 lets the runner opt-in
51+
// without supplying a session id (useful for local repro).
52+
exports.isLoadTestingSession = () => {
53+
if (process.env.BROWSERSTACK_LTS_SESSION_ID) {
54+
return true;
55+
}
56+
const flag = process.env.BROWSERSTACK_LTS;
57+
58+
return flag === 'true' || flag === '1';
59+
};
60+
61+
exports.getLtsSessionId = () => {
62+
return process.env.BROWSERSTACK_LTS_SESSION_ID || '';
63+
};
64+
4565
exports.generateLocalIdentifier = () => {
4666
const formattedDate = new Intl.DateTimeFormat('en-GB', {
4767
month: 'short',
@@ -742,6 +762,17 @@ exports.getUserName = (settings, nwConfig) => {
742762
};
743763

744764
exports.getCloudProvider = (hostname) => {
765+
// LTS BLU runner pods route through a local Selenium hub (localhost:4444)
766+
// so the hostname check below resolves to 'unknown_grid' — TestHub's o11y
767+
// classifier then lands the row with origin=UnknownGrid and
768+
// session_hashed_id=NULL even though build.source contains LTS. Force
769+
// 'browserstack' under LTS so events flow through the
770+
// integrations.browserstack.* path. Mirror of py-sdk 3af3bba6
771+
// (LTS pytest: override AutomationSession.provider to 'browserstack'
772+
// so TestHub records origin=LoadTesting).
773+
if (this.isLoadTestingSession()) {
774+
return 'browserstack';
775+
}
745776
if (hostname && hostname.includes('browserstack')) {
746777
return 'browserstack';
747778
}
@@ -768,14 +799,23 @@ exports.getObservabilityLinkedProductName = (caps, hostname) => {
768799
};
769800

770801
exports.getIntegrationsObject = (capabilities, sessionId, hostname, platform_version) => {
802+
// LTS: override session_id with the pod-iteration LTS env id and force
803+
// product='loadTesting' so TestHub o11y classifier resolves
804+
// test_run.origin=LoadTesting. Mirrors py-sdk 0efca1ae (session_id
805+
// override at event-emission layer) + a245a814 (product=loadTesting
806+
// tag on AutomationSession). Non-LTS Nightwatch runs see zero
807+
// behavior change.
808+
const ltsActive = this.isLoadTestingSession();
809+
const ltsSessionId = ltsActive ? this.getLtsSessionId() : '';
810+
771811
return {
772812
capabilities: capabilities,
773-
session_id: sessionId,
813+
session_id: (ltsActive && ltsSessionId) ? ltsSessionId : sessionId,
774814
browser: capabilities.browserName,
775815
browser_version: capabilities.browserVersion,
776816
platform: capabilities.platformName,
777817
platform_version: capabilities.platformVersion || platform_version,
778-
product: this.getObservabilityLinkedProductName(capabilities, hostname)
818+
product: ltsActive ? 'loadTesting' : this.getObservabilityLinkedProductName(capabilities, hostname)
779819
};
780820
};
781821

0 commit comments

Comments
 (0)