admin-settings.cy.ts 15 KB

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