-
Notifications
You must be signed in to change notification settings - Fork 42
SDK-1884: Cypress SDK not wrapping A11Y commands appropriately #949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
234fcfd
02ea36a
da5fc16
e8d4bc9
ccde61e
f96066a
f04069d
deefe01
2148ba1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,19 +6,59 @@ const browserStackLog = (message) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const commandsToWrap = ['visit', 'click', 'type', 'request', 'dblclick', 'rightclick', 'clear', 'check', 'uncheck', 'select', 'trigger', 'selectFile', 'scrollIntoView', 'scroll', 'scrollTo', 'blur', 'focus', 'go', 'reload', 'submit', 'viewport', 'origin']; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const commandToOverwrite = ['visit', 'click', 'type', 'request', 'dblclick', 'rightclick', 'clear', 'check', 'uncheck', 'select', 'trigger', 'selectFile', 'scrollIntoView', 'scrollTo', 'blur', 'focus', 'go', 'reload', 'submit', 'viewport', 'origin']; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const performModifiedScan = (originalFn, Subject, stateType, ...args) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add some comments explaining the below function for future ref |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let customChaining = cy.wrap(null).performScan(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function changeSub(args, stateType, newSubject) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amaanbs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (stateType !== 'parent') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [newSubject, ...args.slice(1)]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return args; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function runCutomizedCommand() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amaanbs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!Subject) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let orgS1, orgS2, cypressCommandSubject; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if((orgS2 = (orgS1 = cy).subject) !==null && orgS2 !== void 0){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cypressCommandSubject = orgS2.call(orgS1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cypressCommandSubject = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| customChaining.then(()=> cypressCommandSubject).then(() => {originalFn(...args)}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let orgSC1, orgSC2, timeO1, cypressCommandChain, setTimeout; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if((timeO1 = args.find(arg => arg !== null && arg !== void 0 ? arg.timeout : null)) !== null && timeO1 !== void 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setTimeout = timeO1.timeout; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setTimeout = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if((orgSC1 = (orgSC2 = cy).subjectChain) !== null && orgSC1 !== void 0){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cypressCommandChain = orgSC1.call(orgSC2); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cypressCommandChain = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| customChaining.performScanSubjectQuery(cypressCommandChain, setTimeout).then({timeout: 30000}, (newSubject) => originalFn(...changeSub(args, stateType, newSubject))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function runCutomizedCommand() { | |
| if (!Subject) { | |
| let orgS1, orgS2, cypressCommandSubject; | |
| if((orgS2 = (orgS1 = cy).subject) !==null && orgS2 !== void 0){ | |
| cypressCommandSubject = orgS2.call(orgS1); | |
| } | |
| else{ | |
| cypressCommandSubject = null; | |
| } | |
| customChaining.then(()=> cypressCommandSubject).then(() => {originalFn(...args)}); | |
| } | |
| else { | |
| let orgSC1, orgSC2, timeO1, cypressCommandChain, setTimeout; | |
| if((timeO1 = args.find(arg => arg !== null && arg !== void 0 ? arg.timeout : null)) !== null && timeO1 !== void 0) { | |
| setTimeout = timeO1.timeout; | |
| } | |
| else { | |
| setTimeout = null; | |
| } | |
| if((orgSC1 = (orgSC2 = cy).subjectChain) !== null && orgSC1 !== void 0){ | |
| cypressCommandChain = orgSC1.call(orgSC2); | |
| } | |
| else { | |
| cypressCommandChain = null; | |
| } | |
| customChaining.performScanSubjectQuery(cypressCommandChain, setTimeout).then({timeout: 30000}, (newSubject) => originalFn(...changeSub(args, stateType, newSubject))); | |
| function runCutomizedCommand() { | |
| if (!Subject) { | |
| let cypressCommandSubject = (cy.subject?.call(cy)) ?? null; | |
| customChaining.then(() => cypressCommandSubject).then(() => { originalFn(...args); }); | |
| } else { | |
| let setTimeout = args.find(arg => arg?.timeout)?.timeout ?? null; | |
| let cypressCommandChain = (cy.subjectChain?.call(cy)) ?? null; | |
| customChaining.performScanSubjectQuery(cypressCommandChain, setTimeout).then({ timeout: 30000 }, newSubject => originalFn(...changeSub(args, stateType, newSubject))); | |
| } | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is retryCount number intentional ? Why 100 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes a11y team told to retry for 10 sec other framework have same count.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't promise be resolved?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't promise be resolved?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolving do we need return?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sets timeout, which can break the test if mochaTimeout is less than 40s. should we also handle mocha timeout ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the response from performScan take less time no timeout will occur. Eventually if response does not come and mocha timeout occurs it should be considered as timeout.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| const path = require("node:path"); | ||
| const { decodeJWTToken } = require("../../helpers/utils"); | ||
| const utils = require('../../helpers/utils'); | ||
|
|
||
| const browserstackAccessibility = (on, config) => { | ||
| let browser_validation = true; | ||
|
|
@@ -30,7 +32,16 @@ const browserstackAccessibility = (on, config) => { | |
| } | ||
| if (browser_validation) { | ||
| const ally_path = path.dirname(process.env.ACCESSIBILITY_EXTENSION_PATH) | ||
| const {_, payload} = decodeJWTToken(process.env.ACCESSIBILITY_AUTH); | ||
| launchOptions.extensions.push(ally_path); | ||
| if(!utils.isUndefined(payload) && !utils.isUndefined(payload.a11y_core_config) && payload.a11y_core_config.domForge === true) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. significance of these?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. other ticket SDK-1907 |
||
| launchOptions.args.push("--auto-open-devtools-for-tabs"); | ||
| launchOptions.preferences.default["devtools"] = launchOptions.preferences.default["devtools"] || {}; | ||
| launchOptions.preferences.default["devtools"]["preferences"] = launchOptions.preferences.default["devtools"]["preferences"] || {}; | ||
| launchOptions.preferences.default["devtools"]["preferences"][ | ||
| "currentDockState" | ||
| ] = '"undocked"'; | ||
| } | ||
| return launchOptions | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1775,3 +1775,24 @@ exports.getMajorVersion = (version) => { | |
| return null; | ||
| } | ||
| } | ||
|
|
||
| const base64UrlDecode = (str) => { | ||
| const base64 = str.replace(/-/g, '+').replace(/_/g, '/'); | ||
| const buffer = Buffer.from(base64, 'base64'); | ||
| return buffer.toString('utf-8'); | ||
| }; | ||
|
|
||
| exports.decodeJWTToken = (token) => { | ||
| try{ | ||
| const parts = token.split('.'); | ||
| if (parts.length < 2) { | ||
| throw new Error('Invalid JWT token'); | ||
| } | ||
| const header = JSON.parse(base64UrlDecode(parts[0])); | ||
| const payload = JSON.parse(base64UrlDecode(parts[1])); | ||
| return { header, payload }; | ||
|
||
| } catch (error) { | ||
| logger.err(error.message); | ||
amaanbs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return {undefined, undefined}; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any reason for removing
scrollfrom the list ?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scroll is not a default cypress function. This error was occuring.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this verified across all supported cy versions ?