Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/smoke/src/areas/accessibility/accessibility.test.ts
5282 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Application, Logger, Quality } from '../../../../automation';
7
import { installAllHandlers } from '../../utils';
8
9
export function setup(logger: Logger, opts: { web?: boolean }, quality: Quality) {
10
describe('Accessibility', function () {
11
12
// Increase timeout for accessibility scans
13
this.timeout(2 * 60 * 1000);
14
15
// Retry tests to minimize flakiness
16
this.retries(2);
17
18
// Shared before/after handling
19
installAllHandlers(logger);
20
21
let app: Application;
22
23
before(async function () {
24
app = this.app as Application;
25
});
26
27
describe('Workbench', function () {
28
29
(opts.web ? it.skip : it)('workbench has no accessibility violations', async function () {
30
// Wait for workbench to be fully loaded
31
await app.code.waitForElement('.monaco-workbench');
32
33
await app.code.driver.assertNoAccessibilityViolations({
34
selector: '.monaco-workbench',
35
excludeRules: {
36
// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect
37
'link-in-text-block': ['command:workbench.action.chat.generateInstructions'],
38
// Monaco lists use aria-multiselectable on role="list" and aria-setsize/aria-posinset/aria-selected on role="dialog" rows
39
// These violations appear intermittently when notification lists or other dynamic lists are visible
40
// Note: patterns match against HTML string, not CSS selectors, so no leading dots
41
'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],
42
// Monaco lists may temporarily contain dialog children during extension activation errors
43
'aria-required-children': ['monaco-list']
44
}
45
});
46
});
47
48
it('activity bar has no accessibility violations', async function () {
49
await app.code.waitForElement('.activitybar');
50
51
await app.code.driver.assertNoAccessibilityViolations({
52
selector: '.activitybar'
53
});
54
});
55
56
it('sidebar has no accessibility violations', async function () {
57
await app.code.waitForElement('.sidebar');
58
59
await app.code.driver.assertNoAccessibilityViolations({
60
selector: '.sidebar'
61
});
62
});
63
64
it('status bar has no accessibility violations', async function () {
65
await app.code.waitForElement('.statusbar');
66
67
await app.code.driver.assertNoAccessibilityViolations({
68
selector: '.statusbar'
69
});
70
});
71
});
72
73
// Chat is not available in web mode
74
if (quality !== Quality.Dev && quality !== Quality.OSS && !opts.web) {
75
describe('Chat', function () {
76
77
it('chat panel has no accessibility violations', async function () {
78
// Open chat panel
79
await app.workbench.quickaccess.runCommand('workbench.action.chat.open');
80
81
// Wait for chat view to be visible
82
await app.code.waitForElement('div[id="workbench.panel.chat"]');
83
84
await app.code.driver.assertNoAccessibilityViolations({
85
selector: 'div[id="workbench.panel.chat"]',
86
excludeRules: {
87
// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect
88
'link-in-text-block': ['command:workbench.action.chat.generateInstructions']
89
}
90
});
91
});
92
93
// Chat response test requires gallery service which is only available in non-Dev/OSS builds
94
it('chat response has no accessibility violations', async function () {
95
// Disable retries for this test - it modifies settings and retries cause issues
96
this.retries(0);
97
// Extend timeout for this test since AI responses can take a while
98
this.timeout(3 * 60 * 1000);
99
100
// Enable anonymous chat access
101
await app.workbench.settingsEditor.addUserSetting('chat.allowAnonymousAccess', 'true');
102
103
// Open chat panel
104
await app.workbench.quickaccess.runCommand('workbench.action.chat.open');
105
106
// Wait for chat view to be visible
107
await app.workbench.chat.waitForChatView();
108
109
// Send a simple message that does not require tools to avoid external path confirmations
110
await app.workbench.chat.sendMessage('Explain what "Hello World" means in programming. Include a short fenced code block that shows "Hello World".');
111
112
// Wait for the response to complete (1500 retries ~= 150 seconds at 100ms per retry)
113
await app.workbench.chat.waitForResponse(1500);
114
115
// Run accessibility check on the chat panel with the response
116
await app.code.driver.assertNoAccessibilityViolations({
117
selector: 'div[id="workbench.panel.chat"]',
118
excludeRules: {
119
// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect
120
'link-in-text-block': ['command:workbench.action.chat.generateInstructions'],
121
// Monaco lists use aria-multiselectable on role="list" and aria-selected on role="listitem"
122
// These are used intentionally for selection semantics even though technically not spec-compliant
123
'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],
124
// Some icon buttons have empty aria-label during rendering
125
'aria-command-name': ['codicon-plus'],
126
// Todo list widget has clear button nested inside expander button for layout purposes
127
'nested-interactive': ['todo-list-container']
128
}
129
});
130
});
131
132
it('chat terminal tool response has no accessibility violations', async function () {
133
// Disable retries for this test
134
this.retries(0);
135
// Extend timeout for this test since AI responses can take a while
136
this.timeout(3 * 60 * 1000);
137
138
// Enable anonymous chat access
139
await app.workbench.settingsEditor.addUserSetting('chat.allowAnonymousAccess', 'true');
140
// Enable auto-approve for tools so terminal commands run automatically
141
await app.workbench.settingsEditor.addUserSetting('chat.tools.global.autoApprove', 'true');
142
143
// Open chat panel
144
await app.workbench.quickaccess.runCommand('workbench.action.chat.open');
145
146
// Wait for chat view to be visible
147
await app.workbench.chat.waitForChatView();
148
149
// Send a terminal command request
150
await app.workbench.chat.sendMessage('Run ls in the terminal');
151
152
// Wait for the response to complete (1500 retries ~= 150 seconds at 100ms per retry)
153
await app.workbench.chat.waitForResponse(1500);
154
155
// Run accessibility check on the chat panel with the response
156
await app.code.driver.assertNoAccessibilityViolations({
157
selector: 'div[id="workbench.panel.chat"]',
158
excludeRules: {
159
// Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect
160
'link-in-text-block': ['command:workbench.action.chat.generateInstructions'],
161
// Monaco lists use aria-multiselectable on role="list" and aria-selected on role="listitem"
162
// These are used intentionally for selection semantics even though technically not spec-compliant
163
'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],
164
// Some icon buttons have empty aria-label during rendering
165
'aria-command-name': ['codicon-plus'],
166
// Todo list widget has clear button nested inside expander button for layout purposes
167
'nested-interactive': ['todo-list-container']
168
}
169
});
170
});
171
});
172
}
173
});
174
}
175
176