diff options
Diffstat (limited to 'cypress/e2e')
-rw-r--r-- | cypress/e2e/files/files.cy.ts (renamed from cypress/e2e/files.cy.ts) | 12 | ||||
-rw-r--r-- | cypress/e2e/files/files_sorting.cy.ts | 262 | ||||
-rw-r--r-- | cypress/e2e/settings/apps.cy.ts | 2 | ||||
-rw-r--r-- | cypress/e2e/settings/systemtags.cy.ts | 138 |
4 files changed, 404 insertions, 10 deletions
diff --git a/cypress/e2e/files.cy.ts b/cypress/e2e/files/files.cy.ts index 490ddff2d0e..33261be417e 100644 --- a/cypress/e2e/files.cy.ts +++ b/cypress/e2e/files/files.cy.ts @@ -19,21 +19,15 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ -describe('Login with a new user and open the files app', function() { - before(function() { +describe('Files', { testIsolation: true }, () => { + beforeEach(() => { cy.createRandomUser().then((user) => { cy.login(user) }) }) - after(function() { - cy.logout() - }) - - it('See the default file welcome.txt in the files list', function() { + it('Login with a user and open the files app', () => { cy.visit('/apps/files') cy.get('[data-cy-files-list] [data-cy-files-list-row-name="welcome.txt"]').should('be.visible') - // eslint-disable-next-line cypress/no-unnecessary-waiting -- Wait for all to finish loading - cy.wait(500) }) }) diff --git a/cypress/e2e/files/files_sorting.cy.ts b/cypress/e2e/files/files_sorting.cy.ts new file mode 100644 index 00000000000..b0ce1b6d723 --- /dev/null +++ b/cypress/e2e/files/files_sorting.cy.ts @@ -0,0 +1,262 @@ +/** + * @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.com> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +describe('Files: Sorting the file list', { testIsolation: true }, () => { + let currentUser + beforeEach(() => { + cy.createRandomUser().then((user) => { + currentUser = user + cy.login(user) + }) + }) + + it('Files are sorted by name ascending by default', () => { + cy.uploadContent(currentUser, new Blob(), 'text/plain', '/1 first.txt') + .uploadContent(currentUser, new Blob(), 'text/plain', '/z last.txt') + .uploadContent(currentUser, new Blob(), 'text/plain', '/A.txt') + .uploadContent(currentUser, new Blob(), 'text/plain', '/Ä.txt') + .mkdir(currentUser, '/m') + .mkdir(currentUser, '/4') + cy.login(currentUser) + cy.visit('/apps/files') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('4') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('m') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('1 first.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('A.txt') + break + case 4: expect($row.attr('data-cy-files-list-row-name')).to.eq('Ä.txt') + break + case 5: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 6: expect($row.attr('data-cy-files-list-row-name')).to.eq('z last.txt') + break + } + }) + }) + + it('Can sort by size', () => { + cy.uploadContent(currentUser, new Blob(), 'text/plain', '/1 tiny.txt') + .uploadContent(currentUser, new Blob(['a'.repeat(1024)]), 'text/plain', '/z big.txt') + .uploadContent(currentUser, new Blob(['a'.repeat(512)]), 'text/plain', '/a medium.txt') + .mkdir(currentUser, '/folder') + cy.login(currentUser) + cy.visit('/apps/files') + + // click sort button + cy.get('th').contains('button', 'Size').click() + // sorting is set + cy.contains('th', 'Size').should('have.attr', 'aria-sort', 'ascending') + // Files are sorted + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('1 tiny.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('folder') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('a medium.txt') + break + case 4: expect($row.attr('data-cy-files-list-row-name')).to.eq('z big.txt') + break + } + }) + + // click sort button + cy.get('th').contains('button', 'Size').click() + // sorting is set + cy.contains('th', 'Size').should('have.attr', 'aria-sort', 'descending') + // Files are sorted + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('z big.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('a medium.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('folder') + break + case 4: expect($row.attr('data-cy-files-list-row-name')).to.eq('1 tiny.txt') + break + } + }) + }) + + it('Can sort by mtime', () => { + cy.uploadContent(currentUser, new Blob(), 'text/plain', '/1.txt', Date.now() / 1000 - 86400 - 1000) + .uploadContent(currentUser, new Blob(['a'.repeat(1024)]), 'text/plain', '/z.txt', Date.now() / 1000 - 86400) + .uploadContent(currentUser, new Blob(['a'.repeat(512)]), 'text/plain', '/a.txt', Date.now() / 1000 - 86400 - 500) + cy.login(currentUser) + cy.visit('/apps/files') + + // click sort button + cy.get('th').contains('button', 'Modified').click() + // sorting is set + cy.contains('th', 'Modified').should('have.attr', 'aria-sort', 'ascending') + // Files are sorted + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') // uploaded right now + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') // fake time of yesterday + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') // fake time of yesterday and few minutes + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') // fake time of yesterday and ~15 minutes ago + break + } + }) + + // reverse order + cy.get('th').contains('button', 'Modified').click() + cy.contains('th', 'Modified').should('have.attr', 'aria-sort', 'descending') + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') // uploaded right now + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') // fake time of yesterday + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') // fake time of yesterday and few minutes + break + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') // fake time of yesterday and ~15 minutes ago + break + } + }) + }) + + it('Favorites are sorted first', () => { + cy.uploadContent(currentUser, new Blob(), 'text/plain', '/1.txt', Date.now() / 1000 - 86400 - 1000) + .uploadContent(currentUser, new Blob(['a'.repeat(1024)]), 'text/plain', '/z.txt', Date.now() / 1000 - 86400) + .uploadContent(currentUser, new Blob(['a'.repeat(512)]), 'text/plain', '/a.txt', Date.now() / 1000 - 86400 - 500) + .setFileAsFavorite(currentUser, '/a.txt') + cy.login(currentUser) + cy.visit('/apps/files') + + cy.log('By name - ascending') + cy.get('th').contains('button', 'Name').click() + cy.contains('th', 'Name').should('have.attr', 'aria-sort', 'ascending') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') + break + } + }) + + cy.log('By name - descending') + cy.get('th').contains('button', 'Name').click() + cy.contains('th', 'Name').should('have.attr', 'aria-sort', 'descending') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') + break + } + }) + + cy.log('By size - ascending') + cy.get('th').contains('button', 'Size').click() + cy.contains('th', 'Size').should('have.attr', 'aria-sort', 'ascending') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') + break + } + }) + + cy.log('By size - descending') + cy.get('th').contains('button', 'Size').click() + cy.contains('th', 'Size').should('have.attr', 'aria-sort', 'descending') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') + break + } + }) + + cy.log('By mtime - ascending') + cy.get('th').contains('button', 'Modified').click() + cy.contains('th', 'Modified').should('have.attr', 'aria-sort', 'ascending') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') + break + } + }) + + cy.log('By mtime - descending') + cy.get('th').contains('button', 'Modified').click() + cy.contains('th', 'Modified').should('have.attr', 'aria-sort', 'descending') + + cy.get('[data-cy-files-list-row]').each(($row, index) => { + switch (index) { + case 0: expect($row.attr('data-cy-files-list-row-name')).to.eq('a.txt') + break + case 1: expect($row.attr('data-cy-files-list-row-name')).to.eq('1.txt') + break + case 2: expect($row.attr('data-cy-files-list-row-name')).to.eq('z.txt') + break + case 3: expect($row.attr('data-cy-files-list-row-name')).to.eq('welcome.txt') + break + } + }) + }) +}) diff --git a/cypress/e2e/settings/apps.cy.ts b/cypress/e2e/settings/apps.cy.ts index 516ddd0cf82..8bec0bd00f4 100644 --- a/cypress/e2e/settings/apps.cy.ts +++ b/cypress/e2e/settings/apps.cy.ts @@ -125,7 +125,7 @@ describe('Settings: App management', { testIsolation: true }, () => { it('View app details', () => { // When I click on the "QA testing" app - cy.get('#apps-list').contains('tr', 'QA testing').click({ force: true }) + cy.get('#apps-list').contains('a', 'QA testing').click({ force: true }) // I see that the app details are shown cy.get('#app-sidebar-vue') .should('be.visible') diff --git a/cypress/e2e/settings/systemtags.cy.ts b/cypress/e2e/settings/systemtags.cy.ts new file mode 100644 index 00000000000..3c9a8b25cf4 --- /dev/null +++ b/cypress/e2e/settings/systemtags.cy.ts @@ -0,0 +1,138 @@ +/** + * @copyright 2023 Christopher Ng <chrng8@gmail.com> + * + * @author Christopher Ng <chrng8@gmail.com> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +import { User } from '@nextcloud/cypress' + +const admin = new User('admin', 'admin') + +const tagName = 'foo' +const updatedTagName = 'bar' + +describe('Create system tags', () => { + before(() => { + cy.login(admin) + cy.visit('/settings/admin') + }) + + it('Can create a tag', () => { + cy.get('input#system-tag-name').should('exist').and('have.value', '') + cy.get('input#system-tag-name').type(tagName) + cy.get('input#system-tag-name').should('have.value', tagName) + // submit the form + cy.get('input#system-tag-name').type('{enter}') + + // see that the created tag is in the list + cy.get('input#system-tags-input').focus() + cy.get('input#system-tags-input').invoke('attr', 'aria-controls').then(id => { + cy.get(`ul#${id}`).within(() => { + cy.contains('li', tagName).should('exist') + // ensure only one tag exists + cy.get('li').should('have.length', 1) + }) + }) + }) +}) + +describe('Update system tags', { testIsolation: false }, () => { + before(() => { + cy.login(admin) + cy.visit('/settings/admin') + }) + + it('select the tag', () => { + // select the tag to edit + cy.get('input#system-tags-input').focus() + cy.get('input#system-tags-input').invoke('attr', 'aria-controls').then(id => { + cy.get(`ul#${id}`).within(() => { + cy.contains('li', tagName).should('exist').click() + }) + }) + // see that the tag name matches the selected tag + cy.get('input#system-tag-name').should('exist').and('have.value', tagName) + // see that the tag level matches the selected tag + cy.get('input#system-tag-level').click() + cy.get('input#system-tag-level').siblings('.vs__selected').contains('Public').should('exist') + }) + + it('update the tag name and level', () => { + cy.get('input#system-tag-name').clear() + cy.get('input#system-tag-name').type(updatedTagName) + cy.get('input#system-tag-name').should('have.value', updatedTagName) + // select the new tag level + cy.get('input#system-tag-level').focus() + cy.get('input#system-tag-level').invoke('attr', 'aria-controls').then(id => { + cy.get(`ul#${id}`).within(() => { + cy.contains('li', 'Invisible').should('exist').click() + }) + }) + // submit the form + cy.get('input#system-tag-name').type('{enter}') + }) + + it('see the tag was successfully updated', () => { + cy.get('input#system-tags-input').focus() + cy.get('input#system-tags-input').invoke('attr', 'aria-controls').then(id => { + cy.get(`ul#${id}`).within(() => { + cy.contains('li', `${updatedTagName} (invisible)`).should('exist') + // ensure only one tag exists + cy.get('li').should('have.length', 1) + }) + }) + }) +}) + +describe('Delete system tags', { testIsolation: false }, () => { + before(() => { + cy.login(admin) + cy.visit('/settings/admin') + }) + + it('select the tag', () => { + // select the tag to edit + cy.get('input#system-tags-input').focus() + cy.get('input#system-tags-input').invoke('attr', 'aria-controls').then(id => { + cy.get(`ul#${id}`).within(() => { + cy.contains('li', `${updatedTagName} (invisible)`).should('exist').click() + }) + }) + // see that the tag name matches the selected tag + cy.get('input#system-tag-name').should('exist').and('have.value', updatedTagName) + // see that the tag level matches the selected tag + cy.get('input#system-tag-level').focus() + cy.get('input#system-tag-level').siblings('.vs__selected').contains('Invisible').should('exist') + }) + + it('can delete the tag', () => { + cy.get('.system-tag-form__row').within(() => { + cy.contains('button', 'Delete').should('be.enabled').click() + }) + }) + + it('see that the deleted tag is not present', () => { + cy.get('input#system-tags-input').focus() + cy.get('input#system-tags-input').invoke('attr', 'aria-controls').then(id => { + cy.get(`ul#${id}`).within(() => { + cy.contains('li', updatedTagName).should('not.exist') + }) + }) + }) +}) |