diff --git a/packages/wdio-browserstack-service/src/insights-handler.ts b/packages/wdio-browserstack-service/src/insights-handler.ts index 8cce02687fb..0821c9a4679 100644 --- a/packages/wdio-browserstack-service/src/insights-handler.ts +++ b/packages/wdio-browserstack-service/src/insights-handler.ts @@ -1,12 +1,14 @@ import path from 'node:path' -import type { Frameworks } from '@wdio/types' +import type { Frameworks, Options } from '@wdio/types' import type { BeforeCommandArgs, AfterCommandArgs } from '@wdio/reporter' import { v4 as uuidv4 } from 'uuid' import type { CucumberStore, Feature, Scenario, Step, FeatureChild, CucumberHook, CucumberHookParams, Pickle, ITestCaseHookParameter } from './cucumber-types.js' import TestReporter from './reporter.js' +import type { BrowserstackConfig } from './types.js' + import { frameworkSupportsHook, getCloudProvider, getFailureObject, @@ -20,6 +22,7 @@ import { isUndefined, o11yClassErrorHandler, removeAnsiColors, + getObservabilityProduct } from './util.js' import type { TestData, @@ -53,24 +56,30 @@ class _InsightsHandler { private _currentTestId: string | undefined private _cbtQueue: Array = [] - constructor (private _browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser, isAppAutomate?: boolean, private _framework?: string, _userCaps?: Capabilities.RemoteCapability) { + constructor (private _browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser, private _framework?: string, _userCaps?: Capabilities.RemoteCapability, _options?: BrowserstackConfig & Options.Testrunner) { const caps = (this._browser as WebdriverIO.Browser).capabilities as WebdriverIO.Capabilities const sessionId = (this._browser as WebdriverIO.Browser).sessionId + this._userCaps = _userCaps + this._platformMeta = { browserName: caps.browserName, browserVersion: caps?.browserVersion, platformName: caps?.platformName, caps: caps, sessionId, - product: isAppAutomate ? 'app-automate' : 'automate' + product: getObservabilityProduct(_options, this._isAppAutomate()) } - this._userCaps = _userCaps - this.registerListeners() } + _isAppAutomate(): boolean { + const browserDesiredCapabilities = (this._browser?.capabilities ?? {}) as Capabilities.DesiredCapabilities + const desiredCapabilities = (this._userCaps ?? {}) as Capabilities.DesiredCapabilities + return !!browserDesiredCapabilities['appium:app'] || !!desiredCapabilities['appium:app'] || !!(( desiredCapabilities as any)['appium:options']?.app) + } + registerListeners() { if (!(this._framework === 'mocha' || this._framework === 'cucumber')) { return diff --git a/packages/wdio-browserstack-service/src/service.ts b/packages/wdio-browserstack-service/src/service.ts index 9ea9f68d214..6849e983619 100644 --- a/packages/wdio-browserstack-service/src/service.ts +++ b/packages/wdio-browserstack-service/src/service.ts @@ -69,6 +69,7 @@ export default class BrowserstackService implements Services.ServiceInstance { if (process.env.BROWSERSTACK_TURBOSCALE) { this._turboScale = process.env.BROWSERSTACK_TURBOSCALE === 'true' } + process.env.BROWSERSTACK_TURBOSCALE_INTERNAL = String(this._turboScale) // Cucumber specific const strict = Boolean(this._config.cucumberOpts && this._config.cucumberOpts.strict) @@ -153,9 +154,9 @@ export default class BrowserstackService implements Services.ServiceInstance { this._insightsHandler = new InsightsHandler( this._browser, - this._isAppAutomate(), this._config.framework, - this._caps + this._caps, + this._options ) await this._insightsHandler.before() } diff --git a/packages/wdio-browserstack-service/src/util.ts b/packages/wdio-browserstack-service/src/util.ts index d132b095890..8a01a78b417 100644 --- a/packages/wdio-browserstack-service/src/util.ts +++ b/packages/wdio-browserstack-service/src/util.ts @@ -1399,6 +1399,16 @@ export const getErrorString = (err: unknown) => { } } +export function isTurboScale(options: (BrowserstackConfig & Options.Testrunner) | undefined): boolean { + return Boolean(options?.turboScale) +} + +export function getObservabilityProduct(options: (BrowserstackConfig & Options.Testrunner) | undefined, isAppAutomate: boolean | undefined): string { + return isAppAutomate + ? 'app-automate' + : (isTurboScale(options) ? 'turboscale' : 'automate') +} + export const hasBrowserName = (cap: Options.Testrunner): boolean => { if (!cap || !cap.capabilities) { return false diff --git a/packages/wdio-browserstack-service/tests/insights-handler.test.ts b/packages/wdio-browserstack-service/tests/insights-handler.test.ts index 5c38be99e45..a3613182170 100644 --- a/packages/wdio-browserstack-service/tests/insights-handler.test.ts +++ b/packages/wdio-browserstack-service/tests/insights-handler.test.ts @@ -62,11 +62,11 @@ beforeEach(() => { execute: vi.fn(), on: vi.fn(), } as any as WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') }) it('should initialize correctly', () => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') expect(insightsHandler['_tests']).toEqual({}) expect(insightsHandler['_hooks']).toEqual({}) expect(insightsHandler['_commands']).toEqual({}) @@ -77,7 +77,7 @@ describe('before', () => { const isBrowserstackSessionSpy = vi.spyOn(utils, 'isBrowserstackSession') beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') isBrowserstackSessionSpy.mockClear() }) @@ -97,7 +97,7 @@ describe('beforeScenario', () => { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') vi.spyOn(utils, 'getUniqueIdentifierForCucumber').mockReturnValue('test title') insightsHandler['getTestRunDataForCucumber'] = vi.fn() insightsHandler['_tests'] = {} @@ -125,7 +125,7 @@ describe('afterScenario', () => { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') insightsHandler['getTestRunDataForCucumber'] = vi.fn() insightsHandler['_tests'] = {} }) @@ -152,7 +152,7 @@ describe('beforeStep', () => { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') vi.spyOn(utils, 'getUniqueIdentifierForCucumber').mockReturnValue('test title') insightsHandler['getHierarchy'] = vi.fn().mockImplementation(() => { return [] }) }) @@ -205,7 +205,7 @@ describe('afterStep', () => { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') vi.spyOn(utils, 'getUniqueIdentifierForCucumber').mockReturnValue('test title') insightsHandler['getHierarchy'] = vi.fn().mockImplementation(() => { return [] }) }) @@ -328,7 +328,7 @@ describe('attachHookData', () => { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') }) it('add hooks data in test', () => { @@ -377,7 +377,7 @@ describe('attachHookData', () => { describe('setHooksFromSuite', () => { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') insightsHandler['_hooks'] = {} }) @@ -405,7 +405,7 @@ describe('getHierarchy', () => { let insightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') }) it('return array of getHierarchy when context present', () => { @@ -431,7 +431,7 @@ describe('getHierarchy', () => { describe('getTestRunId', function () { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') }) it('should return if null context', () => { @@ -468,7 +468,7 @@ describe('getTestRunId', function () { describe('getTestRunIdFromSuite', function () { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') }) it('should return null if parent null', function () { @@ -494,7 +494,7 @@ describe('beforeTest', () => { describe('mocha', () => { beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'mocha') + insightsHandler = new InsightsHandler(browser, 'mocha') insightsHandler['getRunData'] = vi.fn().mockImplementation(() => { return [] }) vi.spyOn(utils, 'getUniqueIdentifier').mockReturnValue('test title') insightsHandler['_tests'] = {} @@ -512,7 +512,7 @@ describe('beforeTest', () => { describe('jasmine', () => { beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'jasmine') + insightsHandler = new InsightsHandler(browser, 'jasmine') insightsHandler['getRunData'] = vi.fn().mockImplementation(() => { return [] }) insightsHandler['_tests'] = {} }) @@ -530,7 +530,7 @@ describe('beforeHook', () => { describe('mocha', () => { beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'mocha') + insightsHandler = new InsightsHandler(browser, 'mocha') insightsHandler['getRunData'] = vi.fn().mockImplementation(() => { return [] }) insightsHandler['attachHookData'] = vi.fn().mockImplementation(() => { return [] }) insightsHandler['_tests'] = {} @@ -552,7 +552,7 @@ describe('beforeHook', () => { describe('cucumber', () => { beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'cucumber') + insightsHandler = new InsightsHandler(browser, 'cucumber') insightsHandler['processCucumberHook'] = vi.fn().mockImplementation(() => { return [] }) insightsHandler['_framework'] = 'cucumber' }) @@ -569,7 +569,7 @@ describe('afterHook', () => { describe('mocha', () => { beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'mocha') + insightsHandler = new InsightsHandler(browser, 'mocha') insightsHandler['getRunData'] = vi.fn().mockImplementation(() => { return [] }) insightsHandler['attachHookData'] = vi.fn().mockImplementation(() => { return [] }) @@ -596,7 +596,7 @@ describe('afterHook', () => { describe('cucumber', () => { beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'cucumber') + insightsHandler = new InsightsHandler(browser, 'cucumber') insightsHandler['processCucumberHook'] = vi.fn().mockImplementation(() => { return [] }) }) @@ -616,7 +616,7 @@ describe('getIntegrationsObject', () => { }) beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') insightsHandler['_platformMeta'] = { caps: {}, sessionId: '', browserName: '', browserVersion: '', platformName: '', product: '' } }) @@ -649,7 +649,7 @@ describe('browserCommand', () => { let commandSpy beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') insightsHandler['getIdentifier'] = vi.fn().mockImplementation(() => { return 'test title' }) insightsHandler['_tests'] = { 'test title': { 'uuid': 'uuid' } } insightsHandler['_commands'] = { 's_m_e': {} as any } @@ -695,7 +695,7 @@ describe('getIdentifier', () => { let getUniqueIdentifierForCucumberSpy beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') insightsHandler['_tests'] = { 'test title': { 'uuid': 'uuid' } } getUniqueIdentifierSpy = vi.spyOn(utils, 'getUniqueIdentifier') @@ -751,7 +751,7 @@ describe('getCucumberHookType', function () { describe('getCucumberHookUniqueId', function () { let insightsHandler: InsightsHandler beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'framework') + insightsHandler = new InsightsHandler(browser, 'framework') }) it('should return hookId for each hooks', function () { @@ -780,7 +780,7 @@ describe('appendTestItemLog', function () { } let testLogObj: StdLog beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'mocha') + insightsHandler = new InsightsHandler(browser, 'mocha') sendDataSpy = vi.spyOn(insightsHandler['listener'], 'logCreated').mockImplementation(() => { return [] as any }) testLogObj = { ...logObj } }) @@ -812,7 +812,7 @@ describe('processCucumberHook', function () { let insightsHandler: InsightsHandler let getHookRunDataForCucumberSpy, cucumberHookTypeSpy, cucumberHookUniqueIdSpy beforeEach(() => { - insightsHandler = new InsightsHandler(browser, false, 'mocha') + insightsHandler = new InsightsHandler(browser, 'mocha') getHookRunDataForCucumberSpy = vi.spyOn(insightsHandler, 'getHookRunDataForCucumber').mockImplementation(() => { return [] as any }) cucumberHookTypeSpy = vi.spyOn(insightsHandler, 'getCucumberHookType') cucumberHookTypeSpy.mockImplementation(() => { return 'hii' })