user-background.cy.ts 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /**
  2. * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
  3. * SPDX-License-Identifier: AGPL-3.0-or-later
  4. */
  5. import { User } from '@nextcloud/cypress'
  6. import { defaultPrimary, defaultBackground, pickRandomColor, validateBodyThemingCss } from './themingUtils'
  7. const admin = new User('admin', 'admin')
  8. describe('User default background settings', function() {
  9. before(function() {
  10. cy.resetAdminTheming()
  11. cy.resetUserTheming(admin)
  12. cy.createRandomUser().then((user: User) => {
  13. cy.login(user)
  14. })
  15. })
  16. it('See the user background settings', function() {
  17. cy.visit('/settings/user/theming')
  18. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  19. cy.get('[data-user-theming-background-settings]').should('be.visible')
  20. })
  21. // Default cloud background is not rendered if admin theming background remains unchanged
  22. it('Default cloud background is not rendered', function() {
  23. cy.get(`[data-user-theming-background-shipped="${defaultBackground}"]`).should('not.exist')
  24. })
  25. it('Default is selected on new users', function() {
  26. cy.get('[data-user-theming-background-default]').should('be.visible')
  27. cy.get('[data-user-theming-background-default]').should('have.class', 'background--active')
  28. })
  29. it('Default background has accessibility attribute set', function() {
  30. cy.get('[data-user-theming-background-default]').should('have.attr', 'aria-pressed', 'true')
  31. })
  32. })
  33. describe('User select shipped backgrounds and remove background', function() {
  34. before(function() {
  35. cy.createRandomUser().then((user: User) => {
  36. cy.login(user)
  37. })
  38. })
  39. it('See the user background settings', function() {
  40. cy.visit('/settings/user/theming')
  41. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  42. cy.get('[data-user-theming-background-settings]').should('be.visible')
  43. })
  44. it('Select a shipped background', function() {
  45. const background = 'anatoly-mikhaltsov-butterfly-wing-scale.jpg'
  46. cy.intercept('*/apps/theming/background/shipped').as('setBackground')
  47. // Select background
  48. cy.get(`[data-user-theming-background-shipped="${background}"]`).click()
  49. // Set the accessibility state
  50. cy.get(`[data-user-theming-background-shipped="${background}"]`).should('have.attr', 'aria-pressed', 'true')
  51. // Validate changed background and primary
  52. cy.wait('@setBackground')
  53. cy.waitUntil(() => validateBodyThemingCss('#a53c17', background, '#652e11'))
  54. })
  55. it('Select a bright shipped background', function() {
  56. const background = 'bernie-cetonia-aurata-take-off-composition.jpg'
  57. cy.intercept('*/apps/theming/background/shipped').as('setBackground')
  58. // Select background
  59. cy.get(`[data-user-theming-background-shipped="${background}"]`).click()
  60. // Set the accessibility state
  61. cy.get(`[data-user-theming-background-shipped="${background}"]`).should('have.attr', 'aria-pressed', 'true')
  62. // Validate changed background and primary
  63. cy.wait('@setBackground')
  64. cy.waitUntil(() => validateBodyThemingCss('#56633d', background, '#dee0d3'))
  65. })
  66. it('Remove background', function() {
  67. cy.intercept('*/apps/theming/background/color').as('clearBackground')
  68. // Clear background
  69. cy.get('[data-user-theming-background-color]').click()
  70. // Set the accessibility state
  71. cy.get('[data-user-theming-background-color]').should('have.attr', 'aria-pressed', 'true')
  72. // Validate clear background
  73. cy.wait('@clearBackground')
  74. cy.waitUntil(() => validateBodyThemingCss('#56633d', null, '#dee0d3'))
  75. })
  76. })
  77. describe('User select a custom color', function() {
  78. before(function() {
  79. cy.createRandomUser().then((user: User) => {
  80. cy.login(user)
  81. })
  82. })
  83. it('See the user background settings', function() {
  84. cy.visit('/settings/user/theming')
  85. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  86. cy.get('[data-user-theming-background-settings]').should('be.visible')
  87. })
  88. it('Select a custom color', function() {
  89. cy.intercept('*/apps/theming/background/color').as('setColor')
  90. cy.get('[data-user-theming-background-color]').click()
  91. cy.get('.color-picker__simple-color-circle').eq(5).click()
  92. // Validate custom colour change
  93. cy.wait('@setColor')
  94. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, null, '#a5b872'))
  95. })
  96. })
  97. describe('User select a bright custom color and remove background', function() {
  98. before(function() {
  99. cy.createRandomUser().then((user: User) => {
  100. cy.login(user)
  101. })
  102. })
  103. it('See the user background settings', function() {
  104. cy.visit('/settings/user/theming')
  105. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  106. cy.get('[data-user-theming-background-settings]').should('be.visible')
  107. })
  108. it('Remove background', function() {
  109. cy.intercept('*/apps/theming/background/color').as('clearBackground')
  110. // Clear background
  111. cy.get('[data-user-theming-background-color]').click()
  112. cy.get('[data-user-theming-background-color]').click()
  113. // Validate clear background
  114. cy.wait('@clearBackground')
  115. cy.waitUntil(() => validateBodyThemingCss(undefined, null))
  116. })
  117. it('Select a custom color', function() {
  118. cy.intercept('*/apps/theming/background/color').as('setColor')
  119. // Pick one of the bright color preset
  120. cy.get('[data-user-theming-background-color]').scrollIntoView()
  121. cy.get('[data-user-theming-background-color]').click()
  122. cy.get('.color-picker__simple-color-circle:eq(4)').click()
  123. // Validate custom colour change
  124. cy.wait('@setColor')
  125. })
  126. it('See the header being inverted', function() {
  127. cy.waitUntil(() => cy.window().then((win) => {
  128. const firstEntry = win.document.querySelector('.app-menu-main li img')
  129. if (!firstEntry) {
  130. return false
  131. }
  132. return getComputedStyle(firstEntry).filter === 'invert(1)'
  133. }))
  134. })
  135. it('Select another but non-bright shipped background', function() {
  136. const background = 'anatoly-mikhaltsov-butterfly-wing-scale.jpg'
  137. cy.intercept('*/apps/theming/background/shipped').as('setBackground')
  138. // Select background
  139. cy.get(`[data-user-theming-background-shipped="${background}"]`).click()
  140. // Validate changed background and primary
  141. cy.wait('@setBackground')
  142. cy.waitUntil(() => validateBodyThemingCss('#a53c17', background, '#652e11'))
  143. })
  144. it('See the header NOT being inverted this time', function() {
  145. cy.waitUntil(() => cy.window().then((win) => {
  146. const firstEntry = win.document.querySelector('.app-menu-main li')
  147. if (!firstEntry) {
  148. return false
  149. }
  150. return getComputedStyle(firstEntry).filter === 'none'
  151. }))
  152. })
  153. })
  154. describe('User select a custom background', function() {
  155. const image = 'image.jpg'
  156. before(function() {
  157. cy.createRandomUser().then((user: User) => {
  158. cy.uploadFile(user, image, 'image/jpeg')
  159. cy.login(user)
  160. })
  161. })
  162. it('See the user background settings', function() {
  163. cy.visit('/settings/user/theming')
  164. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  165. cy.get('[data-user-theming-background-settings]').should('be.visible')
  166. })
  167. it('Select a custom background', function() {
  168. cy.intercept('*/apps/theming/background/custom').as('setBackground')
  169. cy.on('uncaught:exception', (err) => {
  170. // This can happen because of blink engine & skeleton animation, its not a bug just engine related.
  171. if (err.message.includes('ResizeObserver loop limit exceeded')) {
  172. return false
  173. }
  174. })
  175. // Pick background
  176. cy.get('[data-user-theming-background-custom]').click()
  177. cy.get('.file-picker__files tr').contains(image).click()
  178. cy.get('.dialog__actions .button-vue--vue-primary').click()
  179. // Wait for background to be set
  180. cy.wait('@setBackground')
  181. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, 'apps/theming/background?v=', '#2f2221'))
  182. })
  183. })
  184. describe('User changes settings and reload the page', function() {
  185. const image = 'image.jpg'
  186. const colorFromImage = '#2f2221'
  187. before(function() {
  188. cy.createRandomUser().then((user: User) => {
  189. cy.uploadFile(user, image, 'image/jpeg')
  190. cy.login(user)
  191. })
  192. })
  193. it('See the user background settings', function() {
  194. cy.visit('/settings/user/theming')
  195. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  196. cy.get('[data-user-theming-background-settings]').should('be.visible')
  197. })
  198. it('Select a custom background', function() {
  199. cy.intercept('*/apps/theming/background/custom').as('setBackground')
  200. cy.on('uncaught:exception', (err) => {
  201. // This can happen because of blink engine & skeleton animation, its not a bug just engine related.
  202. if (err.message.includes('ResizeObserver loop limit exceeded')) {
  203. return false
  204. }
  205. })
  206. // Pick background
  207. cy.get('[data-user-theming-background-custom]').click()
  208. cy.get('.file-picker__files tr').contains(image).click()
  209. cy.get('.dialog__actions .button-vue--vue-primary').click()
  210. // Wait for background to be set
  211. cy.wait('@setBackground')
  212. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, 'apps/theming/background?v=', colorFromImage))
  213. })
  214. it('Select a custom color', function() {
  215. cy.intercept('*/apps/theming/background/color').as('setColor')
  216. cy.get('[data-user-theming-background-color]').click()
  217. cy.get('.color-picker__simple-color-circle:eq(5)').click()
  218. cy.get('[data-user-theming-background-color]').click()
  219. // Validate clear background
  220. cy.wait('@setColor')
  221. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, null, '#a5b872'))
  222. })
  223. it('Select a custom primary color', function() {
  224. cy.intercept('/ocs/v2.php/apps/provisioning_api/api/v1/config/users/theming/primary_color').as('setPrimaryColor')
  225. cy.get('[data-user-theming-primary-color-trigger]').scrollIntoView()
  226. cy.get('[data-user-theming-primary-color-trigger]').click()
  227. // eslint-disable-next-line cypress/no-unnecessary-waiting
  228. cy.wait(500)
  229. cy.get('.color-picker__simple-color-circle').should('be.visible')
  230. cy.get('.color-picker__simple-color-circle:eq(2)').click()
  231. cy.get('[data-user-theming-primary-color-trigger]').click()
  232. // Validate clear background
  233. cy.wait('@setPrimaryColor')
  234. cy.waitUntil(() => validateBodyThemingCss('#c98879', null, '#a5b872'))
  235. })
  236. it('Reload the page and validate persistent changes', function() {
  237. cy.reload()
  238. cy.waitUntil(() => validateBodyThemingCss('#c98879', null, '#a5b872'))
  239. })
  240. })