user-settings_background.cy.ts 10 KB

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