user-background.cy.ts 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /**
  2. * @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
  3. *
  4. * @author John Molakvoæ <skjnldsv@protonmail.com>
  5. *
  6. * @license AGPL-3.0-or-later
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. import { User } from '@nextcloud/cypress'
  23. import { pickRandomColor, validateBodyThemingCss } from './themingUtils'
  24. const defaultPrimary = '#006aa3'
  25. const defaultBackground = 'kamil-porembinski-clouds.jpg'
  26. const admin = new User('admin', 'admin')
  27. describe('User default background settings', function() {
  28. before(function() {
  29. cy.resetAdminTheming()
  30. cy.resetUserTheming(admin)
  31. cy.createRandomUser().then((user: User) => {
  32. cy.login(user)
  33. })
  34. })
  35. it('See the user background settings', function() {
  36. cy.visit('/settings/user/theming')
  37. cy.get('[data-user-theming-background-settings]').scrollIntoView().should('be.visible')
  38. })
  39. // Default cloud background is not rendered if admin theming background remains unchanged
  40. it('Default cloud background is not rendered', function() {
  41. cy.get(`[data-user-theming-background-shipped="${defaultBackground}"]`).should('not.exist')
  42. })
  43. it('Default is selected on new users', function() {
  44. cy.get('[data-user-theming-background-default]').should('be.visible')
  45. cy.get('[data-user-theming-background-default]').should('have.class', 'background--active')
  46. })
  47. })
  48. describe('User select shipped backgrounds and remove background', function() {
  49. before(function() {
  50. cy.createRandomUser().then((user: User) => {
  51. cy.login(user)
  52. })
  53. })
  54. it('See the user background settings', function() {
  55. cy.visit('/settings/user/theming')
  56. cy.get('[data-user-theming-background-settings]').scrollIntoView().should('be.visible')
  57. })
  58. it('Select a shipped background', function() {
  59. const background = 'anatoly-mikhaltsov-butterfly-wing-scale.jpg'
  60. cy.intercept('*/apps/theming/background/shipped').as('setBackground')
  61. // Select background
  62. cy.get(`[data-user-theming-background-shipped="${background}"]`).click()
  63. // Validate changed background and primary
  64. cy.wait('@setBackground')
  65. cy.waitUntil(() => validateBodyThemingCss('#a53c17', background))
  66. })
  67. it('Select a bright shipped background', function() {
  68. const background = 'bernie-cetonia-aurata-take-off-composition.jpg'
  69. cy.intercept('*/apps/theming/background/shipped').as('setBackground')
  70. // Select background
  71. cy.get(`[data-user-theming-background-shipped="${background}"]`).click()
  72. // Validate changed background and primary
  73. cy.wait('@setBackground')
  74. cy.waitUntil(() => validateBodyThemingCss('#56633d', background, true))
  75. })
  76. it('Remove background', function() {
  77. cy.intercept('*/apps/theming/background/custom').as('clearBackground')
  78. // Clear background
  79. cy.get('[data-user-theming-background-clear]').click()
  80. // Validate clear background
  81. cy.wait('@clearBackground')
  82. cy.waitUntil(() => validateBodyThemingCss('#56633d', ''))
  83. })
  84. })
  85. describe('User select a custom color', function() {
  86. before(function() {
  87. cy.createRandomUser().then((user: User) => {
  88. cy.login(user)
  89. })
  90. })
  91. it('See the user background settings', function() {
  92. cy.visit('/settings/user/theming')
  93. cy.get('[data-user-theming-background-settings]').scrollIntoView().should('be.visible')
  94. })
  95. it('Select a custom color', function() {
  96. cy.intercept('*/apps/theming/background/color').as('setColor')
  97. pickRandomColor('[data-user-theming-background-color]')
  98. // Validate custom colour change
  99. cy.wait('@setColor')
  100. cy.waitUntil(() => cy.window().then((win) => {
  101. const primary = getComputedStyle(win.document.body).getPropertyValue('--color-primary')
  102. return primary !== defaultPrimary
  103. }))
  104. })
  105. })
  106. describe('User select a bright custom color and remove background', function() {
  107. before(function() {
  108. cy.createRandomUser().then((user: User) => {
  109. cy.login(user)
  110. })
  111. })
  112. it('See the user background settings', function() {
  113. cy.visit('/settings/user/theming')
  114. cy.get('[data-user-theming-background-settings]').scrollIntoView().should('be.visible')
  115. })
  116. it('Remove background', function() {
  117. cy.intercept('*/apps/theming/background/custom').as('clearBackground')
  118. // Clear background
  119. cy.get('[data-user-theming-background-clear]').click()
  120. // Validate clear background
  121. cy.wait('@clearBackground')
  122. cy.waitUntil(() => validateBodyThemingCss(undefined, ''))
  123. })
  124. it('Select a custom color', function() {
  125. cy.intercept('*/apps/theming/background/color').as('setColor')
  126. // Pick one of the bright color preset
  127. cy.get('[data-user-theming-background-color]').click()
  128. cy.get('.color-picker__simple-color-circle:eq(4)').click()
  129. // Validate custom colour change
  130. cy.wait('@setColor')
  131. })
  132. it('See the header being inverted', function() {
  133. cy.waitUntil(() => cy.window().then((win) => {
  134. const firstEntry = win.document.querySelector('.app-menu-main li img')
  135. if (!firstEntry) {
  136. return false
  137. }
  138. return getComputedStyle(firstEntry).filter === 'invert(1)'
  139. }))
  140. })
  141. it('Select a shipped background', function() {
  142. const background = 'anatoly-mikhaltsov-butterfly-wing-scale.jpg'
  143. cy.intercept('*/apps/theming/background/shipped').as('setBackground')
  144. // Select background
  145. cy.get(`[data-user-theming-background-shipped="${background}"]`).click()
  146. // Validate changed background and primary
  147. cy.wait('@setBackground')
  148. cy.waitUntil(() => validateBodyThemingCss('#a53c17', background))
  149. })
  150. it('See the header NOT being inverted', function() {
  151. cy.waitUntil(() => cy.window().then((win) => {
  152. const firstEntry = win.document.querySelector('.app-menu-main li')
  153. if (!firstEntry) {
  154. return false
  155. }
  156. return getComputedStyle(firstEntry).filter === 'none'
  157. }))
  158. })
  159. })
  160. describe('User select a custom background', function() {
  161. const image = 'image.jpg'
  162. before(function() {
  163. cy.createRandomUser().then((user: User) => {
  164. cy.uploadFile(user, image, 'image/jpeg')
  165. cy.login(user)
  166. })
  167. })
  168. it('See the user background settings', function() {
  169. cy.visit('/settings/user/theming')
  170. cy.get('[data-user-theming-background-settings]').scrollIntoView().should('be.visible')
  171. })
  172. it('Select a custom background', function() {
  173. cy.intercept('*/apps/theming/background/custom').as('setBackground')
  174. cy.on('uncaught:exception', (err) => {
  175. // This can happen because of blink engine & skeleton animation, its not a bug just engine related.
  176. if (err.message.includes('ResizeObserver loop limit exceeded')) {
  177. return false
  178. }
  179. })
  180. // Pick background
  181. cy.get('[data-user-theming-background-custom]').click()
  182. cy.get('.file-picker__files tr').contains(image).click()
  183. cy.get('.dialog__actions .button-vue--vue-primary').click()
  184. // Wait for background to be set
  185. cy.wait('@setBackground')
  186. cy.waitUntil(() => validateBodyThemingCss('#4c0c04', 'apps/theming/background?v='))
  187. })
  188. })
  189. describe('User changes settings and reload the page', function() {
  190. const image = 'image.jpg'
  191. const primaryFromImage = '#4c0c04'
  192. let selectedColor = ''
  193. before(function() {
  194. cy.createRandomUser().then((user: User) => {
  195. cy.uploadFile(user, image, 'image/jpeg')
  196. cy.login(user)
  197. })
  198. })
  199. it('See the user background settings', function() {
  200. cy.visit('/settings/user/theming')
  201. cy.get('[data-user-theming-background-settings]').scrollIntoView().should('be.visible')
  202. })
  203. it('Select a custom background', function() {
  204. cy.intercept('*/apps/theming/background/custom').as('setBackground')
  205. cy.on('uncaught:exception', (err) => {
  206. // This can happen because of blink engine & skeleton animation, its not a bug just engine related.
  207. if (err.message.includes('ResizeObserver loop limit exceeded')) {
  208. return false
  209. }
  210. })
  211. // Pick background
  212. cy.get('[data-user-theming-background-custom]').click()
  213. cy.get('.file-picker__files tr').contains(image).click()
  214. cy.get('.dialog__actions .button-vue--vue-primary').click()
  215. // Wait for background to be set
  216. cy.wait('@setBackground')
  217. cy.waitUntil(() => validateBodyThemingCss(primaryFromImage, 'apps/theming/background?v='))
  218. })
  219. it('Select a custom color', function() {
  220. cy.intercept('*/apps/theming/background/color').as('setColor')
  221. cy.get('[data-user-theming-background-color]').click()
  222. cy.get('.color-picker__simple-color-circle:eq(5)').click()
  223. // Validate clear background
  224. cy.wait('@setColor')
  225. cy.waitUntil(() => cy.window().then((win) => {
  226. selectedColor = getComputedStyle(win.document.body).getPropertyValue('--color-primary')
  227. return selectedColor !== primaryFromImage
  228. }))
  229. })
  230. it('Reload the page and validate persistent changes', function() {
  231. cy.reload()
  232. cy.waitUntil(() => validateBodyThemingCss(selectedColor, 'apps/theming/background?v='))
  233. })
  234. })