diff --git a/.changeset/pr-123.md b/.changeset/pr-123.md new file mode 100644 index 0000000..667faf7 --- /dev/null +++ b/.changeset/pr-123.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Fixed Accessibility Automation producing no report for WebdriverIO suites running on the jasmine framework. Accessibility scans now run for jasmine specs, as they already did for mocha. diff --git a/packages/browserstack-service/src/accessibility-handler.ts b/packages/browserstack-service/src/accessibility-handler.ts index 22f61d5..ecb0f93 100644 --- a/packages/browserstack-service/src/accessibility-handler.ts +++ b/packages/browserstack-service/src/accessibility-handler.ts @@ -78,6 +78,12 @@ import * as PERFORMANCE_SDK_EVENTS from './instrumentation/performance/constants import { BStackLogger } from './bstackLogger.js' class _AccessibilityHandler { + /** + * Frameworks whose per-test lifecycle flows through beforeTest/afterTest. + * WDIO's jasmine adapter emits the same service hooks as mocha (SDK-7190); + * cucumber goes through beforeScenario/afterScenario instead. + */ + private static readonly TEST_HOOK_FRAMEWORKS = ['mocha', 'jasmine'] private _platformA11yMeta: PlatformA11yMeta private _caps: Capabilities.ResolvedTestrunnerCapabilities private _suiteFile?: string @@ -276,7 +282,7 @@ class _AccessibilityHandler { async beforeTest (suiteTitle: string | undefined, test: Frameworks.Test) { try { if ( - this._framework !== 'mocha' || + !AccessibilityHandler.TEST_HOOK_FRAMEWORKS.includes(this._framework as string) || !this.shouldRunTestHooks(this._browser, this._accessibility) ) { /* This is to be used when test events are sent */ @@ -284,8 +290,10 @@ class _AccessibilityHandler { return } + /* jasmine test objects carry the spec name in `description` (`title` is unset) */ + const testTitle = test.title ?? test.description // @ts-expect-error fix type - const shouldScanTest = this._autoScanning && shouldScanTestForAccessibility(suiteTitle, test.title, this._accessibilityOptions) + const shouldScanTest = this._autoScanning && shouldScanTestForAccessibility(suiteTitle, testTitle, this._accessibilityOptions) const testIdentifier = this.getIdentifier(test) this._testIdentifier = testIdentifier @@ -315,7 +323,7 @@ class _AccessibilityHandler { async afterTest (suiteTitle: string | undefined, test: Frameworks.Test) { BStackLogger.debug('Accessibility after test hook. Before sending test stop event') if ( - this._framework !== 'mocha' || + !AccessibilityHandler.TEST_HOOK_FRAMEWORKS.includes(this._framework as string) || !this.shouldRunTestHooks(this._browser, this._accessibility) ) { return diff --git a/packages/browserstack-service/tests/accessibility-handler.test.ts b/packages/browserstack-service/tests/accessibility-handler.test.ts index 417003e..a6bcf90 100644 --- a/packages/browserstack-service/tests/accessibility-handler.test.ts +++ b/packages/browserstack-service/tests/accessibility-handler.test.ts @@ -574,18 +574,48 @@ describe('beforeTest', () => { }) describe('jasmine', () => { - let isBrowserstackSession: any beforeEach(() => { accessibilityHandler = new AccessibilityHandler(browser, caps, options, false, config, 'jasmine', true, false, accessibilityOpts) - isBrowserstackSession = vi.spyOn(utils, 'isBrowserstackSession').mockReturnValue(true) + vi.spyOn(utils, 'isBrowserstackSession').mockReturnValue(true) + vi.spyOn(utils, 'isAccessibilityAutomationSession').mockReturnValue(true) + vi.spyOn(utils, 'getUniqueIdentifier').mockReturnValue('suite title test') }) - it('should execute test started in case of jasmine', async () => { + it('should start scan orchestration for jasmine like mocha (SDK-7190)', async () => { + const logInfoMock = vi.spyOn(log, 'info') + const shouldScanSpy = vi.spyOn(utils, 'shouldScanTestForAccessibility').mockReturnValue(true) + + /* jasmine test objects have `description`/`fullName`, no `title`/`parent` */ + await accessibilityHandler.beforeTest('suite title', { description: 'test', fullName: 'suite title test' } as any) + + expect(shouldScanSpy).toBeCalledWith('suite title', 'test', accessibilityOpts) + expect(logInfoMock.mock.calls[0][0]) + .toContain('Automate test case execution has started.') + expect(accessibilityHandler['_testMetadata']['suite title test']).toEqual({ + scanTestForAccessibility: true, + accessibilityScanStarted: true + }) + }) + + it('should arm the a11y scan session map so command scans fire (SDK-7190)', async () => { vi.spyOn(utils, 'shouldScanTestForAccessibility').mockReturnValue(true) + accessibilityHandler['_sessionId'] = 'session123' + + await accessibilityHandler.beforeTest('suite title', { description: 'test', fullName: 'suite title test' } as any) + + expect(AccessibilityHandler['_a11yScanSessionMap']['session123']).toBe(true) + }) + }) + + describe('cucumber', () => { + it('should not run beforeTest orchestration for cucumber', async () => { + accessibilityHandler = new AccessibilityHandler(browser, caps, options, false, config, 'cucumber', true, false, accessibilityOpts) + vi.spyOn(utils, 'isAccessibilityAutomationSession').mockReturnValue(true) + const shouldScanSpy = vi.spyOn(utils, 'shouldScanTestForAccessibility').mockReturnValue(true) await accessibilityHandler.beforeTest('suite title', { parent: 'parent', title: 'test' } as any) - expect(isBrowserstackSession).toBeCalledTimes(0) + expect(shouldScanSpy).toBeCalledTimes(0) }) }) }) @@ -641,6 +671,22 @@ describe('afterTest', () => { expect(logErrorMock.mock.calls[0][0]) .toContain('Accessibility results could not be processed for the test case test. Error :') }) + + it('should send test stop event for jasmine (SDK-7190)', async () => { + accessibilityHandler = new AccessibilityHandler(browser, caps, options, false, config, 'jasmine', true, false, accessibilityOpts) + vi.spyOn(utils, 'isAccessibilityAutomationSession').mockReturnValue(true) + vi.spyOn(utils, 'getUniqueIdentifier').mockReturnValue('test title') + accessibilityHandler['_testMetadata']['test title'] = { + accessibilityScanStarted: true, + scanTestForAccessibility: true + } + const sendStop = vi.fn() + accessibilityHandler['sendTestStopEvent'] = sendStop + + await accessibilityHandler.afterTest('suite title', { description: 'test', fullName: 'suite title test' } as any) + + expect(sendStop).toBeCalledTimes(1) + }) }) describe('getIdentifier', () => {