diff --git a/cypress/e2e/boardFeatures.js b/cypress/e2e/boardFeatures.js index 058da5e8b..79e960be5 100644 --- a/cypress/e2e/boardFeatures.js +++ b/cypress/e2e/boardFeatures.js @@ -1,10 +1,10 @@ -import { randHash } from "../utils" +import { randHash } from '../utils' const randUser = randHash() -describe('Board', function () { - const password = 'pass123' - - before(function () { +describe('Board', function() { + const password = 'pass123' + + before(function() { cy.nextcloudCreateUser(randUser, password) }) @@ -12,30 +12,30 @@ describe('Board', function () { cy.login(randUser, password) }) - it('Can create a board', function () { - let board = 'Test' + it('Can create a board', function() { + const board = 'Test' - cy.intercept({ - method: 'POST', - url: '/index.php/apps/deck/boards', - }).as('createBoardRequest') - - // Click "Add board" - cy.openLeftSidebar() - cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry') - .eq(3).find('a').first().click({force: true}) + cy.intercept({ + method: 'POST', + url: '/index.php/apps/deck/boards', + }).as('createBoardRequest') - // Type the board title - cy.get('.board-create form input[type=text]') - .type(board, {force: true}) + // Click "Add board" + cy.openLeftSidebar() + cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry') + .eq(3).find('a').first().click({ force: true }) - // Submit - cy.get('.board-create form input[type=submit]') - .first().click({force: true}) + // Type the board title + cy.get('.board-create form input[type=text]') + .type(board, { force: true }) - cy.wait('@createBoardRequest').its('response.statusCode').should('equal', 200) - - cy.get('.app-navigation__list .app-navigation-entry__children .app-navigation-entry') - .contains(board).should('be.visible') + // Submit + cy.get('.board-create form input[type=submit]') + .first().click({ force: true }) + + cy.wait('@createBoardRequest').its('response.statusCode').should('equal', 200) + + cy.get('.app-navigation__list .app-navigation-entry__children .app-navigation-entry') + .contains(board).should('be.visible') }) -}) \ No newline at end of file +}) diff --git a/cypress/e2e/cardFeatures.js b/cypress/e2e/cardFeatures.js index 5a413e203..d5449440c 100644 --- a/cypress/e2e/cardFeatures.js +++ b/cypress/e2e/cardFeatures.js @@ -1,38 +1,67 @@ import { randHash } from '../utils' const randUser = randHash() -describe('Card', function () { - const board = 'TestBoard' - const list = 'TestList' - const password = 'pass123' +const testBoardData = { + title: 'MyBoardTest', + color: '00ff00', + stacks: [ + { + title: 'TestList', + cards: [ + { + title: 'Hello world', + }, + ], + }, + ], +} - before(function () { - cy.nextcloudCreateUser(randUser, password) - cy.deckCreateBoard({ user: randUser, password }, board) - cy.deckCreateList({ user: randUser, password }, list) - }) +describe('Card', function() { + before(function() { + cy.nextcloudCreateUser(randUser, randUser) + cy.createExampleBoard({ + user: randUser, + password: randUser, + board: testBoardData, + }) + }) - beforeEach(function () { - cy.login(randUser, password) - }) + beforeEach(function() { + cy.login(randUser, randUser) + }) - it('Can add a card', function () { - let card = 'Card 1' + it('Can show card details modal', function() { + cy.openLeftSidebar() + cy.getNavigationEntry(testBoardData.title) + .first().click({ force: true }) - cy.openLeftSidebar() - cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry') - .eq(3).find('a.app-navigation-entry-link') - .first().click({force: true}) + cy.get('.board .stack').eq(0).within(() => { + cy.get('.card:contains("Hello world")').should('be.visible').click() + }) - cy.get('.board .stack').eq(0).within(() => { - cy.get('button.action-item.action-item--single.icon-add') - .first().click() + cy.get('.modal__card').should('be.visible') + cy.get('.app-sidebar-header__maintitle').contains('Hello world') + }) - cy.get('.stack__card-add form input#new-stack-input-main') - .type(card) - cy.get('.stack__card-add form input[type=submit]') - .first().click() - cy.get('.card').first().contains(card).should('be.visible') - }) - }) -}) \ No newline at end of file + it('Can add a card', function() { + const newCardTitle = 'Write some cypress tests' + + cy.openLeftSidebar() + cy.getNavigationEntry(testBoardData.title) + .first().click({ force: true }) + + cy.get('.board .stack').eq(0).within(() => { + cy.get('.card:contains("Hello world")').should('be.visible') + + cy.get('.button-vue[aria-label*="Add card"]') + .first().click() + + cy.get('.stack__card-add form input#new-stack-input-main') + .type(newCardTitle) + cy.get('.stack__card-add form input[type=submit]') + .first().click() + cy.get(`.card:contains("${newCardTitle}")`).should('be.visible') + }) + }) + +}) diff --git a/cypress/e2e/deckDashboard.js b/cypress/e2e/deckDashboard.js index ce85d43cb..f61e744e3 100644 --- a/cypress/e2e/deckDashboard.js +++ b/cypress/e2e/deckDashboard.js @@ -4,7 +4,7 @@ const randUser = randHash() describe('Deck dashboard', function() { const password = 'pass123' - before(function () { + before(function() { cy.nextcloudCreateUser(randUser, password) }) @@ -18,15 +18,14 @@ describe('Deck dashboard', function() { .should('have.text', 'Upcoming cards') }) - it('Can see the default "Personal Board" created for user by default', function () { + it('Can see the default "Personal Board" created for user by default', function() { const defaultBoard = 'Personal' cy.openLeftSidebar() - cy.get('.app-navigation__list .app-navigation-entry') - .eq(1) - .find('ul.app-navigation-entry__children li.app-navigation-entry') + cy.get('.app-navigation-entry-wrapper[icon=icon-deck]') + .find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + defaultBoard + ')') .first() .contains(defaultBoard) .should('be.visible') }) -}) \ No newline at end of file +}) diff --git a/cypress/e2e/stackFeatures.js b/cypress/e2e/stackFeatures.js index 3ce09fa20..7754643ec 100644 --- a/cypress/e2e/stackFeatures.js +++ b/cypress/e2e/stackFeatures.js @@ -1,33 +1,30 @@ -import { randHash } from "../utils"; -const randUser = randHash(); +import { randHash } from '../utils' +const randUser = randHash() -describe("Stack", function () { - const board = "TestBoard"; - const password = "pass123"; - const stack = "List 1"; +describe('Stack', function() { + const board = 'TestBoard' + const password = 'pass123' + const stack = 'List 1' - before(function () { + before(function() { cy.nextcloudCreateUser(randUser, password) cy.deckCreateBoard({ user: randUser, password }, board) }) - beforeEach(function () { + beforeEach(function() { cy.logout() cy.login(randUser, password) }) - it("Can create a stack", function () { + it('Can create a stack', function() { cy.openLeftSidebar() - cy.get("#app-navigation-vue .app-navigation__list .app-navigation-entry") - .eq(3) - .find("a.app-navigation-entry-link") - .first() + cy.getNavigationEntry(board) .click({ force: true }) - cy.get("#stack-add button").first().click() - cy.get("#stack-add form input#new-stack-input-main").type(stack) - cy.get("#stack-add form input[type=submit]").first().click() + cy.get('#stack-add button').first().click() + cy.get('#stack-add form input#new-stack-input-main').type(stack) + cy.get('#stack-add form input[type=submit]').first().click() - cy.get(".board .stack").eq(0).contains(stack).should("be.visible") + cy.get('.board .stack').eq(0).contains(stack).should('be.visible') }) -}); +}) diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js index 59b2bab6e..96e295355 100644 --- a/cypress/plugins/index.js +++ b/cypress/plugins/index.js @@ -17,6 +17,6 @@ */ // eslint-disable-next-line no-unused-vars module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config } diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 19815e16f..ff69e2344 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -20,94 +20,140 @@ * */ -const url = Cypress.config("baseUrl").replace(/\/index.php\/?$/g, ""); -Cypress.env("baseUrl", url); +const url = Cypress.config('baseUrl').replace(/\/index.php\/?$/g, '') +Cypress.env('baseUrl', url) -Cypress.Commands.add("login", (user, password, route = "/apps/deck/") => { - let session = `${user}-${Date.now()}`; - cy.session(session, function () { - cy.visit(route); - cy.get("input[name=user]").type(user); - cy.get("input[name=password]").type(password); - cy.get("form[name=login] [type=submit]").click(); - cy.url().should("include", route); - }); - // in case the session already existed but we are on a different route... - cy.visit(route); -}); +Cypress.Commands.add('login', (user, password, route = '/apps/deck/') => { + const session = `${user}-${Date.now()}` + cy.session(session, function() { + cy.visit(route) + cy.get('input[name=user]').type(user) + cy.get('input[name=password]').type(password) + cy.get('form[name=login] [type=submit]').click() + cy.url().should('include', route) + }) + cy.visit(route) +}) -Cypress.Commands.add("logout", (route = "/") => { - cy.session("_guest", function () {}); -}); +Cypress.Commands.add('logout', (route = '/') => { + cy.session('_guest', function() {}) +}) -Cypress.Commands.add("nextcloudCreateUser", (user, password) => { - cy.clearCookies(); +Cypress.Commands.add('nextcloudCreateUser', (user, password) => { + cy.clearCookies() cy.request({ - method: "POST", - url: `${Cypress.env("baseUrl")}/ocs/v1.php/cloud/users?format=json`, + method: 'POST', + url: `${Cypress.env('baseUrl')}/ocs/v1.php/cloud/users?format=json`, form: true, body: { userid: user, - password: password, + password, }, - auth: { user: "admin", pass: "admin" }, + auth: { user: 'admin', pass: 'admin' }, headers: { - "OCS-ApiRequest": "true", - "Content-Type": "application/x-www-form-urlencoded", + 'OCS-ApiRequest': 'true', + 'Content-Type': 'application/x-www-form-urlencoded', }, }).then((response) => { - cy.log(`Created user ${user}`, response.status); - }); -}); + cy.log(`Created user ${user}`, response.status) + }) +}) -Cypress.Commands.add("nextcloudUpdateUser", (user, password, key, value) => { +Cypress.Commands.add('nextcloudUpdateUser', (user, password, key, value) => { cy.request({ - method: "PUT", - url: `${Cypress.env("baseUrl")}/ocs/v2.php/cloud/users/${user}`, + method: 'PUT', + url: `${Cypress.env('baseUrl')}/ocs/v2.php/cloud/users/${user}`, form: true, body: { key, value }, auth: { user, pass: password }, headers: { - "OCS-ApiRequest": "true", - "Content-Type": "application/x-www-form-urlencoded", + 'OCS-ApiRequest': 'true', + 'Content-Type': 'application/x-www-form-urlencoded', }, }).then((response) => { - cy.log(`Updated user ${user} ${key} to ${value}`, response.status); - }); -}); + cy.log(`Updated user ${user} ${key} to ${value}`, response.status) + }) +}) -Cypress.Commands.add("openLeftSidebar", () => { - cy.get(".app-navigation button.app-navigation-toggle").click(); -}); +Cypress.Commands.add('openLeftSidebar', () => { + cy.get('.app-navigation button.app-navigation-toggle').click() +}) -Cypress.Commands.add("deckCreateBoard", ({ user, password }, title) => { - cy.login(user, password); +Cypress.Commands.add('deckCreateBoard', ({ user, password }, title) => { + cy.login(user, password) - cy.get(".app-navigation button.app-navigation-toggle").click(); - cy.get("#app-navigation-vue .app-navigation__list .app-navigation-entry") + cy.get('.app-navigation button.app-navigation-toggle').click() + cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry') .eq(3) - .find("a") + .find('a') .first() - .click({ force: true }); + .click({ force: true }) - cy.get(".board-create form input[type=text]").type(title, { force: true }); + cy.get('.board-create form input[type=text]').type(title, { force: true }) - cy.get(".board-create form input[type=submit]") + cy.get('.board-create form input[type=submit]') .first() - .click({ force: true }); -}); + .click({ force: true }) +}) -Cypress.Commands.add("deckCreateList", ({ user, password }, title) => { - cy.login(user, password); +Cypress.Commands.add('deckCreateList', ({ user, password }, title) => { + cy.login(user, password) - cy.get(".app-navigation button.app-navigation-toggle").click(); - cy.get("#app-navigation-vue .app-navigation__list .app-navigation-entry") + cy.get('.app-navigation button.app-navigation-toggle').click() + cy.get('#app-navigation-vue .app-navigation__list .app-navigation-entry') .eq(3) - .find("a.app-navigation-entry-link") + .find('a.app-navigation-entry-link') .first() - .click({ force: true }); + .click({ force: true }) - cy.get("#stack-add button").first().click(); - cy.get("#stack-add form input#new-stack-input-main").type(title); - cy.get("#stack-add form input[type=submit]").first().click(); -}); + cy.get('#stack-add button').first().click() + cy.get('#stack-add form input#new-stack-input-main').type(title) + cy.get('#stack-add form input[type=submit]').first().click() +}) + +Cypress.Commands.add('createExampleBoard', ({ user, password, board }) => { + cy.request({ + method: 'POST', + url: `${Cypress.env('baseUrl')}/index.php/apps/deck/api/v1.0/boards`, + auth: { + user, + password, + }, + body: { title: board.title, color: board.color ?? 'ff0000' }, + }).then((boardResponse) => { + expect(boardResponse.status).to.eq(200) + const boardData = boardResponse.body + for (const stackIndex in board.stacks) { + const stack = board.stacks[stackIndex] + cy.request({ + method: 'POST', + url: `${Cypress.env('baseUrl')}/index.php/apps/deck/api/v1.0/boards/${boardData.id}/stacks`, + auth: { + user, + password, + }, + body: { title: stack.title, order: 0 }, + }).then((stackResponse) => { + const stackData = stackResponse.body + for (const cardIndex in stack.cards) { + const card = stack.cards[cardIndex] + cy.request({ + method: 'POST', + url: `${Cypress.env('baseUrl')}/index.php/apps/deck/api/v1.0/boards/${boardData.id}/stacks/${stackData.id}/cards`, + auth: { + user, + password, + }, + body: { title: card.title }, + }) + } + }) + } + }) +}) + +Cypress.Commands.add('getNavigationEntry', (boardTitle) => { + return cy.get('.app-navigation-entry-wrapper[icon=icon-deck]') + .find('ul.app-navigation-entry__children .app-navigation-entry:contains(' + boardTitle + ')') + .find('a.app-navigation-entry-link') +}) diff --git a/cypress/utils/index.js b/cypress/utils/index.js index 1ace84aaa..aa46b9f07 100644 --- a/cypress/utils/index.js +++ b/cypress/utils/index.js @@ -1 +1 @@ -export const randHash = () => Math.random().toString(36).replace(/[^a-z]+/g, '').slice(0, 10) \ No newline at end of file +export const randHash = () => Math.random().toString(36).replace(/[^a-z]+/g, '').slice(0, 10)