aboutsummaryrefslogtreecommitdiffstats
path: root/cypress/e2e/core
diff options
context:
space:
mode:
Diffstat (limited to 'cypress/e2e/core')
-rw-r--r--cypress/e2e/core/404-error.cy.ts19
-rw-r--r--cypress/e2e/core/header_access-levels.cy.ts101
-rw-r--r--cypress/e2e/core/header_contacts-menu.cy.ts137
-rw-r--r--cypress/e2e/core/setup.ts145
4 files changed, 402 insertions, 0 deletions
diff --git a/cypress/e2e/core/404-error.cy.ts b/cypress/e2e/core/404-error.cy.ts
new file mode 100644
index 00000000000..b24562933e8
--- /dev/null
+++ b/cypress/e2e/core/404-error.cy.ts
@@ -0,0 +1,19 @@
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+describe('404 error page', { testIsolation: true }, () => {
+ it('renders 404 page', () => {
+ cy.visit('/doesnotexist', { failOnStatusCode: false })
+
+ cy.findByRole('heading', { name: /Page not found/ })
+ .should('be.visible')
+ cy.findByRole('link', { name: /Back to Nextcloud/ })
+ .should('be.visible')
+ .click()
+
+ cy.url()
+ .should('match', /(\/index.php)\/login$/)
+ })
+})
diff --git a/cypress/e2e/core/header_access-levels.cy.ts b/cypress/e2e/core/header_access-levels.cy.ts
new file mode 100644
index 00000000000..b0e9ab8bac1
--- /dev/null
+++ b/cypress/e2e/core/header_access-levels.cy.ts
@@ -0,0 +1,101 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { User } from '@nextcloud/cypress'
+import { clearState, getNextcloudUserMenu, getNextcloudUserMenuToggle } from '../../support/commonUtils'
+
+const admin = new User('admin', 'admin')
+
+describe('Header: Ensure regular users do not have admin settings in the Settings menu', { testIsolation: true }, () => {
+ beforeEach(() => {
+ clearState()
+ })
+
+ it('Regular users can see basic items in the Settings menu', () => {
+ // Given I am logged in
+ cy.createRandomUser().then(($user) => {
+ cy.login($user)
+ cy.visit('/')
+ })
+ // I open the settings menu
+ getNextcloudUserMenuToggle().click()
+
+ getNextcloudUserMenu().find('ul').within(($el) => {
+ // I see the settings menu is open
+ cy.wrap($el).should('be.visible')
+
+ // I see that the Settings menu has only 6 items
+ cy.get('li').should('have.length', 6)
+ // I see that the "View profile" item in the Settings menu is shown
+ cy.contains('li', 'View profile').should('be.visible')
+ // I see that the "Set status" item in the Settings menu is shown
+ cy.contains('li', 'Set status').should('be.visible')
+ // I see that the "Appearance and accessibility" item in the Settings menu is shown
+ cy.contains('li', 'Appearance and accessibility').should('be.visible')
+ // I see that the "Settings" item in the Settings menu is shown
+ cy.contains('li', 'Settings').should('be.visible')
+ // I see that the "Help" item in the Settings menu is shown
+ cy.contains('li', 'Help').should('be.visible')
+ // I see that the "Log out" item in the Settings menu is shown
+ cy.contains('li', 'Log out').should('be.visible')
+ })
+ })
+
+ it('Regular users cannot see admin-level items in the Settings menu', () => {
+ // Given I am logged in
+ cy.createRandomUser().then(($user) => {
+ cy.login($user)
+ cy.visit('/')
+ })
+ // I open the settings menu
+ getNextcloudUserMenuToggle().click()
+
+ getNextcloudUserMenu().find('ul').within(($el) => {
+ // I see the settings menu is open
+ cy.wrap($el).should('be.visible')
+
+ // I see that the "Users" item in the Settings menu is NOT shown
+ cy.contains('li', 'Users').should('not.exist')
+ // I see that the "Administration settings" item in the Settings menu is NOT shown
+ cy.contains('li', 'Administration settings').should('not.exist')
+ cy.get('#admin_settings').should('not.exist')
+ })
+ })
+
+ it('Admin users can see admin-level items in the Settings menu', () => {
+ // Given I am logged in
+ cy.login(admin)
+ cy.visit('/')
+
+ // I open the settings menu
+ getNextcloudUserMenuToggle().click()
+
+ getNextcloudUserMenu().find('ul').within(($el) => {
+ // I see the settings menu is open
+ cy.wrap($el).should('be.visible')
+
+ // I see that the Settings menu has only 9 items
+ cy.get('li').should('have.length', 9)
+ // I see that the "Set status" item in the Settings menu is shown
+ cy.contains('li', 'View profile').should('be.visible')
+ // I see that the "Set status" item in the Settings menu is shown
+ cy.contains('li', 'Set status').should('be.visible')
+ // I see that the "Appearance and accessibility" item in the Settings menu is shown
+ cy.contains('li', 'Appearance and accessibility').should('be.visible')
+ // I see that the "Personal Settings" item in the Settings menu is shown
+ cy.contains('li', 'Personal settings').should('be.visible')
+ // I see that the "Administration settings" item in the Settings menu is shown
+ cy.contains('li', 'Administration settings').should('be.visible')
+ // I see that the "Apps" item in the Settings menu is shown
+ cy.contains('li', 'Apps').should('be.visible')
+ // I see that the "Users" item in the Settings menu is shown
+ cy.contains('li', 'Accounts').should('be.visible')
+ // I see that the "Help" item in the Settings menu is shown
+ cy.contains('li', 'Help').should('be.visible')
+ // I see that the "Log out" item in the Settings menu is shown
+ cy.contains('li', 'Log out').should('be.visible')
+ })
+ })
+})
diff --git a/cypress/e2e/core/header_contacts-menu.cy.ts b/cypress/e2e/core/header_contacts-menu.cy.ts
new file mode 100644
index 00000000000..6279b72a78d
--- /dev/null
+++ b/cypress/e2e/core/header_contacts-menu.cy.ts
@@ -0,0 +1,137 @@
+/**
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { User } from '@nextcloud/cypress'
+import { clearState, getNextcloudHeader } from '../../support/commonUtils'
+
+// eslint-disable-next-line n/no-extraneous-import
+import randomString from 'crypto-random-string'
+
+const admin = new User('admin', 'admin')
+
+const getContactsMenu = () => getNextcloudHeader().find('#header-menu-contactsmenu')
+const getContactsMenuToggle = () => getNextcloudHeader().find('#contactsmenu .header-menu__trigger')
+const getContactsSearch = () => getContactsMenu().find('#contactsmenu__menu__search')
+
+describe('Header: Contacts menu', { testIsolation: true }, () => {
+ let user: User
+
+ beforeEach(() => {
+ // clear user and group state
+ clearState()
+ // ensure the contacts menu is not restricted
+ cy.runOccCommand('config:app:set --value no core shareapi_restrict_user_enumeration_to_group')
+ // create a new user for testing the contacts
+ cy.createRandomUser().then(($user) => {
+ user = $user
+ })
+
+ // Given I am logged in as the admin
+ cy.login(admin)
+ cy.visit('/')
+ })
+
+ it('Other users are seen in the contacts menu', () => {
+ // When I open the Contacts menu
+ getContactsMenuToggle().click()
+ // I see that the Contacts menu is shown
+ getContactsMenu().should('exist')
+ // I see that the contact user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', user.userId).should('be.visible')
+ // I see that the contact "admin" in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', admin.userId).should('not.exist')
+ })
+
+ it('Just added users are seen in the contacts menu', () => {
+ // I create a new user
+ const newUserName = randomString(7)
+ // we can not use createRandomUser as it will invalidate the session
+ cy.runOccCommand(`user:add --password-from-env '${newUserName}'`, { env: { OC_PASS: '1234567' } })
+ // I open the Contacts menu
+ getContactsMenuToggle().click()
+ // I see that the Contacts menu is shown
+ getContactsMenu().should('exist')
+ // I see that the contact user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', user.userId).should('be.visible')
+ // I see that the contact of the new user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', newUserName).should('be.visible')
+ // I see that the contact "admin" in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', admin.userId).should('not.exist')
+ })
+
+ it('Search for other users in the contacts menu', () => {
+ cy.createRandomUser().then((otherUser) => {
+ // Given I am logged in as the admin
+ cy.login(admin)
+ cy.visit('/')
+
+ // I open the Contacts menu
+ getContactsMenuToggle().click()
+ // I see that the Contacts menu is shown
+ getContactsMenu().should('exist')
+ // I see that the contact user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', user.userId).should('be.visible')
+ // I see that the contact of the new user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', otherUser.userId).should('be.visible')
+
+ // I see that the Contacts menu search input is shown
+ getContactsSearch().should('exist')
+ // I search for the otherUser
+ getContactsSearch().type(otherUser.userId)
+ // I see that the contact otherUser in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', otherUser.userId).should('be.visible')
+ // I see that the contact user in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', user.userId).should('not.exist')
+ // I see that the contact "admin" in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', admin.userId).should('not.exist')
+ })
+ })
+
+ it('Search for unknown users in the contacts menu', () => {
+ // I open the Contacts menu
+ getContactsMenuToggle().click()
+ // I see that the Contacts menu is shown
+ getContactsMenu().should('exist')
+ // I see that the contact user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', user.userId).should('be.visible')
+
+ // I see that the Contacts menu search input is shown
+ getContactsSearch().should('exist')
+ // I search for an unknown user
+ getContactsSearch().type('surely-unknown-user')
+ // I see that the no results message in the Contacts menu is shown
+ getContactsMenu().find('ul li').should('have.length', 0)
+ // I see that the contact user in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', user.userId).should('not.exist')
+ // I see that the contact "admin" in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', admin.userId).should('not.exist')
+ })
+
+ it('Users from other groups are not seen in the contacts menu when autocompletion is restricted within the same group', () => {
+ // I enable restricting username autocompletion to groups
+ cy.runOccCommand('config:app:set --value yes core shareapi_restrict_user_enumeration_to_group')
+ // I open the Contacts menu
+ getContactsMenuToggle().click()
+ // I see that the Contacts menu is shown
+ getContactsMenu().should('exist')
+ // I see that the contact user in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', user.userId).should('not.exist')
+ // I see that the contact "admin" in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', admin.userId).should('not.exist')
+
+ // I close the Contacts menu
+ getContactsMenuToggle().click()
+ // I disable restricting username autocompletion to groups
+ cy.runOccCommand('config:app:set --value no core shareapi_restrict_user_enumeration_to_group')
+ // I open the Contacts menu
+ getContactsMenuToggle().click()
+ // I see that the Contacts menu is shown
+ getContactsMenu().should('exist')
+ // I see that the contact user in the Contacts menu is shown
+ getContactsMenu().contains('li.contact', user.userId).should('be.visible')
+ // I see that the contact "admin" in the Contacts menu is not shown
+ getContactsMenu().contains('li.contact', admin.userId).should('not.exist')
+ })
+})
diff --git a/cypress/e2e/core/setup.ts b/cypress/e2e/core/setup.ts
new file mode 100644
index 00000000000..a9174a3ebe7
--- /dev/null
+++ b/cypress/e2e/core/setup.ts
@@ -0,0 +1,145 @@
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+/**
+ * DO NOT RENAME THIS FILE to .cy.ts ⚠️
+ * This is not following the pattern of the other files in this folder
+ * because it is manually added to the tests by the cypress config.
+ */
+describe('Can install Nextcloud', { testIsolation: true, retries: 0 }, () => {
+ beforeEach(() => {
+ // Move the config file and data folder
+ cy.runCommand('rm /var/www/html/config/config.php', { failOnNonZeroExit: false })
+ cy.runCommand('rm /var/www/html/data/owncloud.db', { failOnNonZeroExit: false })
+ })
+
+ it('Sqlite', () => {
+ cy.visit('/')
+ cy.get('[data-cy-setup-form]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data')
+
+ // Select the SQLite database
+ cy.get('[data-cy-setup-form-field="dbtype-sqlite"] input').check({ force: true })
+
+ sharedSetup()
+ })
+
+ it('MySQL', () => {
+ cy.visit('/')
+ cy.get('[data-cy-setup-form]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data')
+
+ // Select the SQLite database
+ cy.get('[data-cy-setup-form-field="dbtype-mysql"] input').check({ force: true })
+
+ // Fill in the DB form
+ cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}oc_autotest')
+ cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}nextcloud')
+ cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}oc_autotest')
+ cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}mysql:3306')
+
+ sharedSetup()
+ })
+
+ it('MariaDB', () => {
+ cy.visit('/')
+ cy.get('[data-cy-setup-form]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data')
+
+ // Select the SQLite database
+ cy.get('[data-cy-setup-form-field="dbtype-mysql"] input').check({ force: true })
+
+ // Fill in the DB form
+ cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}oc_autotest')
+ cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}nextcloud')
+ cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}oc_autotest')
+ cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}mariadb:3306')
+
+ sharedSetup()
+ })
+
+ it('PostgreSQL', () => {
+ cy.visit('/')
+ cy.get('[data-cy-setup-form]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data')
+
+ // Select the SQLite database
+ cy.get('[data-cy-setup-form-field="dbtype-pgsql"] input').check({ force: true })
+
+ // Fill in the DB form
+ cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}root')
+ cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}rootpassword')
+ cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}nextcloud')
+ cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}postgres:5432')
+
+ sharedSetup()
+ })
+
+ it('Oracle', () => {
+ cy.runCommand('cp /var/www/html/tests/databases-all-config.php /var/www/html/config/config.php')
+ cy.visit('/')
+ cy.get('[data-cy-setup-form]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminlogin"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="adminpass"]').should('be.visible')
+ cy.get('[data-cy-setup-form-field="directory"]').should('have.value', '/var/www/html/data')
+
+ // Select the SQLite database
+ cy.get('[data-cy-setup-form-field="dbtype-oci"] input').check({ force: true })
+
+ // Fill in the DB form
+ cy.get('[data-cy-setup-form-field="dbuser"]').type('{selectAll}system')
+ cy.get('[data-cy-setup-form-field="dbpass"]').type('{selectAll}oracle')
+ cy.get('[data-cy-setup-form-field="dbname"]').type('{selectAll}FREE')
+ cy.get('[data-cy-setup-form-field="dbhost"]').type('{selectAll}oracle:1521')
+
+ sharedSetup()
+ })
+
+})
+
+/**
+ * Shared admin setup function for the Nextcloud setup
+ */
+function sharedSetup() {
+ const randAdmin = 'admin-' + Math.random().toString(36).substring(2, 15)
+
+ // Fill in the form
+ cy.get('[data-cy-setup-form-field="adminlogin"]').type(randAdmin)
+ cy.get('[data-cy-setup-form-field="adminpass"]').type(randAdmin)
+
+ // Nothing more to do on sqlite, let's continue
+ cy.get('[data-cy-setup-form-submit]').click()
+
+ // Wait for the setup to finish
+ cy.location('pathname', { timeout: 10000 })
+ .should('include', '/core/apps/recommended')
+
+ // See the apps setup
+ cy.get('[data-cy-setup-recommended-apps]')
+ .should('be.visible')
+ .within(() => {
+ cy.findByRole('heading', { name: 'Recommended apps' })
+ .should('be.visible')
+ cy.findByRole('button', { name: 'Skip' })
+ .should('be.visible')
+ cy.findByRole('button', { name: 'Install recommended apps' })
+ .should('be.visible')
+ })
+
+ // Skip the setup apps
+ cy.get('[data-cy-setup-recommended-apps-skip]').click()
+
+ // Go to files
+ cy.visit('/apps/files/')
+ cy.get('[data-cy-files-content]').should('be.visible')
+}