From 699cf8fad6c9c5df8c6438a17f23e97b4d4e7521 Mon Sep 17 00:00:00 2001 From: AdityaHirapara Date: Tue, 16 Apr 2024 16:25:38 +0530 Subject: [PATCH 1/5] Implement API changes for a11y stability --- src/accessibilityAutomation.js | 56 +++++++------------------------ src/utils/helper.js | 22 ++++++++++++ src/utils/scripts.js | 61 ++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 44 deletions(-) create mode 100644 src/utils/scripts.js diff --git a/src/accessibilityAutomation.js b/src/accessibilityAutomation.js index af97fa0..3b2d440 100644 --- a/src/accessibilityAutomation.js +++ b/src/accessibilityAutomation.js @@ -4,6 +4,7 @@ const {makeRequest} = require('./utils/requestHelper'); const Logger = require('./utils/logger'); const {ACCESSIBILITY_URL} = require('./utils/constants'); const util = require('util'); +const scripts = require('./utils/scripts'); class AccessibilityAutomation { configure(settings = {}) { @@ -73,7 +74,10 @@ class AccessibilityAutomation { source: { frameworkName: helper.getFrameworkName(this._testRunner), frameworkVersion: helper.getPackageVersion('nightwatch'), - sdkVersion: helper.getAgentVersion() + sdkVersion: helper.getAgentVersion(), + language: 'javascript', + testFramework: 'selenium', + testFrameworkVersion: helper.getPackageVersion('selenium-webdriver') }, settings: accessibilityOptions, versionControl: await helper.getGitMetaData(), @@ -91,9 +95,11 @@ class AccessibilityAutomation { } }; - const response = await makeRequest('POST', 'test_runs', data, config, ACCESSIBILITY_URL); + const response = await makeRequest('POST', 'v2/test_runs', data, config, ACCESSIBILITY_URL); const responseData = response.data.data || {}; + scripts.parseFromJson(responseData); + scripts.toJson(); accessibilityOptions.scannerVersion = responseData.scannerVersion; process.env.BROWSERSTACK_ACCESSIBILITY_OPTIONS = JSON.stringify(accessibilityOptions); @@ -381,25 +387,6 @@ class AccessibilityAutomation { Logger.info( 'Setup for Accessibility testing has started. Automate test case execution will begin momentarily.' ); - - await browser.executeAsyncScript(` - const callback = arguments[arguments.length - 1]; - const fn = () => { - window.addEventListener('A11Y_TAP_STARTED', fn2); - const e = new CustomEvent('A11Y_FORCE_START'); - window.dispatchEvent(e); - }; - const fn2 = () => { - window.removeEventListener('A11Y_TAP_STARTED', fn); - callback(); - } - fn(); - `); - } else { - await browser.executeAsyncScript(` - const e = new CustomEvent('A11Y_FORCE_STOP'); - window.dispatchEvent(e); - `); } } this.currentTest.accessibilityScanStarted = @@ -435,29 +422,10 @@ class AccessibilityAutomation { }, platform: await this.fetchPlatformDetails(browser) }; - const final_res = await browser.executeAsyncScript( - ` - const callback = arguments[arguments.length - 1]; - - this.res = null; - if (arguments[0].saveResults) { - window.addEventListener('A11Y_TAP_TRANSPORTER', (event) => { - window.tapTransporterData = event.detail; - this.res = window.tapTransporterData; - callback(this.res); - }); - } - const e = new CustomEvent('A11Y_TEST_END', {detail: arguments[0]}); - window.dispatchEvent(e); - if (arguments[0].saveResults !== true ) { - callback(); - } - `, - dataForExtension - ); - if (this.currentTest.shouldScanTestForAccessibility) { - Logger.info('Accessibility testing for this test case has ended.'); - } + Logger.debug('Performing scan before saving results'); + Logger.debug(util.format(await browser.executeAsyncScript(scripts.performScan, {method: testMetaData.testcase}))); + await browser.executeAsyncScript(scripts.saveTestResults, dataForExtension); + Logger.info('Accessibility testing for this test case has ended.'); } } catch (er) { Logger.error( diff --git a/src/utils/helper.js b/src/utils/helper.js index fc02c96..bc4e9f1 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -751,3 +751,25 @@ exports.deepClone = (obj) => { return cloned; }; + +exports.homedir = () => { + if (typeof os.homedir === 'function') {return os.homedir()} + + var env = process.env; + var home = env.HOME; + var user = env.LOGNAME || env.USER || env.LNAME || env.USERNAME; + + if (process.platform === 'win32') { + return env.USERPROFILE || env.HOMEDRIVE + env.HOMEPATH || home || null; + } + + if (process.platform === 'darwin') { + return home || (user ? '/Users/' + user : null); + } + + if (process.platform === 'linux') { + return home || (process.getuid() === 0 ? '/root' : (user ? '/home/' + user : null)); + } + + return home || null; +}; diff --git a/src/utils/scripts.js b/src/utils/scripts.js new file mode 100644 index 0000000..a45e97c --- /dev/null +++ b/src/utils/scripts.js @@ -0,0 +1,61 @@ +const path = require('path'); +const fs = require('fs'); + +const helper = require('./helper'); + +class Scripts { + constructor() { + this.performScan = null; + this.getResults = null; + this.getResultsSummary = null; + this.saveTestResults = null; + + this.browserstackFolderPath = path.join(helper.homedir(), '.browserstack'); + this.commandsPath = path.join(this.browserstackFolderPath, 'commands.json'); + + this.fromJson(); + } + + parseFromJson(responseData) { + if (responseData.scripts) { + this.performScan = responseData.scripts.scan; + this.getResults = responseData.scripts.getResults; + this.getResultsSummary = responseData.scripts.getResultsSummary; + this.saveTestResults = responseData.scripts.saveResults; + } + + this.commandsToWrap = responseData.commands; + } + + shouldWrapCommand(method) { + try { + return this.commandsToWrap.findIndex(el => el.name.toLowerCase() === method.toLowerCase()) !== -1; + } catch { /* empty */ } + + return false; + } + + toJson() { + if (!fs.existsSync(this.browserstackFolderPath)){ + fs.mkdirSync(this.browserstackFolderPath); + } + + fs.writeFileSync(this.commandsPath, JSON.stringify({ + scripts: { + scan: this.performScan, + getResults: this.getResults, + getResultsSummary: this.getResultsSummary, + saveResults: this.saveTestResults + }, + commands: this.commandsToWrap + })); + } + + fromJson() { + if (fs.existsSync(this.commandsPath)) { + this.parseFromJson(require(this.commandsPath)); + } + } +} + +module.exports = new Scripts(); From 19be340c1f14c378f3e45747ba56ce9d3f20a32b Mon Sep 17 00:00:00 2001 From: AdityaHirapara Date: Fri, 3 May 2024 11:13:13 +0530 Subject: [PATCH 2/5] WIP: changes for cucumber support and command wrapping --- nightwatch/globals.js | 48 ++++++++++++++++++++++++++++++++-- src/accessibilityAutomation.js | 14 +++++++--- src/utils/scripts.js | 4 +-- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/nightwatch/globals.js b/nightwatch/globals.js index e9a7812..56c18bf 100644 --- a/nightwatch/globals.js +++ b/nightwatch/globals.js @@ -12,6 +12,11 @@ const localTunnel = new LocalTunnel(); const testObservability = new TestObservability(); const accessibilityAutomation = new AccessibilityAutomation(); +const ElementCommand = helper.requireModule('nightwatch/lib/element/command.js') +const ScopedElement = helper.requireModule('nightwatch/lib/api/web-element/scoped-element.js') +const Transport = helper.requireModule('nightwatch/lib/transport/selenium-webdriver/index.js') +const fs = require('fs'); + const nightwatchRerun = process.env.NIGHTWATCH_RERUN_FAILED; const nightwatchRerunFile = process.env.NIGHTWATCH_RERUN_REPORT_FILE; const _tests = {}; @@ -133,7 +138,7 @@ module.exports = { }); eventBroadcaster.on('TestCaseFinished', async (args) => { - if (!helper.isTestObservabilitySession()) { + if (!helper.isTestObservabilitySession() && !helper.isAccessibilitySession) { return; } try { @@ -147,7 +152,22 @@ module.exports = { if (testMetaData) { delete _tests[testCaseId]; testMetaData.finishedAt = new Date().toISOString(); - await testObservability.sendTestRunEventForCucumber(reportData, gherkinDocument, pickleData, 'TestRunFinished', testMetaData, args); + if (helper.isTestObservabilitySession()) { + await testObservability.sendTestRunEventForCucumber(reportData, gherkinDocument, pickleData, 'TestRunFinished', testMetaData, args); + } + // WIP for cucumber + if (helper.isAccessibilitySession()) { + console.log(testMetaData) + const test = { + testcase: testMetaData.scenario?.name, + metadata: { + name: testMetaData.feature?.name, + modulePath: path.relative(process.cwd(), testMetaData.feature?.path), + tags: pickleData.tags?.map(({name}) => (name)), + } + } + await accessibilityAutomation.afterEachExecution(test); + } } } catch (error) { CrashReporter.uploadCrashReport(error.message, error.stack); @@ -359,6 +379,30 @@ module.exports = { }, async beforeEach(settings) { + // WIP for command wrap + const origExecuteProtocolAction = ElementCommand.prototype.executeProtocolAction; + ElementCommand.prototype.executeProtocolAction = function(actionName, args=[]) { + fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `Action: ${actionName}\n`) + // browser.executeScript(scripts.performScan); + return origExecuteProtocolAction.apply(this, [actionName, args]); + } + const origRunQueuedCommand = ScopedElement.prototype.runQueuedCommand; + ScopedElement.prototype.runQueuedCommand = function(actionName, args={}) { + fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `Action: ${actionName}\n`) + // browser.executeScript(scripts.performScan); + return origRunQueuedCommand.apply(this, [actionName, args]); + } + const origTExecuteProtocolAction = Transport.prototype.executeProtocolAction; + Transport.prototype.executeProtocolAction = function(protocolAction, args) { + if (typeof protocolAction == "object" && protocolAction.actionName) { + fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `transport obj action: ${protocolAction.actionName}\n`) + } else { + fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `transport action: ${protocolAction}\n`) + } + // browser.executeScript(scripts.performScan); + return origTExecuteProtocolAction.apply(this, [protocolAction, args]); + } + browser.getAccessibilityResults = () => { return accessibilityAutomation.getAccessibilityResults() }; browser.getAccessibilityResultsSummary = () => { return accessibilityAutomation.getAccessibilityResultsSummary() }; // await accessibilityAutomation.beforeEachExecution(browser); diff --git a/src/accessibilityAutomation.js b/src/accessibilityAutomation.js index 3b2d440..7bf1897 100644 --- a/src/accessibilityAutomation.js +++ b/src/accessibilityAutomation.js @@ -406,14 +406,20 @@ class AccessibilityAutomation { async afterEachExecution(testMetaData) { try { - if (this.currentTest.accessibilityScanStarted && this.isAccessibilityAutomationSession() && this._isAccessibilitySession) { - if (this.currentTest.shouldScanTestForAccessibility) { + // WIP for cucumber + const shouldScanTestForAccessibility = this.currentTest ? this.currentTest.shouldScanTestForAccessibility : this.shouldScanTestForAccessibility( + testMetaData + ); + const accessibilityScanStarted = this.currentTest ? this.currentTest.accessibilityScanStarted : true; + this._isAccessibilitySession = this.setExtension(browser); + if (accessibilityScanStarted && this.isAccessibilityAutomationSession() && this._isAccessibilitySession) { + if (shouldScanTestForAccessibility) { Logger.info( 'Automate test case execution has ended. Processing for accessibility testing is underway. ' ); } const dataForExtension = { - saveResults: this.currentTest.shouldScanTestForAccessibility, + saveResults: shouldScanTestForAccessibility, testDetails: { name: testMetaData.testcase, testRunId: process.env.BS_A11Y_TEST_RUN_ID, @@ -429,7 +435,7 @@ class AccessibilityAutomation { } } catch (er) { Logger.error( - `Accessibility results could not be processed for the test case ${this.currentTest.module}. Error :`, + `Accessibility results could not be processed for the test case. Error :`, er ); } diff --git a/src/utils/scripts.js b/src/utils/scripts.js index a45e97c..3643038 100644 --- a/src/utils/scripts.js +++ b/src/utils/scripts.js @@ -1,7 +1,7 @@ const path = require('path'); const fs = require('fs'); -const helper = require('./helper'); +const os = require('os'); class Scripts { constructor() { @@ -10,7 +10,7 @@ class Scripts { this.getResultsSummary = null; this.saveTestResults = null; - this.browserstackFolderPath = path.join(helper.homedir(), '.browserstack'); + this.browserstackFolderPath = path.join(os.homedir(), '.browserstack'); this.commandsPath = path.join(this.browserstackFolderPath, 'commands.json'); this.fromJson(); From ba3dff1233563bcd9ff2b5e83d3fac9645b75800 Mon Sep 17 00:00:00 2001 From: Saurav Das Date: Wed, 8 May 2024 15:06:56 +0530 Subject: [PATCH 3/5] fix: Error message --- src/accessibilityAutomation.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/accessibilityAutomation.js b/src/accessibilityAutomation.js index 7bf1897..f5398bf 100644 --- a/src/accessibilityAutomation.js +++ b/src/accessibilityAutomation.js @@ -434,10 +434,7 @@ class AccessibilityAutomation { Logger.info('Accessibility testing for this test case has ended.'); } } catch (er) { - Logger.error( - `Accessibility results could not be processed for the test case. Error :`, - er - ); + Logger.error('Accessibility results could not be processed for the test case. Error: ' + er.toString()); } } From 6ac238a97fa6e74b88c679f7fcf4eacc8ac1a344 Mon Sep 17 00:00:00 2001 From: Saurav Das Date: Wed, 8 May 2024 15:55:42 +0530 Subject: [PATCH 4/5] chore: Accessibility stability --- nightwatch/globals.js | 60 +++---------- nightwatch/observabilityLogPatcherHook.js | 17 +++- src/accessibilityAutomation.js | 5 +- src/utils/helper.js | 102 ++++++++++++++++++++++ 4 files changed, 132 insertions(+), 52 deletions(-) diff --git a/nightwatch/globals.js b/nightwatch/globals.js index 80ccebd..3923d77 100644 --- a/nightwatch/globals.js +++ b/nightwatch/globals.js @@ -12,9 +12,6 @@ const localTunnel = new LocalTunnel(); const testObservability = new TestObservability(); const accessibilityAutomation = new AccessibilityAutomation(); -const ElementCommand = helper.requireModule('nightwatch/lib/element/command.js') -const ScopedElement = helper.requireModule('nightwatch/lib/api/web-element/scoped-element.js') -const Transport = helper.requireModule('nightwatch/lib/transport/selenium-webdriver/index.js') const fs = require('fs'); const nightwatchRerun = process.env.NIGHTWATCH_RERUN_FAILED; @@ -82,7 +79,7 @@ module.exports = { registerEventHandlers(eventBroadcaster) { eventBroadcaster.on('TestCaseStarted', async (args) => { - if (!helper.isTestObservabilitySession()) { + if (!helper.isTestObservabilitySession() && !helper.isAccessibilitySession()) { return; } try { @@ -138,7 +135,7 @@ module.exports = { }); eventBroadcaster.on('TestCaseFinished', async (args) => { - if (!helper.isTestObservabilitySession() && !helper.isAccessibilitySession) { + if (!helper.isTestObservabilitySession() && !helper.isAccessibilitySession()) { return; } try { @@ -155,19 +152,6 @@ module.exports = { if (helper.isTestObservabilitySession()) { await testObservability.sendTestRunEventForCucumber(reportData, gherkinDocument, pickleData, 'TestRunFinished', testMetaData, args); } - // WIP for cucumber - if (helper.isAccessibilitySession()) { - console.log(testMetaData) - const test = { - testcase: testMetaData.scenario?.name, - metadata: { - name: testMetaData.feature?.name, - modulePath: path.relative(process.cwd(), testMetaData.feature?.path), - tags: pickleData.tags?.map(({name}) => (name)), - } - } - await accessibilityAutomation.afterEachExecution(test); - } } } catch (error) { CrashReporter.uploadCrashReport(error.message, error.stack); @@ -176,7 +160,7 @@ module.exports = { }); eventBroadcaster.on('TestStepStarted', async (args) => { - if (!helper.isTestObservabilitySession()) { + if (!helper.isTestObservabilitySession() && !helper.isAccessibilitySession()) { return; } try { @@ -209,7 +193,7 @@ module.exports = { }); eventBroadcaster.on('TestStepFinished', async (args) => { - if (!helper.isTestObservabilitySession()) { + if (!helper.isTestObservabilitySession() && !helper.isAccessibilitySession()) { return; } try { @@ -318,7 +302,6 @@ module.exports = { if (helper.isCucumberTestSuite(settings)) { cucumberPatcher(); process.env.CUCUMBER_SUITE = 'true'; - settings.test_runner.options['require'] = path.resolve(__dirname, 'observabilityLogPatcherHook.js'); } settings.globals['customReporterCallbackTimeout'] = CUSTOM_REPORTER_CALLBACK_TIMEOUT; if (testObservability._user && testObservability._key) { @@ -349,6 +332,9 @@ module.exports = { Logger.error(`Could not configure or launch accessibility automation - ${error}`); } + if ((helper.isAccessibilitySession() || helper.isTestObservabilitySession()) && helper.isCucumberTestSuite(settings)) { + settings.test_runner.options['require'] = path.resolve(__dirname, 'observabilityLogPatcherHook.js'); + } }, async after() { @@ -367,7 +353,6 @@ module.exports = { } catch (error) { Logger.error(`Something went wrong in stopping build session for test observability - ${error}`); } - process.exit(); } if (helper.isAccessibilitySession()){ try { @@ -375,37 +360,18 @@ module.exports = { } catch (error) { Logger.error(`Exception in stop accessibility test run: ${error}`); } - } + process.exit(); }, async beforeEach(settings) { - // WIP for command wrap - const origExecuteProtocolAction = ElementCommand.prototype.executeProtocolAction; - ElementCommand.prototype.executeProtocolAction = function(actionName, args=[]) { - fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `Action: ${actionName}\n`) - // browser.executeScript(scripts.performScan); - return origExecuteProtocolAction.apply(this, [actionName, args]); - } - const origRunQueuedCommand = ScopedElement.prototype.runQueuedCommand; - ScopedElement.prototype.runQueuedCommand = function(actionName, args={}) { - fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `Action: ${actionName}\n`) - // browser.executeScript(scripts.performScan); - return origRunQueuedCommand.apply(this, [actionName, args]); - } - const origTExecuteProtocolAction = Transport.prototype.executeProtocolAction; - Transport.prototype.executeProtocolAction = function(protocolAction, args) { - if (typeof protocolAction == "object" && protocolAction.actionName) { - fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `transport obj action: ${protocolAction.actionName}\n`) - } else { - fs.appendFileSync("/Users/aditya/nightwatch-browserstack/patch.log", `transport action: ${protocolAction}\n`) - } - // browser.executeScript(scripts.performScan); - return origTExecuteProtocolAction.apply(this, [protocolAction, args]); + if (helper.isAccessibilitySession()) { + helper.modifySeleniumCommands(); + helper.modifyNightwatchCommands(); + browser.getAccessibilityResults = () => { return accessibilityAutomation.getAccessibilityResults() }; + browser.getAccessibilityResultsSummary = () => { return accessibilityAutomation.getAccessibilityResultsSummary() }; } - browser.getAccessibilityResults = () => { return accessibilityAutomation.getAccessibilityResults() }; - browser.getAccessibilityResultsSummary = () => { return accessibilityAutomation.getAccessibilityResultsSummary() }; // await accessibilityAutomation.beforeEachExecution(browser); }, diff --git a/nightwatch/observabilityLogPatcherHook.js b/nightwatch/observabilityLogPatcherHook.js index d39e071..ab0bef3 100644 --- a/nightwatch/observabilityLogPatcherHook.js +++ b/nightwatch/observabilityLogPatcherHook.js @@ -1,8 +1,19 @@ try { - const {Before} = require('@cucumber/cucumber'); - - Before((testCase) => { + const {Before, After} = require('@cucumber/cucumber'); + const nightwatchPluginHelper = require('@nightwatch/browserstack/src/utils/helper'); + const AccessibilityAutomation = require('@nightwatch/browserstack/src/accessibilityAutomation'); + + Before(async (testCase) => { + nightwatchPluginHelper.modifySeleniumCommands(); + nightwatchPluginHelper.modifyNightwatchCommands(); console.log(`TEST-OBSERVABILITY-PID-TESTCASE-MAPPING-${testCase.testCaseStartedId}`); + const testMeta = nightwatchPluginHelper.getCucumberTestMetaData(testCase); + await AccessibilityAutomation.prototype.beforeEachExecution(testMeta); + }); + + After(async (testCase) => { + const testMeta = nightwatchPluginHelper.getCucumberTestMetaData(testCase); + await AccessibilityAutomation.prototype.afterEachExecution(testMeta); }); } catch (error) { /* empty */ } diff --git a/src/accessibilityAutomation.js b/src/accessibilityAutomation.js index f5398bf..2926c40 100644 --- a/src/accessibilityAutomation.js +++ b/src/accessibilityAutomation.js @@ -359,11 +359,13 @@ class AccessibilityAutomation { async beforeEachExecution(testMetaData) { try { - this.currentTest = browser.currentTest; + this.currentTest = browser.currentTest || {}; this.currentTest.shouldScanTestForAccessibility = this.shouldScanTestForAccessibility( testMetaData ); + global.shouldScanTestForAccessibility = this.currentTest.shouldScanTestForAccessibility; this.currentTest.accessibilityScanStarted = true; + global.isAccessibilityPlatform = true; this._isAccessibilitySession = this.setExtension(browser); if (this.isAccessibilityAutomationSession() && browser && helper.isAccessibilitySession() && this._isAccessibilitySession) { @@ -406,7 +408,6 @@ class AccessibilityAutomation { async afterEachExecution(testMetaData) { try { - // WIP for cucumber const shouldScanTestForAccessibility = this.currentTest ? this.currentTest.shouldScanTestForAccessibility : this.shouldScanTestForAccessibility( testMetaData ); diff --git a/src/utils/helper.js b/src/utils/helper.js index 47c6322..4056162 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -14,6 +14,7 @@ const Logger = require('./logger'); const LogPatcher = require('./logPatcher'); const BSTestOpsPatcher = new LogPatcher({}); const sessions = {}; +const scripts = require('./scripts'); console = {}; Object.keys(consoleHolder).forEach(method => { @@ -785,3 +786,104 @@ exports.homedir = () => { return home || null; }; + +exports.isBrowserStackCommandExecutor = (parameters) => { + if (parameters && parameters.script && typeof parameters.script === 'string') { + return parameters.script.includes('browserstack_executor'); + } + + return false; +}; + +exports.modifySeleniumCommands = () => { + try { + let Executor = exports.requireModule('selenium-webdriver/lib/webdriver.js').WebDriver; + if (!Executor.prototype || !Executor.prototype.execute) { + Executor = exports.requireModule('selenium-webdriver/lib/http.js').Executor; + } + + if (Executor.prototype && Executor.prototype.execute) { + const originalExecute = Executor.prototype.execute; + Logger.debug('Modifying webdriver execute'); + + Executor.prototype.execute = async function() { + exports.performAccessibilityScan({commandType: 'selenium', arguments}); + + return originalExecute.apply(this, arguments); + }; + } + } catch (err) { + Logger.debug('Unable to find executor class ' + err); + } +}; + +exports.modifyNightwatchCommands = () => { + const modifyClientCommand = (commandMeta) => { + try { + const CommandClass = exports.requireModule(commandMeta.packagePath); + if (CommandClass?.prototype?.performAction) { + const originalCommandClass = CommandClass.prototype.performAction; + + CommandClass.prototype.performAction = function(...args) { + exports.performAccessibilityScan({commandType: 'nightwatch', methodName: commandMeta.commandName}); + + return originalCommandClass.apply(this, ...args); + }; + } + } catch (err) { + Logger.debug(`Unable to find executor class from method ${commandMeta.commandName}, Error: ` + err); + } + }; + + const commandsToModify = [ + { + commandName: 'registerBasicAuth', + packagePath: 'nightwatch/lib/api/client-commands/registerBasicAuth.js' + }, + { + commandName: 'setDeviceDimensions', + packagePath: 'nightwatch/lib/api/client-commands/setDeviceDimensions.js' + }, + { + commandName: 'setGeolocation', + packagePath: 'nightwatch/lib/api/client-commands/setGeolocation.js' + } + ]; + commandsToModify.forEach(commandMeta => { + modifyClientCommand(commandMeta); + }); +}; + +exports.performAccessibilityScan = (data) => { + let shouldScanCommand = false; + let methodName = ''; + if (data.commandType === 'selenium') { + methodName = data.arguments[0].name_; + shouldScanCommand = !global.bstackAllyScanning && global.isAccessibilityPlatform && global.shouldScanTestForAccessibility && scripts.shouldWrapCommand(methodName) && !exports.isBrowserStackCommandExecutor(data.arguments[0].parameters_); + } else if (data.commandType === 'nightwatch') { + methodName = data.methodName; + shouldScanCommand = !global.bstackAllyScanning && global.isAccessibilityPlatform && global.shouldScanTestForAccessibility && scripts.shouldWrapCommand(methodName); + } + + try { + if (shouldScanCommand) { + global.bstackAllyScanning = true, + Logger.debug(`Performing scan for ${methodName}`); + browser.executeAsyncScript(scripts.performScan); + } + } catch (er) { + Logger.debug(`Failed to perform scan for ${methodName}, Error: ${er}`); + } + global.bstackAllyScanning = false; +}; + +exports.getCucumberTestMetaData = (testCase) => { + return { + testcase: testCase.pickle?.name, + metadata: { + name: testCase.gherkinDocument?.feature?.name, + modulePath: path.relative(process.cwd(), testCase.pickle?.uri), + tags: testCase.pickle?.tags?.map(({name}) => (name)) + } + }; +}; From cfba2bfcc708cd0dd3634c9d52d28a99f1a2db62 Mon Sep 17 00:00:00 2001 From: Saurav Das Date: Wed, 8 May 2024 17:23:41 +0530 Subject: [PATCH 5/5] refactor: Remove unwanted import --- nightwatch/globals.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/nightwatch/globals.js b/nightwatch/globals.js index 3923d77..2e009f4 100644 --- a/nightwatch/globals.js +++ b/nightwatch/globals.js @@ -12,8 +12,6 @@ const localTunnel = new LocalTunnel(); const testObservability = new TestObservability(); const accessibilityAutomation = new AccessibilityAutomation(); -const fs = require('fs'); - const nightwatchRerun = process.env.NIGHTWATCH_RERUN_FAILED; const nightwatchRerunFile = process.env.NIGHTWATCH_RERUN_REPORT_FILE; const _tests = {};