From 31f6c41d9085a88167de7bffd4d6c15c404bb3c6 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Mon, 18 Dec 2023 09:54:29 -0500 Subject: [PATCH 01/11] Update aria.js to account for properties to be ignored during a v2 test format version update so applicable results can be transferred over during phase update --- server/resources/ats.json | 28 + .../aria-util/commandButton_V20230823_V1.json | 1411 ++++++++++++ .../aria-util/commandButton_V20231206_V2.json | 1741 +++++++++++++++ .../aria-util/commandButton_V20231213_V2.json | 1909 +++++++++++++++++ server/util/aria.js | 9 +- server/util/aria.test.js | 100 +- 6 files changed, 5196 insertions(+), 2 deletions(-) create mode 100644 server/tests/mock-data/aria-util/commandButton_V20230823_V1.json create mode 100644 server/tests/mock-data/aria-util/commandButton_V20231206_V2.json create mode 100644 server/tests/mock-data/aria-util/commandButton_V20231213_V2.json diff --git a/server/resources/ats.json b/server/resources/ats.json index d23657883..b88da56e5 100644 --- a/server/resources/ats.json +++ b/server/resources/ats.json @@ -72,6 +72,34 @@ "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] } } } diff --git a/server/tests/mock-data/aria-util/commandButton_V20230823_V1.json b/server/tests/mock-data/aria-util/commandButton_V20230823_V1.json new file mode 100644 index 000000000..fd9e84c3f --- /dev/null +++ b/server/tests/mock-data/aria-util/commandButton_V20230823_V1.json @@ -0,0 +1,1411 @@ +[ + { + "id": "NTNmYeyIyIjoiNTU1OTgifQTYwYz", + "atIds": [1, 2], + "title": "Navigate forwards to a button in reading mode", + "atMode": "READING", + "viewers": [], + "rowNumber": "1", + "scenarios": [ + { + "id": "NzZjZeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9mNlYz", + "atId": 1, + "commandIds": ["DOWN"] + }, + { + "id": "YTlhMeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ92M1Nm", + "atId": 1, + "commandIds": ["B"] + }, + { + "id": "ZmYyZeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9DU2ZT", + "atId": 1, + "commandIds": ["F"] + }, + { + "id": "OGJhNeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9jdmMz", + "atId": 1, + "commandIds": ["TAB"] + }, + { + "id": "MzQ3MeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ92FhNT", + "atId": 2, + "commandIds": ["DOWN"] + }, + { + "id": "MmI5ZeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9DViNj", + "atId": 2, + "commandIds": ["B"] + }, + { + "id": "Y2EwMeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9mIwYW", + "atId": 2, + "commandIds": ["F"] + }, + { + "id": "OWVkYeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9jcxZj", + "atId": 2, + "commandIds": ["TAB"] + } + ], + "assertions": [ + { + "id": "M2ZkZeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ9GM0MT", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "OWE5YeyIzIjoiTlRObVlleUl5SWpvaU5UVTFPVGdpZlFUWXdZeiJ92U0Mj", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "1": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-01-navigate-forwards-to-button-reading-jaws.collected.html", + "2": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-01-navigate-forwards-to-button-reading-nvda.collected.html" + }, + "renderableContent": { + "1": { + "info": { + "task": "navigate forwards to button", + "title": "Navigate forwards to a button in reading mode", + "testId": 1, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "jaws", "raw": "JAWS", "name": "JAWS" }, + "mode": "reading", + "setupScript": { + "name": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "description": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "DOWN", + "keystroke": "Down Arrow", + "keypresses": [ + { "id": "DOWN", "keystroke": "Down Arrow" } + ] + }, + { + "id": "B", + "keystroke": "B", + "keypresses": [{ "id": "B", "keystroke": "B" }] + }, + { + "id": "F", + "keystroke": "F", + "keypresses": [{ "id": "F", "keystroke": "F" }] + }, + { + "id": "TAB", + "keystroke": "Tab", + "keypresses": [{ "id": "TAB", "keystroke": "Tab" }] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With the reading cursor on the 'Navigate forwards from here' link, navigate to the 'Print Page' button", + "mode": "Verify the Virtual Cursor is active by pressing Alt+Delete. If it is not, exit Forms Mode to activate the Virtual Cursor by pressing Escape.", + "user": [ + "With the reading cursor on the 'Navigate forwards from here' link, navigate to the 'Print Page' button" + ] + } + }, + "2": { + "info": { + "task": "navigate forwards to button", + "title": "Navigate forwards to a button in reading mode", + "testId": 1, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "nvda", "raw": "NVDA", "name": "NVDA" }, + "mode": "reading", + "setupScript": { + "name": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "description": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "DOWN", + "keystroke": "Down Arrow", + "keypresses": [ + { "id": "DOWN", "keystroke": "Down Arrow" } + ] + }, + { + "id": "B", + "keystroke": "B", + "keypresses": [{ "id": "B", "keystroke": "B" }] + }, + { + "id": "F", + "keystroke": "F", + "keypresses": [{ "id": "F", "keystroke": "F" }] + }, + { + "id": "TAB", + "keystroke": "Tab", + "keypresses": [{ "id": "TAB", "keystroke": "Tab" }] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With the reading cursor on the 'Navigate forwards from here' link, navigate to the 'Print Page' button", + "mode": "Ensure NVDA is in browse mode by pressing Escape. Note: This command has no effect if NVDA is already in browse mode.", + "user": [ + "With the reading cursor on the 'Navigate forwards from here' link, navigate to the 'Print Page' button" + ] + } + } + } + }, + { + "id": "MTY0MeyIyIjoiNTU1OTgifQmIzNG", + "atIds": [1, 2], + "title": "Navigate backwards to a button in reading mode", + "atMode": "READING", + "viewers": [], + "rowNumber": "2", + "scenarios": [ + { + "id": "MTAyMeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ92M2MD", + "atId": 1, + "commandIds": ["UP"] + }, + { + "id": "MTJkMeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9GI3YT", + "atId": 1, + "commandIds": ["SHIFT_B"] + }, + { + "id": "YWYxYeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9zRkYm", + "atId": 1, + "commandIds": ["SHIFT_F"] + }, + { + "id": "YjE5ZeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9jUzMj", + "atId": 1, + "commandIds": ["SHIFT_TAB"] + }, + { + "id": "Y2YxMeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9mEzY2", + "atId": 2, + "commandIds": ["UP"] + }, + { + "id": "YWVlZeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9mM0N2", + "atId": 2, + "commandIds": ["SHIFT_B"] + }, + { + "id": "OWNkYeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9zc4Ym", + "atId": 2, + "commandIds": ["SHIFT_F"] + }, + { + "id": "N2JiZeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9mU1ND", + "atId": 2, + "commandIds": ["SHIFT_TAB"] + } + ], + "assertions": [ + { + "id": "NjRjZeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9mMyYj", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "YzkyYeyIzIjoiTVRZME1leUl5SWpvaU5UVTFPVGdpZlFtSXpORyJ9WM3ND", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "1": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-02-navigate-backwards-to-button-reading-jaws.collected.html", + "2": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-02-navigate-backwards-to-button-reading-nvda.collected.html" + }, + "renderableContent": { + "1": { + "info": { + "task": "navigate backwards to button", + "title": "Navigate backwards to a button in reading mode", + "testId": 2, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "jaws", "raw": "JAWS", "name": "JAWS" }, + "mode": "reading", + "setupScript": { + "name": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "description": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "UP", + "keystroke": "Up Arrow", + "keypresses": [{ "id": "UP", "keystroke": "Up Arrow" }] + }, + { + "id": "SHIFT_B", + "keystroke": "Shift+B", + "keypresses": [ + { "id": "SHIFT_B", "keystroke": "Shift+B" } + ] + }, + { + "id": "SHIFT_F", + "keystroke": "Shift+F", + "keypresses": [ + { "id": "SHIFT_F", "keystroke": "Shift+F" } + ] + }, + { + "id": "SHIFT_TAB", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "SHIFT_TAB", "keystroke": "Shift+Tab" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With the reading cursor on the 'Navigate backwards from here' link, navigate to the 'Print Page' button", + "mode": "Verify the Virtual Cursor is active by pressing Alt+Delete. If it is not, exit Forms Mode to activate the Virtual Cursor by pressing Escape.", + "user": [ + "With the reading cursor on the 'Navigate backwards from here' link, navigate to the 'Print Page' button" + ] + } + }, + "2": { + "info": { + "task": "navigate backwards to button", + "title": "Navigate backwards to a button in reading mode", + "testId": 2, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "nvda", "raw": "NVDA", "name": "NVDA" }, + "mode": "reading", + "setupScript": { + "name": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "description": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "UP", + "keystroke": "Up Arrow", + "keypresses": [{ "id": "UP", "keystroke": "Up Arrow" }] + }, + { + "id": "SHIFT_B", + "keystroke": "Shift+B", + "keypresses": [ + { "id": "SHIFT_B", "keystroke": "Shift+B" } + ] + }, + { + "id": "SHIFT_F", + "keystroke": "Shift+F", + "keypresses": [ + { "id": "SHIFT_F", "keystroke": "Shift+F" } + ] + }, + { + "id": "SHIFT_TAB", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "SHIFT_TAB", "keystroke": "Shift+Tab" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With the reading cursor on the 'Navigate backwards from here' link, navigate to the 'Print Page' button", + "mode": "Ensure NVDA is in browse mode by pressing Escape. Note: This command has no effect if NVDA is already in browse mode.", + "user": [ + "With the reading cursor on the 'Navigate backwards from here' link, navigate to the 'Print Page' button" + ] + } + } + } + }, + { + "id": "MDUxNeyIyIjoiNTU1OTgifQWNiZT", + "atIds": [1, 2], + "title": "Navigate forwards to a button in interaction mode", + "atMode": "INTERACTION", + "viewers": [], + "rowNumber": "3", + "scenarios": [ + { + "id": "MDM2MeyIzIjoiTURVeE5leUl5SWpvaU5UVTFPVGdpZlFXTmlaVCJ9DhjNW", + "atId": 1, + "commandIds": ["TAB"] + }, + { + "id": "ZTc4YeyIzIjoiTURVeE5leUl5SWpvaU5UVTFPVGdpZlFXTmlaVCJ92RhYz", + "atId": 2, + "commandIds": ["TAB"] + } + ], + "assertions": [ + { + "id": "YmY1MeyIzIjoiTURVeE5leUl5SWpvaU5UVTFPVGdpZlFXTmlaVCJ9zg2Yj", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "ZWMyZeyIzIjoiTURVeE5leUl5SWpvaU5UVTFPVGdpZlFXTmlaVCJ9DcxYT", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "1": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-03-navigate-forwards-to-button-interaction-jaws.collected.html", + "2": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-03-navigate-forwards-to-button-interaction-nvda.collected.html" + }, + "renderableContent": { + "1": { + "info": { + "task": "navigate forwards to button", + "title": "Navigate forwards to a button in interaction mode", + "testId": 3, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "jaws", "raw": "JAWS", "name": "JAWS" }, + "mode": "interaction", + "setupScript": { + "name": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "description": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "TAB", + "keystroke": "Tab", + "keypresses": [{ "id": "TAB", "keystroke": "Tab" }] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'navigate forwards from here' link, navigate to the 'Print Page' button.", + "mode": "Verify the PC Cursor is active by pressing Alt+Delete. If it is not, turn off the Virtual Cursor by pressing Insert+Z.", + "user": [ + "With focus on the 'navigate forwards from here' link, navigate to the 'Print Page' button." + ] + } + }, + "2": { + "info": { + "task": "navigate forwards to button", + "title": "Navigate forwards to a button in interaction mode", + "testId": 3, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "nvda", "raw": "NVDA", "name": "NVDA" }, + "mode": "interaction", + "setupScript": { + "name": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "description": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "TAB", + "keystroke": "Tab", + "keypresses": [{ "id": "TAB", "keystroke": "Tab" }] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'navigate forwards from here' link, navigate to the 'Print Page' button.", + "mode": "If NVDA did not make the focus mode sound when the test page loaded, press Insert+Space to turn focus mode on.", + "user": [ + "With focus on the 'navigate forwards from here' link, navigate to the 'Print Page' button." + ] + } + } + } + }, + { + "id": "NjI2MeyIyIjoiNTU1OTgifQ2UzND", + "atIds": [1, 2], + "title": "Navigate backwards to a button in interaction mode", + "atMode": "INTERACTION", + "viewers": [], + "rowNumber": "4", + "scenarios": [ + { + "id": "MjQ3ZeyIzIjoiTmpJMk1leUl5SWpvaU5UVTFPVGdpZlEyVXpORCJ9GVkZj", + "atId": 1, + "commandIds": ["SHIFT_TAB"] + }, + { + "id": "MjBmNeyIzIjoiTmpJMk1leUl5SWpvaU5UVTFPVGdpZlEyVXpORCJ9GIzYT", + "atId": 2, + "commandIds": ["SHIFT_TAB"] + } + ], + "assertions": [ + { + "id": "Zjk4YeyIzIjoiTmpJMk1leUl5SWpvaU5UVTFPVGdpZlEyVXpORCJ9zU2Mj", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "YmVmZeyIzIjoiTmpJMk1leUl5SWpvaU5UVTFPVGdpZlEyVXpORCJ9TYwMD", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "1": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-04-navigate-backwards-to-button-interaction-jaws.collected.html", + "2": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-04-navigate-backwards-to-button-interaction-nvda.collected.html" + }, + "renderableContent": { + "1": { + "info": { + "task": "navigate backwards to button", + "title": "Navigate backwards to a button in interaction mode", + "testId": 4, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "jaws", "raw": "JAWS", "name": "JAWS" }, + "mode": "interaction", + "setupScript": { + "name": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "description": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "SHIFT_TAB", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "SHIFT_TAB", "keystroke": "Shift+Tab" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Navigate backwards from here' link, navigate to the 'Print Page' button.", + "mode": "Verify the PC Cursor is active by pressing Alt+Delete. If it is not, turn off the Virtual Cursor by pressing Insert+Z.", + "user": [ + "With focus on the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + ] + } + }, + "2": { + "info": { + "task": "navigate backwards to button", + "title": "Navigate backwards to a button in interaction mode", + "testId": 4, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "nvda", "raw": "NVDA", "name": "NVDA" }, + "mode": "interaction", + "setupScript": { + "name": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "description": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "SHIFT_TAB", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "SHIFT_TAB", "keystroke": "Shift+Tab" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Navigate backwards from here' link, navigate to the 'Print Page' button.", + "mode": "If NVDA did not make the focus mode sound when the test page loaded, press Insert+Space to turn focus mode on.", + "user": [ + "With focus on the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + ] + } + } + } + }, + { + "id": "ODlmMeyIyIjoiNTU1OTgifQjZlOW", + "atIds": [3], + "title": "Navigate forwards to a button", + "atMode": "INTERACTION", + "viewers": [], + "rowNumber": "5", + "scenarios": [ + { + "id": "NmZhOeyIzIjoiT0RsbU1leUl5SWpvaU5UVTFPVGdpZlFqWmxPVyJ9Dc2N2", + "atId": 3, + "commandIds": ["CTRL_OPT_RIGHT"] + }, + { + "id": "MmQ3NeyIzIjoiT0RsbU1leUl5SWpvaU5UVTFPVGdpZlFqWmxPVyJ9DBlMz", + "atId": 3, + "commandIds": ["TAB"] + }, + { + "id": "YWFkOeyIzIjoiT0RsbU1leUl5SWpvaU5UVTFPVGdpZlFqWmxPVyJ9WU5MD", + "atId": 3, + "commandIds": ["CTRL_OPT_CMD_J"] + } + ], + "assertions": [ + { + "id": "YjU4YeyIzIjoiT0RsbU1leUl5SWpvaU5UVTFPVGdpZlFqWmxPVyJ9zQxN2", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "MzA2ZeyIzIjoiT0RsbU1leUl5SWpvaU5UVTFPVGdpZlFqWmxPVyJ9mY2NT", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "3": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-05-navigate-forwards-to-button-interaction-voiceover_macos.collected.html" + }, + "renderableContent": { + "3": { + "info": { + "task": "navigate forwards to button", + "title": "Navigate forwards to a button", + "testId": 5, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": "voiceover_macos", + "name": "VoiceOver for macOS" + }, + "mode": "interaction", + "setupScript": { + "name": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "description": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "CTRL_OPT_RIGHT", + "keystroke": "Control+Option+Right", + "keypresses": [ + { + "id": "CTRL_OPT_RIGHT", + "keystroke": "Control+Option+Right" + } + ] + }, + { + "id": "TAB", + "keystroke": "Tab", + "keypresses": [{ "id": "TAB", "keystroke": "Tab" }] + }, + { + "id": "CTRL_OPT_CMD_J", + "keystroke": "Control+Option+Command+J", + "keypresses": [ + { + "id": "CTRL_OPT_CMD_J", + "keystroke": "Control+Option+Command+J" + } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Navigate forwards from here' link, navigate to the 'Print Page' button.", + "mode": "Toggle Quick Nav OFF by pressing the Left Arrow and Right Arrow keys at the same time.", + "user": [ + "With focus on the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + ] + } + } + } + }, + { + "id": "YTE1NeyIyIjoiNTU1OTgifQGQ5Nj", + "atIds": [3], + "title": "Navigate backwards to a button", + "atMode": "INTERACTION", + "viewers": [], + "rowNumber": "6", + "scenarios": [ + { + "id": "NmYxMeyIzIjoiWVRFMU5leUl5SWpvaU5UVTFPVGdpZlFHUTVOaiJ9Tk5MT", + "atId": 3, + "commandIds": ["CTRL_OPT_LEFT"] + }, + { + "id": "YTg0MeyIzIjoiWVRFMU5leUl5SWpvaU5UVTFPVGdpZlFHUTVOaiJ9zVmOD", + "atId": 3, + "commandIds": ["SHIFT_TAB"] + }, + { + "id": "OGJkYeyIzIjoiWVRFMU5leUl5SWpvaU5UVTFPVGdpZlFHUTVOaiJ9mZiZj", + "atId": 3, + "commandIds": ["SHIFT_CTRL_OPT_CMD_J"] + } + ], + "assertions": [ + { + "id": "YzBhZeyIzIjoiWVRFMU5leUl5SWpvaU5UVTFPVGdpZlFHUTVOaiJ9TEyMz", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "NGE1NeyIzIjoiWVRFMU5leUl5SWpvaU5UVTFPVGdpZlFHUTVOaiJ92Y2Nm", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "3": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-06-navigate-backwards-to-button-interaction-voiceover_macos.collected.html" + }, + "renderableContent": { + "3": { + "info": { + "task": "navigate backwards to button", + "title": "Navigate backwards to a button", + "testId": 6, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": "voiceover_macos", + "name": "VoiceOver for macOS" + }, + "mode": "interaction", + "setupScript": { + "name": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "description": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "CTRL_OPT_LEFT", + "keystroke": "Ctrl+Option+Left", + "keypresses": [ + { + "id": "CTRL_OPT_LEFT", + "keystroke": "Ctrl+Option+Left" + } + ] + }, + { + "id": "SHIFT_TAB", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "SHIFT_TAB", "keystroke": "Shift+Tab" } + ] + }, + { + "id": "SHIFT_CTRL_OPT_CMD_J", + "keystroke": "Shift+Control+Option+Command+J", + "keypresses": [ + { + "id": "SHIFT_CTRL_OPT_CMD_J", + "keystroke": "Shift+Control+Option+Command+J" + } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Navigate backwards from here' link, navigate to the 'Print Page' button.", + "mode": "Toggle Quick Nav OFF by pressing the Left Arrow and Right Arrow keys at the same time.", + "user": [ + "With focus on the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + ] + } + } + } + }, + { + "id": "MzdhYeyIyIjoiNTU1OTgifQTE1ZD", + "atIds": [1, 2], + "title": "Read information about a button in reading mode", + "atMode": "READING", + "viewers": [], + "rowNumber": "7", + "scenarios": [ + { + "id": "ZmE5MeyIzIjoiTXpkaFlleUl5SWpvaU5UVTFPVGdpZlFURTFaRCJ92Q4OD", + "atId": 1, + "commandIds": ["INS_TAB"] + }, + { + "id": "ZmViZeyIzIjoiTXpkaFlleUl5SWpvaU5UVTFPVGdpZlFURTFaRCJ9DRjMj", + "atId": 1, + "commandIds": ["INS_UP"] + }, + { + "id": "NGY0YeyIzIjoiTXpkaFlleUl5SWpvaU5UVTFPVGdpZlFURTFaRCJ9zEyYT", + "atId": 2, + "commandIds": ["INS_TAB"] + }, + { + "id": "YzQyMeyIzIjoiTXpkaFlleUl5SWpvaU5UVTFPVGdpZlFURTFaRCJ92M2Mj", + "atId": 2, + "commandIds": ["INS_UP"] + } + ], + "assertions": [ + { + "id": "NzM3OeyIzIjoiTXpkaFlleUl5SWpvaU5UVTFPVGdpZlFURTFaRCJ9TlhZW", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "OGNiMeyIzIjoiTXpkaFlleUl5SWpvaU5UVTFPVGdpZlFURTFaRCJ9zg0Nz", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "1": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-07-read-information-about-button-reading-jaws.collected.html", + "2": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-07-read-information-about-button-reading-nvda.collected.html" + }, + "renderableContent": { + "1": { + "info": { + "task": "read information about button", + "title": "Read information about a button in reading mode", + "testId": 7, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "jaws", "raw": "JAWS", "name": "JAWS" }, + "mode": "reading", + "setupScript": { + "name": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "description": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "INS_TAB", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "INS_TAB", "keystroke": "Insert+Tab" } + ] + }, + { + "id": "INS_UP", + "keystroke": "Insert+Up", + "keypresses": [ + { "id": "INS_UP", "keystroke": "Insert+Up" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With the reading cursor on the 'Print Page' button, read information about the button.", + "mode": "Verify the Virtual Cursor is active by pressing Alt+Delete. If it is not, exit Forms Mode to activate the Virtual Cursor by pressing Escape.", + "user": [ + "With the reading cursor on the 'Print Page' button, read information about the button." + ] + } + }, + "2": { + "info": { + "task": "read information about button", + "title": "Read information about a button in reading mode", + "testId": 7, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "nvda", "raw": "NVDA", "name": "NVDA" }, + "mode": "reading", + "setupScript": { + "name": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "description": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "INS_TAB", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "INS_TAB", "keystroke": "Insert+Tab" } + ] + }, + { + "id": "INS_UP", + "keystroke": "Insert+Up", + "keypresses": [ + { "id": "INS_UP", "keystroke": "Insert+Up" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With the reading cursor on the 'Print Page' button, read information about the button.", + "mode": "Ensure NVDA is in browse mode by pressing Escape. Note: This command has no effect if NVDA is already in browse mode.", + "user": [ + "With the reading cursor on the 'Print Page' button, read information about the button." + ] + } + } + } + }, + { + "id": "YjI3MeyIyIjoiNTU1OTgifQGM1M2", + "atIds": [1, 2], + "title": "Read information about a button in interaction mode", + "atMode": "INTERACTION", + "viewers": [], + "rowNumber": "8", + "scenarios": [ + { + "id": "MDlhNeyIzIjoiWWpJM01leUl5SWpvaU5UVTFPVGdpZlFHTTFNMiJ9mZlYz", + "atId": 1, + "commandIds": ["INS_TAB"] + }, + { + "id": "YTcyZeyIzIjoiWWpJM01leUl5SWpvaU5UVTFPVGdpZlFHTTFNMiJ9DhlZD", + "atId": 1, + "commandIds": ["INS_UP"] + }, + { + "id": "MzFhOeyIzIjoiWWpJM01leUl5SWpvaU5UVTFPVGdpZlFHTTFNMiJ9WU3Nz", + "atId": 2, + "commandIds": ["INS_TAB"] + }, + { + "id": "NDE3YeyIzIjoiWWpJM01leUl5SWpvaU5UVTFPVGdpZlFHTTFNMiJ9jc2ND", + "atId": 2, + "commandIds": ["INS_UP"] + } + ], + "assertions": [ + { + "id": "YmM1ZeyIzIjoiWWpJM01leUl5SWpvaU5UVTFPVGdpZlFHTTFNMiJ9DgzZj", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "NWMyNeyIzIjoiWWpJM01leUl5SWpvaU5UVTFPVGdpZlFHTTFNMiJ9mEwZG", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "1": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-08-read-information-about-button-interaction-jaws.collected.html", + "2": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-08-read-information-about-button-interaction-nvda.collected.html" + }, + "renderableContent": { + "1": { + "info": { + "task": "read information about button", + "title": "Read information about a button in interaction mode", + "testId": 8, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "jaws", "raw": "JAWS", "name": "JAWS" }, + "mode": "interaction", + "setupScript": { + "name": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "description": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "INS_TAB", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "INS_TAB", "keystroke": "Insert+Tab" } + ] + }, + { + "id": "INS_UP", + "keystroke": "Insert+Up", + "keypresses": [ + { "id": "INS_UP", "keystroke": "Insert+Up" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Print Page' button, read information about the button.", + "mode": "Verify the PC Cursor is active by pressing Alt+Delete. If it is not, turn off the Virtual Cursor by pressing Insert+Z.", + "user": [ + "With focus on the 'Print Page' button, read information about the button." + ] + } + }, + "2": { + "info": { + "task": "read information about button", + "title": "Read information about a button in interaction mode", + "testId": 8, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { "key": "nvda", "raw": "NVDA", "name": "NVDA" }, + "mode": "interaction", + "setupScript": { + "name": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "description": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "INS_TAB", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "INS_TAB", "keystroke": "Insert+Tab" } + ] + }, + { + "id": "INS_UP", + "keystroke": "Insert+Up", + "keypresses": [ + { "id": "INS_UP", "keystroke": "Insert+Up" } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Print Page' button, read information about the button.", + "mode": "If NVDA did not make the focus mode sound when the test page loaded, press Insert+Space to turn focus mode on.", + "user": [ + "With focus on the 'Print Page' button, read information about the button." + ] + } + } + } + }, + { + "id": "Y2E5NeyIyIjoiNTU1OTgifQTg5ZG", + "atIds": [3], + "title": "Read information about a button", + "atMode": "INTERACTION", + "viewers": [], + "rowNumber": "9", + "scenarios": [ + { + "id": "NjU5NeyIzIjoiWTJFNU5leUl5SWpvaU5UVTFPVGdpZlFUZzVaRyJ9TVhOT", + "atId": 3, + "commandIds": ["CTRL_OPT_F3"] + }, + { + "id": "ZTY2NeyIzIjoiWTJFNU5leUl5SWpvaU5UVTFPVGdpZlFUZzVaRyJ9GM4Nm", + "atId": 3, + "commandIds": ["CTRL_OPT_F4"] + } + ], + "assertions": [ + { + "id": "MzMzMeyIzIjoiWTJFNU5leUl5SWpvaU5UVTFPVGdpZlFUZzVaRyJ92I5Nj", + "text": "Role 'button' is conveyed", + "priority": "MUST" + }, + { + "id": "MTMyZeyIzIjoiWTJFNU5leUl5SWpvaU5UVTFPVGdpZlFUZzVaRyJ9TE3YT", + "text": "Name 'Print Page' is conveyed", + "priority": "MUST" + } + ], + "renderedUrls": { + "3": "/aria-at/836fb2a997f5b2844035b8c934f8fda9833cd5b2/build/tests/command-button/test-09-read-information-about-button-interaction-voiceover_macos.collected.html" + }, + "renderableContent": { + "3": { + "info": { + "task": "read information about button", + "title": "Read information about a button", + "testId": 9, + "references": [ + { + "refId": "example", + "value": "https://w3c.github.io/aria-practices/examples/button/button.html" + }, + { + "refId": "button", + "value": "https://w3c.github.io/aria/#button" + } + ] + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": "voiceover_macos", + "name": "VoiceOver for macOS" + }, + "mode": "interaction", + "setupScript": { + "name": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "description": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "CTRL_OPT_F3", + "keystroke": "Control+Option+F3", + "keypresses": [ + { + "id": "CTRL_OPT_F3", + "keystroke": "Control+Option+F3" + } + ] + }, + { + "id": "CTRL_OPT_F4", + "keystroke": "Control+Option+F4", + "keypresses": [ + { + "id": "CTRL_OPT_F4", + "keystroke": "Control+Option+F4" + } + ] + } + ], + "assertions": [ + { + "priority": 1, + "expectation": "Role 'button' is conveyed" + }, + { + "priority": 1, + "expectation": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "raw": "With focus on the 'Print Page' button, read information about the button.", + "mode": "Toggle Quick Nav OFF by pressing the Left Arrow and Right Arrow keys at the same time.", + "user": [ + "With focus on the 'Print Page' button, read information about the button." + ] + } + } + } + } +] diff --git a/server/tests/mock-data/aria-util/commandButton_V20231206_V2.json b/server/tests/mock-data/aria-util/commandButton_V20231206_V2.json new file mode 100644 index 000000000..14d8ecafa --- /dev/null +++ b/server/tests/mock-data/aria-util/commandButton_V20231206_V2.json @@ -0,0 +1,1741 @@ +[ + { + "at": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + } + }, + "id": "ODgzMeyIyIjoiNTYyOTgifQGMzOT", + "atIds": [1], + "title": "Navigate forwards to a button", + "viewers": [], + "rawTestId": "navForwardsToButton", + "rowNumber": 5, + "scenarios": [ + { + "id": "MzhjMeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9zkwMG", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["down"] + }, + { + "id": "MjM5MeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9zg4OG", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["b"] + }, + { + "id": "MzI5OeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9GZlOG", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["f"] + }, + { + "id": "M2IyYeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9TJiOD", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["tab"] + }, + { + "id": "NzI1ZeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9mQ3Nj", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["tab"] + } + ], + "assertions": [ + { + "id": "NWIwYeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9TI2Yz", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "ZTg3ZeyIzIjoiT0Rnek1leUl5SWpvaU5UWXlPVGdpZlFHTXpPVCJ9DFkND", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-05-navForwardsToButton-jaws.collected.html", + "renderableContent": { + "info": { + "title": "Navigate forwards to a button", + "testId": "navForwardsToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 5 + }, + "target": { + "at": { + "key": "jaws", + "raw": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + }, + "assertionTokens": { + "readingMode": "virtual cursor active", + "screenReader": "JAWS", + "interactionMode": "PC cursor active" + }, + "defaultConfigurationInstructionsHTML": "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "JAWS", + "settings": "virtualCursor_pcCursor" + }, + "setupScript": { + "name": "setFocusBeforeButton", + "script": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "scriptDescription": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "down", + "settings": "virtualCursor", + "keystroke": "Down Arrow", + "keypresses": [{ "id": "down", "keystroke": "Down Arrow" }], + "presentationNumber": 1, + "assertionExceptions": [] + }, + { + "id": "b", + "settings": "virtualCursor", + "keystroke": "b", + "keypresses": [{ "id": "b", "keystroke": "b" }], + "presentationNumber": 1.1, + "assertionExceptions": [] + }, + { + "id": "f", + "settings": "virtualCursor", + "keystroke": "f", + "keypresses": [{ "id": "f", "keystroke": "f" }], + "presentationNumber": 1.2, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "virtualCursor", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 1.3, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "pcCursor", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 3, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "pcCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ], + "virtualCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + }, + "instructions": "Starting at the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + } + }, + "id": "NGVjNeyIyIjoiNTYyOTgifQDE4OD", + "atIds": [2], + "title": "Navigate forwards to a button", + "viewers": [], + "rawTestId": "navForwardsToButton", + "rowNumber": 5, + "scenarios": [ + { + "id": "NTc2ZeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ9mZhZD", + "atId": 2, + "settings": "browseMode", + "commandIds": ["down"] + }, + { + "id": "ZmQwZeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ9WY5NW", + "atId": 2, + "settings": "browseMode", + "commandIds": ["b"] + }, + { + "id": "N2ZkMeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ9WJkMD", + "atId": 2, + "settings": "browseMode", + "commandIds": ["f"] + }, + { + "id": "MWI3MeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ9jk4Zm", + "atId": 2, + "settings": "browseMode", + "commandIds": ["tab"] + }, + { + "id": "MWEzMeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ9TQ4YW", + "atId": 2, + "settings": "focusMode", + "commandIds": ["tab"] + } + ], + "assertions": [ + { + "id": "NjdmZeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ9TVhZj", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "ZmQ3YeyIzIjoiTkdWak5leUl5SWpvaU5UWXlPVGdpZlFERTRPRCJ92Q4OG", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-05-navForwardsToButton-nvda.collected.html", + "renderableContent": { + "info": { + "title": "Navigate forwards to a button", + "testId": "navForwardsToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 5 + }, + "target": { + "at": { + "key": "nvda", + "raw": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + }, + "assertionTokens": { + "readingMode": "browse mode", + "screenReader": "NVDA", + "interactionMode": "focus mode" + }, + "defaultConfigurationInstructionsHTML": "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "NVDA", + "settings": "browseMode_focusMode" + }, + "setupScript": { + "name": "setFocusBeforeButton", + "script": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "scriptDescription": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "down", + "settings": "browseMode", + "keystroke": "Down Arrow", + "keypresses": [{ "id": "down", "keystroke": "Down Arrow" }], + "presentationNumber": 1, + "assertionExceptions": [] + }, + { + "id": "b", + "settings": "browseMode", + "keystroke": "b", + "keypresses": [{ "id": "b", "keystroke": "b" }], + "presentationNumber": 1.1, + "assertionExceptions": [] + }, + { + "id": "f", + "settings": "browseMode", + "keystroke": "f", + "keypresses": [{ "id": "f", "keystroke": "f" }], + "presentationNumber": 1.2, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "browseMode", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 1.3, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "focusMode", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 3, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "focusMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ], + "browseMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + }, + "instructions": "Starting at the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + } + } + }, + "id": "ODM5MeyIyIjoiNTYyOTgifQDc5MG", + "atIds": [3], + "title": "Navigate forwards to a button", + "viewers": [], + "rawTestId": "navForwardsToButton", + "rowNumber": 5, + "scenarios": [ + { + "id": "NWNhNeyIzIjoiT0RNNU1leUl5SWpvaU5UWXlPVGdpZlFEYzVNRyJ92M1ZD", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+right"] + }, + { + "id": "ODFiNeyIzIjoiT0RNNU1leUl5SWpvaU5UWXlPVGdpZlFEYzVNRyJ9WEyZD", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["tab"] + }, + { + "id": "ZWM1NeyIzIjoiT0RNNU1leUl5SWpvaU5UWXlPVGdpZlFEYzVNRyJ9mZkZT", + "atId": 3, + "settings": "quickNavOn", + "commandIds": ["j"] + } + ], + "assertions": [ + { + "id": "MjBjNeyIzIjoiT0RNNU1leUl5SWpvaU5UWXlPVGdpZlFEYzVNRyJ9Dg3YT", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "OTA1NeyIzIjoiT0RNNU1leUl5SWpvaU5UWXlPVGdpZlFEYzVNRyJ9jU2MT", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-05-navForwardsToButton-voiceover_macos.collected.html", + "renderableContent": { + "info": { + "title": "Navigate forwards to a button", + "testId": "navForwardsToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 5 + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + } + }, + "defaultConfigurationInstructionsHTML": "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "VoiceOver for macOS", + "settings": "defaultMode_quickNavOn" + }, + "setupScript": { + "name": "setFocusBeforeButton", + "script": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "scriptDescription": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "ctrl+opt+right", + "settings": "defaultMode", + "keystroke": "Control+Option+Right Arrow", + "keypresses": [ + { + "id": "ctrl+opt+right", + "keystroke": "Control+Option+Right Arrow" + } + ], + "presentationNumber": 5, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "defaultMode", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 5.1, + "assertionExceptions": [] + }, + { + "id": "j", + "settings": "quickNavOn", + "keystroke": "j", + "keypresses": [{ "id": "j", "keystroke": "j" }], + "presentationNumber": 5.2, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "quickNavOn": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ], + "defaultMode": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + ] + }, + "instructions": "Starting at the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + } + }, + "id": "Y2Q3MeyIyIjoiNTYyOTgifQGI0Mm", + "atIds": [1], + "title": "Navigate backwards to a button", + "viewers": [], + "rawTestId": "navBackToButton", + "rowNumber": 6, + "scenarios": [ + { + "id": "NWI1YeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9WI2YW", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["up"] + }, + { + "id": "N2RiNeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9Tg0OD", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["shift+b"] + }, + { + "id": "MGVhMeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9DI0NW", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["shift+f"] + }, + { + "id": "MzUxNeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9TM3OT", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["shift+tab"] + }, + { + "id": "ZWExNeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9jY5MG", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["shift+tab"] + } + ], + "assertions": [ + { + "id": "ZTRlNeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9TU1OG", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "N2I1MeyIzIjoiWTJRM01leUl5SWpvaU5UWXlPVGdpZlFHSTBNbSJ9jA0YW", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-06-navBackToButton-jaws.collected.html", + "renderableContent": { + "info": { + "title": "Navigate backwards to a button", + "testId": "navBackToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 6 + }, + "target": { + "at": { + "key": "jaws", + "raw": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + }, + "assertionTokens": { + "readingMode": "virtual cursor active", + "screenReader": "JAWS", + "interactionMode": "PC cursor active" + }, + "defaultConfigurationInstructionsHTML": "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "JAWS", + "settings": "virtualCursor_pcCursor" + }, + "setupScript": { + "name": "setFocusAfterButton", + "script": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "scriptDescription": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "up", + "settings": "virtualCursor", + "keystroke": "Up Arrow", + "keypresses": [{ "id": "up", "keystroke": "Up Arrow" }], + "presentationNumber": 2, + "assertionExceptions": [] + }, + { + "id": "shift+b", + "settings": "virtualCursor", + "keystroke": "Shift+b", + "keypresses": [{ "id": "shift+b", "keystroke": "Shift+b" }], + "presentationNumber": 2.1, + "assertionExceptions": [] + }, + { + "id": "shift+f", + "settings": "virtualCursor", + "keystroke": "Shift+f", + "keypresses": [{ "id": "shift+f", "keystroke": "Shift+f" }], + "presentationNumber": 2.2, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "virtualCursor", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 2.3, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "pcCursor", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 4, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "pcCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ], + "virtualCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + }, + "instructions": "Starting at the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + } + }, + "id": "ZjIxYeyIyIjoiNTYyOTgifQTI3Mj", + "atIds": [2], + "title": "Navigate backwards to a button", + "viewers": [], + "rawTestId": "navBackToButton", + "rowNumber": 6, + "scenarios": [ + { + "id": "ZGJlNeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9jRiMz", + "atId": 2, + "settings": "browseMode", + "commandIds": ["up"] + }, + { + "id": "MWZkNeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9zZiMz", + "atId": 2, + "settings": "browseMode", + "commandIds": ["shift+b"] + }, + { + "id": "ZDVmZeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9GY4Yj", + "atId": 2, + "settings": "browseMode", + "commandIds": ["shift+f"] + }, + { + "id": "ZTc2YeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9jYxY2", + "atId": 2, + "settings": "browseMode", + "commandIds": ["shift+tab"] + }, + { + "id": "Y2UyYeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9jJlOD", + "atId": 2, + "settings": "focusMode", + "commandIds": ["shift+tab"] + } + ], + "assertions": [ + { + "id": "MDE1ZeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9jU5YW", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "OTdjNeyIzIjoiWmpJeFlleUl5SWpvaU5UWXlPVGdpZlFUSTNNaiJ9WMwND", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-06-navBackToButton-nvda.collected.html", + "renderableContent": { + "info": { + "title": "Navigate backwards to a button", + "testId": "navBackToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 6 + }, + "target": { + "at": { + "key": "nvda", + "raw": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + }, + "assertionTokens": { + "readingMode": "browse mode", + "screenReader": "NVDA", + "interactionMode": "focus mode" + }, + "defaultConfigurationInstructionsHTML": "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "NVDA", + "settings": "browseMode_focusMode" + }, + "setupScript": { + "name": "setFocusAfterButton", + "script": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "scriptDescription": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "up", + "settings": "browseMode", + "keystroke": "Up Arrow", + "keypresses": [{ "id": "up", "keystroke": "Up Arrow" }], + "presentationNumber": 2, + "assertionExceptions": [] + }, + { + "id": "shift+b", + "settings": "browseMode", + "keystroke": "Shift+b", + "keypresses": [{ "id": "shift+b", "keystroke": "Shift+b" }], + "presentationNumber": 2.1, + "assertionExceptions": [] + }, + { + "id": "shift+f", + "settings": "browseMode", + "keystroke": "Shift+f", + "keypresses": [{ "id": "shift+f", "keystroke": "Shift+f" }], + "presentationNumber": 2.2, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "browseMode", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 2.3, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "focusMode", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 4, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "focusMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ], + "browseMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + }, + "instructions": "Starting at the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + } + } + }, + "id": "MzBjNeyIyIjoiNTYyOTgifQ2IyOT", + "atIds": [3], + "title": "Navigate backwards to a button", + "viewers": [], + "rawTestId": "navBackToButton", + "rowNumber": 6, + "scenarios": [ + { + "id": "YmMyNeyIzIjoiTXpCak5leUl5SWpvaU5UWXlPVGdpZlEySXlPVCJ9TY2ZT", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+left"] + }, + { + "id": "OTE1ZeyIzIjoiTXpCak5leUl5SWpvaU5UWXlPVGdpZlEySXlPVCJ9GYwNW", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["shift+tab"] + }, + { + "id": "ZWIzMeyIzIjoiTXpCak5leUl5SWpvaU5UWXlPVGdpZlEySXlPVCJ9Dk1Mz", + "atId": 3, + "settings": "quickNavOn", + "commandIds": ["shift+j"] + } + ], + "assertions": [ + { + "id": "ZGU1MeyIzIjoiTXpCak5leUl5SWpvaU5UWXlPVGdpZlEySXlPVCJ9zk3Zm", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "ZDM4ZeyIzIjoiTXpCak5leUl5SWpvaU5UWXlPVGdpZlEySXlPVCJ9DYxNm", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-06-navBackToButton-voiceover_macos.collected.html", + "renderableContent": { + "info": { + "title": "Navigate backwards to a button", + "testId": "navBackToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 6 + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + } + }, + "defaultConfigurationInstructionsHTML": "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "VoiceOver for macOS", + "settings": "defaultMode_quickNavOn" + }, + "setupScript": { + "name": "setFocusAfterButton", + "script": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "scriptDescription": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "ctrl+opt+left", + "settings": "defaultMode", + "keystroke": "Control+Option+Left Arrow", + "keypresses": [ + { + "id": "ctrl+opt+left", + "keystroke": "Control+Option+Left Arrow" + } + ], + "presentationNumber": 6, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "defaultMode", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 6.1, + "assertionExceptions": [] + }, + { + "id": "shift+j", + "settings": "quickNavOn", + "keystroke": "Shift+j", + "keypresses": [{ "id": "shift+j", "keystroke": "Shift+j" }], + "presentationNumber": 6.2, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "quickNavOn": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ], + "defaultMode": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + ] + }, + "instructions": "Starting at the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + } + }, + "id": "ZGM1NeyIyIjoiNTYyOTgifQjQ5NT", + "atIds": [1], + "title": "Request information about a button", + "viewers": [], + "rawTestId": "reqInfoAboutButton", + "rowNumber": 9, + "scenarios": [ + { + "id": "ZTRjNeyIzIjoiWkdNMU5leUl5SWpvaU5UWXlPVGdpZlFqUTVOVCJ9DgxOG", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["ins+tab"] + }, + { + "id": "ZjM2YeyIzIjoiWkdNMU5leUl5SWpvaU5UWXlPVGdpZlFqUTVOVCJ9jZlND", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["ins+up"] + }, + { + "id": "MTdjMeyIzIjoiWkdNMU5leUl5SWpvaU5UWXlPVGdpZlFqUTVOVCJ9zVmNT", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["ins+tab"] + }, + { + "id": "YTk1MeyIzIjoiWkdNMU5leUl5SWpvaU5UWXlPVGdpZlFqUTVOVCJ9WJiOW", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["ins+up"] + } + ], + "assertions": [ + { + "id": "MDEzYeyIzIjoiWkdNMU5leUl5SWpvaU5UWXlPVGdpZlFqUTVOVCJ9TRhMW", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "ZTNmZeyIzIjoiWkdNMU5leUl5SWpvaU5UWXlPVGdpZlFqUTVOVCJ9WM1NW", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-09-reqInfoAboutButton-jaws.collected.html", + "renderableContent": { + "info": { + "title": "Request information about a button", + "testId": "reqInfoAboutButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 9 + }, + "target": { + "at": { + "key": "jaws", + "raw": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + }, + "assertionTokens": { + "readingMode": "virtual cursor active", + "screenReader": "JAWS", + "interactionMode": "PC cursor active" + }, + "defaultConfigurationInstructionsHTML": "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "JAWS", + "settings": "virtualCursor_pcCursor" + }, + "setupScript": { + "name": "setFocusOnButton", + "script": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "scriptDescription": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "ins+tab", + "settings": "virtualCursor", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 7, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "virtualCursor", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 7.1, + "assertionExceptions": [] + }, + { + "id": "ins+tab", + "settings": "pcCursor", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 8, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "pcCursor", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 8.1, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "pcCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ], + "virtualCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + }, + "instructions": "Starting at the 'Print Page' button, read information about the button." + } + } + }, + { + "at": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + } + }, + "id": "MzE1MeyIyIjoiNTYyOTgifQTRlN2", + "atIds": [2], + "title": "Request information about a button", + "viewers": [], + "rawTestId": "reqInfoAboutButton", + "rowNumber": 9, + "scenarios": [ + { + "id": "YzdjMeyIzIjoiTXpFMU1leUl5SWpvaU5UWXlPVGdpZlFUUmxOMiJ9GY3ZG", + "atId": 2, + "settings": "browseMode", + "commandIds": ["ins+tab"] + }, + { + "id": "YWU3MeyIzIjoiTXpFMU1leUl5SWpvaU5UWXlPVGdpZlFUUmxOMiJ9DM4NG", + "atId": 2, + "settings": "browseMode", + "commandIds": ["ins+up"] + }, + { + "id": "NjcwZeyIzIjoiTXpFMU1leUl5SWpvaU5UWXlPVGdpZlFUUmxOMiJ9DAzZD", + "atId": 2, + "settings": "focusMode", + "commandIds": ["ins+tab"] + }, + { + "id": "NjEyZeyIzIjoiTXpFMU1leUl5SWpvaU5UWXlPVGdpZlFUUmxOMiJ9TRiMD", + "atId": 2, + "settings": "focusMode", + "commandIds": ["ins+up"] + } + ], + "assertions": [ + { + "id": "Njk4OeyIzIjoiTXpFMU1leUl5SWpvaU5UWXlPVGdpZlFUUmxOMiJ9TYxOT", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "ZTczMeyIzIjoiTXpFMU1leUl5SWpvaU5UWXlPVGdpZlFUUmxOMiJ9TdlZW", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-09-reqInfoAboutButton-nvda.collected.html", + "renderableContent": { + "info": { + "title": "Request information about a button", + "testId": "reqInfoAboutButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 9 + }, + "target": { + "at": { + "key": "nvda", + "raw": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + }, + "assertionTokens": { + "readingMode": "browse mode", + "screenReader": "NVDA", + "interactionMode": "focus mode" + }, + "defaultConfigurationInstructionsHTML": "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "NVDA", + "settings": "browseMode_focusMode" + }, + "setupScript": { + "name": "setFocusOnButton", + "script": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "scriptDescription": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "ins+tab", + "settings": "browseMode", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 7, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "browseMode", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 7.1, + "assertionExceptions": [] + }, + { + "id": "ins+tab", + "settings": "focusMode", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 8, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "focusMode", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 8.1, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "focusMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ], + "browseMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + }, + "instructions": "Starting at the 'Print Page' button, read information about the button." + } + } + }, + { + "at": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + } + } + }, + "id": "MGQ3MeyIyIjoiNTYyOTgifQzRmYT", + "atIds": [3], + "title": "Request information about a button", + "viewers": [], + "rawTestId": "reqInfoAboutButton", + "rowNumber": 9, + "scenarios": [ + { + "id": "NmQ0NeyIzIjoiTUdRM01leUl5SWpvaU5UWXlPVGdpZlF6Um1ZVCJ9DNmND", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+f3"] + }, + { + "id": "OTg5MeyIzIjoiTUdRM01leUl5SWpvaU5UWXlPVGdpZlF6Um1ZVCJ9DhlMD", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+f4"] + } + ], + "assertions": [ + { + "id": "ZjhlZeyIzIjoiTUdRM01leUl5SWpvaU5UWXlPVGdpZlF6Um1ZVCJ9GViMD", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "NTM5MeyIzIjoiTUdRM01leUl5SWpvaU5UWXlPVGdpZlF6Um1ZVCJ9zAxZW", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7/build/tests/command-button/test-09-reqInfoAboutButton-voiceover_macos.collected.html", + "renderableContent": { + "info": { + "title": "Request information about a button", + "testId": "reqInfoAboutButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 9 + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + } + }, + "defaultConfigurationInstructionsHTML": "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "VoiceOver for macOS", + "settings": "defaultMode" + }, + "setupScript": { + "name": "setFocusOnButton", + "script": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "scriptDescription": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "ctrl+opt+f3", + "settings": "defaultMode", + "keystroke": "Control+Option+F3", + "keypresses": [ + { + "id": "ctrl+opt+f3", + "keystroke": "Control+Option+F3" + } + ], + "presentationNumber": 9, + "assertionExceptions": [] + }, + { + "id": "ctrl+opt+f4", + "settings": "defaultMode", + "keystroke": "Control+Option+F4", + "keypresses": [ + { + "id": "ctrl+opt+f4", + "keystroke": "Control+Option+F4" + } + ], + "presentationNumber": 9.1, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "defaultMode": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + ] + }, + "instructions": "Starting at the 'Print Page' button, read information about the button." + } + } + } +] diff --git a/server/tests/mock-data/aria-util/commandButton_V20231213_V2.json b/server/tests/mock-data/aria-util/commandButton_V20231213_V2.json new file mode 100644 index 000000000..ba1f2f9ea --- /dev/null +++ b/server/tests/mock-data/aria-util/commandButton_V20231213_V2.json @@ -0,0 +1,1909 @@ +[ + { + "at": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + } + }, + "id": "ZTQzMeyIyIjoiNTYzNjgifQDk1ZW", + "atIds": [1], + "title": "Navigate forwards to a button", + "viewers": [], + "rawTestId": "navForwardsToButton", + "rowNumber": 5, + "scenarios": [ + { + "id": "NmFiMeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9jYxND", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["down"] + }, + { + "id": "ZjA0YeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9jZkOD", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["b"] + }, + { + "id": "NjU5NeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9jdhNW", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["f"] + }, + { + "id": "ZTIyNeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9DgwZj", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["tab"] + }, + { + "id": "MTBkZeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9mMwOW", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["tab"] + } + ], + "assertions": [ + { + "id": "Yzc5YeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9jcyZT", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "YWU2ZeyIzIjoiWlRRek1leUl5SWpvaU5UWXpOamdpZlFEazFaVyJ9TQ4YW", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-05-navForwardsToButton-jaws.collected.html", + "renderableContent": { + "info": { + "title": "Navigate forwards to a button", + "testId": "navForwardsToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 5 + }, + "target": { + "at": { + "key": "jaws", + "raw": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + }, + "assertionTokens": { + "readingMode": "virtual cursor active", + "screenReader": "JAWS", + "interactionMode": "PC cursor active" + }, + "defaultConfigurationInstructionsHTML": "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "JAWS", + "settings": "virtualCursor_pcCursor" + }, + "setupScript": { + "name": "setFocusBeforeButton", + "script": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "scriptDescription": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "down", + "settings": "virtualCursor", + "keystroke": "Down Arrow", + "keypresses": [{ "id": "down", "keystroke": "Down Arrow" }], + "presentationNumber": 1, + "assertionExceptions": [] + }, + { + "id": "b", + "settings": "virtualCursor", + "keystroke": "b", + "keypresses": [{ "id": "b", "keystroke": "b" }], + "presentationNumber": 1.1, + "assertionExceptions": [] + }, + { + "id": "f", + "settings": "virtualCursor", + "keystroke": "f", + "keypresses": [{ "id": "f", "keystroke": "f" }], + "presentationNumber": 1.2, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "virtualCursor", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 1.3, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "pcCursor", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 3, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "pcCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ], + "virtualCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + }, + "instructions": "Starting at the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + } + }, + "id": "YzNjOeyIyIjoiNTYzNjgifQTNlMD", + "atIds": [2], + "title": "Navigate forwards to a button", + "viewers": [], + "rawTestId": "navForwardsToButton", + "rowNumber": 5, + "scenarios": [ + { + "id": "YWJlYeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9Tc1MD", + "atId": 2, + "settings": "browseMode", + "commandIds": ["down"] + }, + { + "id": "OThhOeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9DRlNz", + "atId": 2, + "settings": "browseMode", + "commandIds": ["b"] + }, + { + "id": "YWNmNeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9jA2ZT", + "atId": 2, + "settings": "browseMode", + "commandIds": ["f"] + }, + { + "id": "OTljOeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9GU1Mj", + "atId": 2, + "settings": "browseMode", + "commandIds": ["tab"] + }, + { + "id": "MGZiYeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9WMyNm", + "atId": 2, + "settings": "focusMode", + "commandIds": ["tab"] + } + ], + "assertions": [ + { + "id": "NGUzZeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9mIzN2", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "M2JjOeyIzIjoiWXpOak9leUl5SWpvaU5UWXpOamdpZlFUTmxNRCJ9DYwOT", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-05-navForwardsToButton-nvda.collected.html", + "renderableContent": { + "info": { + "title": "Navigate forwards to a button", + "testId": "navForwardsToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 5 + }, + "target": { + "at": { + "key": "nvda", + "raw": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + }, + "assertionTokens": { + "readingMode": "browse mode", + "screenReader": "NVDA", + "interactionMode": "focus mode" + }, + "defaultConfigurationInstructionsHTML": "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "NVDA", + "settings": "browseMode_focusMode" + }, + "setupScript": { + "name": "setFocusBeforeButton", + "script": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "scriptDescription": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "down", + "settings": "browseMode", + "keystroke": "Down Arrow", + "keypresses": [{ "id": "down", "keystroke": "Down Arrow" }], + "presentationNumber": 1, + "assertionExceptions": [] + }, + { + "id": "b", + "settings": "browseMode", + "keystroke": "b", + "keypresses": [{ "id": "b", "keystroke": "b" }], + "presentationNumber": 1.1, + "assertionExceptions": [] + }, + { + "id": "f", + "settings": "browseMode", + "keystroke": "f", + "keypresses": [{ "id": "f", "keystroke": "f" }], + "presentationNumber": 1.2, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "browseMode", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 1.3, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "focusMode", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 3, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "focusMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ], + "browseMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + }, + "instructions": "Starting at the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] + } + } + }, + "id": "ZDU1MeyIyIjoiNTYzNjgifQ2FjYz", + "atIds": [3], + "title": "Navigate forwards to a button", + "viewers": [], + "rawTestId": "navForwardsToButton", + "rowNumber": 5, + "scenarios": [ + { + "id": "ODk0NeyIzIjoiWkRVMU1leUl5SWpvaU5UWXpOamdpZlEyRmpZeiJ9mI2Mj", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+right"] + }, + { + "id": "NWQyMeyIzIjoiWkRVMU1leUl5SWpvaU5UWXpOamdpZlEyRmpZeiJ9mZlMW", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["tab"] + }, + { + "id": "YmU3ZeyIzIjoiWkRVMU1leUl5SWpvaU5UWXpOamdpZlEyRmpZeiJ9jhmNm", + "atId": 3, + "settings": "singleQuickKeyNavOn", + "commandIds": ["j"] + } + ], + "assertions": [ + { + "id": "NGNjMeyIzIjoiWkRVMU1leUl5SWpvaU5UWXpOamdpZlEyRmpZeiJ9DEyM2", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "NzMyYeyIzIjoiWkRVMU1leUl5SWpvaU5UWXpOamdpZlEyRmpZeiJ92VmMD", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-05-navForwardsToButton-voiceover_macos.collected.html", + "renderableContent": { + "info": { + "title": "Navigate forwards to a button", + "testId": "navForwardsToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 5 + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] + } + }, + "defaultConfigurationInstructionsHTML": "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "VoiceOver for macOS", + "settings": "defaultMode_singleQuickKeyNavOn" + }, + "setupScript": { + "name": "setFocusBeforeButton", + "script": "setFocusBeforeButton", + "source": "// sets focus on a link before the button\ntestPageDocument.querySelector('#beforelink').focus();\n", + "jsonpPath": "scripts/setFocusBeforeButton.jsonp.js", + "modulePath": "scripts/setFocusBeforeButton.module.js", + "scriptDescription": "sets focus on a link before the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusBeforeButton.html" + }, + "commands": [ + { + "id": "ctrl+opt+right", + "settings": "defaultMode", + "keystroke": "Control+Option+Right Arrow", + "keypresses": [ + { + "id": "ctrl+opt+right", + "keystroke": "Control+Option+Right Arrow" + } + ], + "presentationNumber": 5, + "assertionExceptions": [] + }, + { + "id": "tab", + "settings": "defaultMode", + "keystroke": "Tab", + "keypresses": [{ "id": "tab", "keystroke": "Tab" }], + "presentationNumber": 5.1, + "assertionExceptions": [] + }, + { + "id": "j", + "settings": "singleQuickKeyNavOn", + "keystroke": "j", + "keypresses": [{ "id": "j", "keystroke": "j" }], + "presentationNumber": 5.2, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "defaultMode": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + ], + "singleQuickKeyNavOn": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "instructions": "Starting at the 'Navigate forwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + } + }, + "id": "MzRiMeyIyIjoiNTYzNjgifQWM5NT", + "atIds": [1], + "title": "Navigate backwards to a button", + "viewers": [], + "rawTestId": "navBackToButton", + "rowNumber": 6, + "scenarios": [ + { + "id": "ODAzYeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9WM0Nj", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["up"] + }, + { + "id": "NDZiNeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9GQ1MT", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["shift+b"] + }, + { + "id": "MTlmNeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9WM3Mz", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["shift+f"] + }, + { + "id": "MTVhMeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9DcyZW", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["shift+tab"] + }, + { + "id": "NDE4ZeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9jkwYW", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["shift+tab"] + } + ], + "assertions": [ + { + "id": "MGI1YeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9jViMD", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "YzViMeyIzIjoiTXpSaU1leUl5SWpvaU5UWXpOamdpZlFXTTVOVCJ9zFkMz", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-06-navBackToButton-jaws.collected.html", + "renderableContent": { + "info": { + "title": "Navigate backwards to a button", + "testId": "navBackToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 6 + }, + "target": { + "at": { + "key": "jaws", + "raw": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + }, + "assertionTokens": { + "readingMode": "virtual cursor active", + "screenReader": "JAWS", + "interactionMode": "PC cursor active" + }, + "defaultConfigurationInstructionsHTML": "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "JAWS", + "settings": "virtualCursor_pcCursor" + }, + "setupScript": { + "name": "setFocusAfterButton", + "script": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "scriptDescription": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "up", + "settings": "virtualCursor", + "keystroke": "Up Arrow", + "keypresses": [{ "id": "up", "keystroke": "Up Arrow" }], + "presentationNumber": 2, + "assertionExceptions": [] + }, + { + "id": "shift+b", + "settings": "virtualCursor", + "keystroke": "Shift+b", + "keypresses": [{ "id": "shift+b", "keystroke": "Shift+b" }], + "presentationNumber": 2.1, + "assertionExceptions": [] + }, + { + "id": "shift+f", + "settings": "virtualCursor", + "keystroke": "Shift+f", + "keypresses": [{ "id": "shift+f", "keystroke": "Shift+f" }], + "presentationNumber": 2.2, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "virtualCursor", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 2.3, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "pcCursor", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 4, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "pcCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ], + "virtualCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + }, + "instructions": "Starting at the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + } + }, + "id": "ZWM3NeyIyIjoiNTYzNjgifQzRhMj", + "atIds": [2], + "title": "Navigate backwards to a button", + "viewers": [], + "rawTestId": "navBackToButton", + "rowNumber": 6, + "scenarios": [ + { + "id": "MTVhZeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9jQwNT", + "atId": 2, + "settings": "browseMode", + "commandIds": ["up"] + }, + { + "id": "NDJkZeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9GY4NT", + "atId": 2, + "settings": "browseMode", + "commandIds": ["shift+b"] + }, + { + "id": "NzI3NeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9WJjMD", + "atId": 2, + "settings": "browseMode", + "commandIds": ["shift+f"] + }, + { + "id": "NjU0OeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9WY4ZT", + "atId": 2, + "settings": "browseMode", + "commandIds": ["shift+tab"] + }, + { + "id": "ZmEwNeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9mNlYT", + "atId": 2, + "settings": "focusMode", + "commandIds": ["shift+tab"] + } + ], + "assertions": [ + { + "id": "YzE4OeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9DkxOG", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "Y2I1OeyIzIjoiWldNM05leUl5SWpvaU5UWXpOamdpZlF6UmhNaiJ9TVjZW", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-06-navBackToButton-nvda.collected.html", + "renderableContent": { + "info": { + "title": "Navigate backwards to a button", + "testId": "navBackToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 6 + }, + "target": { + "at": { + "key": "nvda", + "raw": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + }, + "assertionTokens": { + "readingMode": "browse mode", + "screenReader": "NVDA", + "interactionMode": "focus mode" + }, + "defaultConfigurationInstructionsHTML": "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "NVDA", + "settings": "browseMode_focusMode" + }, + "setupScript": { + "name": "setFocusAfterButton", + "script": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "scriptDescription": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "up", + "settings": "browseMode", + "keystroke": "Up Arrow", + "keypresses": [{ "id": "up", "keystroke": "Up Arrow" }], + "presentationNumber": 2, + "assertionExceptions": [] + }, + { + "id": "shift+b", + "settings": "browseMode", + "keystroke": "Shift+b", + "keypresses": [{ "id": "shift+b", "keystroke": "Shift+b" }], + "presentationNumber": 2.1, + "assertionExceptions": [] + }, + { + "id": "shift+f", + "settings": "browseMode", + "keystroke": "Shift+f", + "keypresses": [{ "id": "shift+f", "keystroke": "Shift+f" }], + "presentationNumber": 2.2, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "browseMode", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 2.3, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "focusMode", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 4, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "focusMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ], + "browseMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + }, + "instructions": "Starting at the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] + } + } + }, + "id": "YWYxMeyIyIjoiNTYzNjgifQjAzZD", + "atIds": [3], + "title": "Navigate backwards to a button", + "viewers": [], + "rawTestId": "navBackToButton", + "rowNumber": 6, + "scenarios": [ + { + "id": "NmVkMeyIzIjoiWVdZeE1leUl5SWpvaU5UWXpOamdpZlFqQXpaRCJ9DhkMT", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+left"] + }, + { + "id": "ZjE5ZeyIzIjoiWVdZeE1leUl5SWpvaU5UWXpOamdpZlFqQXpaRCJ9TEwNG", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["shift+tab"] + }, + { + "id": "NjViYeyIzIjoiWVdZeE1leUl5SWpvaU5UWXpOamdpZlFqQXpaRCJ9TYzYT", + "atId": 3, + "settings": "singleQuickKeyNavOn", + "commandIds": ["shift+j"] + } + ], + "assertions": [ + { + "id": "YzJkZeyIzIjoiWVdZeE1leUl5SWpvaU5UWXpOamdpZlFqQXpaRCJ9mVjNm", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "NTY4NeyIzIjoiWVdZeE1leUl5SWpvaU5UWXpOamdpZlFqQXpaRCJ9GJhMm", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-06-navBackToButton-voiceover_macos.collected.html", + "renderableContent": { + "info": { + "title": "Navigate backwards to a button", + "testId": "navBackToButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 6 + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] + } + }, + "defaultConfigurationInstructionsHTML": "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "VoiceOver for macOS", + "settings": "defaultMode_singleQuickKeyNavOn" + }, + "setupScript": { + "name": "setFocusAfterButton", + "script": "setFocusAfterButton", + "source": "// sets focus on a link after the button\ntestPageDocument.querySelector('#afterlink').focus();\n", + "jsonpPath": "scripts/setFocusAfterButton.jsonp.js", + "modulePath": "scripts/setFocusAfterButton.module.js", + "scriptDescription": "sets focus on a link after the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusAfterButton.html" + }, + "commands": [ + { + "id": "ctrl+opt+left", + "settings": "defaultMode", + "keystroke": "Control+Option+Left Arrow", + "keypresses": [ + { + "id": "ctrl+opt+left", + "keystroke": "Control+Option+Left Arrow" + } + ], + "presentationNumber": 6, + "assertionExceptions": [] + }, + { + "id": "shift+tab", + "settings": "defaultMode", + "keystroke": "Shift+Tab", + "keypresses": [ + { "id": "shift+tab", "keystroke": "Shift+Tab" } + ], + "presentationNumber": 6.1, + "assertionExceptions": [] + }, + { + "id": "shift+j", + "settings": "singleQuickKeyNavOn", + "keystroke": "Shift+j", + "keypresses": [{ "id": "shift+j", "keystroke": "Shift+j" }], + "presentationNumber": 6.2, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "defaultMode": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + ], + "singleQuickKeyNavOn": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "instructions": "Starting at the 'Navigate backwards from here' link, navigate to the 'Print Page' button." + } + } + }, + { + "at": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + } + }, + "id": "MGNkZeyIyIjoiNTYzNjgifQDZmZW", + "atIds": [1], + "title": "Request information about a button", + "viewers": [], + "rawTestId": "reqInfoAboutButton", + "rowNumber": 9, + "scenarios": [ + { + "id": "NDJhZeyIzIjoiTUdOa1pleUl5SWpvaU5UWXpOamdpZlFEWm1aVyJ9jA1ND", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["ins+tab"] + }, + { + "id": "NzExOeyIzIjoiTUdOa1pleUl5SWpvaU5UWXpOamdpZlFEWm1aVyJ9WY0ZG", + "atId": 1, + "settings": "virtualCursor", + "commandIds": ["ins+up"] + }, + { + "id": "ODFlMeyIzIjoiTUdOa1pleUl5SWpvaU5UWXpOamdpZlFEWm1aVyJ9jY4Nj", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["ins+tab"] + }, + { + "id": "ZDI5NeyIzIjoiTUdOa1pleUl5SWpvaU5UWXpOamdpZlFEWm1aVyJ9GRlNj", + "atId": 1, + "settings": "pcCursor", + "commandIds": ["ins+up"] + } + ], + "assertions": [ + { + "id": "NzA0OeyIzIjoiTUdOa1pleUl5SWpvaU5UWXpOamdpZlFEWm1aVyJ9DEzNW", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "ZTY4OeyIzIjoiTUdOa1pleUl5SWpvaU5UWXpOamdpZlFEWm1aVyJ9WM2Yz", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-09-reqInfoAboutButton-jaws.collected.html", + "renderableContent": { + "info": { + "title": "Request information about a button", + "testId": "reqInfoAboutButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 9 + }, + "target": { + "at": { + "key": "jaws", + "raw": { + "key": "jaws", + "name": "JAWS", + "settings": { + "pcCursor": { + "screenText": "PC cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ] + }, + "virtualCursor": { + "screenText": "virtual cursor active", + "instructions": [ + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + } + }, + "assertionTokens": { + "readingMode": "virtual cursor active", + "screenReader": "JAWS", + "interactionMode": "PC cursor active" + }, + "defaultConfigurationInstructionsHTML": "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "JAWS", + "settings": "virtualCursor_pcCursor" + }, + "setupScript": { + "name": "setFocusOnButton", + "script": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "scriptDescription": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "ins+tab", + "settings": "virtualCursor", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 7, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "virtualCursor", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 7.1, + "assertionExceptions": [] + }, + { + "id": "ins+tab", + "settings": "pcCursor", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 8, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "pcCursor", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 8.1, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "pcCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the virtual cursor is active, press <kbd>Insert</kbd>+<kbd>z</kbd> to disable the virtual cursor." + ], + "virtualCursor": [ + "Configure JAWS with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Alt</kbd>+<kbd>Delete</kbd> to determine which cursor is active.", + "If the PC cursor is active, press <kbd>Escape</kbd> to activate the virtual cursor." + ] + }, + "instructions": "Starting at the 'Print Page' button, read information about the button." + } + } + }, + { + "at": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + } + }, + "id": "YTk1YeyIyIjoiNTYzNjgifQmI1OT", + "atIds": [2], + "title": "Request information about a button", + "viewers": [], + "rawTestId": "reqInfoAboutButton", + "rowNumber": 9, + "scenarios": [ + { + "id": "YjdmOeyIzIjoiWVRrMVlleUl5SWpvaU5UWXpOamdpZlFtSTFPVCJ9Tk5ZD", + "atId": 2, + "settings": "browseMode", + "commandIds": ["ins+tab"] + }, + { + "id": "ZjFkMeyIzIjoiWVRrMVlleUl5SWpvaU5UWXpOamdpZlFtSTFPVCJ9mY1Ym", + "atId": 2, + "settings": "browseMode", + "commandIds": ["ins+up"] + }, + { + "id": "OTMxNeyIzIjoiWVRrMVlleUl5SWpvaU5UWXpOamdpZlFtSTFPVCJ9zMxMz", + "atId": 2, + "settings": "focusMode", + "commandIds": ["ins+tab"] + }, + { + "id": "YTNmNeyIzIjoiWVRrMVlleUl5SWpvaU5UWXpOamdpZlFtSTFPVCJ9mYyNT", + "atId": 2, + "settings": "focusMode", + "commandIds": ["ins+up"] + } + ], + "assertions": [ + { + "id": "NTU3NeyIzIjoiWVRrMVlleUl5SWpvaU5UWXpOamdpZlFtSTFPVCJ9mJhN2", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "OWVmNeyIzIjoiWVRrMVlleUl5SWpvaU5UWXpOamdpZlFtSTFPVCJ9GJmMj", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-09-reqInfoAboutButton-nvda.collected.html", + "renderableContent": { + "info": { + "title": "Request information about a button", + "testId": "reqInfoAboutButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 9 + }, + "target": { + "at": { + "key": "nvda", + "raw": { + "key": "nvda", + "name": "NVDA", + "settings": { + "focusMode": { + "screenText": "focus mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ] + }, + "browseMode": { + "screenText": "browse mode on", + "instructions": [ + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + } + }, + "assertionTokens": { + "readingMode": "browse mode", + "screenReader": "NVDA", + "interactionMode": "focus mode" + }, + "defaultConfigurationInstructionsHTML": "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "NVDA", + "settings": "browseMode_focusMode" + }, + "setupScript": { + "name": "setFocusOnButton", + "script": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "scriptDescription": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "ins+tab", + "settings": "browseMode", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 7, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "browseMode", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 7.1, + "assertionExceptions": [] + }, + { + "id": "ins+tab", + "settings": "focusMode", + "keystroke": "Insert+Tab", + "keypresses": [ + { "id": "ins+tab", "keystroke": "Insert+Tab" } + ], + "presentationNumber": 8, + "assertionExceptions": [] + }, + { + "id": "ins+up", + "settings": "focusMode", + "keystroke": "Insert+Up Arrow", + "keypresses": [ + { "id": "ins+up", "keystroke": "Insert+Up Arrow" } + ], + "presentationNumber": 8.1, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "focusMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the browse mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn focus mode back on." + ], + "browseMode": [ + "Configure NVDA with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>.", + "Press <kbd>Insert</kbd>+<kbd>Space</kbd>.", + "If NVDA made the focus mode sound, press <kbd>Insert</kbd>+<kbd>Space</kbd> again to turn browse mode back on." + ] + }, + "instructions": "Starting at the 'Print Page' button, read information about the button." + } + } + }, + { + "at": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] + } + } + }, + "id": "NTNmMeyIyIjoiNTYzNjgifQWQwNz", + "atIds": [3], + "title": "Request information about a button", + "viewers": [], + "rawTestId": "reqInfoAboutButton", + "rowNumber": 9, + "scenarios": [ + { + "id": "Yzg2MeyIzIjoiTlRObU1leUl5SWpvaU5UWXpOamdpZlFXUXdOeiJ9jE3Nz", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+f3"] + }, + { + "id": "YjRkNeyIzIjoiTlRObU1leUl5SWpvaU5UWXpOamdpZlFXUXdOeiJ9TUwYz", + "atId": 3, + "settings": "defaultMode", + "commandIds": ["ctrl+opt+f4"] + } + ], + "assertions": [ + { + "id": "ZDU4MeyIzIjoiTlRObU1leUl5SWpvaU5UWXpOamdpZlFXUXdOeiJ9mQzNm", + "priority": "MUST", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "id": "YTU4YeyIzIjoiTlRObU1leUl5SWpvaU5UWXpOamdpZlFXUXdOeiJ9WQ5M2", + "priority": "MUST", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "renderedUrl": "/aria-at/565a87b4111acebdb883d187b581e82c42a73844/build/tests/command-button/test-09-reqInfoAboutButton-voiceover_macos.collected.html", + "renderableContent": { + "info": { + "title": "Request information about a button", + "testId": "reqInfoAboutButton", + "references": [ + { + "type": "metadata", + "refId": "example", + "value": "https://www.w3.org/WAI/ARIA/apg/patterns/button/examples/button/", + "linkText": "APG Example: Button" + } + ], + "presentationNumber": 9 + }, + "target": { + "at": { + "key": "voiceover_macos", + "raw": { + "key": "voiceover_macos", + "name": "VoiceOver for macOS", + "settings": { + "quickNavOn": { + "screenText": "quick nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "quickNavOff": { + "screenText": "quick nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'quick nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "arrowQuickKeyNavOn": { + "screenText": "arrow quick key nav on", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav off', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back on." + ] + }, + "arrowQuickKeyNavOff": { + "screenText": "arrow quick key nav off", + "instructions": [ + "Simultaneously press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd>.", + "If VoiceOver said 'arrow quick key nav on', press <kbd>Left Arrow</kbd> and <kbd>Right Arrow</kbd> again to turn it back off." + ] + }, + "singleQuickKeyNavOn": { + "screenText": "single quick key nav on", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav off', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back on." + ] + }, + "singleQuickKeyNavOff": { + "screenText": "single quick key nav off", + "instructions": [ + "Press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd>.", + "If VoiceOver said 'single quick key nav on', press <kbd>Control</kbd>+<kbd>Option</kbd>+<kbd>q</kbd> again to turn it back off." + ] + } + }, + "defaultConfigurationInstructionsHTML": "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + }, + "name": "VoiceOver for macOS", + "settings": "defaultMode" + }, + "setupScript": { + "name": "setFocusOnButton", + "script": "setFocusOnButton", + "source": "// sets focus on the button\ntestPageDocument.querySelector('#action').focus();\n", + "jsonpPath": "scripts/setFocusOnButton.jsonp.js", + "modulePath": "scripts/setFocusOnButton.module.js", + "scriptDescription": "sets focus on the button" + }, + "referencePage": "reference/2022-4-8_124112/button.setFocusOnButton.html" + }, + "commands": [ + { + "id": "ctrl+opt+f3", + "settings": "defaultMode", + "keystroke": "Control+Option+F3", + "keypresses": [ + { + "id": "ctrl+opt+f3", + "keystroke": "Control+Option+F3" + } + ], + "presentationNumber": 9, + "assertionExceptions": [] + }, + { + "id": "ctrl+opt+f4", + "settings": "defaultMode", + "keystroke": "Control+Option+F4", + "keypresses": [ + { + "id": "ctrl+opt+f4", + "keystroke": "Control+Option+F4" + } + ], + "presentationNumber": 9.1, + "assertionExceptions": [] + } + ], + "assertions": [ + { + "refIds": "", + "priority": 1, + "assertionId": "roleButton", + "assertionPhrase": "convey role 'button'", + "assertionStatement": "Role 'button' is conveyed" + }, + { + "refIds": "", + "priority": 1, + "assertionId": "namePrintPage", + "assertionPhrase": "convey name 'Print Page'", + "assertionStatement": "Name 'Print Page' is conveyed" + } + ], + "instructions": { + "mode": { + "defaultMode": [ + "Configure VoiceOver with default settings. For help, read <a href="https://github.com/w3c/aria-at/wiki/Configuring-Screen-Readers-for-Testing">Configuring Screen Readers for Testing</a>." + ] + }, + "instructions": "Starting at the 'Print Page' button, read information about the button." + } + } + } +] diff --git a/server/util/aria.js b/server/util/aria.js index 0cf123afe..e39696138 100644 --- a/server/util/aria.js +++ b/server/util/aria.js @@ -8,7 +8,14 @@ const evaluateAtNameKey = atName => { }; const testWithNoIds = test => ({ - ...omit(test, ['id', 'renderedUrls', 'viewers']), + ...omit(test, [ + 'id', + 'at', + 'renderedUrls', + 'renderedUrl', + 'renderableContent.target.at.raw', + 'viewers' + ]), assertions: test.assertions.map(assertion => omit(assertion, ['id'])), scenarios: test.scenarios.map(scenario => omit(scenario, ['id'])) }); diff --git a/server/util/aria.test.js b/server/util/aria.test.js index 5a86f9d6e..def532207 100644 --- a/server/util/aria.test.js +++ b/server/util/aria.test.js @@ -6,8 +6,12 @@ const singleTestWithoutIds = require('../tests/mock-data/aria-util/singleTestWit const testsWithInstructionsSayingEnsureA = require('../tests/mock-data/aria-util/testsWithInstructionsSayingEnsureA.json'); const testsWithInstructionsSayingInsureA = require('../tests/mock-data/aria-util/testsWithInstructionsSayingInsureA.json'); const testsWithInstructionsSayingInsureB = require('../tests/mock-data/aria-util/testsWithInstructionsSayingInsureB.json'); +// Sourced from https://github.com/w3c/aria-at/commits/master/tests/command-button +const commandButton_V20230823_V1 = require('../tests/mock-data/aria-util/commandButton_V20230823_V1.json'); +const commandButton_V20231206_V2 = require('../tests/mock-data/aria-util/commandButton_V20231206_V2.json'); +const commandButton_V20231213_V2 = require('../tests/mock-data/aria-util/commandButton_V20231213_V2.json'); -describe('Verify test hashes are matching as expected', () => { +describe('Verify test hashes are matching as expected - (v1 test format)', () => { it('should have a matching hash for with the same test, but with ids excluded for one', () => { const testHashA = hashTest(singleTest); const testHashB = hashTest(singleTestWithoutIds); @@ -79,3 +83,97 @@ describe('Verify test hashes are matching as expected', () => { expect(testsHashA).not.toEqual(testsHashB); }); }); + +describe('Verify test hashes are matching as expected - (v2 test format)', () => { + it('should not match a v2 test format version with a v1 test format version', () => { + // Based on https://github.com/w3c/aria-at/commit/836fb2a997f5b2844035b8c934f8fda9833cd5b2 + const v1TestsHash = hashTests(commandButton_V20230823_V1); + + // Based on https://github.com/w3c/aria-at/commit/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7 + const v2TestsHash_1 = hashTests(commandButton_V20231206_V2); + // Based on https://github.com/w3c/aria-at/commit/565a87b4111acebdb883d187b581e82c42a73844 + const v2TestsHash_2 = hashTests(commandButton_V20231213_V2); + + expect(v1TestsHash).not.toEqual(v2TestsHash_1); + expect(v1TestsHash).not.toEqual(v2TestsHash_2); + }); + + it('should not completely match a collection of tests hash with updated AT settings', () => { + // The difference between them is that there have been updated setting identifiers for VoiceOver tests; + // quickNavOn -> singleQuickKeyNavOn + // Compare with https://github.com/w3c/aria-at/compare/d9a19f8..565a87b + + // Based on https://github.com/w3c/aria-at/commit/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7 + const v2TestsHash_1 = hashTests(commandButton_V20231206_V2); + // Based on https://github.com/w3c/aria-at/commit/565a87b4111acebdb883d187b581e82c42a73844 + const v2TestsHash_2 = hashTests(commandButton_V20231213_V2); + + expect(v2TestsHash_1).not.toEqual(v2TestsHash_2); + }); + + it('should match collection of tests not a part of updated AT settings', () => { + // Only tests[].at.key === 'voiceover_macos' was affected, not nvda or jaws + const filterFn = t => t.at.key !== 'voiceover_macos'; + + // Based on https://github.com/w3c/aria-at/commit/d9a19f815d0f21194023b1c5919eb3b04d5c1ab7 + const v2TestsHash_1 = hashTests( + commandButton_V20231206_V2.filter(filterFn) + ); + + // Based on https://github.com/w3c/aria-at/commit/565a87b4111acebdb883d187b581e82c42a73844 + const v2TestsHash_2 = hashTests( + commandButton_V20231213_V2.filter(filterFn) + ); + + expect(v2TestsHash_1).toEqual(v2TestsHash_2); + }); + + it('should match individual tests not a part of updated AT settings', () => { + // Pos 0 and pos 1 of both commandButtonV2 tests point to JAWS and NVDA tests respectively + const v2TestHash_1_JAWS = hashTest(commandButton_V20231206_V2[0]); + const v2TestHash_2_JAWS = hashTest(commandButton_V20231213_V2[0]); + + const v2TestHash_1_NVDA = hashTest(commandButton_V20231206_V2[1]); + const v2TestHash_2_NVDA = hashTest(commandButton_V20231213_V2[1]); + + expect(v2TestHash_1_JAWS).toEqual(v2TestHash_2_JAWS); + expect(v2TestHash_1_NVDA).toEqual(v2TestHash_2_NVDA); + }); + + /* eslint-disable */ + it('should ONLY match affected individual tests for AT with updated settings', () => { + // The difference between them is that there have been updated setting identifiers for VoiceOver tests; + // quickNavOn -> singleQuickKeyNavOn + // + // Based on https://github.com/w3c/aria-at/compare/d9a19f8...565a87b#diff-4e3dcd0a202f268ebec2316344f136c3a83d6e03b3f726775cb46c57322ff3a0, + // only 'navForwardsToButton' and 'navBackToButton' tests were affected. The individual tests for 'reqInfoAboutButton' + // should still match + const findFn = (t, testId) => + t.at.key === 'voiceover_macos' && t.rawTestId === testId; + + // Original VO tests + const navForwardsToButtonVO_1 = commandButton_V20231206_V2.find(t => findFn(t, 'navForwardsToButton')); + const navForwardsToButtonVOHash_1 = hashTest(navForwardsToButtonVO_1); + + const navBackToButtonVO_1 = commandButton_V20231206_V2.find(t => findFn(t, 'navBackToButton')); + const navBackToButtonVOHash_1 = hashTest(navBackToButtonVO_1); + + const reqInfoAboutButtonVO_1 = commandButton_V20231206_V2.find(t => findFn(t, 'reqInfoAboutButton')); + const reqInfoAboutButtonVOHash_1 = hashTest(reqInfoAboutButtonVO_1); + + // Updated VO tests + const navForwardsToButtonVO_2 = commandButton_V20231213_V2.find(t => findFn(t, 'navForwardsToButton')); + const navForwardsToButtonVOHash_2 = hashTest(navForwardsToButtonVO_2); + + const navBackToButtonVO_2 = commandButton_V20231213_V2.find(t => findFn(t, 'navBackToButton')); + const navBackToButtonVOHash_2 = hashTest(navBackToButtonVO_2); + + const reqInfoAboutButtonVO_2 = commandButton_V20231213_V2.find(t => findFn(t, 'reqInfoAboutButton')); + const reqInfoAboutButtonVOHash_2 = hashTest(reqInfoAboutButtonVO_2); + + expect(navForwardsToButtonVOHash_1).not.toEqual(navForwardsToButtonVOHash_2); + expect(navBackToButtonVOHash_1).not.toEqual(navBackToButtonVOHash_2); + expect(reqInfoAboutButtonVOHash_1).toEqual(reqInfoAboutButtonVOHash_2); + }); + /* eslint-enable */ +}); From 0ccbdcdc8594d8ca988eab2e4a4574b99d5371bc Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 20 Dec 2023 11:19:36 -0500 Subject: [PATCH 02/11] Recalculate the hashes for already existing v2 items --- .../20231219212344-recalculateV2TestHashes.js | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 server/migrations/20231219212344-recalculateV2TestHashes.js diff --git a/server/migrations/20231219212344-recalculateV2TestHashes.js b/server/migrations/20231219212344-recalculateV2TestHashes.js new file mode 100644 index 000000000..9c221e78d --- /dev/null +++ b/server/migrations/20231219212344-recalculateV2TestHashes.js @@ -0,0 +1,195 @@ +'use strict'; + +const { + createTestResultId, + createScenarioResultId, + createAssertionResultId +} = require('../services/PopulatedData/locationOfDataId'); +const { hashTests } = require('../util/aria'); + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + /** + * Compute TestPlanVersion.hashedTests and return the unique TestPlanVersions found for each + * hash + * @param transaction - The Sequelize.Transaction object. + * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} + * @returns {Promise<{testPlanVersionsByHashedTests: {}}>} + */ + const computeTestPlanVersionHashedTests = async transaction => { + const results = await queryInterface.sequelize.query( + `SELECT COUNT(*) FROM "TestPlanVersion" WHERE metadata->>'testFormatVersion' = '2'`, + { transaction } + ); + const [[{ count: testPlanVersionCount }]] = results; + + const testPlanVersionBatchSize = 10; + const iterationsNeeded = Math.ceil( + testPlanVersionCount / testPlanVersionBatchSize + ); + + for (let i = 0; i < iterationsNeeded; i += 1) { + const multipleOf100 = i % testPlanVersionBatchSize === 0; + if (multipleOf100) + // eslint-disable-next-line no-console + console.info( + 'Indexing TestPlanVersions', + i * testPlanVersionBatchSize, + 'of', + Number(testPlanVersionCount) + ); + const currentOffset = i * testPlanVersionBatchSize; + + const [testPlanVersions] = await queryInterface.sequelize.query( + `SELECT id, directory, "gitSha", tests, "updatedAt" FROM "TestPlanVersion" WHERE metadata->>'testFormatVersion' = '2' ORDER BY id LIMIT ? OFFSET ?`, + { + replacements: [testPlanVersionBatchSize, currentOffset], + transaction + } + ); + + await Promise.all( + testPlanVersions.map(async testPlanVersion => { + const hashedTests = hashTests(testPlanVersion.tests); + + await queryInterface.sequelize.query( + `UPDATE "TestPlanVersion" SET "hashedTests" = ? WHERE id = ?`, + { + replacements: [hashedTests, testPlanVersion.id], + transaction + } + ); + }) + ); + } + }; + + /** + * Regenerate the testIds, scenarioIds and assertionsIds in TestRun.testResults, for + * TestRuns + * @param transaction - The Sequelize.Transaction object. + * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} + * @returns {Promise} + */ + const regenerateExistingTestResults = async transaction => { + const testPlanVersions = await queryInterface.sequelize.query( + `SELECT id, tests FROM "TestPlanVersion" WHERE metadata->>'testFormatVersion' = '2'`, + { + type: Sequelize.QueryTypes.SELECT, + transaction + } + ); + + const testPlanReports = await queryInterface.sequelize.query( + `SELECT id, "testPlanVersionId" FROM "TestPlanReport" WHERE "testPlanVersionId" IN (?)`, + { + replacements: [testPlanVersions.map(e => e.id)], + type: Sequelize.QueryTypes.SELECT, + transaction + } + ); + + for (const key in testPlanReports) { + const { id: testPlanReportId } = testPlanReports[key]; + + const testPlanRuns = await queryInterface.sequelize.query( + `SELECT testPlanRun.id, "testPlanReportId", "atId", "testPlanVersionId", "testResults", tests + FROM "TestPlanRun" testPlanRun + JOIN "TestPlanReport" testPlanReport ON testPlanReport.id = testPlanRun."testPlanReportId" + JOIN "TestPlanVersion" testPlanVersion ON testPlanVersion.id = testPlanReport."testPlanVersionId" + WHERE "testPlanReportId" = ?`, + { + replacements: [testPlanReportId], + type: Sequelize.QueryTypes.SELECT, + transaction + } + ); + + for (const key in testPlanRuns) { + const { + id: testPlanRunId, + atId, + testResults, + tests + } = testPlanRuns[key]; + + tests.forEach(test => { + const testId = test.id; + + testResults.forEach(testResult => { + if (testResult.testId === testId) { + // Update testResult.id + const testResultId = createTestResultId( + testPlanRunId, + testResult.testId + ); + testResult.id = testResultId; + + // The sub-arrays should be in the same order + testResult.scenarioResults.forEach( + (eachScenarioResult, scenarioIndex) => { + eachScenarioResult.scenarioId = + test.scenarios.filter( + scenario => + scenario.atId === atId + )[scenarioIndex].id; + + // Update eachScenarioResult.id + const scenarioResultId = + createScenarioResultId( + testResultId, + eachScenarioResult.scenarioId + ); + eachScenarioResult.id = + scenarioResultId; + + eachScenarioResult.assertionResults.forEach( + ( + eachAssertionResult, + assertionIndex + ) => { + eachAssertionResult.assertionId = + test.assertions[ + assertionIndex + ].id; + + // Update eachAssertionResult.id + eachAssertionResult.id = + createAssertionResultId( + scenarioResultId, + eachAssertionResult.assertionId + ); + } + ); + } + ); + } + }); + }); + + await queryInterface.sequelize.query( + `UPDATE "TestPlanRun" SET "testResults" = ? WHERE id = ?`, + { + replacements: [ + JSON.stringify(testResults), + testPlanRunId + ], + transaction + } + ); + // eslint-disable-next-line no-console + console.info( + 'Fixing testResults for TestPlanRun', + testPlanRunId + ); + } + } + }; + + return queryInterface.sequelize.transaction(async transaction => { + await computeTestPlanVersionHashedTests(transaction); + await regenerateExistingTestResults(transaction); + }); + } +}; From 4cf714325654c1bae62e44f0297f38a2e8927598 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 20 Dec 2023 11:29:28 -0500 Subject: [PATCH 03/11] Check testPlanVersions.length before updating related test plan reports and runs --- .../20231219212344-recalculateV2TestHashes.js | 192 +++++++++--------- 1 file changed, 100 insertions(+), 92 deletions(-) diff --git a/server/migrations/20231219212344-recalculateV2TestHashes.js b/server/migrations/20231219212344-recalculateV2TestHashes.js index 9c221e78d..0bb49cf9b 100644 --- a/server/migrations/20231219212344-recalculateV2TestHashes.js +++ b/server/migrations/20231219212344-recalculateV2TestHashes.js @@ -81,108 +81,116 @@ module.exports = { } ); - const testPlanReports = await queryInterface.sequelize.query( - `SELECT id, "testPlanVersionId" FROM "TestPlanReport" WHERE "testPlanVersionId" IN (?)`, - { - replacements: [testPlanVersions.map(e => e.id)], - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - for (const key in testPlanReports) { - const { id: testPlanReportId } = testPlanReports[key]; - - const testPlanRuns = await queryInterface.sequelize.query( - `SELECT testPlanRun.id, "testPlanReportId", "atId", "testPlanVersionId", "testResults", tests - FROM "TestPlanRun" testPlanRun - JOIN "TestPlanReport" testPlanReport ON testPlanReport.id = testPlanRun."testPlanReportId" - JOIN "TestPlanVersion" testPlanVersion ON testPlanVersion.id = testPlanReport."testPlanVersionId" - WHERE "testPlanReportId" = ?`, + if (testPlanVersions.length) { + const testPlanReports = await queryInterface.sequelize.query( + `select id, "testPlanVersionId" + from "TestPlanReport" + where "testPlanVersionId" in (?)`, { - replacements: [testPlanReportId], + replacements: [testPlanVersions.map(e => e.id)], type: Sequelize.QueryTypes.SELECT, transaction } ); - for (const key in testPlanRuns) { - const { - id: testPlanRunId, - atId, - testResults, - tests - } = testPlanRuns[key]; - - tests.forEach(test => { - const testId = test.id; - - testResults.forEach(testResult => { - if (testResult.testId === testId) { - // Update testResult.id - const testResultId = createTestResultId( - testPlanRunId, - testResult.testId - ); - testResult.id = testResultId; - - // The sub-arrays should be in the same order - testResult.scenarioResults.forEach( - (eachScenarioResult, scenarioIndex) => { - eachScenarioResult.scenarioId = - test.scenarios.filter( - scenario => - scenario.atId === atId - )[scenarioIndex].id; - - // Update eachScenarioResult.id - const scenarioResultId = - createScenarioResultId( - testResultId, - eachScenarioResult.scenarioId - ); - eachScenarioResult.id = - scenarioResultId; - - eachScenarioResult.assertionResults.forEach( - ( - eachAssertionResult, - assertionIndex - ) => { - eachAssertionResult.assertionId = - test.assertions[ - assertionIndex - ].id; - - // Update eachAssertionResult.id - eachAssertionResult.id = - createAssertionResultId( - scenarioResultId, - eachAssertionResult.assertionId - ); - } - ); - } - ); - } - }); - }); - - await queryInterface.sequelize.query( - `UPDATE "TestPlanRun" SET "testResults" = ? WHERE id = ?`, + for (const key in testPlanReports) { + const { id: testPlanReportId } = testPlanReports[key]; + + const testPlanRuns = await queryInterface.sequelize.query( + `select testPlanRun.id, "testPlanReportId", "atId", "testPlanVersionId", "testResults", tests + from "TestPlanRun" testPlanRun + join "TestPlanReport" testPlanReport + on testPlanReport.id = testPlanRun."testPlanReportId" + join "TestPlanVersion" testPlanVersion + on testPlanVersion.id = testPlanReport."testPlanVersionId" + where "testPlanReportId" = ?`, { - replacements: [ - JSON.stringify(testResults), - testPlanRunId - ], + replacements: [testPlanReportId], + type: Sequelize.QueryTypes.SELECT, transaction } ); - // eslint-disable-next-line no-console - console.info( - 'Fixing testResults for TestPlanRun', - testPlanRunId - ); + + for (const key in testPlanRuns) { + const { + id: testPlanRunId, + atId, + testResults, + tests + } = testPlanRuns[key]; + + tests.forEach(test => { + const testId = test.id; + + testResults.forEach(testResult => { + if (testResult.testId === testId) { + // Update testResult.id + const testResultId = createTestResultId( + testPlanRunId, + testResult.testId + ); + testResult.id = testResultId; + + // The sub-arrays should be in the same order + testResult.scenarioResults.forEach( + (eachScenarioResult, scenarioIndex) => { + eachScenarioResult.scenarioId = + test.scenarios.filter( + scenario => + scenario.atId === atId + )[scenarioIndex].id; + + // Update eachScenarioResult.id + const scenarioResultId = + createScenarioResultId( + testResultId, + eachScenarioResult.scenarioId + ); + eachScenarioResult.id = + scenarioResultId; + + eachScenarioResult.assertionResults.forEach( + ( + eachAssertionResult, + assertionIndex + ) => { + eachAssertionResult.assertionId = + test.assertions[ + assertionIndex + ].id; + + // Update eachAssertionResult.id + eachAssertionResult.id = + createAssertionResultId( + scenarioResultId, + eachAssertionResult.assertionId + ); + } + ); + } + ); + } + }); + }); + + await queryInterface.sequelize.query( + `update "TestPlanRun" + set "testResults" = ? + where id = ?`, + { + replacements: [ + JSON.stringify(testResults), + testPlanRunId + ], + transaction + } + ); + // eslint-disable-next-line no-console + console.info( + 'Fixing testResults for TestPlanRun', + testPlanRunId + ); + } } } }; From e6511ec1ff4c43aff3652b4606669ac06d68fc54 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Mon, 8 Jan 2024 16:41:48 -0500 Subject: [PATCH 04/11] * Remove stray eslint-disable * Rename testWithNoIds -> testWithOmittedAttributes --- server/util/aria.js | 6 +++--- server/util/aria.test.js | 30 +++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/server/util/aria.js b/server/util/aria.js index e39696138..0146131c3 100644 --- a/server/util/aria.js +++ b/server/util/aria.js @@ -7,7 +7,7 @@ const evaluateAtNameKey = atName => { else return atName.toLowerCase(); }; -const testWithNoIds = test => ({ +const testWithOmittedAttributes = test => ({ ...omit(test, [ 'id', 'at', @@ -21,11 +21,11 @@ const testWithNoIds = test => ({ }); // Ideally the hash of tests being imported will never change -const hashTests = tests => objectHash(tests.map(testWithNoIds)); +const hashTests = tests => objectHash(tests.map(testWithOmittedAttributes)); // Generate the hash of a test. const hashTest = test => { - return objectHash(testWithNoIds(test)); + return objectHash(testWithOmittedAttributes(test)); }; module.exports = { diff --git a/server/util/aria.test.js b/server/util/aria.test.js index def532207..35ad3b7ad 100644 --- a/server/util/aria.test.js +++ b/server/util/aria.test.js @@ -140,7 +140,6 @@ describe('Verify test hashes are matching as expected - (v2 test format)', () => expect(v2TestHash_1_NVDA).toEqual(v2TestHash_2_NVDA); }); - /* eslint-disable */ it('should ONLY match affected individual tests for AT with updated settings', () => { // The difference between them is that there have been updated setting identifiers for VoiceOver tests; // quickNavOn -> singleQuickKeyNavOn @@ -152,28 +151,41 @@ describe('Verify test hashes are matching as expected - (v2 test format)', () => t.at.key === 'voiceover_macos' && t.rawTestId === testId; // Original VO tests - const navForwardsToButtonVO_1 = commandButton_V20231206_V2.find(t => findFn(t, 'navForwardsToButton')); + const navForwardsToButtonVO_1 = commandButton_V20231206_V2.find(t => + findFn(t, 'navForwardsToButton') + ); const navForwardsToButtonVOHash_1 = hashTest(navForwardsToButtonVO_1); - const navBackToButtonVO_1 = commandButton_V20231206_V2.find(t => findFn(t, 'navBackToButton')); + const navBackToButtonVO_1 = commandButton_V20231206_V2.find(t => + findFn(t, 'navBackToButton') + ); const navBackToButtonVOHash_1 = hashTest(navBackToButtonVO_1); - const reqInfoAboutButtonVO_1 = commandButton_V20231206_V2.find(t => findFn(t, 'reqInfoAboutButton')); + const reqInfoAboutButtonVO_1 = commandButton_V20231206_V2.find(t => + findFn(t, 'reqInfoAboutButton') + ); const reqInfoAboutButtonVOHash_1 = hashTest(reqInfoAboutButtonVO_1); // Updated VO tests - const navForwardsToButtonVO_2 = commandButton_V20231213_V2.find(t => findFn(t, 'navForwardsToButton')); + const navForwardsToButtonVO_2 = commandButton_V20231213_V2.find(t => + findFn(t, 'navForwardsToButton') + ); const navForwardsToButtonVOHash_2 = hashTest(navForwardsToButtonVO_2); - const navBackToButtonVO_2 = commandButton_V20231213_V2.find(t => findFn(t, 'navBackToButton')); + const navBackToButtonVO_2 = commandButton_V20231213_V2.find(t => + findFn(t, 'navBackToButton') + ); const navBackToButtonVOHash_2 = hashTest(navBackToButtonVO_2); - const reqInfoAboutButtonVO_2 = commandButton_V20231213_V2.find(t => findFn(t, 'reqInfoAboutButton')); + const reqInfoAboutButtonVO_2 = commandButton_V20231213_V2.find(t => + findFn(t, 'reqInfoAboutButton') + ); const reqInfoAboutButtonVOHash_2 = hashTest(reqInfoAboutButtonVO_2); - expect(navForwardsToButtonVOHash_1).not.toEqual(navForwardsToButtonVOHash_2); + expect(navForwardsToButtonVOHash_1).not.toEqual( + navForwardsToButtonVOHash_2 + ); expect(navBackToButtonVOHash_1).not.toEqual(navBackToButtonVOHash_2); expect(reqInfoAboutButtonVOHash_1).toEqual(reqInfoAboutButtonVOHash_2); }); - /* eslint-enable */ }); From e9dcc4cc0ad85cb56421e5370a634a76f3bc30d8 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Mon, 22 Jan 2024 13:00:04 -0500 Subject: [PATCH 05/11] Created util for regenerating the hashedTests and test results; additionally, now deleting found duplicates as there is an error when tested against prod data where unnecessary duplicates were created --- .../20231219212344-recalculateV2TestHashes.js | 201 +------------- server/migrations/utils/index.js | 245 ++++++++++++++++++ 2 files changed, 252 insertions(+), 194 deletions(-) create mode 100644 server/migrations/utils/index.js diff --git a/server/migrations/20231219212344-recalculateV2TestHashes.js b/server/migrations/20231219212344-recalculateV2TestHashes.js index 0bb49cf9b..7f82268bc 100644 --- a/server/migrations/20231219212344-recalculateV2TestHashes.js +++ b/server/migrations/20231219212344-recalculateV2TestHashes.js @@ -1,203 +1,16 @@ 'use strict'; -const { - createTestResultId, - createScenarioResultId, - createAssertionResultId -} = require('../services/PopulatedData/locationOfDataId'); -const { hashTests } = require('../util/aria'); +const { regenerateResultsAndRecalculateHashes } = require('./utils'); /** @type {import('sequelize-cli').Migration} */ module.exports = { - async up(queryInterface, Sequelize) { - /** - * Compute TestPlanVersion.hashedTests and return the unique TestPlanVersions found for each - * hash - * @param transaction - The Sequelize.Transaction object. - * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} - * @returns {Promise<{testPlanVersionsByHashedTests: {}}>} - */ - const computeTestPlanVersionHashedTests = async transaction => { - const results = await queryInterface.sequelize.query( - `SELECT COUNT(*) FROM "TestPlanVersion" WHERE metadata->>'testFormatVersion' = '2'`, - { transaction } - ); - const [[{ count: testPlanVersionCount }]] = results; - - const testPlanVersionBatchSize = 10; - const iterationsNeeded = Math.ceil( - testPlanVersionCount / testPlanVersionBatchSize - ); - - for (let i = 0; i < iterationsNeeded; i += 1) { - const multipleOf100 = i % testPlanVersionBatchSize === 0; - if (multipleOf100) - // eslint-disable-next-line no-console - console.info( - 'Indexing TestPlanVersions', - i * testPlanVersionBatchSize, - 'of', - Number(testPlanVersionCount) - ); - const currentOffset = i * testPlanVersionBatchSize; - - const [testPlanVersions] = await queryInterface.sequelize.query( - `SELECT id, directory, "gitSha", tests, "updatedAt" FROM "TestPlanVersion" WHERE metadata->>'testFormatVersion' = '2' ORDER BY id LIMIT ? OFFSET ?`, - { - replacements: [testPlanVersionBatchSize, currentOffset], - transaction - } - ); - - await Promise.all( - testPlanVersions.map(async testPlanVersion => { - const hashedTests = hashTests(testPlanVersion.tests); - - await queryInterface.sequelize.query( - `UPDATE "TestPlanVersion" SET "hashedTests" = ? WHERE id = ?`, - { - replacements: [hashedTests, testPlanVersion.id], - transaction - } - ); - }) - ); - } - }; - - /** - * Regenerate the testIds, scenarioIds and assertionsIds in TestRun.testResults, for - * TestRuns - * @param transaction - The Sequelize.Transaction object. - * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} - * @returns {Promise} - */ - const regenerateExistingTestResults = async transaction => { - const testPlanVersions = await queryInterface.sequelize.query( - `SELECT id, tests FROM "TestPlanVersion" WHERE metadata->>'testFormatVersion' = '2'`, - { - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - if (testPlanVersions.length) { - const testPlanReports = await queryInterface.sequelize.query( - `select id, "testPlanVersionId" - from "TestPlanReport" - where "testPlanVersionId" in (?)`, - { - replacements: [testPlanVersions.map(e => e.id)], - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - for (const key in testPlanReports) { - const { id: testPlanReportId } = testPlanReports[key]; - - const testPlanRuns = await queryInterface.sequelize.query( - `select testPlanRun.id, "testPlanReportId", "atId", "testPlanVersionId", "testResults", tests - from "TestPlanRun" testPlanRun - join "TestPlanReport" testPlanReport - on testPlanReport.id = testPlanRun."testPlanReportId" - join "TestPlanVersion" testPlanVersion - on testPlanVersion.id = testPlanReport."testPlanVersionId" - where "testPlanReportId" = ?`, - { - replacements: [testPlanReportId], - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - for (const key in testPlanRuns) { - const { - id: testPlanRunId, - atId, - testResults, - tests - } = testPlanRuns[key]; - - tests.forEach(test => { - const testId = test.id; - - testResults.forEach(testResult => { - if (testResult.testId === testId) { - // Update testResult.id - const testResultId = createTestResultId( - testPlanRunId, - testResult.testId - ); - testResult.id = testResultId; - - // The sub-arrays should be in the same order - testResult.scenarioResults.forEach( - (eachScenarioResult, scenarioIndex) => { - eachScenarioResult.scenarioId = - test.scenarios.filter( - scenario => - scenario.atId === atId - )[scenarioIndex].id; - - // Update eachScenarioResult.id - const scenarioResultId = - createScenarioResultId( - testResultId, - eachScenarioResult.scenarioId - ); - eachScenarioResult.id = - scenarioResultId; - - eachScenarioResult.assertionResults.forEach( - ( - eachAssertionResult, - assertionIndex - ) => { - eachAssertionResult.assertionId = - test.assertions[ - assertionIndex - ].id; - - // Update eachAssertionResult.id - eachAssertionResult.id = - createAssertionResultId( - scenarioResultId, - eachAssertionResult.assertionId - ); - } - ); - } - ); - } - }); - }); - - await queryInterface.sequelize.query( - `update "TestPlanRun" - set "testResults" = ? - where id = ?`, - { - replacements: [ - JSON.stringify(testResults), - testPlanRunId - ], - transaction - } - ); - // eslint-disable-next-line no-console - console.info( - 'Fixing testResults for TestPlanRun', - testPlanRunId - ); - } - } - } - }; - + async up(queryInterface) { return queryInterface.sequelize.transaction(async transaction => { - await computeTestPlanVersionHashedTests(transaction); - await regenerateExistingTestResults(transaction); + await regenerateResultsAndRecalculateHashes( + queryInterface, + transaction, + `WHERE metadata->>'testFormatVersion' = '2'` + ); }); } }; diff --git a/server/migrations/utils/index.js b/server/migrations/utils/index.js new file mode 100644 index 000000000..d34e14492 --- /dev/null +++ b/server/migrations/utils/index.js @@ -0,0 +1,245 @@ +const { Sequelize } = require('sequelize'); +const { + createTestResultId, + createScenarioResultId, + createAssertionResultId +} = require('../../services/PopulatedData/locationOfDataId'); +const { hashTests } = require('../../util/aria'); + +/** + * Recompute TestPlanVersion.hashedTests + * @param queryInterface - The Sequelize.QueryInterface object. + * @param transaction - The Sequelize.Transaction object. + * @param testPlanVersionWhere - Additional WHERE clauses when querying TestPlanVersion if needed + * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} + * @returns {Promise} + */ +const computeTestPlanVersionHashedTests = async ( + queryInterface, + transaction, + testPlanVersionWhere +) => { + const results = await queryInterface.sequelize.query( + `SELECT COUNT(*) FROM "TestPlanVersion" ${testPlanVersionWhere}`, + { transaction } + ); + const [[{ count: testPlanVersionCount }]] = results; + + const testPlanVersionBatchSize = 10; + const iterationsNeeded = Math.ceil( + testPlanVersionCount / testPlanVersionBatchSize + ); + + const knownHashedTests = []; + for (let i = 0; i < iterationsNeeded; i += 1) { + const multipleOf100 = i % testPlanVersionBatchSize === 0; + if (multipleOf100) + // eslint-disable-next-line no-console + console.info( + 'Indexing TestPlanVersions', + i * testPlanVersionBatchSize, + 'of', + Number(testPlanVersionCount) + ); + const currentOffset = i * testPlanVersionBatchSize; + + const [testPlanVersions] = await queryInterface.sequelize.query( + `SELECT id, directory, "gitSha", tests, "updatedAt" FROM "TestPlanVersion" ${testPlanVersionWhere} ORDER BY id LIMIT ? OFFSET ?`, + { + replacements: [testPlanVersionBatchSize, currentOffset], + transaction + } + ); + + await Promise.all( + testPlanVersions.map(async testPlanVersion => { + const hashedTests = hashTests(testPlanVersion.tests); + + if (!knownHashedTests.includes(hashedTests)) { + knownHashedTests.push(hashedTests); + await queryInterface.sequelize.query( + `UPDATE "TestPlanVersion" SET "hashedTests" = ? WHERE id = ?`, + { + replacements: [hashedTests, testPlanVersion.id], + transaction + } + ); + } else { + // Remove any accidentally created TestPlanVersion rows created prior to migration + await queryInterface.sequelize.query( + `DELETE FROM "TestPlanVersion" WHERE id = ?`, + { + replacements: [testPlanVersion.id], + transaction + } + ); + } + }) + ); + } +}; + +/** + * Regenerate the testIds, scenarioIds and assertionsIds in TestRun.testResults, for + * TestRuns + * @param queryInterface - The Sequelize.QueryInterface object. + * @param transaction - The Sequelize.Transaction object. + * @param testPlanVersionWhere - Additional WHERE clauses when querying TestPlanVersion if needed + * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} + * @returns {Promise} + */ +const regenerateExistingTestResults = async ( + queryInterface, + transaction, + testPlanVersionWhere +) => { + const testPlanVersions = await queryInterface.sequelize.query( + `SELECT id, tests FROM "TestPlanVersion" ${testPlanVersionWhere}`, + { + type: Sequelize.QueryTypes.SELECT, + transaction + } + ); + + if (testPlanVersions.length) { + const testPlanReports = await queryInterface.sequelize.query( + `select id, "testPlanVersionId" + from "TestPlanReport" + where "testPlanVersionId" in (?)`, + { + replacements: [testPlanVersions.map(e => e.id)], + type: Sequelize.QueryTypes.SELECT, + transaction + } + ); + + for (const key in testPlanReports) { + const { id: testPlanReportId } = testPlanReports[key]; + + const testPlanRuns = await queryInterface.sequelize.query( + `select testPlanRun.id, "testPlanReportId", "atId", "testPlanVersionId", "testResults", tests + from "TestPlanRun" testPlanRun + join "TestPlanReport" testPlanReport + on testPlanReport.id = testPlanRun."testPlanReportId" + join "TestPlanVersion" testPlanVersion + on testPlanVersion.id = testPlanReport."testPlanVersionId" + where "testPlanReportId" = ?`, + { + replacements: [testPlanReportId], + type: Sequelize.QueryTypes.SELECT, + transaction + } + ); + + for (const key in testPlanRuns) { + const { + id: testPlanRunId, + atId, + testResults, + tests + } = testPlanRuns[key]; + + tests.forEach(test => { + const testId = test.id; + + testResults.forEach(testResult => { + if (testResult.testId === testId) { + // Update testResult.id + const testResultId = createTestResultId( + testPlanRunId, + testResult.testId + ); + testResult.id = testResultId; + + // The sub-arrays should be in the same order + testResult.scenarioResults.forEach( + (eachScenarioResult, scenarioIndex) => { + eachScenarioResult.scenarioId = + test.scenarios.filter( + scenario => scenario.atId === atId + )[scenarioIndex].id; + + // Update eachScenarioResult.id + const scenarioResultId = + createScenarioResultId( + testResultId, + eachScenarioResult.scenarioId + ); + eachScenarioResult.id = scenarioResultId; + + eachScenarioResult.assertionResults.forEach( + ( + eachAssertionResult, + assertionIndex + ) => { + eachAssertionResult.assertionId = + test.assertions[ + assertionIndex + ].id; + + // Update eachAssertionResult.id + eachAssertionResult.id = + createAssertionResultId( + scenarioResultId, + eachAssertionResult.assertionId + ); + } + ); + } + ); + } + }); + }); + + await queryInterface.sequelize.query( + `update "TestPlanRun" + set "testResults" = ? + where id = ?`, + { + replacements: [ + JSON.stringify(testResults), + testPlanRunId + ], + transaction + } + ); + // eslint-disable-next-line no-console + console.info( + 'Fixing testResults for TestPlanRun', + testPlanRunId + ); + } + } + } +}; + +/** + * Regenerate the testIds, scenarioIds and assertionsIds in TestRun.testResults, for + * TestRuns and regenerates TestPlanVersion.hashedTests if required + * @param queryInterface - The Sequelize.QueryInterface object. + * @param transaction - The Sequelize.Transaction object. + * @param testPlanVersionWhere - Additional WHERE clauses when querying TestPlanVersion if needed + * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} + * @returns {Promise} + */ +const regenerateResultsAndRecalculateHashes = async ( + queryInterface, + transaction, + testPlanVersionWhere = '' +) => { + await computeTestPlanVersionHashedTests( + queryInterface, + transaction, + testPlanVersionWhere + ); + + await regenerateExistingTestResults( + queryInterface, + transaction, + testPlanVersionWhere + ); +}; + +module.exports = { + regenerateResultsAndRecalculateHashes +}; From 3c6d02022409b49b5a321706bf92c56632ba8a53 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Mon, 22 Jan 2024 13:18:34 -0500 Subject: [PATCH 06/11] Update migration testFormatVersion migration to use util following rebase --- ...deAdditionalTestFormatVersionAttributes.js | 197 +----------------- 1 file changed, 5 insertions(+), 192 deletions(-) diff --git a/server/migrations/20240104150500-includeAdditionalTestFormatVersionAttributes.js b/server/migrations/20240104150500-includeAdditionalTestFormatVersionAttributes.js index 56e691de5..49a9721b9 100644 --- a/server/migrations/20240104150500-includeAdditionalTestFormatVersionAttributes.js +++ b/server/migrations/20240104150500-includeAdditionalTestFormatVersionAttributes.js @@ -1,199 +1,10 @@ 'use strict'; -const { - createTestResultId, - createScenarioResultId, - createAssertionResultId -} = require('../services/PopulatedData/locationOfDataId'); -const { hashTests } = require('../util/aria'); +const { regenerateResultsAndRecalculateHashes } = require('./utils'); /** @type {import('sequelize-cli').Migration} */ module.exports = { async up(queryInterface, Sequelize) { - /** - * Recompute TestPlanVersion.hashedTests - * @param transaction - The Sequelize.Transaction object. - * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} - * @returns {Promise} - */ - const computeTestPlanVersionHashedTests = async transaction => { - const results = await queryInterface.sequelize.query( - `SELECT COUNT(*) FROM "TestPlanVersion"`, - { transaction } - ); - const [[{ count: testPlanVersionCount }]] = results; - - const testPlanVersionBatchSize = 10; - const iterationsNeeded = Math.ceil( - testPlanVersionCount / testPlanVersionBatchSize - ); - - for (let i = 0; i < iterationsNeeded; i += 1) { - const multipleOf100 = i % testPlanVersionBatchSize === 0; - if (multipleOf100) - // eslint-disable-next-line no-console - console.info( - 'Indexing TestPlanVersions', - i * testPlanVersionBatchSize, - 'of', - Number(testPlanVersionCount) - ); - const currentOffset = i * testPlanVersionBatchSize; - - const [testPlanVersions] = await queryInterface.sequelize.query( - `SELECT id, directory, "gitSha", tests, "updatedAt" FROM "TestPlanVersion" ORDER BY id LIMIT ? OFFSET ?`, - { - replacements: [testPlanVersionBatchSize, currentOffset], - transaction - } - ); - - await Promise.all( - testPlanVersions.map(async testPlanVersion => { - const hashedTests = hashTests(testPlanVersion.tests); - - await queryInterface.sequelize.query( - `UPDATE "TestPlanVersion" SET "hashedTests" = ? WHERE id = ?`, - { - replacements: [hashedTests, testPlanVersion.id], - transaction - } - ); - }) - ); - } - }; - - /** - * Regenerate the testIds, scenarioIds and assertionsIds in TestRun.testResults, for - * TestRuns - * @param transaction - The Sequelize.Transaction object. - * See {@https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-transaction} - * @returns {Promise} - */ - const regenerateExistingTestResults = async transaction => { - const testPlanVersions = await queryInterface.sequelize.query( - `SELECT id, tests FROM "TestPlanVersion"`, - { - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - if (testPlanVersions.length) { - const testPlanReports = await queryInterface.sequelize.query( - `select id, "testPlanVersionId" - from "TestPlanReport" - where "testPlanVersionId" in (?)`, - { - replacements: [testPlanVersions.map(e => e.id)], - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - for (const key in testPlanReports) { - const { id: testPlanReportId } = testPlanReports[key]; - - const testPlanRuns = await queryInterface.sequelize.query( - `select testPlanRun.id, "testPlanReportId", "atId", "testPlanVersionId", "testResults", tests - from "TestPlanRun" testPlanRun - join "TestPlanReport" testPlanReport - on testPlanReport.id = testPlanRun."testPlanReportId" - join "TestPlanVersion" testPlanVersion - on testPlanVersion.id = testPlanReport."testPlanVersionId" - where "testPlanReportId" = ?`, - { - replacements: [testPlanReportId], - type: Sequelize.QueryTypes.SELECT, - transaction - } - ); - - for (const key in testPlanRuns) { - const { - id: testPlanRunId, - atId, - testResults, - tests - } = testPlanRuns[key]; - - tests.forEach(test => { - const testId = test.id; - - testResults.forEach(testResult => { - if (testResult.testId === testId) { - // Update testResult.id - const testResultId = createTestResultId( - testPlanRunId, - testResult.testId - ); - testResult.id = testResultId; - - // The sub-arrays should be in the same order - testResult.scenarioResults.forEach( - (eachScenarioResult, scenarioIndex) => { - eachScenarioResult.scenarioId = - test.scenarios.filter( - scenario => - scenario.atId === atId - )[scenarioIndex].id; - - // Update eachScenarioResult.id - const scenarioResultId = - createScenarioResultId( - testResultId, - eachScenarioResult.scenarioId - ); - eachScenarioResult.id = - scenarioResultId; - - eachScenarioResult.assertionResults.forEach( - ( - eachAssertionResult, - assertionIndex - ) => { - eachAssertionResult.assertionId = - test.assertions[ - assertionIndex - ].id; - - // Update eachAssertionResult.id - eachAssertionResult.id = - createAssertionResultId( - scenarioResultId, - eachAssertionResult.assertionId - ); - } - ); - } - ); - } - }); - }); - - await queryInterface.sequelize.query( - `update "TestPlanRun" - set "testResults" = ? - where id = ?`, - { - replacements: [ - JSON.stringify(testResults), - testPlanRunId - ], - transaction - } - ); - // eslint-disable-next-line no-console - console.info( - 'Fixing testResults for TestPlanRun', - testPlanRunId - ); - } - } - } - }; - const updateV1TestPlanVersionsToIncludeTestFormatVersion = async transaction => { // No testFormatVersion indicates this is v1 TestPlanVersion data @@ -254,8 +65,10 @@ module.exports = { ); // Recalculate the hashes - await computeTestPlanVersionHashedTests(transaction); - await regenerateExistingTestResults(transaction); + await regenerateResultsAndRecalculateHashes( + queryInterface, + transaction + ); }); } }; From 022d86ea9bb4c6f363bf2e8b74c1eaca662e77d6 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 24 Jan 2024 09:34:26 -0500 Subject: [PATCH 07/11] Avoid showing reports for DEPRECATED test plan versions on Test Queue page --- client/components/TestQueue/queries.js | 5 ++++- server/resources/ats.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client/components/TestQueue/queries.js b/client/components/TestQueue/queries.js index aace78e43..faaf8300d 100644 --- a/client/components/TestQueue/queries.js +++ b/client/components/TestQueue/queries.js @@ -44,7 +44,10 @@ export const TEST_QUEUE_PAGE_QUERY = gql` } updatedAt } - testPlanReports(isFinal: false) { + testPlanReports( + isFinal: false + testPlanVersionPhases: [DRAFT, CANDIDATE, RECOMMENDED] + ) { id conflictsLength runnableTestsLength diff --git a/server/resources/ats.json b/server/resources/ats.json index b704498e8..b88da56e5 100644 --- a/server/resources/ats.json +++ b/server/resources/ats.json @@ -103,4 +103,4 @@ } } } -] +] \ No newline at end of file From 2e0d090c0411e550948488dcdee5db4be5db0ada Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 24 Jan 2024 17:20:02 -0500 Subject: [PATCH 08/11] Update workflow to separate commits for v1-related and v2-related test format tests to be imported --- .github/workflows/runtest.yml | 1 + config/test.env | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/runtest.yml b/.github/workflows/runtest.yml index 30414e155..72f194930 100644 --- a/.github/workflows/runtest.yml +++ b/.github/workflows/runtest.yml @@ -39,6 +39,7 @@ jobs: yarn workspace server db-import-tests:test -c ${IMPORT_ARIA_AT_TESTS_COMMIT_1} yarn workspace server db-import-tests:test -c ${IMPORT_ARIA_AT_TESTS_COMMIT_2} yarn workspace server db-import-tests:test -c ${IMPORT_ARIA_AT_TESTS_COMMIT_3} + yarn workspace server db-import-tests:test -c ${IMPORT_ARIA_AT_TESTS_COMMIT_4} yarn workspace server db-populate-sample-data:test - name: test run: yarn test diff --git a/config/test.env b/config/test.env index 19e169cce..171e15800 100644 --- a/config/test.env +++ b/config/test.env @@ -10,10 +10,12 @@ ENVIRONMENT=test ALLOW_FAKE_ROLE=true IMPORT_CONFIG=../config/test.env +# Older and newer v1 test format tests, respectively IMPORT_ARIA_AT_TESTS_COMMIT_1=5fe7afd82fe51c185b8661276105190a59d47322 IMPORT_ARIA_AT_TESTS_COMMIT_2=1aa3b74d24d340362e9f511eae33788d55487d12 -# Commit before incoming v2 test format changes -IMPORT_ARIA_AT_TESTS_COMMIT_3=836fb2a997f5b2844035b8c934f8fda9833cd5b2 +# Older and newer v2 test format tests, respectively +IMPORT_ARIA_AT_TESTS_COMMIT_3=ab77d47ab19db71c635c9bb459ba5c34182e1400 +IMPORT_ARIA_AT_TESTS_COMMIT_4=d34eddbb8e751f07bd28d952de15fa7fe5f07353 GITHUB_OAUTH_SERVER=http://localhost:4466 GITHUB_GRAPHQL_SERVER=http://localhost:4466 From fb28a2ea23f0906d2e705bbad9256798d57dfd41 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 24 Jan 2024 17:22:09 -0500 Subject: [PATCH 09/11] Update updatePhaseResolver to better align with the deprecation of test results process described in #877; update dataManagement.test.js; update sample populate script to support testing v2 test format tests workflow --- .../updatePhaseResolver.js | 15 +- server/scripts/populate-test-data/index.js | 8 +- ...05_test_data.sql => pg_dump_test_data.sql} | 54 ++- .../tests/integration/dataManagement.test.js | 425 ++++++++++-------- 4 files changed, 297 insertions(+), 205 deletions(-) rename server/scripts/populate-test-data/{pg_dump_2021_05_test_data.sql => pg_dump_test_data.sql} (77%) diff --git a/server/resolvers/TestPlanVersionOperations/updatePhaseResolver.js b/server/resolvers/TestPlanVersionOperations/updatePhaseResolver.js index 19d7b9bcb..7550ec254 100644 --- a/server/resolvers/TestPlanVersionOperations/updatePhaseResolver.js +++ b/server/resolvers/TestPlanVersionOperations/updatePhaseResolver.js @@ -265,8 +265,9 @@ const updatePhaseResolver = async ( ); let updateParams = {}; - // Mark the report as final if previously was on the TestPlanVersion being - // deprecated + // Mark the report as final if previously was for TestPlanVersion being deprecated; may still be + // nullified if finalized test results aren't equal to the amount known number of possible + // runnable tests, because no tests should be skipped. Would mean it CANNOT be final. if (testPlanReportDataToInclude.markedFinalAt) updateParams = { markedFinalAt: new Date() }; @@ -280,6 +281,7 @@ const updatePhaseResolver = async ( // marked as final yet updateParams = { ...updateParams, + markedFinalAt: null, metrics: { ...populatedTestPlanReport.metrics, conflictsCount: conflicts.length @@ -297,9 +299,9 @@ const updatePhaseResolver = async ( !finalizedTestResults || !finalizedTestResults.length ) { - // Just update with current { markedFinalAt } if available updateParams = { ...updateParams, + markedFinalAt: null, metrics: { ...populatedTestPlanReport.metrics } @@ -315,6 +317,13 @@ const updatePhaseResolver = async ( updateParams = { ...updateParams, + // means test results have now been 'skipped' during the update process so these + // cannot be finalized and must be updated in the test queue + markedFinalAt: + finalizedTestResults.length < + runnableTests.length + ? null + : updateParams.markedFinalAt, metrics: { ...populatedTestPlanReport.metrics, ...metrics diff --git a/server/scripts/populate-test-data/index.js b/server/scripts/populate-test-data/index.js index 4ae76b696..30f36ad76 100644 --- a/server/scripts/populate-test-data/index.js +++ b/server/scripts/populate-test-data/index.js @@ -5,7 +5,7 @@ const populateFakeTestResults = require('./populateFakeTestResults'); const populateTestDatabase = async () => { const testDataScript = fs.readFileSync( - __dirname + '/pg_dump_2021_05_test_data.sql', + __dirname + '/pg_dump_test_data.sql', 'utf-8' ); @@ -165,6 +165,12 @@ const populateTestDatabase = async () => { await populateFakeTestResults(15, new Array(8).fill('completeAndPassing')); + await populateFakeTestResults(16, new Array(3).fill('completeAndPassing')); + + await populateFakeTestResults(17, new Array(3).fill('completeAndPassing')); + + await populateFakeTestResults(18, new Array(3).fill('completeAndPassing')); + console.info( 'Successfully populated. Please wait a moment for the process to close.' ); diff --git a/server/scripts/populate-test-data/pg_dump_2021_05_test_data.sql b/server/scripts/populate-test-data/pg_dump_test_data.sql similarity index 77% rename from server/scripts/populate-test-data/pg_dump_2021_05_test_data.sql rename to server/scripts/populate-test-data/pg_dump_test_data.sql index e2ba8630b..56d1f74f0 100644 --- a/server/scripts/populate-test-data/pg_dump_2021_05_test_data.sql +++ b/server/scripts/populate-test-data/pg_dump_test_data.sql @@ -20,10 +20,9 @@ BEGIN SELECT id INTO test_plan_version_id FROM "TestPlanVersion" WHERE "TestPlanVersion".title = testPlanVersionTitle - AND ( - testFormatNumber IS NULL OR - ("TestPlanVersion".metadata->'testFormatVersion' IS NOT NULL AND "TestPlanVersion".metadata->>'testFormatVersion' = testFormatNumber) - ); + AND "TestPlanVersion".metadata->>'testFormatVersion' = testFormatNumber + ORDER BY id + LIMIT 1; RETURN test_plan_version_id; END; $$; @@ -72,31 +71,35 @@ INSERT INTO "AtMode" ("atId", name) VALUES (3, 'INTERACTION'); -- Data for Name: TestPlanReport; Type: TABLE DATA; Schema: public; Owner: atr -- -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId") VALUES (1, get_test_plan_version_id(text 'Toggle Button', null), '2021-05-14 14:18:23.602-05', 1, 2); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId") VALUES (2, get_test_plan_version_id(text 'Select Only Combobox Example', null), '2021-05-14 14:18:23.602-05', 2, 1); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (3, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', '2022-07-06', 1, 2, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (4, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', '2022-07-06', 2, 2, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (5, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', '2022-07-06', 3, 3, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (6, get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', null), '2021-05-14 14:18:23.602-05', '2022-07-06', 3, 3, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId") VALUES (7, get_test_plan_version_id(text 'Alert Example', null), '2021-05-14 14:18:23.602-05', 3, 1); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (8, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', 1, 1, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (9, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', 2, 1, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (10, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', 3, 1, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (11, get_test_plan_version_id(text 'Modal Dialog Example', null), '2021-05-14 14:18:23.602-05', 3, 2, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (12, get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', null), '2021-05-14 14:18:23.602-05', '2022-07-06', 1, 2, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (13, get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', null), '2021-05-14 14:18:23.602-05', '2022-07-07', 2, 2, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (14, get_test_plan_version_id(text 'Toggle Button', null), '2021-05-14 14:18:23.602-05', '2022-07-07', 2, 2, 'READY'); -INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (15, get_test_plan_version_id(text 'Toggle Button', null), '2021-05-14 14:18:23.602-05', '2022-07-07', 3, 3, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId") VALUES (1, get_test_plan_version_id(text 'Toggle Button', '1'), '2021-05-14 14:18:23.602-05', 1, 2); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId") VALUES (2, get_test_plan_version_id(text 'Select Only Combobox Example', '1'), '2021-05-14 14:18:23.602-05', 2, 1); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (3, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', '2022-07-06', 1, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (4, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', '2022-07-06', 2, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (5, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', '2022-07-06', 3, 3, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (6, get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', '1'), '2021-05-14 14:18:23.602-05', '2022-07-06', 3, 3, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId") VALUES (7, get_test_plan_version_id(text 'Alert Example', '1'), '2021-05-14 14:18:23.602-05', 3, 1); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (8, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', 1, 1, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (9, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', 2, 1, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (10, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', 3, 1, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "atId", "browserId", "vendorReviewStatus") VALUES (11, get_test_plan_version_id(text 'Modal Dialog Example', '1'), '2021-05-14 14:18:23.602-05', 3, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (12, get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', '1'), '2021-05-14 14:18:23.602-05', '2022-07-06', 1, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (13, get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', '1'), '2021-05-14 14:18:23.602-05', '2022-07-07', 2, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (14, get_test_plan_version_id(text 'Toggle Button', '1'), '2021-05-14 14:18:23.602-05', '2022-07-07', 2, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (15, get_test_plan_version_id(text 'Toggle Button', '1'), '2021-05-14 14:18:23.602-05', '2022-07-07', 3, 3, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (16, get_test_plan_version_id(text 'Command Button Example', '2'), '2023-12-13 14:18:23.602-05', '2023-12-14', 1, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (17, get_test_plan_version_id(text 'Command Button Example', '2'), '2023-12-13 14:18:23.602-05', '2023-12-14', 2, 2, 'READY'); +INSERT INTO "TestPlanReport" (id, "testPlanVersionId", "createdAt", "markedFinalAt", "atId", "browserId", "vendorReviewStatus") VALUES (18, get_test_plan_version_id(text 'Command Button Example', '2'), '2023-12-13 14:18:23.602-05', '2023-12-14', 3, 3, 'READY'); -- -- Data for Name: TestPlanVersion; Type: TABLE DATA; Schema: public; Owner: atr -- -UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2022-07-06' WHERE id = get_test_plan_version_id(text 'Toggle Button', null); -UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2022-07-06' WHERE id = get_test_plan_version_id(text 'Select Only Combobox Example', null); -UPDATE "TestPlanVersion" SET "phase" = 'CANDIDATE', "draftPhaseReachedAt" = '2022-07-06', "candidatePhaseReachedAt" = '2022-07-06', "recommendedPhaseTargetDate" = '2023-01-02' WHERE id = get_test_plan_version_id(text 'Modal Dialog Example', null); -UPDATE "TestPlanVersion" SET "phase" = 'RECOMMENDED', "candidatePhaseReachedAt" = '2022-07-06', "recommendedPhaseTargetDate" = '2023-01-02', "recommendedPhaseReachedAt" = '2023-01-03' WHERE id = get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', null); -UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2022-07-06' WHERE id = get_test_plan_version_id(text 'Alert Example', null); +UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2022-07-06' WHERE id = get_test_plan_version_id(text 'Toggle Button', '1'); +UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2022-07-06' WHERE id = get_test_plan_version_id(text 'Select Only Combobox Example', '1'); +UPDATE "TestPlanVersion" SET "phase" = 'CANDIDATE', "draftPhaseReachedAt" = '2022-07-06', "candidatePhaseReachedAt" = '2022-07-06', "recommendedPhaseTargetDate" = '2023-01-02' WHERE id = get_test_plan_version_id(text 'Modal Dialog Example', '1'); +UPDATE "TestPlanVersion" SET "phase" = 'RECOMMENDED', "candidatePhaseReachedAt" = '2022-07-06', "recommendedPhaseTargetDate" = '2023-01-02', "recommendedPhaseReachedAt" = '2023-01-03' WHERE id = get_test_plan_version_id(text 'Checkbox Example (Mixed-State)', '1'); +UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2022-07-06' WHERE id = get_test_plan_version_id(text 'Alert Example', '1'); +UPDATE "TestPlanVersion" SET "phase" = 'DRAFT', "draftPhaseReachedAt" = '2023-12-14' WHERE id = get_test_plan_version_id(text 'Command Button Example', '2'); -- -- Data for Name: User; Type: TABLE DATA; Schema: public; Owner: atr @@ -131,6 +134,9 @@ INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults" INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults") VALUES (13, 1, 13, '[]'); INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults") VALUES (14, 1, 14, '[]'); INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults") VALUES (15, 1, 15, '[]'); +INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults") VALUES (16, 1, 16, '[]'); +INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults") VALUES (17, 1, 17, '[]'); +INSERT INTO "TestPlanRun" (id, "testerUserId", "testPlanReportId", "testResults") VALUES (18, 1, 18, '[]'); -- -- Data for Name: CollectionJob; Type: TABLE DATA; Schema: public; Owner: atr diff --git a/server/tests/integration/dataManagement.test.js b/server/tests/integration/dataManagement.test.js index e991431d5..064f20c0f 100644 --- a/server/tests/integration/dataManagement.test.js +++ b/server/tests/integration/dataManagement.test.js @@ -10,66 +10,66 @@ afterAll(async () => { await db.sequelize.close(); }, 20000); -describe('data management', () => { - const testPlanVersionsQuery = () => { - return query(gql` - query { - testPlanVersions(phases: [RD, CANDIDATE]) { +const testPlanVersionsQuery = () => { + return query(gql` + query { + testPlanVersions(phases: [RD, DRAFT, CANDIDATE]) { + id + phase + gitSha + metadata + testPlan { + directory + } + testPlanReports { id - phase - gitSha - testPlan { - directory + markedFinalAt + at { + id } - testPlanReports { + browser { id - at { - id - } - browser { + } + draftTestPlanRuns { + testResults { id - } - draftTestPlanRuns { - testResults { + completedAt + test { id - completedAt - test { + rowNumber + title + ats { id - rowNumber - title - ats { - id - name - } - atMode - scenarios { - id - commands { - id - text - } - } - assertions { + name + } + atMode + scenarios { + id + commands { id - priority text } } - scenarioResults { - output - assertionResults { - id - assertion { - text - } - passed + assertions { + id + priority + text + } + } + scenarioResults { + output + assertionResults { + id + assertion { + text } - scenario { + passed + } + scenario { + id + commands { id - commands { - id - text - } + text } } } @@ -77,72 +77,73 @@ describe('data management', () => { } } } - `); - }; - - const updateVersionToPhaseQuery = ( - testPlanVersionId, - testPlanVersionDataToIncludeId, - phase - ) => { - return mutate(gql` - mutation { - testPlanVersion(id: ${testPlanVersionId}) { - updatePhase( - phase: ${phase} - testPlanVersionDataToIncludeId: ${testPlanVersionDataToIncludeId} - ) { - testPlanVersion { - phase - testPlanReports { + } + `); +}; + +const updateVersionToPhaseQuery = ( + testPlanVersionId, + testPlanVersionDataToIncludeId, + phase +) => { + return mutate(gql` + mutation { + testPlanVersion(id: ${testPlanVersionId}) { + updatePhase( + phase: ${phase} + testPlanVersionDataToIncludeId: ${testPlanVersionDataToIncludeId} + ) { + testPlanVersion { + phase + testPlanReports { + id + markedFinalAt + at { id - at { - id - } - browser { + } + browser { + id + } + draftTestPlanRuns { + testResults { id - } - draftTestPlanRuns { - testResults { + completedAt + test { id - completedAt - test { + rowNumber + title + ats { id - rowNumber - title - ats { - id - name - } - atMode - scenarios { - id - commands { - id - text - } - } - assertions { + name + } + atMode + scenarios { + id + commands { id - priority text } } - scenarioResults { - output - assertionResults { - id - assertion { - text - } - passed + assertions { + id + priority + text + } + } + scenarioResults { + output + assertionResults { + id + assertion { + text } - scenario { + passed + } + scenario { + id + commands { id - commands { - id - text - } + text } } } @@ -152,22 +153,24 @@ describe('data management', () => { } } } - `); - }; - - const countCompletedTests = testPlanReports => { - return testPlanReports.reduce((acc, testPlanReport) => { - return ( - acc + - testPlanReport.draftTestPlanRuns[0]?.testResults.reduce( - (acc, testResult) => - testResult.completedAt ? acc + 1 : acc, - 0 - ) || 0 - ); - }, 0); - }; + } + `); +}; + +const countCompletedTests = testPlanReports => { + return testPlanReports.reduce((acc, testPlanReport) => { + return ( + acc + + testPlanReport.draftTestPlanRuns[0]?.testResults.reduce( + (acc, testResult) => + testResult.completedAt ? acc + 1 : acc, + 0 + ) || 0 + ); + }, 0); +}; +describe('data management', () => { it('can set test plan version to candidate and recommended', async () => { await dbCleaner(async () => { const candidateTestPlanVersions = await query(gql` @@ -181,9 +184,9 @@ describe('data management', () => { const candidateTestPlanVersion = candidateTestPlanVersions.testPlanVersions[0]; - let testPlanVersionId = candidateTestPlanVersion.id; - // This version is in 'CANDIDATE' phase. Let's set it to DRAFT + // This version is in 'CANDIDATE' phase. Set it to DRAFT // This will also remove the associated TestPlanReports markedFinalAt values + const testPlanVersionId = candidateTestPlanVersion.id; await mutate(gql` mutation { testPlanVersion(id: ${testPlanVersionId}) { @@ -315,6 +318,22 @@ describe('data management', () => { e.testPlan.directory === 'modal-dialog' && e.phase === 'CANDIDATE' ); + + // This version is in 'CANDIDATE' phase. Set it to DRAFT + // This will also remove the associated TestPlanReports markedFinalAt values + const oldTestPlanVersionId = oldModalDialogVersion.id; + await mutate(gql` + mutation { + testPlanVersion(id: ${oldTestPlanVersionId}) { + updatePhase(phase: DRAFT) { + testPlanVersion { + phase + } + } + } + } + `); + const oldModalDialogVersionTestPlanReports = oldModalDialogVersion.testPlanReports; const oldModalDialogVersionTestPlanReportsCount = @@ -354,56 +373,37 @@ describe('data management', () => { newModalDialogVersion.testPlanReports.length; const { testPlanVersion: newModalDialogVersionInDraft } = - await mutate(gql` - mutation { - testPlanVersion(id: ${newModalDialogVersion.id}) { - updatePhase(phase: DRAFT) { - testPlanVersion { - phase - testPlanReports { - id - } - } - } - } - } - `); - const newModalDialogVersionTestPlanReportsInDraftCount = - newModalDialogVersionInDraft.updatePhase.testPlanVersion - .testPlanReports.length; - - const { testPlanVersion: newModalDialogVersionInCandidate } = await updateVersionToPhaseQuery( newModalDialogVersion.id, oldModalDialogVersion.id, - 'CANDIDATE' + 'DRAFT' ); - const newModalDialogVersionTestPlanReportsInCandidate = - newModalDialogVersionInCandidate.updatePhase.testPlanVersion + const newModalDialogVersionTestPlanReportsInDraft = + newModalDialogVersionInDraft.updatePhase.testPlanVersion .testPlanReports; - const newModalDialogVersionTestPlanReportsInCandidateCount = - newModalDialogVersionTestPlanReportsInCandidate.length; + const newModalDialogVersionTestPlanReportsInDraftCount = + newModalDialogVersionTestPlanReportsInDraft.length; // Get JAWS-specific tests count for new version - const newModalDialogVersionJAWSCompletedTestsInCandidateCount = + const newModalDialogVersionJAWSCompletedTestsInDraftCount = countCompletedTests( - newModalDialogVersionTestPlanReportsInCandidate.filter( + newModalDialogVersionTestPlanReportsInDraft.filter( el => el.at.id == 1 ) ); // Get NVDA-specific tests count for new version - const newModalDialogVersionNVDACompletedTestsInCandidateCount = + const newModalDialogVersionNVDACompletedTestsInDraftCount = countCompletedTests( - newModalDialogVersionTestPlanReportsInCandidate.filter( + newModalDialogVersionTestPlanReportsInDraft.filter( el => el.at.id == 2 ) ); // Get VO-specific tests count for new version - const newModalDialogVersionVOCompletedTestsInCandidateCount = + const newModalDialogVersionVOCompletedTestsInDraftCount = countCompletedTests( - newModalDialogVersionTestPlanReportsInCandidate.filter( + newModalDialogVersionTestPlanReportsInDraft.filter( el => el.at.id == 3 ) ); @@ -422,23 +422,22 @@ describe('data management', () => { 0 ); expect(newModalDialogVersionTestPlanReportsInRDCount).toBe(0); - expect(newModalDialogVersionTestPlanReportsInDraftCount).toEqual(0); - expect( - newModalDialogVersionTestPlanReportsInCandidateCount - ).toEqual(oldModalDialogVersionTestPlanReportsCount); + expect(newModalDialogVersionTestPlanReportsInDraftCount).toEqual( + oldModalDialogVersionTestPlanReportsCount + ); expect( oldModalDialogVersionJAWSCompletedTestsCount ).toBeGreaterThan( - newModalDialogVersionJAWSCompletedTestsInCandidateCount + newModalDialogVersionJAWSCompletedTestsInDraftCount ); expect( oldModalDialogVersionNVDACompletedTestsCount ).toBeGreaterThan( - newModalDialogVersionNVDACompletedTestsInCandidateCount + newModalDialogVersionNVDACompletedTestsInDraftCount ); expect(oldModalDialogVersionVOCompletedTestsCount).toEqual( - newModalDialogVersionVOCompletedTestsInCandidateCount + newModalDialogVersionVOCompletedTestsInDraftCount ); }); }); @@ -455,6 +454,22 @@ describe('data management', () => { e.testPlan.directory === 'modal-dialog' && e.phase === 'CANDIDATE' ); + + // This version is in 'CANDIDATE' phase. Set it to DRAFT + // This will also remove the associated TestPlanReports markedFinalAt values + const oldTestPlanVersionId = oldModalDialogVersion.id; + await mutate(gql` + mutation { + testPlanVersion(id: ${oldTestPlanVersionId}) { + updatePhase(phase: DRAFT) { + testPlanVersion { + phase + } + } + } + } + `); + const oldModalDialogVersionTestPlanReports = oldModalDialogVersion.testPlanReports; const oldModalDialogVersionTestPlanReportsCount = @@ -533,22 +548,23 @@ describe('data management', () => { const newModalDialogVersionTestPlanReportsInDraftCount = newModalDialogVersionInDraft.testPlanReports.length; - const { testPlanVersion: newModalDialogVersionInCandidate } = - await updateVersionToPhaseQuery( - newModalDialogVersion.id, - oldModalDialogVersion.id, - 'CANDIDATE' - ); - const newModalDialogVersionTestPlanReportsInCandidate = - newModalDialogVersionInCandidate.updatePhase.testPlanVersion - .testPlanReports; - const newModalDialogVersionTestPlanReportsInCandidateCount = - newModalDialogVersionTestPlanReportsInCandidate.length; + const { + testPlanVersion: newModalDialogVersionInDraftWithOldResults + } = await updateVersionToPhaseQuery( + newModalDialogVersion.id, + oldModalDialogVersion.id, + 'DRAFT' + ); + const newModalDialogVersionTestPlanReportsInDraftWithOldResults = + newModalDialogVersionInDraftWithOldResults.updatePhase + .testPlanVersion.testPlanReports; + const newModalDialogVersionTestPlanReportsInDraftWithOldResultsCount = + newModalDialogVersionTestPlanReportsInDraftWithOldResults.length; // Get VO+Firefox-specific tests count for new version - const newModalDialogVersionVOFirefoxCompletedTestsInCandidateCount = + const newModalDialogVersionVOFirefoxCompletedTestsInDraftWithOldResultsCount = countCompletedTests( - newModalDialogVersionTestPlanReportsInCandidate.filter( + newModalDialogVersionTestPlanReportsInDraftWithOldResults.filter( el => el.at.id == 3 && el.browser.id == 1 ) ); @@ -569,16 +585,16 @@ describe('data management', () => { expect(newModalDialogVersionTestPlanReportsInRDCount).toBe(0); expect(newModalDialogVersionTestPlanReportsInDraftCount).toEqual(1); expect( - newModalDialogVersionTestPlanReportsInCandidateCount + newModalDialogVersionTestPlanReportsInDraftWithOldResultsCount ).toEqual(oldModalDialogVersionTestPlanReportsCount); expect( oldModalDialogVersionVOFirefoxCompletedTestsCount ).toBeGreaterThan( - newModalDialogVersionVOFirefoxCompletedTestsInCandidateCount + newModalDialogVersionVOFirefoxCompletedTestsInDraftWithOldResultsCount ); expect( - newModalDialogVersionVOFirefoxCompletedTestsInCandidateCount + newModalDialogVersionVOFirefoxCompletedTestsInDraftWithOldResultsCount ).toEqual(0); }); }); @@ -680,9 +696,7 @@ describe('data management', () => { oldModalDialogVersion.id, 'CANDIDATE' ); - }).rejects.toThrow( - /Cannot set phase to candidate because the following required reports have not been collected or finalized:/i - ); + }).rejects.toThrow(/No reports have been marked as final/i); // https://github.com/w3c/aria-at/compare/5fe7afd82fe51c185b8661276105190a59d47322..d0e16b42179de6f6c070da2310e99de837c71215 // Modal Dialog was updated to show have differences between several NVDA and JAWS tests @@ -704,4 +718,61 @@ describe('data management', () => { expect(newModalDialogVersionTestPlanReportsInDraftCount).toEqual(1); }); }); + + it('updates test plan version but removes marked as final for test plan report when new report has incomplete runs', async () => { + await dbCleaner(async () => { + function markedFinalAtReduce(acc, curr) { + return acc + (curr.markedFinalAt ? 1 : 0); + } + + const testPlanVersions = await testPlanVersionsQuery(); + + const [oldCommandButtonVersion] = + testPlanVersions.testPlanVersions.filter( + e => + e.testPlan.directory === 'command-button' && + e.phase === 'DRAFT' && + e.metadata.testFormatVersion === 2 + ); + + const oldCommandButtonVersionMarkedFinalReportsCount = + oldCommandButtonVersion.testPlanReports.reduce( + markedFinalAtReduce, + 0 + ); + + const [newCommandButtonVersion] = + testPlanVersions.testPlanVersions.filter( + e => + e.testPlan.directory === 'command-button' && + e.phase === 'RD' && + e.metadata.testFormatVersion === 2 + ); + + const { testPlanVersion: newCommandButtonVersionInDraft } = + await updateVersionToPhaseQuery( + newCommandButtonVersion.id, + oldCommandButtonVersion.id, + 'DRAFT' + ); + const newCommandButtonVersionInDraftMarkedFinalReportsCount = + newCommandButtonVersionInDraft.updatePhase.testPlanVersion.testPlanReports.reduce( + markedFinalAtReduce, + 0 + ); + + // The difference between them is that there have been updated setting identifiers for VoiceOver tests; + // 2 were switched to quickNavOn -> singleQuickKeyNavOn + // + // Based on https://github.com/w3c/aria-at/compare/d9a19f8...565a87b#diff-4e3dcd0a202f268ebec2316344f136c3a83d6e03b3f726775cb46c57322ff3a0, + // only 'navForwardsToButton' and 'navBackToButton' tests were affected. The individual tests for 'reqInfoAboutButton' + // should still match + // + // This means only 1 test plan report should be affected and now unmarked as final because the JAWS and NVDA + // reports are unaffected + expect( + newCommandButtonVersionInDraftMarkedFinalReportsCount + ).toEqual(oldCommandButtonVersionMarkedFinalReportsCount - 1); + }); + }); }); From 3c03686f18aa5b9048b1f594fcdfb1fc43c92ef5 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 24 Jan 2024 17:33:35 -0500 Subject: [PATCH 10/11] Update comments on test --- server/tests/integration/dataManagement.test.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/server/tests/integration/dataManagement.test.js b/server/tests/integration/dataManagement.test.js index 064f20c0f..4b3ce96cf 100644 --- a/server/tests/integration/dataManagement.test.js +++ b/server/tests/integration/dataManagement.test.js @@ -761,15 +761,16 @@ describe('data management', () => { 0 ); - // The difference between them is that there have been updated setting identifiers for VoiceOver tests; - // 2 were switched to quickNavOn -> singleQuickKeyNavOn + // The difference between them is that there have been updated settings for VoiceOver tests; + // 2 were switched from 'quickNavOn' to 'singleQuickKeyNavOn' // // Based on https://github.com/w3c/aria-at/compare/d9a19f8...565a87b#diff-4e3dcd0a202f268ebec2316344f136c3a83d6e03b3f726775cb46c57322ff3a0, - // only 'navForwardsToButton' and 'navBackToButton' tests were affected. The individual tests for 'reqInfoAboutButton' - // should still match + // only 'navForwardsToButton' and 'navBackToButton' tests were affected. The individual tests for + // 'reqInfoAboutButton' should still match // - // This means only 1 test plan report should be affected and now unmarked as final because the JAWS and NVDA - // reports are unaffected + // This means only 1 test plan report should be affected, for VoiceOver and now unmarked as final. + // The single JAWS and NVDA reports should be unaffected + expect(oldCommandButtonVersionMarkedFinalReportsCount).toEqual(3); expect( newCommandButtonVersionInDraftMarkedFinalReportsCount ).toEqual(oldCommandButtonVersionMarkedFinalReportsCount - 1); From 20e841e6bcbc756d2bcb47056b891205419ef93b Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Mon, 29 Jan 2024 13:03:00 -0500 Subject: [PATCH 11/11] Update dataManagement.test.js --- .../tests/integration/dataManagement.test.js | 300 +++++++----------- 1 file changed, 107 insertions(+), 193 deletions(-) diff --git a/server/tests/integration/dataManagement.test.js b/server/tests/integration/dataManagement.test.js index 4b3ce96cf..660afc968 100644 --- a/server/tests/integration/dataManagement.test.js +++ b/server/tests/integration/dataManagement.test.js @@ -83,15 +83,17 @@ const testPlanVersionsQuery = () => { const updateVersionToPhaseQuery = ( testPlanVersionId, - testPlanVersionDataToIncludeId, - phase + phase, + { testPlanVersionDataToIncludeId } = {} ) => { return mutate(gql` mutation { testPlanVersion(id: ${testPlanVersionId}) { updatePhase( phase: ${phase} - testPlanVersionDataToIncludeId: ${testPlanVersionDataToIncludeId} + testPlanVersionDataToIncludeId: ${ + testPlanVersionDataToIncludeId ?? null + } ) { testPlanVersion { phase @@ -157,6 +159,59 @@ const updateVersionToPhaseQuery = ( `); }; +const findOrCreateTestPlanReportQuery = ( + testPlanVersionId, + atId, + browserId +) => { + return mutate(gql` + mutation { + findOrCreateTestPlanReport(input: { + testPlanVersionId: ${testPlanVersionId} + atId: ${atId} + browserId: ${browserId} + }) { + populatedData { + testPlanReport { + id + at { + id + } + browser { + id + } + } + testPlanVersion { + id + phase + testPlanReports { + id + } + } + } + created { + locationOfData + } + } + } + `); +}; + +const markAsFinal = testPlanReportId => { + return mutate(gql` + mutation { + testPlanReport(id: ${testPlanReportId}) { + markAsFinal { + testPlanReport { + id + markedFinalAt + } + } + } + } + `); +}; + const countCompletedTests = testPlanReports => { return testPlanReports.reduce((acc, testPlanReport) => { return ( @@ -187,17 +242,7 @@ describe('data management', () => { // This version is in 'CANDIDATE' phase. Set it to DRAFT // This will also remove the associated TestPlanReports markedFinalAt values const testPlanVersionId = candidateTestPlanVersion.id; - await mutate(gql` - mutation { - testPlanVersion(id: ${testPlanVersionId}) { - updatePhase(phase: DRAFT) { - testPlanVersion { - phase - } - } - } - } - `); + await updateVersionToPhaseQuery(testPlanVersionId, 'DRAFT'); const previous = await query(gql` query { @@ -214,33 +259,15 @@ describe('data management', () => { previous.testPlanVersion.testPlanReports[0].id; // Need to approve at least one of the associated reports - await mutate(gql` - mutation { - testPlanReport(id: ${previousPhaseTestPlanReportId}) { - markAsFinal { - testPlanReport { - id - markedFinalAt - } - } - } - } - `); + await markAsFinal(previousPhaseTestPlanReportId); // Check to see that the testPlanVersion cannot be updated until the reports have been // finalized await expect(() => { - return mutate(gql` - mutation { - testPlanVersion(id: ${testPlanVersionId}) { - updatePhase(phase: CANDIDATE) { - testPlanVersion { - phase - } - } - } - } - `); + return updateVersionToPhaseQuery( + testPlanVersionId, + 'CANDIDATE' + ); }).rejects.toThrow( /Cannot set phase to candidate because the following required reports have not been collected or finalized:/i ); @@ -254,47 +281,21 @@ describe('data management', () => { `); for (const testPlanReport of testPlanReportsToMarkAsFinalResult.testPlanReports) { - await mutate(gql` - mutation { - testPlanReport(id: ${testPlanReport.id}) { - markAsFinal { - testPlanReport { - id - markedFinalAt - } - } - } - } - - `); + await markAsFinal(testPlanReport.id); } - const candidateResult = await mutate(gql` - mutation { - testPlanVersion(id: ${testPlanVersionId}) { - updatePhase(phase: CANDIDATE) { - testPlanVersion { - phase - } - } - } - } - `); + const candidateResult = await updateVersionToPhaseQuery( + testPlanVersionId, + 'CANDIDATE' + ); const candidateResultPhase = candidateResult.testPlanVersion.updatePhase.testPlanVersion .phase; - const recommendedResult = await mutate(gql` - mutation { - testPlanVersion(id: ${testPlanVersionId}) { - updatePhase(phase: RECOMMENDED) { - testPlanVersion { - phase - } - } - } - } - `); + const recommendedResult = await updateVersionToPhaseQuery( + testPlanVersionId, + 'RECOMMENDED' + ); const recommendedResultPhase = recommendedResult.testPlanVersion.updatePhase.testPlanVersion .phase; @@ -322,17 +323,7 @@ describe('data management', () => { // This version is in 'CANDIDATE' phase. Set it to DRAFT // This will also remove the associated TestPlanReports markedFinalAt values const oldTestPlanVersionId = oldModalDialogVersion.id; - await mutate(gql` - mutation { - testPlanVersion(id: ${oldTestPlanVersionId}) { - updatePhase(phase: DRAFT) { - testPlanVersion { - phase - } - } - } - } - `); + await updateVersionToPhaseQuery(oldTestPlanVersionId, 'DRAFT'); const oldModalDialogVersionTestPlanReports = oldModalDialogVersion.testPlanReports; @@ -375,8 +366,10 @@ describe('data management', () => { const { testPlanVersion: newModalDialogVersionInDraft } = await updateVersionToPhaseQuery( newModalDialogVersion.id, - oldModalDialogVersion.id, - 'DRAFT' + 'DRAFT', + { + testPlanVersionDataToIncludeId: oldModalDialogVersion.id + } ); const newModalDialogVersionTestPlanReportsInDraft = newModalDialogVersionInDraft.updatePhase.testPlanVersion @@ -458,17 +451,7 @@ describe('data management', () => { // This version is in 'CANDIDATE' phase. Set it to DRAFT // This will also remove the associated TestPlanReports markedFinalAt values const oldTestPlanVersionId = oldModalDialogVersion.id; - await mutate(gql` - mutation { - testPlanVersion(id: ${oldTestPlanVersionId}) { - updatePhase(phase: DRAFT) { - testPlanVersion { - phase - } - } - } - } - `); + await updateVersionToPhaseQuery(oldTestPlanVersionId, 'DRAFT'); const oldModalDialogVersionTestPlanReports = oldModalDialogVersion.testPlanReports; @@ -492,20 +475,7 @@ describe('data management', () => { const newModalDialogVersionTestPlanReportsInRDCount = newModalDialogVersion.testPlanReports.length; - await mutate(gql` - mutation { - testPlanVersion(id: ${newModalDialogVersion.id}) { - updatePhase(phase: DRAFT) { - testPlanVersion { - phase - testPlanReports { - id - } - } - } - } - } - `); + await updateVersionToPhaseQuery(newModalDialogVersion.id, 'DRAFT'); const { findOrCreateTestPlanReport: { @@ -513,37 +483,11 @@ describe('data management', () => { testPlanVersion: newModalDialogVersionInDraft } } - } = await mutate(gql` - mutation { - findOrCreateTestPlanReport(input: { - testPlanVersionId: ${newModalDialogVersion.id} - atId: 3 - browserId: 1 - }) { - populatedData { - testPlanReport { - id - at { - id - } - browser { - id - } - } - testPlanVersion { - id - phase - testPlanReports { - id - } - } - } - created { - locationOfData - } - } - } - `); + } = await findOrCreateTestPlanReportQuery( + newModalDialogVersion.id, + 3, + 1 + ); const newModalDialogVersionTestPlanReportsInDraftCount = newModalDialogVersionInDraft.testPlanReports.length; @@ -552,8 +496,10 @@ describe('data management', () => { testPlanVersion: newModalDialogVersionInDraftWithOldResults } = await updateVersionToPhaseQuery( newModalDialogVersion.id, - oldModalDialogVersion.id, - 'DRAFT' + 'DRAFT', + { + testPlanVersionDataToIncludeId: oldModalDialogVersion.id + } ); const newModalDialogVersionTestPlanReportsInDraftWithOldResults = newModalDialogVersionInDraftWithOldResults.updatePhase @@ -633,20 +579,7 @@ describe('data management', () => { const newModalDialogVersionTestPlanReportsInRDCount = newModalDialogVersion.testPlanReports.length; - await mutate(gql` - mutation { - testPlanVersion(id: ${newModalDialogVersion.id}) { - updatePhase(phase: DRAFT) { - testPlanVersion { - phase - testPlanReports { - id - } - } - } - } - } - `); + await updateVersionToPhaseQuery(newModalDialogVersion.id, 'DRAFT'); const { findOrCreateTestPlanReport: { @@ -654,37 +587,11 @@ describe('data management', () => { testPlanVersion: newModalDialogVersionInDraft } } - } = await mutate(gql` - mutation { - findOrCreateTestPlanReport(input: { - testPlanVersionId: ${newModalDialogVersion.id} - atId: 3 - browserId: 3 - }) { - populatedData { - testPlanReport { - id - at { - id - } - browser { - id - } - } - testPlanVersion { - id - phase - testPlanReports { - id - } - } - } - created { - locationOfData - } - } - } - `); + } = await findOrCreateTestPlanReportQuery( + newModalDialogVersion.id, + 3, + 3 + ); const newModalDialogVersionTestPlanReportsInDraftCount = newModalDialogVersionInDraft.testPlanReports.length; @@ -693,8 +600,10 @@ describe('data management', () => { await expect(() => { return updateVersionToPhaseQuery( newModalDialogVersion.id, - oldModalDialogVersion.id, - 'CANDIDATE' + 'CANDIDATE', + { + testPlanVersionDataToIncludeId: oldModalDialogVersion.id + } ); }).rejects.toThrow(/No reports have been marked as final/i); @@ -752,8 +661,11 @@ describe('data management', () => { const { testPlanVersion: newCommandButtonVersionInDraft } = await updateVersionToPhaseQuery( newCommandButtonVersion.id, - oldCommandButtonVersion.id, - 'DRAFT' + 'DRAFT', + { + testPlanVersionDataToIncludeId: + oldCommandButtonVersion.id + } ); const newCommandButtonVersionInDraftMarkedFinalReportsCount = newCommandButtonVersionInDraft.updatePhase.testPlanVersion.testPlanReports.reduce( @@ -770,7 +682,9 @@ describe('data management', () => { // // This means only 1 test plan report should be affected, for VoiceOver and now unmarked as final. // The single JAWS and NVDA reports should be unaffected - expect(oldCommandButtonVersionMarkedFinalReportsCount).toEqual(3); + expect( + newCommandButtonVersionInDraftMarkedFinalReportsCount + ).toBeGreaterThan(1); expect( newCommandButtonVersionInDraftMarkedFinalReportsCount ).toEqual(oldCommandButtonVersionMarkedFinalReportsCount - 1);