a11y-color-contrast.cy.ts 4.1 KB

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