admin-settings.cy.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. /**
  2. * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
  3. * SPDX-License-Identifier: AGPL-3.0-or-later
  4. */
  5. /* eslint-disable n/no-unpublished-import */
  6. import { User } from '@nextcloud/cypress'
  7. import {
  8. defaultPrimary,
  9. defaultBackground,
  10. pickRandomColor,
  11. validateBodyThemingCss,
  12. validateUserThemingDefaultCss,
  13. expectBackgroundColor,
  14. } from './themingUtils'
  15. const admin = new User('admin', 'admin')
  16. describe('Admin theming settings visibility check', function() {
  17. before(function() {
  18. // Just in case previous test failed
  19. cy.resetAdminTheming()
  20. cy.login(admin)
  21. })
  22. it('See the admin theming section', function() {
  23. cy.visit('/settings/admin/theming')
  24. cy.get('[data-admin-theming-settings]')
  25. .should('exist')
  26. .scrollIntoView()
  27. cy.get('[data-admin-theming-settings]').should('be.visible')
  28. })
  29. it('See the default settings', function() {
  30. cy.get('[data-admin-theming-setting-color-picker]').should('exist')
  31. cy.get('[data-admin-theming-setting-file-reset]').should('not.exist')
  32. cy.get('[data-admin-theming-setting-file-remove]').should('exist')
  33. cy.get(
  34. '[data-admin-theming-setting-primary-color] [data-admin-theming-setting-color]',
  35. ).then(($el) => expectBackgroundColor($el, defaultPrimary))
  36. cy.get(
  37. '[data-admin-theming-setting-background-color] [data-admin-theming-setting-color]',
  38. ).then(($el) => expectBackgroundColor($el, defaultPrimary))
  39. })
  40. })
  41. describe('Change the primary color and reset it', function() {
  42. let selectedColor = ''
  43. before(function() {
  44. // Just in case previous test failed
  45. cy.resetAdminTheming()
  46. cy.login(admin)
  47. })
  48. it('See the admin theming section', function() {
  49. cy.visit('/settings/admin/theming')
  50. cy.get('[data-admin-theming-settings]')
  51. .should('exist')
  52. .scrollIntoView()
  53. cy.get('[data-admin-theming-settings]').should('be.visible')
  54. })
  55. it('Change the primary color', function() {
  56. cy.intercept('*/apps/theming/ajax/updateStylesheet').as('setColor')
  57. pickRandomColor('[data-admin-theming-setting-primary-color]').then(
  58. (color) => {
  59. selectedColor = color
  60. },
  61. )
  62. cy.wait('@setColor')
  63. cy.waitUntil(() =>
  64. validateBodyThemingCss(
  65. selectedColor,
  66. defaultBackground,
  67. defaultPrimary,
  68. ),
  69. )
  70. })
  71. it('Screenshot the login page and validate login page', function() {
  72. cy.logout()
  73. cy.visit('/')
  74. cy.waitUntil(() =>
  75. validateBodyThemingCss(
  76. selectedColor,
  77. defaultBackground,
  78. defaultPrimary,
  79. ),
  80. )
  81. cy.screenshot()
  82. })
  83. it('Undo theming settings and validate login page again', function() {
  84. cy.resetAdminTheming()
  85. cy.visit('/')
  86. cy.waitUntil(validateBodyThemingCss)
  87. cy.screenshot()
  88. })
  89. })
  90. describe('Remove the default background and restore it', function() {
  91. before(function() {
  92. // Just in case previous test failed
  93. cy.resetAdminTheming()
  94. cy.login(admin)
  95. })
  96. it('See the admin theming section', function() {
  97. cy.visit('/settings/admin/theming')
  98. cy.get('[data-admin-theming-settings]')
  99. .should('exist')
  100. .scrollIntoView()
  101. cy.get('[data-admin-theming-settings]').should('be.visible')
  102. })
  103. it('Remove the default background', function() {
  104. cy.intercept('*/apps/theming/ajax/updateStylesheet').as(
  105. 'removeBackground',
  106. )
  107. cy.get('[data-admin-theming-setting-file-remove]').click()
  108. cy.wait('@removeBackground')
  109. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, null))
  110. cy.waitUntil(() =>
  111. cy.window().then((win) => {
  112. const backgroundPlain = getComputedStyle(
  113. win.document.body,
  114. ).getPropertyValue('--image-background')
  115. return backgroundPlain !== ''
  116. }),
  117. )
  118. })
  119. it('Screenshot the login page and validate login page', function() {
  120. cy.logout()
  121. cy.visit('/')
  122. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, null))
  123. cy.screenshot()
  124. })
  125. it('Undo theming settings and validate login page again', function() {
  126. cy.resetAdminTheming()
  127. cy.visit('/')
  128. cy.waitUntil(validateBodyThemingCss)
  129. cy.screenshot()
  130. })
  131. })
  132. describe('Remove the default background with a custom background color', function() {
  133. let selectedColor = ''
  134. before(function() {
  135. // Just in case previous test failed
  136. cy.resetAdminTheming()
  137. cy.login(admin)
  138. })
  139. it('See the admin theming section', function() {
  140. cy.visit('/settings/admin/theming')
  141. cy.get('[data-admin-theming-settings]')
  142. .should('exist')
  143. .scrollIntoView()
  144. cy.get('[data-admin-theming-settings]').should('be.visible')
  145. })
  146. it('Change the background color', function() {
  147. cy.intercept('*/apps/theming/ajax/updateStylesheet').as('setColor')
  148. pickRandomColor('[data-admin-theming-setting-background-color]').then(
  149. (color) => {
  150. selectedColor = color
  151. },
  152. )
  153. cy.wait('@setColor')
  154. cy.waitUntil(() =>
  155. validateBodyThemingCss(
  156. defaultPrimary,
  157. defaultBackground,
  158. selectedColor,
  159. ),
  160. )
  161. })
  162. it('Remove the default background', function() {
  163. cy.intercept('*/apps/theming/ajax/updateStylesheet').as(
  164. 'removeBackground',
  165. )
  166. cy.get('[data-admin-theming-setting-file-remove]').scrollIntoView()
  167. cy.get('[data-admin-theming-setting-file-remove]').click({
  168. force: true,
  169. })
  170. cy.wait('@removeBackground')
  171. })
  172. it('Screenshot the login page and validate login page', function() {
  173. cy.logout()
  174. cy.visit('/')
  175. cy.waitUntil(() =>
  176. validateBodyThemingCss(defaultPrimary, null, selectedColor),
  177. )
  178. cy.screenshot()
  179. })
  180. it('Undo theming settings and validate login page again', function() {
  181. cy.resetAdminTheming()
  182. cy.visit('/')
  183. cy.waitUntil(validateBodyThemingCss)
  184. cy.screenshot()
  185. })
  186. })
  187. describe('Remove the default background with a bright color', function() {
  188. let selectedColor = ''
  189. before(function() {
  190. // Just in case previous test failed
  191. cy.resetAdminTheming()
  192. cy.resetUserTheming(admin)
  193. cy.login(admin)
  194. })
  195. it('See the admin theming section', function() {
  196. cy.visit('/settings/admin/theming')
  197. cy.get('[data-admin-theming-settings]')
  198. .should('exist')
  199. .scrollIntoView()
  200. cy.get('[data-admin-theming-settings]').should('be.visible')
  201. })
  202. it('Remove the default background', function() {
  203. cy.intercept('*/apps/theming/ajax/updateStylesheet').as(
  204. 'removeBackground',
  205. )
  206. cy.get('[data-admin-theming-setting-file-remove]').click()
  207. cy.wait('@removeBackground')
  208. })
  209. it('Change the background color', function() {
  210. cy.intercept('*/apps/theming/ajax/updateStylesheet').as('setColor')
  211. // Pick one of the bright color preset
  212. pickRandomColor(
  213. '[data-admin-theming-setting-background-color]',
  214. 4,
  215. ).then((color) => {
  216. selectedColor = color
  217. })
  218. cy.wait('@setColor')
  219. cy.waitUntil(() =>
  220. validateBodyThemingCss(defaultPrimary, null, selectedColor),
  221. )
  222. })
  223. it('See the header being inverted', function() {
  224. cy.waitUntil(() =>
  225. cy.window().then((win) => {
  226. const firstEntry = win.document.querySelector(
  227. '.app-menu-main li img',
  228. )
  229. if (!firstEntry) {
  230. return false
  231. }
  232. return getComputedStyle(firstEntry).filter === 'invert(1)'
  233. }),
  234. )
  235. })
  236. })
  237. describe('Change the login fields then reset them', function() {
  238. const name = 'ABCdef123'
  239. const url = 'https://example.com'
  240. const slogan = 'Testing is fun'
  241. before(function() {
  242. // Just in case previous test failed
  243. cy.resetAdminTheming()
  244. cy.login(admin)
  245. })
  246. it('See the admin theming section', function() {
  247. cy.visit('/settings/admin/theming')
  248. cy.get('[data-admin-theming-settings]')
  249. .should('exist')
  250. .scrollIntoView()
  251. cy.get('[data-admin-theming-settings]').should('be.visible')
  252. })
  253. it('Change the name field', function() {
  254. cy.intercept('*/apps/theming/ajax/updateStylesheet').as('updateFields')
  255. // Name
  256. cy.get(
  257. '[data-admin-theming-setting-field="name"] input[type="text"]',
  258. ).scrollIntoView()
  259. cy.get(
  260. '[data-admin-theming-setting-field="name"] input[type="text"]',
  261. ).type(`{selectall}${name}{enter}`)
  262. cy.wait('@updateFields')
  263. // Url
  264. cy.get(
  265. '[data-admin-theming-setting-field="url"] input[type="url"]',
  266. ).scrollIntoView()
  267. cy.get(
  268. '[data-admin-theming-setting-field="url"] input[type="url"]',
  269. ).type(`{selectall}${url}{enter}`)
  270. cy.wait('@updateFields')
  271. // Slogan
  272. cy.get(
  273. '[data-admin-theming-setting-field="slogan"] input[type="text"]',
  274. ).scrollIntoView()
  275. cy.get(
  276. '[data-admin-theming-setting-field="slogan"] input[type="text"]',
  277. ).type(`{selectall}${slogan}{enter}`)
  278. cy.wait('@updateFields')
  279. })
  280. it('Ensure undo button presence', function() {
  281. cy.get(
  282. '[data-admin-theming-setting-field="name"] .input-field__trailing-button',
  283. ).scrollIntoView()
  284. cy.get(
  285. '[data-admin-theming-setting-field="name"] .input-field__trailing-button',
  286. ).should('be.visible')
  287. cy.get(
  288. '[data-admin-theming-setting-field="url"] .input-field__trailing-button',
  289. ).scrollIntoView()
  290. cy.get(
  291. '[data-admin-theming-setting-field="url"] .input-field__trailing-button',
  292. ).should('be.visible')
  293. cy.get(
  294. '[data-admin-theming-setting-field="slogan"] .input-field__trailing-button',
  295. ).scrollIntoView()
  296. cy.get(
  297. '[data-admin-theming-setting-field="slogan"] .input-field__trailing-button',
  298. ).should('be.visible')
  299. })
  300. it('Validate login screen changes', function() {
  301. cy.logout()
  302. cy.visit('/')
  303. cy.get('[data-login-form-headline]').should('contain.text', name)
  304. cy.get('footer p a').should('have.text', name)
  305. cy.get('footer p a').should('have.attr', 'href', url)
  306. cy.get('footer p').should('contain.text', `– ${slogan}`)
  307. })
  308. it('Undo theming settings', function() {
  309. cy.resetAdminTheming()
  310. })
  311. it('Validate login screen changes again', function() {
  312. cy.visit('/')
  313. cy.get('[data-login-form-headline]').should('not.contain.text', name)
  314. cy.get('footer p a').should('not.have.text', name)
  315. cy.get('footer p a').should('not.have.attr', 'href', url)
  316. cy.get('footer p').should('not.contain.text', `– ${slogan}`)
  317. })
  318. })
  319. describe('Disable user theming and enable it back', function() {
  320. before(function() {
  321. // Just in case previous test failed
  322. cy.resetAdminTheming()
  323. cy.login(admin)
  324. })
  325. it('See the admin theming section', function() {
  326. cy.visit('/settings/admin/theming')
  327. cy.get('[data-admin-theming-settings]')
  328. .should('exist')
  329. .scrollIntoView()
  330. cy.get('[data-admin-theming-settings]').should('be.visible')
  331. })
  332. it('Disable user background theming', function() {
  333. cy.intercept('*/apps/theming/ajax/updateStylesheet').as(
  334. 'disableUserTheming',
  335. )
  336. cy.get(
  337. '[data-admin-theming-setting-disable-user-theming]',
  338. ).scrollIntoView()
  339. cy.get('[data-admin-theming-setting-disable-user-theming]').should(
  340. 'be.visible',
  341. )
  342. cy.get(
  343. '[data-admin-theming-setting-disable-user-theming] input[type="checkbox"]',
  344. ).check({ force: true })
  345. cy.get(
  346. '[data-admin-theming-setting-disable-user-theming] input[type="checkbox"]',
  347. ).should('be.checked')
  348. cy.wait('@disableUserTheming')
  349. })
  350. it('Login as user', function() {
  351. cy.logout()
  352. cy.createRandomUser().then((user) => {
  353. cy.login(user)
  354. })
  355. })
  356. it('User cannot not change background settings', function() {
  357. cy.visit('/settings/user/theming')
  358. cy.contains(
  359. 'Customization has been disabled by your administrator',
  360. ).should('exist')
  361. })
  362. })
  363. describe('The user default background settings reflect the admin theming settings', function() {
  364. let selectedColor = ''
  365. before(function() {
  366. // Just in case previous test failed
  367. cy.resetAdminTheming()
  368. cy.login(admin)
  369. })
  370. after(function() {
  371. cy.resetAdminTheming()
  372. })
  373. it('See the admin theming section', function() {
  374. cy.visit('/settings/admin/theming')
  375. cy.get('[data-admin-theming-settings]')
  376. .should('exist')
  377. .scrollIntoView()
  378. cy.get('[data-admin-theming-settings]').should('be.visible')
  379. })
  380. it('Change the default background', function() {
  381. cy.intercept('*/apps/theming/ajax/uploadImage').as('setBackground')
  382. cy.fixture('image.jpg', null).as('background')
  383. cy.get(
  384. '[data-admin-theming-setting-file="background"] input[type="file"]',
  385. ).selectFile('@background', { force: true })
  386. cy.wait('@setBackground')
  387. cy.waitUntil(() =>
  388. validateBodyThemingCss(
  389. defaultPrimary,
  390. '/apps/theming/image/background?v=',
  391. null,
  392. ),
  393. )
  394. })
  395. it('Change the background color', function() {
  396. cy.intercept('*/apps/theming/ajax/updateStylesheet').as('setColor')
  397. pickRandomColor('[data-admin-theming-setting-background-color]').then(
  398. (color) => {
  399. selectedColor = color
  400. },
  401. )
  402. cy.wait('@setColor')
  403. cy.waitUntil(() =>
  404. validateBodyThemingCss(
  405. defaultPrimary,
  406. '/apps/theming/image/background?v=',
  407. selectedColor,
  408. ),
  409. )
  410. })
  411. it('Login page should match admin theming settings', function() {
  412. cy.logout()
  413. cy.visit('/')
  414. cy.waitUntil(() =>
  415. validateBodyThemingCss(
  416. defaultPrimary,
  417. '/apps/theming/image/background?v=',
  418. selectedColor,
  419. ),
  420. )
  421. })
  422. it('Login as user', function() {
  423. cy.createRandomUser().then((user) => {
  424. cy.login(user)
  425. })
  426. })
  427. it('See the user background settings', function() {
  428. cy.visit('/settings/user/theming')
  429. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  430. cy.get('[data-user-theming-background-settings]').should('be.visible')
  431. })
  432. it('Default user background settings should match admin theming settings', function() {
  433. cy.get('[data-user-theming-background-default]').should('be.visible')
  434. cy.get('[data-user-theming-background-default]').should(
  435. 'have.class',
  436. 'background--active',
  437. )
  438. cy.waitUntil(() =>
  439. validateUserThemingDefaultCss(
  440. selectedColor,
  441. '/apps/theming/image/background?v=',
  442. ),
  443. )
  444. })
  445. })
  446. describe('The user default background settings reflect the admin theming settings with background removed', function() {
  447. before(function() {
  448. // Just in case previous test failed
  449. cy.resetAdminTheming()
  450. cy.login(admin)
  451. })
  452. after(function() {
  453. cy.resetAdminTheming()
  454. })
  455. it('See the admin theming section', function() {
  456. cy.visit('/settings/admin/theming')
  457. cy.get('[data-admin-theming-settings]')
  458. .should('exist')
  459. .scrollIntoView()
  460. cy.get('[data-admin-theming-settings]').should('be.visible')
  461. })
  462. it('Remove the default background', function() {
  463. cy.intercept('*/apps/theming/ajax/updateStylesheet').as(
  464. 'removeBackground',
  465. )
  466. cy.get('[data-admin-theming-setting-file-remove]').click()
  467. cy.wait('@removeBackground')
  468. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, null))
  469. })
  470. it('Login page should match admin theming settings', function() {
  471. cy.logout()
  472. cy.visit('/')
  473. cy.waitUntil(() => validateBodyThemingCss(defaultPrimary, null))
  474. })
  475. it('Login as user', function() {
  476. cy.createRandomUser().then((user) => {
  477. cy.login(user)
  478. })
  479. })
  480. it('See the user background settings', function() {
  481. cy.visit('/settings/user/theming')
  482. cy.get('[data-user-theming-background-settings]').scrollIntoView()
  483. cy.get('[data-user-theming-background-settings]').should('be.visible')
  484. })
  485. it('Default user background settings should match admin theming settings', function() {
  486. cy.get('[data-user-theming-background-default]').should('be.visible')
  487. cy.get('[data-user-theming-background-default]').should(
  488. 'have.class',
  489. 'background--active',
  490. )
  491. cy.waitUntil(() => validateUserThemingDefaultCss(defaultPrimary, null))
  492. })
  493. })