@wdio/browserstack-service 8.16.6 → 8.16.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/accessibility-handler.d.ts +38 -0
- package/build/accessibility-handler.d.ts.map +1 -0
- package/build/accessibility-handler.js +260 -0
- package/build/constants.d.ts +2 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +4 -1
- package/build/launcher.d.ts +4 -0
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +156 -2
- package/build/scripts/test-event-scripts.d.ts +10 -0
- package/build/scripts/test-event-scripts.d.ts.map +1 -0
- package/build/scripts/test-event-scripts.js +65 -0
- package/build/service.d.ts +2 -0
- package/build/service.d.ts.map +1 -1
- package/build/service.js +18 -0
- package/build/types.d.ts +17 -0
- package/build/types.d.ts.map +1 -1
- package/build/util.d.ts +22 -0
- package/build/util.d.ts.map +1 -1
- package/build/util.js +259 -1
- package/package.json +7 -6
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Capabilities, Frameworks } from '@wdio/types';
|
|
2
|
+
import type { ITestCaseHookParameter } from './cucumber-types.js';
|
|
3
|
+
declare class _AccessibilityHandler {
|
|
4
|
+
private _browser;
|
|
5
|
+
private _capabilities;
|
|
6
|
+
private _framework?;
|
|
7
|
+
private _accessibilityAutomation?;
|
|
8
|
+
private _accessibilityOpts?;
|
|
9
|
+
private _platformA11yMeta;
|
|
10
|
+
private _caps;
|
|
11
|
+
private _suiteFile?;
|
|
12
|
+
private _accessibility?;
|
|
13
|
+
private _accessibilityOptions?;
|
|
14
|
+
private _testMetadata;
|
|
15
|
+
constructor(_browser: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser, _capabilities: Capabilities.RemoteCapability, isAppAutomate?: boolean, _framework?: string | undefined, _accessibilityAutomation?: string | boolean | undefined, _accessibilityOpts?: {
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
} | undefined);
|
|
18
|
+
setSuiteFile(filename: string): void;
|
|
19
|
+
_getCapabilityValue(caps: Capabilities.RemoteCapability, capType: string, legacyCapType: string): WebdriverIO.SafaridriverOptions | undefined;
|
|
20
|
+
before(): Promise<void>;
|
|
21
|
+
beforeTest(suiteTitle: string | undefined, test: Frameworks.Test): Promise<void>;
|
|
22
|
+
afterTest(suiteTitle: string | undefined, test: Frameworks.Test): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Cucumber Only
|
|
25
|
+
*/
|
|
26
|
+
beforeScenario(world: ITestCaseHookParameter): Promise<void>;
|
|
27
|
+
afterScenario(world: ITestCaseHookParameter): Promise<void>;
|
|
28
|
+
private sendTestStartEvent;
|
|
29
|
+
private sendTestForceStopEvent;
|
|
30
|
+
private sendTestStopEvent;
|
|
31
|
+
private getIdentifier;
|
|
32
|
+
private shouldRunTestHooks;
|
|
33
|
+
private checkIfPageOpened;
|
|
34
|
+
}
|
|
35
|
+
declare const AccessibilityHandler: typeof _AccessibilityHandler;
|
|
36
|
+
type AccessibilityHandler = _AccessibilityHandler;
|
|
37
|
+
export default AccessibilityHandler;
|
|
38
|
+
//# sourceMappingURL=accessibility-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility-handler.d.ts","sourceRoot":"","sources":["../src/accessibility-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAkBjE,cAAM,qBAAqB;IASnB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,aAAa;IAErB,OAAO,CAAC,UAAU,CAAC;IACnB,OAAO,CAAC,wBAAwB,CAAC;IACjC,OAAO,CAAC,kBAAkB,CAAC;IAb/B,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,qBAAqB,CAAC,CAAyB;IACvD,OAAO,CAAC,aAAa,CAA8B;gBAGvC,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB,EAC9D,aAAa,EAAE,YAAY,CAAC,gBAAgB,EACpD,aAAa,CAAC,EAAE,OAAO,EACf,UAAU,CAAC,oBAAQ,EACnB,wBAAwB,CAAC,8BAAkB,EAC3C,kBAAkB,CAAC;;iBAAyB;IAgBxD,YAAY,CAAC,QAAQ,EAAE,MAAM;IAI7B,mBAAmB,CAAC,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IA6BzF,MAAM;IAmBN,UAAU,CAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI;IAiCjE,SAAS,CAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI;IA0CtE;;MAEE;IACI,cAAc,CAAE,KAAK,EAAE,sBAAsB;IAiC7C,aAAa,CAAE,KAAK,EAAE,sBAAsB;IA8ClD,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,kBAAkB;YAOZ,iBAAiB;CAiBlC;AAGD,QAAA,MAAM,oBAAoB,EAAE,OAAO,qBAAoE,CAAA;AACvG,KAAK,oBAAoB,GAAG,qBAAqB,CAAA;AAEjD,eAAe,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import logger from '@wdio/logger';
|
|
2
|
+
import { getA11yResultsSummary, getA11yResults, getUniqueIdentifier, getUniqueIdentifierForCucumber, isAccessibilityAutomationSession, isBrowserstackSession, o11yClassErrorHandler, shouldScanTestForAccessibility, validateCapsWithA11y, isTrue, } from './util.js';
|
|
3
|
+
import { testForceStop, testStartEvent, testStop } from './scripts/test-event-scripts.js';
|
|
4
|
+
const log = logger('@wdio/browserstack-service');
|
|
5
|
+
class _AccessibilityHandler {
|
|
6
|
+
_browser;
|
|
7
|
+
_capabilities;
|
|
8
|
+
_framework;
|
|
9
|
+
_accessibilityAutomation;
|
|
10
|
+
_accessibilityOpts;
|
|
11
|
+
_platformA11yMeta;
|
|
12
|
+
_caps;
|
|
13
|
+
_suiteFile;
|
|
14
|
+
_accessibility;
|
|
15
|
+
_accessibilityOptions;
|
|
16
|
+
_testMetadata = {};
|
|
17
|
+
constructor(_browser, _capabilities, isAppAutomate, _framework, _accessibilityAutomation, _accessibilityOpts) {
|
|
18
|
+
this._browser = _browser;
|
|
19
|
+
this._capabilities = _capabilities;
|
|
20
|
+
this._framework = _framework;
|
|
21
|
+
this._accessibilityAutomation = _accessibilityAutomation;
|
|
22
|
+
this._accessibilityOpts = _accessibilityOpts;
|
|
23
|
+
const caps = this._browser.capabilities;
|
|
24
|
+
this._platformA11yMeta = {
|
|
25
|
+
browser_name: caps.browserName,
|
|
26
|
+
browser_version: caps?.browserVersion || caps?.version || 'latest',
|
|
27
|
+
os_name: this._getCapabilityValue(_capabilities, 'os', 'os'),
|
|
28
|
+
os_version: this._getCapabilityValue(_capabilities, 'osVersion', 'os_version')
|
|
29
|
+
};
|
|
30
|
+
this._caps = _capabilities;
|
|
31
|
+
this._accessibility = isTrue(_accessibilityAutomation);
|
|
32
|
+
this._accessibilityOptions = _accessibilityOpts;
|
|
33
|
+
}
|
|
34
|
+
setSuiteFile(filename) {
|
|
35
|
+
this._suiteFile = filename;
|
|
36
|
+
}
|
|
37
|
+
_getCapabilityValue(caps, capType, legacyCapType) {
|
|
38
|
+
if (caps) {
|
|
39
|
+
if (capType === 'accessibility') {
|
|
40
|
+
if (caps['bstack:options'] && (isTrue(caps['bstack:options']?.accessibility))) {
|
|
41
|
+
return caps['bstack:options']?.accessibility;
|
|
42
|
+
}
|
|
43
|
+
else if (isTrue(caps['browserstack.accessibility'])) {
|
|
44
|
+
return caps['browserstack.accessibility'];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (capType === 'deviceName') {
|
|
48
|
+
if (caps['bstack:options'] && caps['bstack:options']?.deviceName) {
|
|
49
|
+
return caps['bstack:options']?.deviceName;
|
|
50
|
+
}
|
|
51
|
+
else if (caps['bstack:options'] && caps['bstack:options']?.device) {
|
|
52
|
+
return caps['bstack:options']?.device;
|
|
53
|
+
}
|
|
54
|
+
else if (caps['appium:deviceName']) {
|
|
55
|
+
return caps['appium:deviceName'];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (capType === 'goog:chromeOptions' && caps['goog:chromeOptions']) {
|
|
59
|
+
return caps['goog:chromeOptions'];
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const bstackOptions = caps['bstack:options'];
|
|
63
|
+
if (bstackOptions && bstackOptions?.[capType]) {
|
|
64
|
+
return bstackOptions?.[capType];
|
|
65
|
+
}
|
|
66
|
+
else if (caps[legacyCapType]) {
|
|
67
|
+
return caps[legacyCapType];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async before() {
|
|
73
|
+
this._accessibility = isTrue(this._getCapabilityValue(this._caps, 'accessibility', 'browserstack.accessibility'));
|
|
74
|
+
if (isBrowserstackSession(this._browser) && isAccessibilityAutomationSession(this._accessibility)) {
|
|
75
|
+
const deviceName = this._getCapabilityValue(this._caps, 'deviceName', 'device');
|
|
76
|
+
const chromeOptions = this._getCapabilityValue(this._caps, 'goog:chromeOptions', '');
|
|
77
|
+
this._accessibility = validateCapsWithA11y(deviceName, this._platformA11yMeta, chromeOptions);
|
|
78
|
+
}
|
|
79
|
+
this._browser.getAccessibilityResultsSummary = async () => {
|
|
80
|
+
return await getA11yResultsSummary(this._browser, isBrowserstackSession(this._browser), this._accessibility);
|
|
81
|
+
};
|
|
82
|
+
this._browser.getAccessibilityResults = async () => {
|
|
83
|
+
return await getA11yResults(this._browser, isBrowserstackSession(this._browser), this._accessibility);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async beforeTest(suiteTitle, test) {
|
|
87
|
+
if (this._framework !== 'mocha' ||
|
|
88
|
+
!this.shouldRunTestHooks(this._browser, this._accessibility)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const shouldScanTest = shouldScanTestForAccessibility(suiteTitle, test.title, this._accessibilityOptions);
|
|
92
|
+
const testIdentifier = this.getIdentifier(test);
|
|
93
|
+
const isPageOpened = await this.checkIfPageOpened(this._browser, testIdentifier, shouldScanTest);
|
|
94
|
+
if (!isPageOpened) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
if (shouldScanTest) {
|
|
99
|
+
log.info('Setup for Accessibility testing has started. Automate test case execution will begin momentarily.');
|
|
100
|
+
await this.sendTestStartEvent(this._browser);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
await this.sendTestForceStopEvent(this._browser);
|
|
104
|
+
}
|
|
105
|
+
this._testMetadata[testIdentifier].accessibilityScanStarted = shouldScanTest;
|
|
106
|
+
if (shouldScanTest) {
|
|
107
|
+
log.info('Automate test case execution has started.');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
log.error(`Exception in starting accessibility automation scan for this test case ${error}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async afterTest(suiteTitle, test) {
|
|
115
|
+
if (this._framework !== 'mocha' ||
|
|
116
|
+
!this.shouldRunTestHooks(this._browser, this._accessibility)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const testIdentifier = this.getIdentifier(test);
|
|
121
|
+
const accessibilityScanStarted = this._testMetadata[testIdentifier]?.accessibilityScanStarted;
|
|
122
|
+
const shouldScanTestForAccessibility = this._testMetadata[testIdentifier]?.scanTestForAccessibility;
|
|
123
|
+
if (!accessibilityScanStarted) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (shouldScanTestForAccessibility) {
|
|
127
|
+
log.info('Automate test case execution has ended. Processing for accessibility testing is underway. ');
|
|
128
|
+
}
|
|
129
|
+
const dataForExtension = {
|
|
130
|
+
saveResults: shouldScanTestForAccessibility,
|
|
131
|
+
testDetails: {
|
|
132
|
+
'name': test.title,
|
|
133
|
+
'testRunId': process.env.BS_A11Y_TEST_RUN_ID,
|
|
134
|
+
'filePath': this._suiteFile,
|
|
135
|
+
'scopeList': [suiteTitle, test.title]
|
|
136
|
+
},
|
|
137
|
+
platform: this._platformA11yMeta
|
|
138
|
+
};
|
|
139
|
+
await this.sendTestStopEvent(this._browser, dataForExtension);
|
|
140
|
+
if (shouldScanTestForAccessibility) {
|
|
141
|
+
log.info('Accessibility testing for this test case has ended.');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
log.error(`Accessibility results could not be processed for the test case ${test.title}. Error :`, error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Cucumber Only
|
|
150
|
+
*/
|
|
151
|
+
async beforeScenario(world) {
|
|
152
|
+
if (!this.shouldRunTestHooks(this._browser, this._accessibility)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const pickleData = world.pickle;
|
|
156
|
+
const gherkinDocument = world.gherkinDocument;
|
|
157
|
+
const featureData = gherkinDocument.feature;
|
|
158
|
+
const uniqueId = getUniqueIdentifierForCucumber(world);
|
|
159
|
+
const shouldScanScenario = shouldScanTestForAccessibility(featureData?.name, pickleData.name, this._accessibilityOptions);
|
|
160
|
+
const isPageOpened = await this.checkIfPageOpened(this._browser, uniqueId, shouldScanScenario);
|
|
161
|
+
if (!isPageOpened) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
if (shouldScanScenario) {
|
|
166
|
+
log.info('Setup for Accessibility testing has started. Automate test case execution will begin momentarily.');
|
|
167
|
+
await this.sendTestStartEvent(this._browser);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
await this.sendTestForceStopEvent(this._browser);
|
|
171
|
+
}
|
|
172
|
+
this._testMetadata[uniqueId].accessibilityScanStarted = shouldScanScenario;
|
|
173
|
+
if (shouldScanScenario) {
|
|
174
|
+
log.info('Automate test case execution has started.');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
log.error(`Exception in starting accessibility automation scan for this test case ${error}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async afterScenario(world) {
|
|
182
|
+
if (!this.shouldRunTestHooks(this._browser, this._accessibility)) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const pickleData = world.pickle;
|
|
186
|
+
try {
|
|
187
|
+
const gherkinDocument = world.gherkinDocument;
|
|
188
|
+
const featureData = gherkinDocument.feature;
|
|
189
|
+
const uniqueId = getUniqueIdentifierForCucumber(world);
|
|
190
|
+
const accessibilityScanStarted = this._testMetadata[uniqueId]?.accessibilityScanStarted;
|
|
191
|
+
const shouldScanTestForAccessibility = this._testMetadata[uniqueId]?.scanTestForAccessibility;
|
|
192
|
+
if (!accessibilityScanStarted) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (shouldScanTestForAccessibility) {
|
|
196
|
+
log.info('Automate test case execution has ended. Processing for accessibility testing is underway. ');
|
|
197
|
+
}
|
|
198
|
+
const dataForExtension = {
|
|
199
|
+
saveResults: shouldScanTestForAccessibility,
|
|
200
|
+
testDetails: {
|
|
201
|
+
'name': pickleData.name,
|
|
202
|
+
'testRunId': process.env.BS_A11Y_TEST_RUN_ID,
|
|
203
|
+
'filePath': gherkinDocument.uri,
|
|
204
|
+
'scopeList': [featureData?.name, pickleData.name]
|
|
205
|
+
},
|
|
206
|
+
platform: this._platformA11yMeta
|
|
207
|
+
};
|
|
208
|
+
await this.sendTestStopEvent(this._browser, dataForExtension);
|
|
209
|
+
if (shouldScanTestForAccessibility) {
|
|
210
|
+
log.info('Accessibility testing for this test case has ended.');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
log.error(`Accessibility results could not be processed for the test case ${pickleData.name}. Error :`, error);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/*
|
|
218
|
+
* private methods
|
|
219
|
+
*/
|
|
220
|
+
sendTestStartEvent(browser) {
|
|
221
|
+
return browser.executeAsync(testStartEvent);
|
|
222
|
+
}
|
|
223
|
+
sendTestForceStopEvent(browser) {
|
|
224
|
+
return browser.execute(testForceStop);
|
|
225
|
+
}
|
|
226
|
+
sendTestStopEvent(browser, dataForExtension) {
|
|
227
|
+
return browser.executeAsync(testStop, dataForExtension);
|
|
228
|
+
}
|
|
229
|
+
getIdentifier(test) {
|
|
230
|
+
if ('pickle' in test) {
|
|
231
|
+
return getUniqueIdentifierForCucumber(test);
|
|
232
|
+
}
|
|
233
|
+
return getUniqueIdentifier(test, this._framework);
|
|
234
|
+
}
|
|
235
|
+
shouldRunTestHooks(browser, isAccessibility) {
|
|
236
|
+
if (!browser) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
return isBrowserstackSession(browser) && isAccessibilityAutomationSession(isAccessibility);
|
|
240
|
+
}
|
|
241
|
+
async checkIfPageOpened(browser, testIdentifier, shouldScanTest) {
|
|
242
|
+
let pageOpen = false;
|
|
243
|
+
this._testMetadata[testIdentifier] = {
|
|
244
|
+
scanTestForAccessibility: shouldScanTest,
|
|
245
|
+
accessibilityScanStarted: true
|
|
246
|
+
};
|
|
247
|
+
try {
|
|
248
|
+
const currentURL = await browser.getUrl();
|
|
249
|
+
const url = new URL(currentURL);
|
|
250
|
+
pageOpen = url?.protocol === 'http:' || url?.protocol === 'https:';
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
pageOpen = false;
|
|
254
|
+
}
|
|
255
|
+
return pageOpen;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// https://github.com/microsoft/TypeScript/issues/6543
|
|
259
|
+
const AccessibilityHandler = o11yClassErrorHandler(_AccessibilityHandler);
|
|
260
|
+
export default AccessibilityHandler;
|
package/build/constants.d.ts
CHANGED
|
@@ -13,4 +13,6 @@ export declare const BATCH_EVENT_TYPES: string[];
|
|
|
13
13
|
export declare const DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = 5000;
|
|
14
14
|
export declare const DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = 100;
|
|
15
15
|
export declare const BSTACK_SERVICE_VERSION: any;
|
|
16
|
+
export declare const ACCESSIBILITY_API_URL = "https://accessibility.browserstack.com/api";
|
|
17
|
+
export declare const NOT_ALLOWED_KEYS_IN_CAPS: string[];
|
|
16
18
|
//# sourceMappingURL=constants.d.ts.map
|
package/build/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAKpD,eAAO,MAAM,mBAAmB,qHAStB,CAAA;AAEV,eAAO,MAAM,mBAAmB,UAI/B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAKpD,eAAO,MAAM,mBAAmB,qHAStB,CAAA;AAEV,eAAO,MAAM,mBAAmB,UAI/B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,kBAAkB,CAKvD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,OAAO,OAAoC,CAAA;AAEvE,eAAO,MAAM,aAAa,qDAAqD,CAAA;AAC/E,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AACjD,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,iBAAiB,UAAgH,CAAA;AAC9I,eAAO,MAAM,wCAAwC,OAAO,CAAA;AAC5D,eAAO,MAAM,yCAAyC,MAAM,CAAA;AAC5D,eAAO,MAAM,sBAAsB,KAAuB,CAAA;AAE1D,eAAO,MAAM,qBAAqB,+CAA+C,CAAA;AACjF,eAAO,MAAM,wBAAwB,UAA6D,CAAA"}
|
package/build/constants.js
CHANGED
|
@@ -19,7 +19,8 @@ export const VALID_APP_EXTENSION = [
|
|
|
19
19
|
export const DEFAULT_OPTIONS = {
|
|
20
20
|
setSessionName: true,
|
|
21
21
|
setSessionStatus: true,
|
|
22
|
-
testObservability: true
|
|
22
|
+
testObservability: true,
|
|
23
|
+
accessibility: false
|
|
23
24
|
};
|
|
24
25
|
export const consoleHolder = Object.assign({}, console);
|
|
25
26
|
export const DATA_ENDPOINT = 'https://collector-observability.browserstack.com';
|
|
@@ -32,3 +33,5 @@ export const BATCH_EVENT_TYPES = ['LogCreated', 'TestRunStarted', 'TestRunFinish
|
|
|
32
33
|
export const DEFAULT_WAIT_TIMEOUT_FOR_PENDING_UPLOADS = 5000; // 5s
|
|
33
34
|
export const DEFAULT_WAIT_INTERVAL_FOR_PENDING_UPLOADS = 100; // 100ms
|
|
34
35
|
export const BSTACK_SERVICE_VERSION = bstackServiceVersion;
|
|
36
|
+
export const ACCESSIBILITY_API_URL = 'https://accessibility.browserstack.com/api';
|
|
37
|
+
export const NOT_ALLOWED_KEYS_IN_CAPS = ['includeTagsInTestingScope', 'excludeTagsInTestingScope'];
|
package/build/launcher.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export default class BrowserstackLauncherService implements Services.ServiceInst
|
|
|
13
13
|
private _projectName?;
|
|
14
14
|
private _buildTag?;
|
|
15
15
|
private _buildIdentifier?;
|
|
16
|
+
private _accessibilityAutomation?;
|
|
16
17
|
constructor(_options: BrowserstackConfig & Options.Testrunner, capabilities: Capabilities.RemoteCapability, _config: Options.Testrunner);
|
|
17
18
|
onPrepare(config?: Options.Testrunner, capabilities?: Capabilities.RemoteCapabilities): Promise<unknown>;
|
|
18
19
|
onComplete(): Promise<unknown>;
|
|
@@ -22,6 +23,9 @@ export default class BrowserstackLauncherService implements Services.ServiceInst
|
|
|
22
23
|
* <object>: only "path" and "custom_id" should coexist as multiple properties.
|
|
23
24
|
*/
|
|
24
25
|
_validateApp(appConfig: AppConfig | string): Promise<App>;
|
|
26
|
+
_updateObjectTypeCaps(capabilities?: Capabilities.RemoteCapabilities, capType?: string, value?: {
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
}): void;
|
|
25
29
|
_updateCaps(capabilities?: Capabilities.RemoteCapabilities, capType?: string, value?: string): void;
|
|
26
30
|
_handleBuildIdentifier(capabilities?: Capabilities.RemoteCapabilities): void;
|
|
27
31
|
/**
|
package/build/launcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAGlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,yBAAyB,MAAM,oBAAoB,CAAA;AAG/D,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAGlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAkBvF,KAAK,iBAAiB,GAAG,yBAAyB,CAAC,KAAK,GAAG;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7C,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,2BAA4B,YAAW,QAAQ,CAAC,eAAe;IAS5E,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,OAAO;IAVnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAQ;IACjC,OAAO,CAAC,wBAAwB,CAAC,CAAS;gBAG9B,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,EACzD,YAAY,EAAE,YAAY,CAAC,gBAAgB,EACnC,OAAO,EAAE,OAAO,CAAC,UAAU;IAwGjC,SAAS,CAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IA8ItF,UAAU;IA4DV,UAAU,CAAC,GAAG,EAAC,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsBrD;;;OAGG;IACG,YAAY,CAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBhE,qBAAqB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KAAE;IAiFvH,WAAW,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IA4F5F,sBAAsB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,kBAAkB;IAyCrE;;;OAGG;IACH,oBAAoB;IA6BpB,sBAAsB,CAAC,QAAQ,CAAC,EAAC,MAAM,EAAE,SAAS,CAAC,EAAC,MAAM,EAAE,eAAe,CAAC,EAAC,MAAM;CAQtF"}
|
package/build/launcher.js
CHANGED
|
@@ -9,8 +9,8 @@ import os from 'node:os';
|
|
|
9
9
|
import * as BrowserstackLocalLauncher from 'browserstack-local';
|
|
10
10
|
import logger from '@wdio/logger';
|
|
11
11
|
import PerformanceTester from './performance-tester.js';
|
|
12
|
-
import { BSTACK_SERVICE_VERSION, VALID_APP_EXTENSION } from './constants.js';
|
|
13
|
-
import { launchTestSession, shouldAddServiceVersion, stopBuildUpstream, getCiInfo, isBStackSession, } from './util.js';
|
|
12
|
+
import { BSTACK_SERVICE_VERSION, NOT_ALLOWED_KEYS_IN_CAPS, VALID_APP_EXTENSION } from './constants.js';
|
|
13
|
+
import { launchTestSession, createAccessibilityTestRun, shouldAddServiceVersion, stopBuildUpstream, getCiInfo, isBStackSession, isUndefined, isAccessibilityAutomationSession, stopAccessibilityTestRun, isTrue } from './util.js';
|
|
14
14
|
import CrashReporter from './crash-reporter.js';
|
|
15
15
|
const log = logger('@wdio/browserstack-service');
|
|
16
16
|
export default class BrowserstackLauncherService {
|
|
@@ -21,6 +21,7 @@ export default class BrowserstackLauncherService {
|
|
|
21
21
|
_projectName;
|
|
22
22
|
_buildTag;
|
|
23
23
|
_buildIdentifier;
|
|
24
|
+
_accessibilityAutomation;
|
|
24
25
|
constructor(_options, capabilities, _config) {
|
|
25
26
|
this._options = _options;
|
|
26
27
|
this._config = _config;
|
|
@@ -41,6 +42,12 @@ export default class BrowserstackLauncherService {
|
|
|
41
42
|
const extensionCaps = Object.keys(capability).filter((cap) => cap.includes(':'));
|
|
42
43
|
if (extensionCaps.length) {
|
|
43
44
|
capability['bstack:options'] = { wdioService: BSTACK_SERVICE_VERSION };
|
|
45
|
+
if (!isUndefined(capability['browserstack.accessibility'])) {
|
|
46
|
+
this._accessibilityAutomation ||= isTrue(capability['browserstack.accessibility']);
|
|
47
|
+
}
|
|
48
|
+
else if (isTrue(this._options.accessibility)) {
|
|
49
|
+
capability['bstack:options'].accessibility = true;
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
else if (shouldAddServiceVersion(this._config, this._options.testObservability)) {
|
|
46
53
|
capability['browserstack.wdioService'] = BSTACK_SERVICE_VERSION;
|
|
@@ -56,6 +63,12 @@ export default class BrowserstackLauncherService {
|
|
|
56
63
|
this._projectName = capability['bstack:options'].projectName;
|
|
57
64
|
this._buildTag = capability['bstack:options'].buildTag;
|
|
58
65
|
this._buildIdentifier = capability['bstack:options'].buildIdentifier;
|
|
66
|
+
if (!isUndefined(capability['bstack:options'].accessibility)) {
|
|
67
|
+
this._accessibilityAutomation ||= isTrue(capability['bstack:options'].accessibility);
|
|
68
|
+
}
|
|
69
|
+
else if (isTrue(this._options.accessibility)) {
|
|
70
|
+
capability['bstack:options'].accessibility = (isTrue(this._options.accessibility));
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
73
|
});
|
|
61
74
|
}
|
|
@@ -66,6 +79,12 @@ export default class BrowserstackLauncherService {
|
|
|
66
79
|
const extensionCaps = Object.keys(caps.capabilities).filter((cap) => cap.includes(':'));
|
|
67
80
|
if (extensionCaps.length) {
|
|
68
81
|
caps.capabilities['bstack:options'] = { wdioService: BSTACK_SERVICE_VERSION };
|
|
82
|
+
if (!isUndefined(caps.capabilities['browserstack.accessibility'])) {
|
|
83
|
+
this._accessibilityAutomation ||= isTrue(caps.capabilities['browserstack.accessibility']);
|
|
84
|
+
}
|
|
85
|
+
else if (isTrue(this._options.accessibility)) {
|
|
86
|
+
caps.capabilities['bstack:options'] = { wdioService: BSTACK_SERVICE_VERSION, accessibility: (isTrue(this._options.accessibility)) };
|
|
87
|
+
}
|
|
69
88
|
}
|
|
70
89
|
else if (shouldAddServiceVersion(this._config, this._options.testObservability)) {
|
|
71
90
|
caps.capabilities['browserstack.wdioService'] = BSTACK_SERVICE_VERSION;
|
|
@@ -80,12 +99,20 @@ export default class BrowserstackLauncherService {
|
|
|
80
99
|
this._projectName = bstackOptions.projectName;
|
|
81
100
|
this._buildTag = bstackOptions.buildTag;
|
|
82
101
|
this._buildIdentifier = bstackOptions.buildIdentifier;
|
|
102
|
+
if (!isUndefined(bstackOptions.accessibility)) {
|
|
103
|
+
this._accessibilityAutomation ||= isTrue(bstackOptions.accessibility);
|
|
104
|
+
}
|
|
105
|
+
else if (isTrue(this._options.accessibility)) {
|
|
106
|
+
bstackOptions.accessibility = isTrue(this._options.accessibility);
|
|
107
|
+
}
|
|
83
108
|
}
|
|
84
109
|
});
|
|
85
110
|
}
|
|
86
111
|
if (process.env.BROWSERSTACK_O11Y_PERF_MEASUREMENT) {
|
|
87
112
|
PerformanceTester.startMonitoring('performance-report-launcher.csv');
|
|
88
113
|
}
|
|
114
|
+
this._accessibilityAutomation ||= isTrue(this._options.accessibility);
|
|
115
|
+
this._options.accessibility = this._accessibilityAutomation;
|
|
89
116
|
// by default observability will be true unless specified as false
|
|
90
117
|
this._options.testObservability = this._options.testObservability === false ? false : true;
|
|
91
118
|
if (this._options.testObservability
|
|
@@ -146,6 +173,38 @@ export default class BrowserstackLauncherService {
|
|
|
146
173
|
* e.g., ${BUILD_NUMBER} and ${DATE_TIME}
|
|
147
174
|
*/
|
|
148
175
|
this._handleBuildIdentifier(capabilities);
|
|
176
|
+
// remove accessibilityOptions from the capabilities if present
|
|
177
|
+
this._updateObjectTypeCaps(capabilities, 'accessibilityOptions');
|
|
178
|
+
if (this._accessibilityAutomation) {
|
|
179
|
+
const scannerVersion = await createAccessibilityTestRun(this._options, this._config, {
|
|
180
|
+
projectName: this._projectName,
|
|
181
|
+
buildName: this._buildName,
|
|
182
|
+
buildTag: this._buildTag,
|
|
183
|
+
bstackServiceVersion: BSTACK_SERVICE_VERSION,
|
|
184
|
+
buildIdentifier: this._buildIdentifier,
|
|
185
|
+
accessibilityOptions: this._options.accessibilityOptions
|
|
186
|
+
});
|
|
187
|
+
if (scannerVersion) {
|
|
188
|
+
process.env.BSTACK_A11Y_SCANNER_VERSION = scannerVersion;
|
|
189
|
+
}
|
|
190
|
+
log.debug(`Accessibility scannerVersion ${scannerVersion}`);
|
|
191
|
+
}
|
|
192
|
+
if (this._options.accessibilityOptions) {
|
|
193
|
+
const filteredOpts = Object.keys(this._options.accessibilityOptions)
|
|
194
|
+
.filter(key => !NOT_ALLOWED_KEYS_IN_CAPS.includes(key))
|
|
195
|
+
.reduce((opts, key) => {
|
|
196
|
+
return {
|
|
197
|
+
...opts,
|
|
198
|
+
[key]: this._options.accessibilityOptions?.[key]
|
|
199
|
+
};
|
|
200
|
+
}, {});
|
|
201
|
+
if (Object.keys(filteredOpts).length > 0) {
|
|
202
|
+
this._updateObjectTypeCaps(capabilities, 'accessibilityOptions', filteredOpts);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else if (isAccessibilityAutomationSession(this._accessibilityAutomation)) {
|
|
206
|
+
this._updateObjectTypeCaps(capabilities, 'accessibilityOptions', {});
|
|
207
|
+
}
|
|
149
208
|
if (this._options.testObservability) {
|
|
150
209
|
log.debug('Sending launch start event');
|
|
151
210
|
await launchTestSession(this._options, this._config, {
|
|
@@ -197,6 +256,11 @@ export default class BrowserstackLauncherService {
|
|
|
197
256
|
});
|
|
198
257
|
}
|
|
199
258
|
async onComplete() {
|
|
259
|
+
if (isAccessibilityAutomationSession(this._accessibilityAutomation)) {
|
|
260
|
+
await stopAccessibilityTestRun().catch((error) => {
|
|
261
|
+
log.error(`Exception in stop accessibility test run: ${error}`);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
200
264
|
if (this._options.testObservability) {
|
|
201
265
|
log.debug('Sending stop launch event');
|
|
202
266
|
await stopBuildUpstream();
|
|
@@ -285,6 +349,96 @@ export default class BrowserstackLauncherService {
|
|
|
285
349
|
}
|
|
286
350
|
return app;
|
|
287
351
|
}
|
|
352
|
+
_updateObjectTypeCaps(capabilities, capType, value) {
|
|
353
|
+
try {
|
|
354
|
+
if (Array.isArray(capabilities)) {
|
|
355
|
+
capabilities
|
|
356
|
+
.flatMap((c) => {
|
|
357
|
+
if (Object.values(c).length > 0 && Object.values(c).every(c => typeof c === 'object' && c.capabilities)) {
|
|
358
|
+
return Object.values(c).map((o) => o.capabilities);
|
|
359
|
+
}
|
|
360
|
+
return c;
|
|
361
|
+
})
|
|
362
|
+
.forEach((capability) => {
|
|
363
|
+
if (!capability['bstack:options']) {
|
|
364
|
+
const extensionCaps = Object.keys(capability).filter((cap) => cap.includes(':'));
|
|
365
|
+
if (extensionCaps.length) {
|
|
366
|
+
if (capType === 'accessibilityOptions' && value) {
|
|
367
|
+
capability['bstack:options'] = { accessibilityOptions: value };
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else if (capType === 'accessibilityOptions') {
|
|
371
|
+
if (value) {
|
|
372
|
+
const accessibilityOpts = { ...value };
|
|
373
|
+
if (capability?.accessibility) {
|
|
374
|
+
accessibilityOpts.authToken = process.env.BSTACK_A11Y_JWT;
|
|
375
|
+
accessibilityOpts.scannerVersion = process.env.BSTACK_A11Y_SCANNER_VERSION;
|
|
376
|
+
}
|
|
377
|
+
capability['browserstack.accessibilityOptions'] = accessibilityOpts;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
delete capability['browserstack.accessibilityOptions'];
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else if (capType === 'accessibilityOptions') {
|
|
385
|
+
if (value) {
|
|
386
|
+
const accessibilityOpts = { ...value };
|
|
387
|
+
if (capability['bstack:options'].accessibility) {
|
|
388
|
+
accessibilityOpts.authToken = process.env.BSTACK_A11Y_JWT;
|
|
389
|
+
accessibilityOpts.scannerVersion = process.env.BSTACK_A11Y_SCANNER_VERSION;
|
|
390
|
+
}
|
|
391
|
+
capability['bstack:options'].accessibilityOptions = accessibilityOpts;
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
delete capability['bstack:options'].accessibilityOptions;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
else if (typeof capabilities === 'object') {
|
|
400
|
+
Object.entries(capabilities).forEach(([, caps]) => {
|
|
401
|
+
if (!caps.capabilities['bstack:options']) {
|
|
402
|
+
const extensionCaps = Object.keys(caps.capabilities).filter((cap) => cap.includes(':'));
|
|
403
|
+
if (extensionCaps.length) {
|
|
404
|
+
if (capType === 'accessibilityOptions' && value) {
|
|
405
|
+
caps.capabilities['bstack:options'] = { accessibilityOptions: value };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
else if (capType === 'accessibilityOptions') {
|
|
409
|
+
if (value) {
|
|
410
|
+
const accessibilityOpts = { ...value };
|
|
411
|
+
if (caps.capabilities['browserstack.accessibility']) {
|
|
412
|
+
accessibilityOpts.authToken = process.env.BSTACK_A11Y_JWT;
|
|
413
|
+
accessibilityOpts.scannerVersion = process.env.BSTACK_A11Y_SCANNER_VERSION;
|
|
414
|
+
}
|
|
415
|
+
caps.capabilities['browserstack.accessibilityOptions'] = accessibilityOpts;
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
delete caps.capabilities['browserstack.accessibilityOptions'];
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
else if (capType === 'accessibilityOptions') {
|
|
423
|
+
if (value) {
|
|
424
|
+
const accessibilityOpts = { ...value };
|
|
425
|
+
if (caps.capabilities['bstack:options'].accessibility) {
|
|
426
|
+
accessibilityOpts.authToken = process.env.BSTACK_A11Y_JWT;
|
|
427
|
+
accessibilityOpts.scannerVersion = process.env.BSTACK_A11Y_SCANNER_VERSION;
|
|
428
|
+
}
|
|
429
|
+
caps.capabilities['bstack:options'].accessibilityOptions = accessibilityOpts;
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
delete caps.capabilities['bstack:options'].accessibilityOptions;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
log.debug(`Exception while retrieving capability value. Error - ${error}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
288
442
|
_updateCaps(capabilities, capType, value) {
|
|
289
443
|
if (Array.isArray(capabilities)) {
|
|
290
444
|
capabilities
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function testStartEvent(): void;
|
|
2
|
+
export declare function testForceStop(): void;
|
|
3
|
+
export declare function testStop(this: any): void;
|
|
4
|
+
export declare function accessibilityResults(): Promise<Array<{
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}>>;
|
|
7
|
+
export declare function accessibilityResultsSummary(): Promise<{
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=test-event-scripts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-event-scripts.d.ts","sourceRoot":"","sources":["../../src/scripts/test-event-scripts.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,SAY7B;AAED,wBAAgB,aAAa,SAG5B;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,GAAG,QAgBjC;AAED,wBAAgB,oBAAoB,IAAK,OAAO,CAAC,KAAK,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CAAE,CAAC,CAAC,CAc/E;AAED,wBAAgB,2BAA2B,IAAK,OAAO,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CAAE,CAAC,CAc/E"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export function testStartEvent() {
|
|
2
|
+
const callback = arguments[arguments.length - 1];
|
|
3
|
+
const fn = () => {
|
|
4
|
+
window.addEventListener('A11Y_TAP_STARTED', fn2);
|
|
5
|
+
const e = new CustomEvent('A11Y_FORCE_START');
|
|
6
|
+
window.dispatchEvent(e);
|
|
7
|
+
};
|
|
8
|
+
const fn2 = () => {
|
|
9
|
+
window.removeEventListener('A11Y_TAP_STARTED', fn);
|
|
10
|
+
callback();
|
|
11
|
+
};
|
|
12
|
+
fn();
|
|
13
|
+
}
|
|
14
|
+
export function testForceStop() {
|
|
15
|
+
const e = new CustomEvent('A11Y_FORCE_STOP');
|
|
16
|
+
window.dispatchEvent(e);
|
|
17
|
+
}
|
|
18
|
+
export function testStop() {
|
|
19
|
+
const callback = arguments[arguments.length - 1];
|
|
20
|
+
this.res = null;
|
|
21
|
+
if (arguments[0].saveResults) {
|
|
22
|
+
window.addEventListener('A11Y_TAP_TRANSPORTER', (event) => {
|
|
23
|
+
window.tapTransporterData = event.detail;
|
|
24
|
+
this.res = window.tapTransporterData;
|
|
25
|
+
callback(this.res);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const e = new CustomEvent('A11Y_TEST_END', { detail: arguments[0] });
|
|
29
|
+
window.dispatchEvent(e);
|
|
30
|
+
if (arguments[0].saveResults !== true) {
|
|
31
|
+
callback();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function accessibilityResults() {
|
|
35
|
+
return new Promise(function (resolve, reject) {
|
|
36
|
+
try {
|
|
37
|
+
const event = new CustomEvent('A11Y_TAP_GET_RESULTS');
|
|
38
|
+
const fn = function (event) {
|
|
39
|
+
window.removeEventListener('A11Y_RESULTS_RESPONSE', fn);
|
|
40
|
+
resolve(event.detail.data);
|
|
41
|
+
};
|
|
42
|
+
window.addEventListener('A11Y_RESULTS_RESPONSE', fn);
|
|
43
|
+
window.dispatchEvent(event);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
reject();
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export function accessibilityResultsSummary() {
|
|
51
|
+
return new Promise(function (resolve, reject) {
|
|
52
|
+
try {
|
|
53
|
+
const event = new CustomEvent('A11Y_TAP_GET_RESULTS_SUMMARY');
|
|
54
|
+
const fn = function (event) {
|
|
55
|
+
window.removeEventListener('A11Y_RESULTS_SUMMARY_RESPONSE', fn);
|
|
56
|
+
resolve(event.detail.summary);
|
|
57
|
+
};
|
|
58
|
+
window.addEventListener('A11Y_RESULTS_SUMMARY_RESPONSE', fn);
|
|
59
|
+
window.dispatchEvent(event);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
reject();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
package/build/service.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export default class BrowserstackService implements Services.ServiceInstance {
|
|
|
17
17
|
private _observability;
|
|
18
18
|
private _currentTest?;
|
|
19
19
|
private _insightsHandler?;
|
|
20
|
+
private _accessibility;
|
|
21
|
+
private _accessibilityHandler?;
|
|
20
22
|
constructor(options: BrowserstackConfig & Options.Testrunner, _caps: Capabilities.RemoteCapability, _config: Options.Testrunner);
|
|
21
23
|
_updateCaps(fn: (caps: Capabilities.Capabilities | Capabilities.DesiredCapabilities) => void): void;
|
|
22
24
|
beforeSession(config: Omit<Options.Testrunner, 'capabilities'>): void;
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAW9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAmB,MAAM,YAAY,CAAA;AACxF,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/build/service.js
CHANGED
|
@@ -6,6 +6,7 @@ import InsightsHandler from './insights-handler.js';
|
|
|
6
6
|
import TestReporter from './reporter.js';
|
|
7
7
|
import { DEFAULT_OPTIONS } from './constants.js';
|
|
8
8
|
import CrashReporter from './crash-reporter.js';
|
|
9
|
+
import AccessibilityHandler from './accessibility-handler.js';
|
|
9
10
|
const log = logger('@wdio/browserstack-service');
|
|
10
11
|
export default class BrowserstackService {
|
|
11
12
|
_caps;
|
|
@@ -23,6 +24,8 @@ export default class BrowserstackService {
|
|
|
23
24
|
_observability;
|
|
24
25
|
_currentTest;
|
|
25
26
|
_insightsHandler;
|
|
27
|
+
_accessibility;
|
|
28
|
+
_accessibilityHandler;
|
|
26
29
|
constructor(options, _caps, _config) {
|
|
27
30
|
this._caps = _caps;
|
|
28
31
|
this._config = _config;
|
|
@@ -30,6 +33,7 @@ export default class BrowserstackService {
|
|
|
30
33
|
// added to maintain backward compatibility with webdriverIO v5
|
|
31
34
|
this._config || (this._config = this._options);
|
|
32
35
|
this._observability = this._options.testObservability;
|
|
36
|
+
this._accessibility = this._options.accessibility;
|
|
33
37
|
if (this._observability) {
|
|
34
38
|
this._config.reporters?.push(TestReporter);
|
|
35
39
|
if (process.env.BROWSERSTACK_O11Y_PERF_MEASUREMENT) {
|
|
@@ -91,6 +95,15 @@ export default class BrowserstackService {
|
|
|
91
95
|
CrashReporter.uploadCrashReport(`Error in service class before function: ${err}`, err && err.stack);
|
|
92
96
|
}
|
|
93
97
|
}
|
|
98
|
+
if (this._browser && isBrowserstackSession(this._browser)) {
|
|
99
|
+
try {
|
|
100
|
+
this._accessibilityHandler = new AccessibilityHandler(this._browser, this._caps, this._isAppAutomate(), this._config.framework, this._accessibility, this._options.accessibilityOptions);
|
|
101
|
+
await this._accessibilityHandler.before();
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
log.error(`[Accessibility Test Run] Error in service class before function: ${err}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
94
107
|
return await this._printSessionURL();
|
|
95
108
|
}
|
|
96
109
|
/**
|
|
@@ -103,6 +116,7 @@ export default class BrowserstackService {
|
|
|
103
116
|
async beforeSuite(suite) {
|
|
104
117
|
this._suiteTitle = suite.title;
|
|
105
118
|
this._insightsHandler?.setSuiteFile(suite.file);
|
|
119
|
+
this._accessibilityHandler?.setSuiteFile(suite.file);
|
|
106
120
|
if (suite.title && suite.title !== 'Jasmine__TopLevel__Suite') {
|
|
107
121
|
await this._setSessionName(suite.title);
|
|
108
122
|
}
|
|
@@ -133,6 +147,7 @@ export default class BrowserstackService {
|
|
|
133
147
|
await this._setSessionName(suiteTitle, test);
|
|
134
148
|
await this._setAnnotation(`Test: ${test.fullName ?? test.title}`);
|
|
135
149
|
await this._insightsHandler?.beforeTest(test);
|
|
150
|
+
await this._accessibilityHandler?.beforeTest(suiteTitle, test);
|
|
136
151
|
}
|
|
137
152
|
async afterTest(test, context, results) {
|
|
138
153
|
this._specsRan = true;
|
|
@@ -141,6 +156,7 @@ export default class BrowserstackService {
|
|
|
141
156
|
this._failReasons.push((error && error.message) || 'Unknown Error');
|
|
142
157
|
}
|
|
143
158
|
await this._insightsHandler?.afterTest(test, results);
|
|
159
|
+
await this._accessibilityHandler?.afterTest(this._suiteTitle, test);
|
|
144
160
|
}
|
|
145
161
|
async after(result) {
|
|
146
162
|
const { preferScenarioName, setSessionName, setSessionStatus } = this._options;
|
|
@@ -185,6 +201,7 @@ export default class BrowserstackService {
|
|
|
185
201
|
async beforeScenario(world) {
|
|
186
202
|
this._currentTest = world;
|
|
187
203
|
await this._insightsHandler?.beforeScenario(world);
|
|
204
|
+
await this._accessibilityHandler?.beforeScenario(world);
|
|
188
205
|
const scenarioName = world.pickle.name || 'unknown scenario';
|
|
189
206
|
await this._setAnnotation(`Scenario: ${scenarioName}`);
|
|
190
207
|
}
|
|
@@ -202,6 +219,7 @@ export default class BrowserstackService {
|
|
|
202
219
|
this._failReasons.push(exception);
|
|
203
220
|
}
|
|
204
221
|
await this._insightsHandler?.afterScenario(world);
|
|
222
|
+
await this._accessibilityHandler?.afterScenario(world);
|
|
205
223
|
}
|
|
206
224
|
async beforeStep(step, scenario) {
|
|
207
225
|
await this._insightsHandler?.beforeStep(step, scenario);
|
package/build/types.d.ts
CHANGED
|
@@ -48,6 +48,20 @@ export interface BrowserstackConfig {
|
|
|
48
48
|
* For e.g. buildName, projectName, BrowserStack access credentials, etc.
|
|
49
49
|
*/
|
|
50
50
|
testObservabilityOptions?: TestObservabilityOptions;
|
|
51
|
+
/**
|
|
52
|
+
* Set this to true to enable BrowserStack Accessibility Automation which will
|
|
53
|
+
* automically conduct accessibility testing on your pre-existing test builds
|
|
54
|
+
* and generate health reports which can be viewed in the Accessibility dashboard.
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
|
+
accessibility?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Customise the Accessibility-related config options under this key.
|
|
60
|
+
* For e.g. wcagVersion, bestPractice issues, needsReview issues etc.
|
|
61
|
+
*/
|
|
62
|
+
accessibilityOptions?: {
|
|
63
|
+
[key: string]: any;
|
|
64
|
+
};
|
|
51
65
|
/**
|
|
52
66
|
* Set this with app file path present locally on your device or
|
|
53
67
|
* app hashed id returned after uploading app to BrowserStack or
|
|
@@ -185,6 +199,9 @@ export interface UserConfig {
|
|
|
185
199
|
buildTag?: string;
|
|
186
200
|
bstackServiceVersion?: string;
|
|
187
201
|
buildIdentifier?: string;
|
|
202
|
+
accessibilityOptions?: {
|
|
203
|
+
[key: string]: any;
|
|
204
|
+
};
|
|
188
205
|
}
|
|
189
206
|
export interface UploadType {
|
|
190
207
|
event_type: string;
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/util.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import http from 'node:http';
|
|
|
4
4
|
import https from 'node:https';
|
|
5
5
|
import type { Capabilities, Frameworks, Options } from '@wdio/types';
|
|
6
6
|
import type { BeforeCommandArgs, AfterCommandArgs } from '@wdio/reporter';
|
|
7
|
+
import type { Method } from 'got';
|
|
7
8
|
import type { UploadType, BrowserstackConfig } from './types.js';
|
|
8
9
|
import type { ITestCaseHookParameter } from './cucumber-types.js';
|
|
9
10
|
import RequestQueueHandler from './request-handler.js';
|
|
@@ -36,11 +37,28 @@ export declare function getBrowserCapabilities(browser: WebdriverIO.Browser | We
|
|
|
36
37
|
export declare function isBrowserstackCapability(cap?: Capabilities.Capabilities): boolean;
|
|
37
38
|
export declare function getParentSuiteName(fullTitle: string, testSuiteTitle: string): string;
|
|
38
39
|
export declare function o11yErrorHandler(fn: Function): (...args: any) => any;
|
|
40
|
+
export declare function errorHandler(fn: Function): (...args: any) => any;
|
|
41
|
+
export declare function nodeRequest(requestType: Method, apiEndpoint: string, options: any, apiUrl: string, timeout?: number): Promise<Object>;
|
|
39
42
|
type ClassType = {
|
|
40
43
|
new (...args: any[]): any;
|
|
41
44
|
};
|
|
42
45
|
export declare function o11yClassErrorHandler<T extends ClassType>(errorClass: T): T;
|
|
43
46
|
export declare const launchTestSession: (...args: any) => any;
|
|
47
|
+
export declare const validateCapsWithA11y: (deviceName?: any, platformMeta?: {
|
|
48
|
+
[key: string]: any;
|
|
49
|
+
} | undefined, chromeOptions?: any) => boolean;
|
|
50
|
+
export declare const shouldScanTestForAccessibility: (suiteTitle: string | undefined, testTitle: string, accessibilityOptions?: {
|
|
51
|
+
[key: string]: any;
|
|
52
|
+
} | undefined) => boolean | undefined;
|
|
53
|
+
export declare const isAccessibilityAutomationSession: (accessibilityFlag?: boolean | string) => boolean | "" | undefined;
|
|
54
|
+
export declare const createAccessibilityTestRun: (...args: any) => any;
|
|
55
|
+
export declare const getA11yResults: (browser: WebdriverIO.Browser, isBrowserStackSession?: boolean, isAccessibility?: boolean | string) => Promise<{
|
|
56
|
+
[key: string]: any;
|
|
57
|
+
}[]>;
|
|
58
|
+
export declare const getA11yResultsSummary: (browser: WebdriverIO.Browser, isBrowserStackSession?: boolean, isAccessibility?: boolean | string) => Promise<{
|
|
59
|
+
[key: string]: any;
|
|
60
|
+
}>;
|
|
61
|
+
export declare const stopAccessibilityTestRun: (...args: any) => any;
|
|
44
62
|
export declare const stopBuildUpstream: (...args: any) => any;
|
|
45
63
|
export declare function getCiInfo(): {
|
|
46
64
|
name: string;
|
|
@@ -101,6 +119,10 @@ export declare function getObservabilityKey(options: BrowserstackConfig & Option
|
|
|
101
119
|
export declare function getObservabilityProject(options: BrowserstackConfig & Options.Testrunner, bstackProjectName?: string): string | undefined;
|
|
102
120
|
export declare function getObservabilityBuild(options: BrowserstackConfig & Options.Testrunner, bstackBuildName?: string): string;
|
|
103
121
|
export declare function getObservabilityBuildTags(options: BrowserstackConfig & Options.Testrunner, bstackBuildTag?: string): string[];
|
|
122
|
+
export declare function getBrowserStackUser(config: Options.Testrunner): string | undefined;
|
|
123
|
+
export declare function getBrowserStackKey(config: Options.Testrunner): string | undefined;
|
|
124
|
+
export declare function isUndefined(value: any): boolean;
|
|
125
|
+
export declare function isTrue(value?: any): boolean;
|
|
104
126
|
export declare function frameworkSupportsHook(hook: string, framework?: string): boolean;
|
|
105
127
|
export declare function patchConsoleLogs(): void;
|
|
106
128
|
export declare function getFailureObject(error: string | Error): {
|
package/build/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAEA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,MAAM,YAAY,CAAA;AAI9B,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/build/util.js
CHANGED
|
@@ -10,9 +10,10 @@ import gitRepoInfo from 'git-repo-info';
|
|
|
10
10
|
import gitconfig from 'gitconfiglocal';
|
|
11
11
|
import logPatcher from './logPatcher.js';
|
|
12
12
|
import PerformanceTester from './performance-tester.js';
|
|
13
|
-
import { BROWSER_DESCRIPTION, DATA_ENDPOINT, DATA_EVENT_ENDPOINT, DATA_SCREENSHOT_ENDPOINT, consoleHolder } from './constants.js';
|
|
13
|
+
import { ACCESSIBILITY_API_URL, BROWSER_DESCRIPTION, DATA_ENDPOINT, DATA_EVENT_ENDPOINT, DATA_SCREENSHOT_ENDPOINT, consoleHolder } from './constants.js';
|
|
14
14
|
import RequestQueueHandler from './request-handler.js';
|
|
15
15
|
import CrashReporter from './crash-reporter.js';
|
|
16
|
+
import { accessibilityResults, accessibilityResultsSummary } from './scripts/test-event-scripts.js';
|
|
16
17
|
const pGitconfig = promisify(gitconfig);
|
|
17
18
|
const log = logger('@wdio/browserstack-service');
|
|
18
19
|
export const DEFAULT_REQUEST_CONFIG = {
|
|
@@ -109,6 +110,50 @@ export function o11yErrorHandler(fn) {
|
|
|
109
110
|
}
|
|
110
111
|
};
|
|
111
112
|
}
|
|
113
|
+
export function errorHandler(fn) {
|
|
114
|
+
return function (...args) {
|
|
115
|
+
try {
|
|
116
|
+
const functionToHandle = fn;
|
|
117
|
+
const result = functionToHandle(...args);
|
|
118
|
+
if (result instanceof Promise) {
|
|
119
|
+
return result.catch(error => log.error(`Error in executing ${fn.name} with args ${args}: ${error}`));
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
log.error(`Error in executing ${fn.name} with args ${args}: ${error}`);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export async function nodeRequest(requestType, apiEndpoint, options, apiUrl, timeout = 120000) {
|
|
129
|
+
try {
|
|
130
|
+
const response = await got(`${apiUrl}/${apiEndpoint}`, {
|
|
131
|
+
method: requestType,
|
|
132
|
+
timeout: {
|
|
133
|
+
request: timeout
|
|
134
|
+
},
|
|
135
|
+
...options
|
|
136
|
+
}).json();
|
|
137
|
+
return response;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
if (error instanceof HTTPError && error.response) {
|
|
141
|
+
const errorMessageJson = error.response.body ? JSON.parse(error.response.body.toString()) : null;
|
|
142
|
+
const errorMessage = errorMessageJson ? errorMessageJson.message : null;
|
|
143
|
+
if (errorMessage) {
|
|
144
|
+
log.error(`${errorMessage} - ${error.stack}`);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
log.error(`${error.stack}`);
|
|
148
|
+
}
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
log.error(`Failed to fire api request due to ${error} - ${error.stack}`);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
112
157
|
export function o11yClassErrorHandler(errorClass) {
|
|
113
158
|
const prototype = errorClass.prototype;
|
|
114
159
|
if (Object.getOwnPropertyNames(prototype).length < 2) {
|
|
@@ -214,6 +259,201 @@ export const launchTestSession = o11yErrorHandler(async function launchTestSessi
|
|
|
214
259
|
}
|
|
215
260
|
}
|
|
216
261
|
});
|
|
262
|
+
export const validateCapsWithA11y = (deviceName, platformMeta, chromeOptions) => {
|
|
263
|
+
try {
|
|
264
|
+
if (deviceName) {
|
|
265
|
+
log.warn('Accessibility Automation will run only on Desktop browsers.');
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
if (platformMeta?.browser_name?.toLowerCase() !== 'chrome') {
|
|
269
|
+
log.warn('Accessibility Automation will run only on Chrome browsers.');
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
const browserVersion = platformMeta?.browser_version;
|
|
273
|
+
if (!isUndefined(browserVersion) && !(browserVersion === 'latest' || parseFloat(browserVersion + '') > 94)) {
|
|
274
|
+
log.warn('Accessibility Automation will run only on Chrome browser version greater than 94.');
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
if (chromeOptions?.args?.includes('--headless')) {
|
|
278
|
+
log.warn('Accessibility Automation will not run on legacy headless mode. Switch to new headless mode or avoid using headless mode.');
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
log.debug(`Exception in checking capabilities compatibility with Accessibility. Error: ${error}`);
|
|
285
|
+
}
|
|
286
|
+
return false;
|
|
287
|
+
};
|
|
288
|
+
export const shouldScanTestForAccessibility = (suiteTitle, testTitle, accessibilityOptions) => {
|
|
289
|
+
try {
|
|
290
|
+
const includeTags = Array.isArray(accessibilityOptions?.includeTagsInTestingScope) ? accessibilityOptions?.includeTagsInTestingScope : [];
|
|
291
|
+
const excludeTags = Array.isArray(accessibilityOptions?.excludeTagsInTestingScope) ? accessibilityOptions?.excludeTagsInTestingScope : [];
|
|
292
|
+
const fullTestName = suiteTitle + ' ' + testTitle;
|
|
293
|
+
const excluded = excludeTags?.some((exclude) => fullTestName.includes(exclude));
|
|
294
|
+
const included = includeTags?.length === 0 || includeTags?.some((include) => fullTestName.includes(include));
|
|
295
|
+
return !excluded && included;
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
log.debug('Error while validating test case for accessibility before scanning. Error : ', error);
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
};
|
|
302
|
+
export const isAccessibilityAutomationSession = (accessibilityFlag) => {
|
|
303
|
+
try {
|
|
304
|
+
const hasA11yJwtToken = typeof process.env.BSTACK_A11Y_JWT === 'string' && process.env.BSTACK_A11Y_JWT.length > 0 && process.env.BSTACK_A11Y_JWT !== 'null' && process.env.BSTACK_A11Y_JWT !== 'undefined';
|
|
305
|
+
return accessibilityFlag && hasA11yJwtToken;
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
log.debug(`Exception in verifying the Accessibility session with error : ${error}`);
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
};
|
|
312
|
+
export const createAccessibilityTestRun = errorHandler(async function createAccessibilityTestRun(options, config, bsConfig) {
|
|
313
|
+
const userName = getBrowserStackUser(config);
|
|
314
|
+
const accessKey = getBrowserStackKey(config);
|
|
315
|
+
if (isUndefined(userName) || isUndefined(accessKey)) {
|
|
316
|
+
log.error('Exception while creating test run for BrowserStack Accessibility Automation: Missing BrowserStack credentials');
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
const data = {
|
|
320
|
+
'projectName': bsConfig.projectName,
|
|
321
|
+
'buildName': bsConfig.buildName ||
|
|
322
|
+
path.basename(path.resolve(process.cwd())),
|
|
323
|
+
'startTime': (new Date()).toISOString(),
|
|
324
|
+
'description': '',
|
|
325
|
+
'source': {
|
|
326
|
+
frameworkName: 'WebdriverIO-' + config.framework,
|
|
327
|
+
frameworkVersion: bsConfig.bstackServiceVersion,
|
|
328
|
+
sdkVersion: bsConfig.bstackServiceVersion
|
|
329
|
+
},
|
|
330
|
+
'settings': bsConfig.accessibilityOptions || {},
|
|
331
|
+
'versionControl': await getGitMetaData(),
|
|
332
|
+
'ciInfo': getCiInfo(),
|
|
333
|
+
'hostInfo': {
|
|
334
|
+
hostname: hostname(),
|
|
335
|
+
platform: platform(),
|
|
336
|
+
type: type(),
|
|
337
|
+
version: version(),
|
|
338
|
+
arch: arch()
|
|
339
|
+
},
|
|
340
|
+
'browserstackAutomation': true,
|
|
341
|
+
};
|
|
342
|
+
const requestOptions = {
|
|
343
|
+
json: data,
|
|
344
|
+
username: getBrowserStackUser(config),
|
|
345
|
+
password: getBrowserStackKey(config),
|
|
346
|
+
};
|
|
347
|
+
try {
|
|
348
|
+
const response = await nodeRequest('POST', 'test_runs', requestOptions, ACCESSIBILITY_API_URL);
|
|
349
|
+
log.debug(`[Create Accessibility Test Run] Success response: ${JSON.stringify(response)}`);
|
|
350
|
+
if (response.data.accessibilityToken) {
|
|
351
|
+
process.env.BSTACK_A11Y_JWT = response.data.accessibilityToken;
|
|
352
|
+
}
|
|
353
|
+
if (response.data.id) {
|
|
354
|
+
process.env.BS_A11Y_TEST_RUN_ID = response.data.id;
|
|
355
|
+
}
|
|
356
|
+
log.debug(`BrowserStack Accessibility Automation Test Run ID: ${response.data.id}`);
|
|
357
|
+
return response.data.scannerVersion;
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
if (error.response) {
|
|
361
|
+
log.error(`Exception while creating test run for BrowserStack Accessibility Automation: ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`);
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
const errorMessage = error.message;
|
|
365
|
+
if (errorMessage === 'Invalid configuration passed.') {
|
|
366
|
+
log.error(`Exception while creating test run for BrowserStack Accessibility Automation: ${errorMessage || error.stack}`);
|
|
367
|
+
for (const errorkey of error.errors) {
|
|
368
|
+
log.error(errorkey.message);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
log.error(`Exception while creating test run for BrowserStack Accessibility Automation: ${errorMessage || error.stack}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
export const getA11yResults = async (browser, isBrowserStackSession, isAccessibility) => {
|
|
379
|
+
if (!isBrowserStackSession) {
|
|
380
|
+
log.warn('Not a BrowserStack Automate session, cannot retrieve Accessibility results.');
|
|
381
|
+
return []; // since we are running only on Automate as of now
|
|
382
|
+
}
|
|
383
|
+
if (!isAccessibilityAutomationSession(isAccessibility)) {
|
|
384
|
+
log.warn('Not an Accessibility Automation session, cannot retrieve Accessibility results.');
|
|
385
|
+
return [];
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
const results = await browser.execute(accessibilityResults);
|
|
389
|
+
return results;
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
log.error('No accessibility results were found.');
|
|
393
|
+
return [];
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
export const getA11yResultsSummary = async (browser, isBrowserStackSession, isAccessibility) => {
|
|
397
|
+
if (!isBrowserStackSession) {
|
|
398
|
+
return {}; // since we are running only on Automate as of now
|
|
399
|
+
}
|
|
400
|
+
if (!isAccessibilityAutomationSession(isAccessibility)) {
|
|
401
|
+
log.warn('Not an Accessibility Automation session, cannot retrieve Accessibility results summary.');
|
|
402
|
+
return {};
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
const summaryResults = await browser.execute(accessibilityResultsSummary);
|
|
406
|
+
return summaryResults;
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
log.error('No accessibility summary was found.');
|
|
410
|
+
return {};
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
export const stopAccessibilityTestRun = errorHandler(async function stopAccessibilityTestRun() {
|
|
414
|
+
const hasA11yJwtToken = typeof process.env.BSTACK_A11Y_JWT === 'string' && process.env.BSTACK_A11Y_JWT.length > 0 && process.env.BSTACK_A11Y_JWT !== 'null' && process.env.BSTACK_A11Y_JWT !== 'undefined';
|
|
415
|
+
if (!hasA11yJwtToken) {
|
|
416
|
+
return {
|
|
417
|
+
status: 'error',
|
|
418
|
+
message: 'Build creation had failed.'
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
const data = {
|
|
422
|
+
'endTime': (new Date()).toISOString(),
|
|
423
|
+
};
|
|
424
|
+
const requestOptions = { ...{
|
|
425
|
+
json: data,
|
|
426
|
+
headers: {
|
|
427
|
+
'Authorization': `Bearer ${process.env.BSTACK_A11Y_JWT}`,
|
|
428
|
+
}
|
|
429
|
+
} };
|
|
430
|
+
try {
|
|
431
|
+
const response = await nodeRequest('PUT', 'test_runs/stop', requestOptions, ACCESSIBILITY_API_URL);
|
|
432
|
+
if (response.data && response.data.error) {
|
|
433
|
+
throw new Error('Invalid request: ' + response.data.error);
|
|
434
|
+
}
|
|
435
|
+
else if (response.error) {
|
|
436
|
+
throw new Error('Invalid request: ' + response.error);
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
log.info(`BrowserStack Accessibility Automation Test Run marked as completed at ${new Date().toISOString()}`);
|
|
440
|
+
return { status: 'success', message: '' };
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
catch (error) {
|
|
444
|
+
if (error.response && error.response.status && error.response.statusText && error.response.data) {
|
|
445
|
+
log.error(`Exception while marking completion of BrowserStack Accessibility Automation Test Run: ${error.response.status} ${error.response.statusText} ${JSON.stringify(error.response.data)}`);
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
log.error(`Exception while marking completion of BrowserStack Accessibility Automation Test Run: ${error.message || util.format(error)}`);
|
|
449
|
+
}
|
|
450
|
+
return {
|
|
451
|
+
status: 'error',
|
|
452
|
+
message: error.message ||
|
|
453
|
+
(error.response ? `${error.response.status}:${error.response.statusText}` : error)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
});
|
|
217
457
|
export const stopBuildUpstream = o11yErrorHandler(async function stopBuildUpstream() {
|
|
218
458
|
if (!process.env.BS_TESTOPS_BUILD_COMPLETED) {
|
|
219
459
|
return;
|
|
@@ -593,6 +833,24 @@ export function getObservabilityBuildTags(options, bstackBuildTag) {
|
|
|
593
833
|
}
|
|
594
834
|
return [];
|
|
595
835
|
}
|
|
836
|
+
export function getBrowserStackUser(config) {
|
|
837
|
+
if (process.env.BROWSERSTACK_USERNAME) {
|
|
838
|
+
return process.env.BROWSERSTACK_USERNAME;
|
|
839
|
+
}
|
|
840
|
+
return config.user;
|
|
841
|
+
}
|
|
842
|
+
export function getBrowserStackKey(config) {
|
|
843
|
+
if (process.env.BROWSERSTACK_ACCESS_KEY) {
|
|
844
|
+
return process.env.BROWSERSTACK_ACCESS_KEY;
|
|
845
|
+
}
|
|
846
|
+
return config.key;
|
|
847
|
+
}
|
|
848
|
+
export function isUndefined(value) {
|
|
849
|
+
return value === undefined || value === null;
|
|
850
|
+
}
|
|
851
|
+
export function isTrue(value) {
|
|
852
|
+
return (value + '') === 'true';
|
|
853
|
+
}
|
|
596
854
|
export function frameworkSupportsHook(hook, framework) {
|
|
597
855
|
if (framework === 'mocha' && (hook === 'before' || hook === 'after' || hook === 'beforeEach' || hook === 'afterEach')) {
|
|
598
856
|
return true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browserstack-service",
|
|
3
|
-
"version": "8.16.
|
|
3
|
+
"version": "8.16.7",
|
|
4
4
|
"description": "WebdriverIO service for better Browserstack integration",
|
|
5
5
|
"author": "Adam Bjerstedt <abjerstedt@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browserstack-service",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@types/gitconfiglocal": "^2.0.1",
|
|
34
34
|
"@wdio/logger": "8.11.0",
|
|
35
|
-
"@wdio/reporter": "8.16.
|
|
36
|
-
"@wdio/types": "8.16.
|
|
35
|
+
"@wdio/reporter": "8.16.7",
|
|
36
|
+
"@wdio/types": "8.16.7",
|
|
37
37
|
"browserstack-local": "^1.5.1",
|
|
38
38
|
"csv-writer": "^1.6.0",
|
|
39
39
|
"form-data": "^4.0.0",
|
|
@@ -41,17 +41,18 @@
|
|
|
41
41
|
"gitconfiglocal": "^2.1.0",
|
|
42
42
|
"got": "^ 12.6.1",
|
|
43
43
|
"uuid": "^9.0.0",
|
|
44
|
-
"webdriverio": "8.16.
|
|
44
|
+
"webdriverio": "8.16.7",
|
|
45
45
|
"winston-transport": "^4.5.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@types/node": "^20.1.0"
|
|
51
|
+
"@types/node": "^20.1.0",
|
|
52
|
+
"@wdio/globals": "8.16.7"
|
|
52
53
|
},
|
|
53
54
|
"publishConfig": {
|
|
54
55
|
"access": "public"
|
|
55
56
|
},
|
|
56
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "15f7f225e6a81ea0e5e7a9ba8067ca59007f09c2"
|
|
57
58
|
}
|