Path: blob/main/test/smoke/src/areas/accessibility/accessibility.test.ts
5282 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Application, Logger, Quality } from '../../../../automation';6import { installAllHandlers } from '../../utils';78export function setup(logger: Logger, opts: { web?: boolean }, quality: Quality) {9describe('Accessibility', function () {1011// Increase timeout for accessibility scans12this.timeout(2 * 60 * 1000);1314// Retry tests to minimize flakiness15this.retries(2);1617// Shared before/after handling18installAllHandlers(logger);1920let app: Application;2122before(async function () {23app = this.app as Application;24});2526describe('Workbench', function () {2728(opts.web ? it.skip : it)('workbench has no accessibility violations', async function () {29// Wait for workbench to be fully loaded30await app.code.waitForElement('.monaco-workbench');3132await app.code.driver.assertNoAccessibilityViolations({33selector: '.monaco-workbench',34excludeRules: {35// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect36'link-in-text-block': ['command:workbench.action.chat.generateInstructions'],37// Monaco lists use aria-multiselectable on role="list" and aria-setsize/aria-posinset/aria-selected on role="dialog" rows38// These violations appear intermittently when notification lists or other dynamic lists are visible39// Note: patterns match against HTML string, not CSS selectors, so no leading dots40'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],41// Monaco lists may temporarily contain dialog children during extension activation errors42'aria-required-children': ['monaco-list']43}44});45});4647it('activity bar has no accessibility violations', async function () {48await app.code.waitForElement('.activitybar');4950await app.code.driver.assertNoAccessibilityViolations({51selector: '.activitybar'52});53});5455it('sidebar has no accessibility violations', async function () {56await app.code.waitForElement('.sidebar');5758await app.code.driver.assertNoAccessibilityViolations({59selector: '.sidebar'60});61});6263it('status bar has no accessibility violations', async function () {64await app.code.waitForElement('.statusbar');6566await app.code.driver.assertNoAccessibilityViolations({67selector: '.statusbar'68});69});70});7172// Chat is not available in web mode73if (quality !== Quality.Dev && quality !== Quality.OSS && !opts.web) {74describe('Chat', function () {7576it('chat panel has no accessibility violations', async function () {77// Open chat panel78await app.workbench.quickaccess.runCommand('workbench.action.chat.open');7980// Wait for chat view to be visible81await app.code.waitForElement('div[id="workbench.panel.chat"]');8283await app.code.driver.assertNoAccessibilityViolations({84selector: 'div[id="workbench.panel.chat"]',85excludeRules: {86// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect87'link-in-text-block': ['command:workbench.action.chat.generateInstructions']88}89});90});9192// Chat response test requires gallery service which is only available in non-Dev/OSS builds93it('chat response has no accessibility violations', async function () {94// Disable retries for this test - it modifies settings and retries cause issues95this.retries(0);96// Extend timeout for this test since AI responses can take a while97this.timeout(3 * 60 * 1000);9899// Enable anonymous chat access100await app.workbench.settingsEditor.addUserSetting('chat.allowAnonymousAccess', 'true');101102// Open chat panel103await app.workbench.quickaccess.runCommand('workbench.action.chat.open');104105// Wait for chat view to be visible106await app.workbench.chat.waitForChatView();107108// Send a simple message that does not require tools to avoid external path confirmations109await app.workbench.chat.sendMessage('Explain what "Hello World" means in programming. Include a short fenced code block that shows "Hello World".');110111// Wait for the response to complete (1500 retries ~= 150 seconds at 100ms per retry)112await app.workbench.chat.waitForResponse(1500);113114// Run accessibility check on the chat panel with the response115await app.code.driver.assertNoAccessibilityViolations({116selector: 'div[id="workbench.panel.chat"]',117excludeRules: {118// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect119'link-in-text-block': ['command:workbench.action.chat.generateInstructions'],120// Monaco lists use aria-multiselectable on role="list" and aria-selected on role="listitem"121// These are used intentionally for selection semantics even though technically not spec-compliant122'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],123// Some icon buttons have empty aria-label during rendering124'aria-command-name': ['codicon-plus'],125// Todo list widget has clear button nested inside expander button for layout purposes126'nested-interactive': ['todo-list-container']127}128});129});130131it('chat terminal tool response has no accessibility violations', async function () {132// Disable retries for this test133this.retries(0);134// Extend timeout for this test since AI responses can take a while135this.timeout(3 * 60 * 1000);136137// Enable anonymous chat access138await app.workbench.settingsEditor.addUserSetting('chat.allowAnonymousAccess', 'true');139// Enable auto-approve for tools so terminal commands run automatically140await app.workbench.settingsEditor.addUserSetting('chat.tools.global.autoApprove', 'true');141142// Open chat panel143await app.workbench.quickaccess.runCommand('workbench.action.chat.open');144145// Wait for chat view to be visible146await app.workbench.chat.waitForChatView();147148// Send a terminal command request149await app.workbench.chat.sendMessage('Run ls in the terminal');150151// Wait for the response to complete (1500 retries ~= 150 seconds at 100ms per retry)152await app.workbench.chat.waitForResponse(1500);153154// Run accessibility check on the chat panel with the response155await app.code.driver.assertNoAccessibilityViolations({156selector: 'div[id="workbench.panel.chat"]',157excludeRules: {158// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect159'link-in-text-block': ['command:workbench.action.chat.generateInstructions'],160// Monaco lists use aria-multiselectable on role="list" and aria-selected on role="listitem"161// These are used intentionally for selection semantics even though technically not spec-compliant162'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],163// Some icon buttons have empty aria-label during rendering164'aria-command-name': ['codicon-plus'],165// Todo list widget has clear button nested inside expander button for layout purposes166'nested-interactive': ['todo-list-container']167}168});169});170});171}172});173}174175176