1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
const themesToTest = ['light', 'dark', 'light-highcontrast', 'dark-highcontrast']
const testCases = {
'Main text': {
foregroundColors: [
'color-main-text',
// 'color-text-light', deprecated
// 'color-text-lighter', deprecated
'color-text-maxcontrast',
],
backgroundColors: [
'color-main-background',
'color-background-hover',
'color-background-dark',
// 'color-background-darker', this should only be used for elements not for text
],
},
'blurred background': {
foregroundColors: [
'color-main-text',
'color-text-maxcontrast-blur',
],
backgroundColors: [
'color-main-background-blur',
],
},
Primary: {
foregroundColors: [
'color-primary-text',
],
backgroundColors: [
// 'color-primary-default', this should only be used for elements not for text!
// 'color-primary-hover', this should only be used for elements and not for text!
'color-primary',
],
},
'Primary light': {
foregroundColors: [
'color-primary-light-text',
],
backgroundColors: [
'color-primary-light',
'color-primary-light-hover',
],
},
'Primary element': {
foregroundColors: [
'color-primary-element-text',
'color-primary-element-text-dark',
],
backgroundColors: [
'color-primary-element',
'color-primary-element-hover',
],
},
'Primary element light': {
foregroundColors: [
'color-primary-element-light-text',
],
backgroundColors: [
'color-primary-element-light',
'color-primary-element-light-hover',
],
},
'Servity information texts': {
foregroundColors: [
'color-error-text',
'color-warning-text',
'color-success-text',
'color-info-text',
],
backgroundColors: [
'color-main-background',
'color-background-hover',
'color-main-background-blur',
],
},
}
/**
* Create a wrapper element with color and background set
*
* @param foreground The foreground color (css variable without leading --)
* @param background The background color
*/
function createTestCase(foreground: string, background: string) {
const wrapper = document.createElement('div')
wrapper.style.padding = '14px'
wrapper.style.color = `var(--${foreground})`
wrapper.style.backgroundColor = `var(--${background})`
if (background.includes('blur')) {
wrapper.style.backdropFilter = 'var(--filter-background-blur)'
}
const testCase = document.createElement('div')
testCase.innerText = `${foreground} ${background}`
testCase.setAttribute('data-cy-testcase', '')
wrapper.appendChild(testCase)
return wrapper
}
describe('Accessibility of Nextcloud theming colors', () => {
for (const theme of themesToTest) {
context(`Theme: ${theme}`, () => {
before(() => {
cy.createRandomUser().then(($user) => {
// set user theme
cy.runOccCommand(`user:setting -- '${$user.userId}' theming enabled-themes '[\\"${theme}\\"]'`)
cy.login($user)
cy.visit('/')
cy.injectAxe({ axeCorePath: 'node_modules/axe-core/axe.min.js' })
})
})
beforeEach(() => {
cy.document().then(doc => {
// Unset background image and thus use background-color for testing blur background (images do not work with axe-core)
doc.body.style.backgroundImage = 'unset'
const root = doc.querySelector('main')
if (root === null) {
throw new Error('No test root found')
}
root.innerHTML = ''
})
})
for (const [name, { backgroundColors, foregroundColors }] of Object.entries(testCases)) {
context(`Accessibility of CSS color variables for ${name}`, () => {
for (const foreground of foregroundColors) {
for (const background of backgroundColors) {
it(`color contrast of ${foreground} on ${background}`, () => {
cy.document().then(doc => {
const element = createTestCase(foreground, background)
const root = doc.querySelector('main')
// eslint-disable-next-line no-unused-expressions
expect(root).not.to.be.undefined
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
root!.appendChild(element)
cy.checkA11y('[data-cy-testcase]', {
runOnly: ['color-contrast'],
})
})
})
}
}
})
}
})
}
})
|