navigation-bar-settings.cy.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /**
  2. * @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
  3. *
  4. * @author Ferdinand Thiessen <opensource@fthiessen.de>
  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 { installTestApp, uninstallTestApp } from '../../support/commonUtils'
  24. const admin = new User('admin', 'admin')
  25. describe('Admin theming set default apps', () => {
  26. before(function() {
  27. // Just in case previous test failed
  28. cy.resetAdminTheming()
  29. cy.login(admin)
  30. })
  31. it('See the current default app is the dashboard', () => {
  32. cy.visit('/')
  33. cy.url().should('match', /apps\/dashboard/)
  34. // Also check the top logo link
  35. cy.get('#nextcloud').click()
  36. cy.url().should('match', /apps\/dashboard/)
  37. })
  38. it('See the default app settings', () => {
  39. cy.visit('/settings/admin/theming')
  40. cy.get('.settings-section').contains('Navigation bar settings').should('exist')
  41. cy.get('[data-cy-switch-default-app]').should('exist')
  42. cy.get('[data-cy-switch-default-app]').scrollIntoView()
  43. })
  44. it('Toggle the "use custom default app" switch', () => {
  45. cy.get('[data-cy-switch-default-app] input').should('not.be.checked')
  46. cy.get('[data-cy-switch-default-app] .checkbox-content').click()
  47. cy.get('[data-cy-switch-default-app] input').should('be.checked')
  48. })
  49. it('See the default app order selector', () => {
  50. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  51. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  52. expect(appIDs).to.deep.eq(['dashboard', 'files'])
  53. })
  54. })
  55. it('Change the default app', () => {
  56. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"]').scrollIntoView()
  57. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('be.visible')
  58. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').click()
  59. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('not.be.visible')
  60. })
  61. it('See the default app is changed', () => {
  62. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  63. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  64. expect(appIDs).to.deep.eq(['files', 'dashboard'])
  65. })
  66. // Check the redirect to the default app works
  67. cy.request({ url: '/', followRedirect: false }).then((response) => {
  68. expect(response.status).to.eq(302)
  69. expect(response).to.have.property('headers')
  70. expect(response.headers.location).to.contain('/apps/files')
  71. })
  72. })
  73. it('Toggle the "use custom default app" switch back to reset the default apps', () => {
  74. cy.visit('/settings/admin/theming')
  75. cy.get('[data-cy-switch-default-app]').scrollIntoView()
  76. cy.get('[data-cy-switch-default-app] input').should('be.checked')
  77. cy.get('[data-cy-switch-default-app] .checkbox-content').click()
  78. cy.get('[data-cy-switch-default-app] input').should('be.not.checked')
  79. })
  80. it('See the default app is changed back to default', () => {
  81. // Check the redirect to the default app works
  82. cy.request({ url: '/', followRedirect: false }).then((response) => {
  83. expect(response.status).to.eq(302)
  84. expect(response).to.have.property('headers')
  85. expect(response.headers.location).to.contain('/apps/dashboard')
  86. })
  87. })
  88. })
  89. describe('User theming set app order', () => {
  90. let user: User
  91. before(() => {
  92. cy.resetAdminTheming()
  93. // Create random user for this test
  94. cy.createRandomUser().then(($user) => {
  95. user = $user
  96. cy.login($user)
  97. })
  98. })
  99. after(() => cy.deleteUser(user))
  100. it('See the app order settings', () => {
  101. cy.visit('/settings/user/theming')
  102. cy.get('.settings-section').contains('Navigation bar settings').should('exist')
  103. cy.get('[data-cy-app-order]').scrollIntoView()
  104. })
  105. it('See that the dashboard app is the first one', () => {
  106. // Check the app order settings UI
  107. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  108. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  109. expect(appIDs).to.deep.eq(['dashboard', 'files'])
  110. })
  111. // Check the top app menu order
  112. cy.get('.app-menu-main .app-menu-entry').then(elements => {
  113. const appIDs = elements.map((idx, el) => el.getAttribute('data-app-id')).get()
  114. expect(appIDs).to.deep.eq(['dashboard', 'files'])
  115. })
  116. })
  117. it('Change the app order', () => {
  118. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('be.visible')
  119. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').click()
  120. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('not.be.visible')
  121. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  122. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  123. expect(appIDs).to.deep.eq(['files', 'dashboard'])
  124. })
  125. })
  126. it('See the app menu order is changed', () => {
  127. cy.reload()
  128. cy.get('.app-menu-main .app-menu-entry').then(elements => {
  129. const appIDs = elements.map((idx, el) => el.getAttribute('data-app-id')).get()
  130. expect(appIDs).to.deep.eq(['files', 'dashboard'])
  131. })
  132. })
  133. })
  134. describe('User theming set app order with default app', () => {
  135. let user: User
  136. before(() => {
  137. cy.resetAdminTheming()
  138. // install a third app
  139. installTestApp()
  140. // set files as default app
  141. cy.runOccCommand('config:system:set --value "files" defaultapp')
  142. // Create random user for this test
  143. cy.createRandomUser().then(($user) => {
  144. user = $user
  145. cy.login($user)
  146. })
  147. })
  148. after(() => {
  149. cy.deleteUser(user)
  150. uninstallTestApp()
  151. })
  152. it('See files is the default app', () => {
  153. // Check the redirect to the default app works
  154. cy.request({ url: '/', followRedirect: false }).then((response) => {
  155. expect(response.status).to.eq(302)
  156. expect(response).to.have.property('headers')
  157. expect(response.headers.location).to.contain('/apps/files')
  158. })
  159. })
  160. it('See the app order settings: files is the first one', () => {
  161. cy.visit('/settings/user/theming')
  162. cy.get('[data-cy-app-order]').scrollIntoView()
  163. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  164. expect(elements).to.have.length(4)
  165. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  166. expect(appIDs).to.deep.eq(['files', 'dashboard', 'testapp1', 'testapp'])
  167. })
  168. })
  169. it('Can not change the default app', () => {
  170. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('not.be.visible')
  171. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="down"]').should('not.be.visible')
  172. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="up"]').should('not.be.visible')
  173. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="down"]').should('be.visible')
  174. cy.get('[data-cy-app-order] [data-cy-app-order-element="testapp"] [data-cy-app-order-button="up"]').should('be.visible')
  175. cy.get('[data-cy-app-order] [data-cy-app-order-element="testapp"] [data-cy-app-order-button="down"]').should('not.be.visible')
  176. })
  177. it('Change the order of the other apps', () => {
  178. cy.intercept('POST', '**/apps/provisioning_api/api/v1/config/users/core/apporder').as('setAppOrder')
  179. // Move the testapp up twice, it should be the first one after files
  180. cy.get('[data-cy-app-order] [data-cy-app-order-element="testapp"] [data-cy-app-order-button="up"]').click()
  181. cy.wait('@setAppOrder')
  182. cy.get('[data-cy-app-order] [data-cy-app-order-element="testapp"] [data-cy-app-order-button="up"]').click()
  183. cy.wait('@setAppOrder')
  184. // Can't get up anymore, files is enforced as default app
  185. cy.get('[data-cy-app-order] [data-cy-app-order-element="testapp"] [data-cy-app-order-button="up"]').should('not.be.visible')
  186. // Check the final list order
  187. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  188. expect(elements).to.have.length(4)
  189. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  190. expect(appIDs).to.deep.eq(['files', 'testapp', 'dashboard', 'testapp1'])
  191. })
  192. })
  193. it('See the app menu order is changed', () => {
  194. cy.reload()
  195. cy.get('.app-menu-main .app-menu-entry').then(elements => {
  196. expect(elements).to.have.length(4)
  197. const appIDs = elements.map((idx, el) => el.getAttribute('data-app-id')).get()
  198. expect(appIDs).to.deep.eq(['files', 'testapp', 'dashboard', 'testapp1'])
  199. })
  200. })
  201. })
  202. describe('User theming app order list accessibility', () => {
  203. let user: User
  204. before(() => {
  205. cy.resetAdminTheming()
  206. // Create random user for this test
  207. cy.createRandomUser().then(($user) => {
  208. user = $user
  209. cy.login($user)
  210. })
  211. })
  212. after(() => {
  213. cy.deleteUser(user)
  214. })
  215. it('See the app order settings', () => {
  216. cy.visit('/settings/user/theming')
  217. cy.get('[data-cy-app-order]').scrollIntoView()
  218. cy.get('[data-cy-app-order] [data-cy-app-order-element]').should('have.length', 2)
  219. })
  220. it('click the first button', () => {
  221. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="down"]').should('be.visible').focus()
  222. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="down"]').click()
  223. })
  224. it('see the same app kept the focus', () => {
  225. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="down"]').should('not.have.focus')
  226. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('not.have.focus')
  227. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="down"]').should('not.have.focus')
  228. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="up"]').should('have.focus')
  229. })
  230. it('click the last button', () => {
  231. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="up"]').should('be.visible').focus()
  232. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="up"]').click()
  233. })
  234. it('see the same app kept the focus', () => {
  235. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="down"]').should('not.have.focus')
  236. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('not.have.focus')
  237. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="up"]').should('not.have.focus')
  238. cy.get('[data-cy-app-order] [data-cy-app-order-element="dashboard"] [data-cy-app-order-button="down"]').should('have.focus')
  239. })
  240. })
  241. describe('User theming reset app order', () => {
  242. let user: User
  243. before(() => {
  244. cy.resetAdminTheming()
  245. // Create random user for this test
  246. cy.createRandomUser().then(($user) => {
  247. user = $user
  248. cy.login($user)
  249. })
  250. })
  251. after(() => cy.deleteUser(user))
  252. it('See the app order settings', () => {
  253. cy.visit('/settings/user/theming')
  254. cy.get('.settings-section').contains('Navigation bar settings').should('exist')
  255. cy.get('[data-cy-app-order]').scrollIntoView()
  256. })
  257. it('See that the dashboard app is the first one', () => {
  258. // Check the app order settings UI
  259. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  260. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  261. expect(appIDs).to.deep.eq(['dashboard', 'files'])
  262. })
  263. // Check the top app menu order
  264. cy.get('.app-menu-main .app-menu-entry').then(elements => {
  265. const appIDs = elements.map((idx, el) => el.getAttribute('data-app-id')).get()
  266. expect(appIDs).to.deep.eq(['dashboard', 'files'])
  267. })
  268. })
  269. it('See the reset button is disabled', () => {
  270. cy.get('[data-test-id="btn-apporder-reset"]').scrollIntoView()
  271. cy.get('[data-test-id="btn-apporder-reset"]').should('be.visible').and('have.attr', 'disabled')
  272. })
  273. it('Change the app order', () => {
  274. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('be.visible')
  275. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').click()
  276. cy.get('[data-cy-app-order] [data-cy-app-order-element="files"] [data-cy-app-order-button="up"]').should('not.be.visible')
  277. // Check the app order settings UI
  278. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  279. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  280. expect(appIDs).to.deep.eq(['files', 'dashboard'])
  281. })
  282. })
  283. it('See the reset button is no longer disabled', () => {
  284. cy.get('[data-test-id="btn-apporder-reset"]').scrollIntoView()
  285. cy.get('[data-test-id="btn-apporder-reset"]').should('be.visible').and('not.have.attr', 'disabled')
  286. })
  287. it('Reset the app order', () => {
  288. cy.get('[data-test-id="btn-apporder-reset"]').click({ force: true })
  289. })
  290. it('See the app order is restored', () => {
  291. cy.get('[data-cy-app-order] [data-cy-app-order-element]').then(elements => {
  292. const appIDs = elements.map((idx, el) => el.getAttribute('data-cy-app-order-element')).get()
  293. expect(appIDs).to.deep.eq(['dashboard', 'files'])
  294. })
  295. })
  296. it('See the reset button is disabled again', () => {
  297. cy.get('[data-test-id="btn-apporder-reset"]').should('be.visible').and('have.attr', 'disabled')
  298. })
  299. })