aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/theming/__tests__/accessibility.cy.ts128
-rw-r--r--apps/theming/css/default.css8
-rw-r--r--apps/theming/lib/Themes/DarkTheme.php8
-rw-r--r--apps/theming/lib/Themes/DefaultTheme.php2
-rw-r--r--cypress/e2e/theming/a11y-color-contrast.cy.ts153
-rw-r--r--cypress/support/e2e.ts1
6 files changed, 163 insertions, 137 deletions
diff --git a/apps/theming/__tests__/accessibility.cy.ts b/apps/theming/__tests__/accessibility.cy.ts
deleted file mode 100644
index 3bbf8a64972..00000000000
--- a/apps/theming/__tests__/accessibility.cy.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-// eslint-disable-next-line import/no-webpack-loader-syntax, import/no-unresolved
-import style from '!raw-loader!../css/default.css'
-
-const testCases = {
- 'Main text': {
- foregroundColors: [
- 'color-main-text',
- // 'color-text-light', deprecated
- // 'color-text-lighter', deprecated
- 'color-text-maxcontrast',
- 'color-text-maxcontrast-default',
- ],
- backgroundColors: [
- 'color-background-main',
- 'color-background-hover',
- 'color-background-dark',
- // 'color-background-darker', this should only be used for elements not for text
- ],
- },
- 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-background-main',
- 'color-background-hover',
- ],
- },
-}
-
-/**
- * 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.innerText = `${foreground} ${background}`
- wrapper.style.color = `var(--${foreground})`
- wrapper.style.backgroundColor = `var(--${background})`
- wrapper.style.padding = '4px'
- wrapper.setAttribute('data-cy-testcase', '')
- return wrapper
-}
-
-describe('Accessibility of Nextcloud theming', () => {
- before(() => {
- cy.injectAxe()
-
- const el = document.createElement('style')
- el.innerText = style
- document.head.appendChild(el)
- })
-
- beforeEach(() => {
- cy.document().then(doc => {
- const root = doc.querySelector('[data-cy-root]')
- if (root === null) {
- throw new Error('No test root found')
- }
- for (const child of root.children) {
- root.removeChild(child)
- }
- })
- })
-
- 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}`, () => {
- const element = createTestCase(foreground, background)
- cy.document().then(doc => {
- const root = doc.querySelector('[data-cy-root]')
- // 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]')
- })
- })
- }
- }
- })
- }
-})
diff --git a/apps/theming/css/default.css b/apps/theming/css/default.css
index 190ec0fb9cf..17b3eea8381 100644
--- a/apps/theming/css/default.css
+++ b/apps/theming/css/default.css
@@ -25,10 +25,10 @@
--color-error-rgb: 217,24,18;
--color-error-hover: #dd342f;
--color-error-text: #c61610;
- --color-warning: #c28900;
- --color-warning-rgb: 194,137,0;
- --color-warning-hover: #cea032;
- --color-warning-text: #8f6500;
+ --color-warning: #b88100;
+ --color-warning-rgb: 184,129,0;
+ --color-warning-hover: #c69a32;
+ --color-warning-text: #855d00;
--color-success: #2d7b41;
--color-success-rgb: 45,123,65;
--color-success-hover: #448955;
diff --git a/apps/theming/lib/Themes/DarkTheme.php b/apps/theming/lib/Themes/DarkTheme.php
index af374a01603..d33f13dc579 100644
--- a/apps/theming/lib/Themes/DarkTheme.php
+++ b/apps/theming/lib/Themes/DarkTheme.php
@@ -55,15 +55,15 @@ class DarkTheme extends DefaultTheme implements ITheme {
$colorMainText = '#D8D8D8';
$colorMainBackground = '#171717';
$colorMainBackgroundRGB = join(',', $this->util->hexToRGB($colorMainBackground));
- $colorTextMaxcontrast = $this->util->darken($colorMainText, 30);
+ $colorTextMaxcontrast = $this->util->darken($colorMainText, 28);
$colorBoxShadow = $this->util->darken($colorMainBackground, 70);
$colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow));
- $colorError = '#d91812';
+ $colorError = '#ee312b';
$colorWarning = '#c28900';
- $colorSuccess = '#2d7b41';
- $colorInfo = '#0071ad';
+ $colorSuccess = '#36914e';
+ $colorInfo = '#007bbd';
return array_merge(
$defaultVariables,
diff --git a/apps/theming/lib/Themes/DefaultTheme.php b/apps/theming/lib/Themes/DefaultTheme.php
index 44930e457fa..e215ade7b6d 100644
--- a/apps/theming/lib/Themes/DefaultTheme.php
+++ b/apps/theming/lib/Themes/DefaultTheme.php
@@ -112,7 +112,7 @@ class DefaultTheme implements ITheme {
$colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow));
$colorError = '#d91812';
- $colorWarning = '#c28900';
+ $colorWarning = '#b88100';
$colorSuccess = '#2d7b41';
$colorInfo = '#0071ad';
diff --git a/cypress/e2e/theming/a11y-color-contrast.cy.ts b/cypress/e2e/theming/a11y-color-contrast.cy.ts
new file mode 100644
index 00000000000..03a6814ea1f
--- /dev/null
+++ b/cypress/e2e/theming/a11y-color-contrast.cy.ts
@@ -0,0 +1,153 @@
+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'],
+ })
+ })
+ })
+ }
+ }
+ })
+ }
+ })
+ }
+})
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
index 2bc91f83ebd..6cf83e94961 100644
--- a/cypress/support/e2e.ts
+++ b/cypress/support/e2e.ts
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+import 'cypress-axe'
import './commands.ts'
// Fix ResizeObserver loop limit exceeded happening in Cypress only