diff --git a/.github/workflows/cypress-test-run.yml b/.github/workflows/cypress-test-run.yml
new file mode 100644
index 000000000..81b99fc5d
--- /dev/null
+++ b/.github/workflows/cypress-test-run.yml
@@ -0,0 +1,34 @@
+name: Cypress Test Run
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ build:
+ runs-on: windows-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Install dependencies
+ run: npm install
+ - name: setup local server
+ run: start npm start
+ - name: Run Cypress tests
+ run: npx cypress run
+ - uses: cypress-io/github-action@v2
+ - uses: actions/upload-artifact@v2
+ if: always()
+ with:
+ name: cypress-videos
+ path: cypress/videos
+
+
+# - name: "Upload screenshots to Slack"
+# uses: trymbill/cypress-slack-video-upload-action@v1.3.0
+# if: failure()
+# with:
+# token: ${{ secrets.SLACK_TOKEN }}
+# channels: "_tolk"
+# message-text: "Cypress tests failed! They have been placed in this thread, good luck."R
\ No newline at end of file
diff --git a/.github/workflows/run-cypress.yml b/.github/workflows/run-cypress.yml
deleted file mode 100644
index 16af3e6fa..000000000
--- a/.github/workflows/run-cypress.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Run tests manually
-on: workflow_dispatch
-jobs:
- cypress-run:
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- containers: [1, 2, 3]
- steps:
- - name: Checkout
- uses: actions/checkout@v2
- - name: Cypress run
- uses: cypress-io/github-action@v4
- with:
- start: npm start
- record: true
- parallel: true
- env:
- CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Codecov
- uses: codecov/codecov-action@v2
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
deleted file mode 100644
index 2b067675a..000000000
--- a/.github/workflows/static.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: Lint checks
-on: [push]
-jobs:
- static-checks:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v2
- - uses: bahmutov/npm-install@v1
- with:
- useLockFile: false
- - run: npm run selectorcheck
- - run: npm run typecheck
- - run: npm run lint
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
deleted file mode 100644
index a48305f71..000000000
--- a/.github/workflows/tests.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: e2e-tests
-on: [pull_request]
-jobs:
- cypress-run:
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- containers: [1, 2, 3]
- steps:
- - name: Checkout
- uses: actions/checkout@v2
- - name: Cypress run
- uses: cypress-io/github-action@v4
- with:
- start: npm start
- record: true
- parallel: true
- env:
- CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Codecov
- uses: codecov/codecov-action@v2
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 0f36b718a..a863bfe23 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,7 +9,6 @@ coverage
cypress/screenshots
cypress/videos
cypress/downloads
-backend/data/uploaded/*
.env
.vscode/*
diff --git a/README.md b/README.md
index 68c2c724b..531298ff6 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,7 @@
-## Trello clone app written in Vue 3 + Typescript + Vite + TailwindCSS
-
-[](https://dashboard.cypress.io/projects/qmz9cz/runs) [](https://codecov.io/gh/filiphric/trelloapp-vue-vite-ts)
-
-
-
-
-
-This is a second version of [Trello clone](https://github.com/filiphric/trelloapp) app, which I use for my Cypress.io workshops. I create this to explain and showcase Cypress capabilities, much like [Real world application](https://github.com/cypress-io/cypress-realworld-app) by Cypress.
-
-To install, simply clone this project and
-
-1. `npm install`
-2. `npm start`
-
-What you can see here is pretty much still work in progress and far from done. This is my Playground, don’t judge the code quality.
+To run
+
+npm install
+
+npm start
+
+npm cypress run
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
index 000000000..9701a0205
--- /dev/null
+++ b/azure-pipelines.yml
@@ -0,0 +1,20 @@
+# Node.js
+# Build a general Node.js project with npm.
+# Add steps that analyze code, save build artifacts, deploy, and more:
+# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
+
+trigger:
+- main
+
+pool:
+ vmImage: ubuntu-latest
+
+steps:
+- task: NodeTool@0
+ inputs:
+ versionSpec: '10.x'
+ displayName: 'Install Node.js'
+
+- script: |
+ npm install
+ displayName: 'npm install'
diff --git a/backend/data/uploaded/3_chrome_q4SL915vQ0.png b/backend/data/uploaded/3_chrome_q4SL915vQ0.png
new file mode 100644
index 000000000..e4a9b6dc9
Binary files /dev/null and b/backend/data/uploaded/3_chrome_q4SL915vQ0.png differ
diff --git a/cypress.config.ts b/cypress.config.ts
index 7aae0b8ab..eb5676a65 100644
--- a/cypress.config.ts
+++ b/cypress.config.ts
@@ -1,37 +1,17 @@
-import { defineConfig } from 'cypress'
-import constants from './constants'
-const { APP } = constants
+import { defineConfig } from "cypress";
export default defineConfig({
- env: {
- coverage: true,
- },
- retries: {
- openMode: 0,
- runMode: 1,
- },
- videoUploadOnPasses: false,
- viewportHeight: 550,
- viewportWidth: 700,
- projectId: 'qmz9cz',
+ video: true,
+ projectId: 'm2fvqo',
e2e: {
- // We've imported your old cypress plugins here.
- // You may want to clean this up later by importing these.
+ specPattern: "**/e2e/*/*.spec.ts",
+ baseUrl: 'http://localhost:3000',
+ reporter: 'spec',
setupNodeEvents(on, config) {
- return require('./cypress/plugins/index.ts')(on, config)
- },
- baseUrl: `http://localhost:${APP}`,
- specPattern: 'cypress/e2e/**/*.spec.ts',
- },
- component: {
- devServer: {
- framework: 'vue',
- bundler: 'vite',
- },
- setupNodeEvents(on, config) { },
- env: {
- coverage: false,
+ // implement node event listeners here
+ require('@cypress/grep/src/plugin')(config);
+ return config;
},
- specPattern: 'src/**/*.spec.ts',
+
},
-})
+});
diff --git a/cypress/e2e/board.spec.ts b/cypress/e2e/board.spec.ts
deleted file mode 100644
index 3d7632912..000000000
--- a/cypress/e2e/board.spec.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-
-it('board actions', () => {
- cy.request('POST', '/api/reset');
- cy.intercept({
- method: 'POST',
- url: '/api/boards',
- times: 3
- }).as('createBoard');
- cy.visit('/');
-
- cy.step('create first board')
- cy.getDataCy('first-board').type('new board{enter}');
- cy.wait('@createBoard').then(({ response }) => {
- cy.location('pathname')
- .should('eq', `/board/${response!.body.id}`);
- });
- cy.getDataCy('board-detail').should('be.visible');
- cy.getDataCy('loading').should('not.exist');
- cy.getDataCy('home').click();
-
- cy.step('star board')
- cy.intercept('PATCH', '/api/boards/*').as('starBoard');
- cy.getDataCy('board-item').should('be.visible');
- cy.getDataCy('starred-boards').should('not.exist');
- cy.getDataCy('board-item').trigger('mouseover');
- cy.getDataCy('star').click();
- cy.wait('@starBoard')
- .its('request.body.starred')
- .should('be.true');
- cy.getDataCy('starred-boards').should('be.visible');
-
- cy.step('board create field')
- cy.getDataCy('create-board').click();
- cy.getDataCy('board-list').click('bottomRight');
- cy.getDataCy('new-board-input').should('not.be.visible');
- cy.getDataCy('create-board').click();
- cy.getDataCy('new-board-input').type('{enter}');
- cy.getDataCy('create-board').click();
- cy.getDataCy('cancel').click();
- cy.location('pathname').should('eq', '/');
- cy.getDataCy('board-item').should('have.length', 1);
- cy.getDataCy('create-board').should('be.visible');
-
- cy.step('create second board with enter key')
- cy.getDataCy('create-board').click();
- cy.getDataCy('new-board-input').should('be.focused');
- cy.getDataCy('new-board-input').type('new board{enter}');
- cy.wait('@createBoard').then(({ response }) => {
- cy.location('pathname')
- .should('eq', `/board/${response!.body.id}`);
- });
- cy.getDataCy('board-detail').should('be.visible');
- cy.getDataCy('loading').should('not.exist');
-
- cy.getDataCy('trello-logo').click();
-
- cy.step('create third board with click')
- cy.getDataCy('create-board').click();
- cy.getDataCy('new-board-input').type('new board');
- cy.getDataCy('new-board-create').click();
- cy.wait('@createBoard').then(({ response }) => {
- cy.location('pathname').should('eq', `/board/${response!.body.id}`);
- });
- cy.getDataCy('board-detail').should('be.visible');
- cy.getDataCy('loading').should('not.exist');
-
- cy.go('back')
-
- cy.step('show error message on network error')
- cy.intercept({
- method: 'POST',
- url: '/api/boards',
- times: 1
- }, {
- statusCode: 500
- }).as('createBoard');
- cy.clock();
- cy.getDataCy('create-board').click();
- cy.getDataCy('new-board-input').type('new{enter}');
- cy.getDataCy('notification-message').should('be.visible');
- cy.tick(4000);
- cy.getDataCy('notification-message').should('not.exist');
- cy.location('pathname').should('eq', '/');
- cy.getDataCy('board-item').should('have.length', 3);
- cy.getDataCy('new-board-input').should('be.visible');
-
-
- cy.step('shows network error when board are not loaded')
- cy.intercept({
- url:'/api/boards',
- times: 1
- }, {
- statusCode: 404
- })
- cy.reload()
- cy.getDataCy('board-list-error-message')
- .should('contain.text', 'There was an error loading your boards')
-
- cy.contains('Try again').click()
-
- cy.location('pathname').should('eq', '/')
- cy.getDataCy('board-item').should('be.visible')
-});
\ No newline at end of file
diff --git a/cypress/e2e/boardDetail.spec.ts b/cypress/e2e/boardDetail.spec.ts
deleted file mode 100644
index fe15922a2..000000000
--- a/cypress/e2e/boardDetail.spec.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-const oldName = 'board';
-const newName = 'new board';
-
-beforeEach(() => {
- cy.request('POST', '/api/reset');
- cy.addBoardApi(oldName);
-});
-
-it('board actions', function() {
-
- const boardId = this.board.id;
-
- cy.visit(`/board/${boardId}`);
-
- cy.step('rename cancel')
- cy.getDataCy('board-title').should('have.value', oldName);
- cy.getDataCy('board-title').click();
- cy.getDataCy('board-detail').click();
- cy.getDataCy('board-title').type('{esc}');
- cy.getDataCy('board-title').should('have.value', oldName);
-
- cy.step('renames of a board')
- cy.intercept('PATCH', '/api/boards/*').as('boardChange');
- cy.getDataCy('board-title')
- .clear()
- .type(`${newName}{enter}`);
- cy.wait('@boardChange')
- .its('request.body.name')
- .should('eq', newName);
- cy.getDataCy('board-title').should('have.value', newName);
-
- cy.step('star board')
- cy.getDataCy('star').click()
- cy.wait('@boardChange')
- .its('request.body.starred')
- .should('be.true')
-
- cy.step('dropdown actions')
- cy.getDataCy('board-options').click()
- cy.getDataCy('board-dropdown').should('be.visible')
- cy.getDataCy('cancel').click()
- cy.getDataCy('board-dropdown').should('not.exist')
- cy.getDataCy('board-options').click()
- cy.getDataCy('board-dropdown').should('be.visible')
- cy.root().click()
- cy.getDataCy('board-dropdown').should('not.exist')
-
- cy.step('delete board')
- cy.intercept('DELETE', '/api/boards/*').as('boardDelete');
- cy.getDataCy('board-options').click()
- cy.getDataCy('delete-board').click()
- cy.wait('@boardDelete')
- .its('response.statusCode')
- .should('eq', 200)
- cy.getDataCy('board-dropdown').should('not.exist')
- cy.location('pathname').should('eq', '/')
-
-});
diff --git a/cypress/e2e/card.spec.ts b/cypress/e2e/card.spec.ts
deleted file mode 100644
index 974abc14d..000000000
--- a/cypress/e2e/card.spec.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-beforeEach(() => {
- cy.request('POST', '/api/reset');
- cy.addBoardApi('new board');
-});
-
-it('card actions', function() {
-
- const boardId = this.board.id
-
- cy.intercept('POST', '/api/cards').as('createCard');
- cy.addListApi({name: 'list 1'})
- cy.addListApi({name: 'list 2'})
- cy.visit(`/board/${boardId}`);
-
- cy.step('card create cancel')
- // esc key
- cy.getDataCy('new-card').eq(0).click();
- cy.getDataCy('new-card-input').type('new card{esc}');
- cy.getDataCy('new-card-input').should('not.exist');
- cy.getDataCy('card').should('not.exist');
- // click away
- cy.getDataCy('new-card').eq(0).click();
- cy.getDataCy('board-detail').click();
- cy.getDataCy('new-card-input').should('not.exist');
- cy.getDataCy('card').should('not.exist');
- // enter no input
- cy.getDataCy('new-card').eq(0).click();
- cy.getDataCy('new-card-input').type('{enter}');
- cy.getDataCy('card').should('not.exist');
- // cancel button
- cy.getDataCy('cancel').click();
- cy.getDataCy('new-card-input').should('not.exist');
- cy.getDataCy('card').should('not.exist');
-
- cy.step('create card')
- cy.getDataCy('new-card').eq(0).click();
- cy.getDataCy('new-card-input').eq(0).type('card 1{enter}');
- cy.wait('@createCard')
- .its('request.body.name')
- .should('eq', 'card 1');
- cy.getDataCy('card').should('be.visible');
-
- cy.step('card edit icon')
- cy.getDataCy('card').realHover();
- cy.getDataCy('card-edit').should('be.visible');
-
- cy.step('card complete')
- cy.intercept('PATCH', '/api/cards/*').as('patchCard');
- cy.getDataCy('card-checkbox').check();
- cy.wait('@patchCard')
- .its('request.body.completed')
- .should('be.true');
- cy.getDataCy('card-checkbox').uncheck();
- cy.wait('@patchCard')
- .its('request.body.completed')
- .should('be.false');
-
- cy.step('uses dropdown to create card')
- cy.getDataCy('list-options').eq(1).click();
- cy.getDataCy('card-add').click();
- cy.getDataCy('new-card-input')
- .should('be.visible')
- .should('be.focused');
- cy.getDataCy('new-card-input').type('card 2{enter}');
- cy.wait('@createCard')
- .its('request.body.name')
- .should('eq', 'card 2');
- cy.getDataCy('card').should('have.length', 2);
- cy.getDataCy('new-card-input').type('{esc}');
-
- cy.step('card move')
- cy.getDataCy('card-list').eq(0).as('list1')
- cy.getDataCy('card-list').eq(1).as('list2')
- cy.getDataCy('card').eq(0).drag('@list2')
-
- cy.step('card create error')
- cy.intercept('POST', '/api/cards', { forceNetworkError: true }).as('createCard');
- cy.getDataCy('new-card').eq(0).click();
- cy.getDataCy('new-card-input').type('new card{enter}');
- cy.getDataCy('notification-message').should('be.visible').and('contain.text', 'Card was not created')
-
-});
diff --git a/cypress/e2e/cardDetail.spec.ts b/cypress/e2e/cardDetail.spec.ts
deleted file mode 100644
index caa53f422..000000000
--- a/cypress/e2e/cardDetail.spec.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-beforeEach(() => {
- cy.request('POST', '/api/reset');
- cy.addBoardApi('new board')
- .addListApi({ name: 'new list' })
- .addCardApi({ name: 'new card' });
-});
-
-it('card detail actions', function() {
-
- const boardId = this.board.id
- const cardId = this.card.id
- const card = this.card
-
- cy.intercept('PATCH', '/api/cards/*').as('updateCard');
- cy.intercept('DELETE', '/api/cards/*').as('deleteCard');
- cy.visit(`/board/${boardId}?card=${cardId}`);
-
- cy.step('closing and opening card')
- cy.getDataCy('card-detail').should('be.visible');
- cy.getDataCy('card-detail-backdrop').click('topRight');
- cy.getDataCy('card-detail').should('not.exist');
- cy.getDataCy('card').click();
- cy.getDataCy('card-detail').should('be.visible');
- cy.getDataCy('cancel').click()
- cy.getDataCy('card-detail').should('not.exist');
- cy.getDataCy('card').click();
-
- cy.step('card properties')
- cy.getDataCy('copy-properties').realClick();
- cy.window().its('navigator.clipboard')
- .invoke('readText').should('eq', JSON.stringify(card, null, 2));
- cy.getDataCy('notification-message')
- .should('exist')
- .and('contain.text', 'Card info copied to clipboard');
-
- cy.step('card rename')
- cy.getDataCy('card-detail-title').click();
- cy.getDataCy('card-detail-title').type('new name{enter}');
- cy.wait('@updateCard').its('request.body.name').should('eq', 'new name');
- cy.getDataCy('card-detail-title').should('have.value', 'new name');
- cy.getDataCy('card-detail-title').type('{esc}');
- cy.getDataCy('card-detail-title').should('have.value', 'new name');
- cy.getDataCy('notification-message')
- .should('exist')
- .and('contain.text', 'Card was renamed');
-
- cy.step('card deadline hide')
- cy.getDataCy('calendar-dropdown').click();
- cy.getDataCy('card-detail-deadline').should('be.visible');
- cy.getDataCy('calendar-dropdown').click();
- cy.getDataCy('card-detail-deadline').should('not.exist');
-
- cy.step('card deadline hide')
- cy.getDataCy('calendar-button').click();
- cy.getDataCy('card-detail-deadline').should('be.visible');
- cy.getDataCy('header-year').click();
- cy.contains('[data-cy=year]', '2021').click();
- cy.getDataCy('header-month').click();
- cy.contains('[data-cy=month]', 'Aug').click();
- cy.contains('[data-cy=day]', '15').click();
- cy.wait('@updateCard')
- .its('response.body.deadline')
- .should('eq', '2021-08-15');
-
- cy.step('card description')
- cy.getDataCy('card-description').type('new description{enter}');
- cy.wait('@updateCard').its('request.body').should('have.property', 'description', 'new description');
-
- cy.step('image upload')
- cy.intercept({
- method: 'POST',
- url: '/api/upload?card=*',
- }).as('imageUpload');
- cy.getDataCy('upload-image').selectFile('cypress/fixtures/cypressLogo.png', { action: 'drag-drop' });
- cy.wait('@imageUpload').its('response.body').should('have.property', 'image').and('not.be.empty');
- cy.getDataCy('image-attachment').should('exist');
- cy.getDataCy('notification-message').should('exist').and('contain.text', 'File was sucessfully uploaded');
- cy.getDataCy('image-delete').click();
- cy.wait('@updateCard').its('response.body.image').should('be.null');
- cy.getDataCy('image-attachment').should('not.exist');
- cy.getDataCy('upload-image').should('be.visible');
-
- cy.step('error when upload does not work')
- cy.intercept({
- method: 'POST',
- url: '/api/upload?card=*'
- }, {
- statusCode: 400
- }).as('imageUpload');
- cy.getDataCy('upload-image').selectFile('cypress/fixtures/cypressLogo.png', { action: 'drag-drop' });
- cy.getDataCy('notification-message').should('exist').and('contain.text', 'There was an error uploading file');
-
- cy.step('delete a card')
- cy.getDataCy('card-detail-delete').click();
- cy.wait('@deleteCard').its('response.statusCode').should('eq', 200);
- cy.getDataCy('card-detail').should('not.exist');
- cy.getDataCy('notification-message').should('exist').and('contain.text', 'Card was deleted');
-
-});
\ No newline at end of file
diff --git a/cypress/e2e/google.spec.ts b/cypress/e2e/google.spec.ts
deleted file mode 100644
index 0beb34004..000000000
--- a/cypress/e2e/google.spec.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { onlyOn } from '@cypress/skip-test'
-
-beforeEach( () => {
- cy.request('POST', '/api/reset')
-})
-
-it('Google SSO signup and login', () => {
-
- onlyOn(Cypress.env('googleEnabled') === 'true')
-
- cy.step('Signup with Google')
- cy.googleSignup()
-
- cy.visit('/')
-
- cy.step('User is logged in')
- cy.getDataCy('logged-user')
- .should('contain.text', 'filip@filiphric.sk')
-
- cy.step('create board')
- cy.getDataCy('first-board')
- .type('google board{enter}')
-
- cy.step('go back to home page')
- cy.go('back')
-
- cy.step('board is visible')
- cy.getDataCy('board-item')
- .should('be.visible')
-
- cy.step('logout')
- cy.getDataCy('logged-user')
- .click()
-
- cy.step('board disappears from view')
- cy.getDataCy('board-item')
- .should('not.exist')
-
- cy.googleLogin()
- cy.reload()
-
- cy.step('board is visible')
- cy.getDataCy('board-item')
- .should('be.visible')
-
-})
\ No newline at end of file
diff --git a/cypress/e2e/list.spec.ts b/cypress/e2e/list.spec.ts
deleted file mode 100644
index 18d023cb0..000000000
--- a/cypress/e2e/list.spec.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-beforeEach(() => {
- cy.request('POST', '/api/reset');
- cy.addBoardApi('new board');
-});
-
-it('list actions', function() {
-
- const list1 = 'list1'
- const list2 = 'list2'
- const boardId = this.board.id
-
- cy.intercept({
- method: 'POST',
- url:'/api/lists',
- times: 1
- }, {
- statusCode: 500
- }).as('createList');
-
- cy.visit(`/board/${boardId}`);
-
- cy.step('show error message')
- cy.getDataCy('add-list-input').type('new list{enter}');
- cy.getDataCy('notification-message').should('be.visible').and('contain.text', 'List was not created')
-
- cy.step('does not accept empty list names')
- cy.getDataCy('add-list-input').type('{enter}');
- cy.getDataCy('list').should('not.exist');
- cy.getDataCy('add-list-input').should('be.focused');
-
- cy.step('cancels list creation')
- cy.getDataCy('add-list-input').type(`${list1}{esc}`);
- cy.getDataCy('list').should('not.exist');
- cy.getDataCy('add-list-input').should('not.exist');
-
- cy.step('cancel button')
- cy.getDataCy('create-list').click();
- cy.getDataCy('cancel').click();
- cy.getDataCy('list').should('not.exist');
- cy.getDataCy('add-list-input').should('not.exist');
-
- cy.step('click away')
- cy.getDataCy('create-list').click();
- cy.getDataCy('add-list-input').click();
- cy.getDataCy('board-detail').click();
-
- cy.step('create a list')
- cy.getDataCy('create-list').click();
- cy.getDataCy('add-list-input').should('be.focused').type(`${list1}{enter}`);
- cy.contains('Add list').click();
- cy.getDataCy('list').should('have.length', 1);
-
- cy.step('rename list')
- cy.getDataCy('list-name').type('renamed list{enter}');
- cy.getDataCy('list-name').should('have.value', 'renamed list');
-
- cy.step('open and close dropdown ')
- cy.getDataCy('list-options').click();
- cy.getDataCy('list-dropdown').should('be.visible');
- cy.getDataCy('cancel').click();
- cy.getDataCy('list-options').click();
- cy.getDataCy('board-detail').click('bottomRight');
- cy.getDataCy('list-dropdown').should('not.exist');
-
- cy.step('delete list')
- cy.getDataCy('list-options').click();
- cy.getDataCy('delete-list').click();
- cy.getDataCy('list').should('not.exist');
-
- cy.step('create first list')
- cy.getDataCy('create-list').click();
- cy.getDataCy('add-list-input').type(`${list1}{enter}`);
- cy.getDataCy('list').should('have.length', 1);
-
- cy.step('create second list')
- cy.getDataCy('add-list-input').type(`${list2}{enter}`);
- cy.getDataCy('list').should('have.length', 2);
-
- cy.step('reorder lists')
- cy.getDataCy('list-name').eq(0).as('list1').should('have.value', list1);
- cy.getDataCy('list-name').eq(1).as('list2').should('have.value', list2);
- cy.getDataCy('list').eq(0).drag('[data-cy=list-placeholder]:nth-child(2)', { force: true });
- cy.get('@list2').should('have.value', list1);
- cy.get('@list1').should('have.value', list2);
-
-});
diff --git a/cypress/e2e/login.spec.ts b/cypress/e2e/login.spec.ts
deleted file mode 100644
index 4bb20c282..000000000
--- a/cypress/e2e/login.spec.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-describe('Login', () => {
-
- const user = {
- email: 'filip@example.com',
- password: 'Asdf.1234#'
- }
-
- beforeEach(() => {
-
- cy.request('POST', '/api/reset')
- cy.signupApi({ login: false, ...user })
-
- });
-
- it('logs in a user (click)', () => {
-
- cy.visit('/')
-
- cy.getDataCy('login-menu')
- .should('be.visible')
- .click()
-
- cy.location('pathname')
- .should('eq', '/login')
-
- cy.getDataCy('login-email')
- .type(user.email)
-
- cy.getDataCy('login-password')
- .type('invalid{enter}')
-
- cy.getDataCy('notification-message')
- .should('contain.text', 'Incorrect password')
-
- cy.location('pathname')
- .should('eq', '/')
-
- cy.go('back')
-
- cy.getDataCy('login-password')
- .clear()
- .type(user.password)
-
- cy.getDataCy('login-submit')
- .click()
-
- cy.location('pathname')
- .should('eq', '/')
-
- cy.getCookie('auth_token')
- .should('exist')
-
- cy.getDataCy('logged-user')
- .click()
-
- cy.getDataCy('notification-message')
- .should('contain.text', 'User was logged out')
-
- });
-
- it('logs in a user (enter)', () => {
-
- cy.visit('/')
-
- cy.getDataCy('login-menu')
- .should('be.visible')
- .click()
-
- cy.location('pathname')
- .should('eq', '/login')
-
- cy.getDataCy('login-email')
- .type(user.email)
-
- cy.getDataCy('login-password')
- .type(`${user.password}{enter}`)
-
- cy.location('pathname')
- .should('eq', '/')
-
- cy.getCookie('auth_token')
- .should('exist')
-
- cy.getDataCy('logged-user')
- .click()
-
- cy.getDataCy('notification-message')
- .should('contain.text', 'User was logged out')
-
- });
-
- it('shows error on invalid login', () => {
-
- cy.setCookie('auth_token', 'invalid')
-
- cy.visit('/login')
-
- cy.getDataCy('notification-message')
- .should('contain.text', 'Invalid authorization')
-
- })
-
-});
\ No newline at end of file
diff --git a/cypress/e2e/main.spec.ts b/cypress/e2e/main.spec.ts
deleted file mode 100644
index 525af1410..000000000
--- a/cypress/e2e/main.spec.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-describe('main page', () => {
-
- beforeEach(() => {
- cy.addBoardApi('new board')
- });
-
- it('has 404 page', function() {
-
- const boardId = this.board.id
-
- cy.visit('/board/9999999999');
- cy.getDataCy('board-list-error-message').should('be.visible');
-
- cy.contains('Go back home').click()
- cy.location('pathname').should('eq', '/')
-
- cy.visit(`/board/${boardId}?card=1`);
- cy.getDataCy('notification-message').should('contain.text', 'Card with id: 1 was not found')
-
- });
-
-
-});
diff --git a/cypress/e2e/pricing.spec.ts b/cypress/e2e/pricing.spec.ts
deleted file mode 100644
index 40ef59d02..000000000
--- a/cypress/e2e/pricing.spec.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-it('shows pricing', () => {
-
- cy.intercept({
- method: 'GET',
- url: '/api/location',
- times: 1
- }, {
- location: 'us',
- currency: 'USD',
- discountEligible: false
- }).as('locationUS')
-
- cy.visit('/pricing')
- cy.wait('@locationUS')
-
- cy.getDataCy('plan-item').eq(1).should('have.class', 'border-blue6')
- cy.getDataCy('plan-item').eq(0).click().should('have.class', 'border-blue6')
- cy.getDataCy('plan-item').eq(1).should('not.have.class', 'border-blue6')
-
- // USD
- cy.getDataCy('plan-price').should('contain', '$')
-
- // GBP
- cy.intercept({
- method: 'GET',
- url: '/api/location',
- times: 1
- }, {
- location: 'uk',
- currency: 'GBP',
- discountEligible: false
- }).as('locationUK')
-
-
- cy.reload()
- cy.wait('@locationUK')
-
- cy.getDataCy('plan-price').should('contain', '£')
-
- // EUR
- cy.intercept({
- method: 'GET',
- url: '/api/location',
- times: 1
- }, {
- location: 'sk',
- currency: 'EUR',
- discountEligible: true,
- discountAmount: 20
- }).as('locationEU')
-
-
- cy.reload()
- cy.wait('@locationEU')
-
- cy.getDataCy('plan-price').should('contain', '€')
- cy.getDataCy('discount').should('be.visible').and('contain', '20%')
-
-});
-
-it('shows map', () => {
-
- cy.visit('/pricing', {
- onBeforeLoad (win) {
- // e.g., force Barcelona geolocation
- const latitude = 41.38879;
- const longitude = 2.15899;
- cy.stub(win.navigator.geolocation, 'getCurrentPosition').callsFake((cb) => {
- return cb({ coords: { latitude, longitude } });
- });
- }
- })
-
- cy.getDataCy('find-location')
- .click()
-
- cy.get('#map')
- .should('be.visible')
-
-})
\ No newline at end of file
diff --git a/cypress/e2e/search.spec.ts b/cypress/e2e/search.spec.ts
deleted file mode 100644
index 4bb30e2f5..000000000
--- a/cypress/e2e/search.spec.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-beforeEach(() => {
- cy.request('POST', '/api/reset');
- cy.addBoardApi('new board').its('id').as('boardId')
- .addListApi({ name: 'new list' })
- .addCardApi({ name: 'new card' }).its('id').as('cardId');
-});
-
-it('performs a card search', function() {
-
- cy.visit('/')
-
- cy.window().invoke('store').invoke('toggleSearch', true)
-
- cy.getDataCy('search-input').type('new card')
- cy.getDataCy('result-item').contains('new card').click()
-
- cy.location('href').should('include', `/board/${this.boardId}?card=${this.cardId}`)
-
- cy.window().invoke('store').invoke('toggleSearch', true)
- cy.getDataCy('search-input').type('n')
- cy.getDataCy('result-item').should('be.visible')
- cy.getDataCy('search-input').type('{backspace}')
-
-});
\ No newline at end of file
diff --git a/cypress/e2e/signup.spec.ts b/cypress/e2e/signup.spec.ts
deleted file mode 100644
index f4d2abe04..000000000
--- a/cypress/e2e/signup.spec.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-describe('Signup', () => {
-
- beforeEach(() => {
- cy.request('POST', '/api/reset')
- });
-
- it('sign up a user (click)', () => {
-
- const user = {
- email: 'filip@example.com',
- password: 'Asdf.1234#'
- }
-
- cy.visit('/signup')
-
- cy.getDataCy('signup-email')
- .type(user.email)
-
- cy.getDataCy('signup-password')
- .type(user.password)
-
- cy.getDataCy('signup-submit')
- .click()
-
- cy.location('pathname')
- .should('eq', '/')
-
- cy.getCookie('auth_token')
- .should('exist')
-
- });
-
- it('sign up a user (enter)', () => {
-
- const user = {
- email: 'filip@example.com',
- password: 'Asdf.1234#'
- }
-
- cy.visit('/signup')
-
- cy.getDataCy('signup-email')
- .type(user.email)
-
- cy.getDataCy('signup-password')
- .type(`${user.password}{enter}`)
-
- cy.location('pathname')
- .should('eq', '/')
-
- cy.getCookie('auth_token')
- .should('exist')
-
- });
-});
\ No newline at end of file
diff --git a/cypress/e2e/specs/boards.spec.ts b/cypress/e2e/specs/boards.spec.ts
new file mode 100644
index 000000000..aa6b821c7
--- /dev/null
+++ b/cypress/e2e/specs/boards.spec.ts
@@ -0,0 +1,84 @@
+beforeEach(() => {
+ //seed the database with boards
+ cy.fixture('users').then((fixture) => {
+ cy.request('POST', '/api/signup', fixture[0]).then(function (response) {
+ const auth = response.body.accessToken;
+ cy.seedData('boards', undefined, auth);
+ });
+ });
+
+ //Given I am logged in as a valid user
+ cy.visit('/login');
+ cy.loginAs('Existinguser@test.com', 'Existinguser123');
+});
+
+describe('Boards control: as a valid user', () => {
+ it('I can create a board', () => {
+ //Given I click on the create board button
+ cy.get('[data-cy="create-board"]').click();
+ //When I enter the name of the board in the title field
+ cy.get('[data-cy="new-board-input"]').type('New Board');
+ cy.get('[data-cy="new-board-create"]').click();
+ //Then I should see the newly created board
+ cy.get('[data-cy="board-title"]').should('have.text', 'New Board');
+ cy.url().should('include', '/board/');
+ });
+
+ it('I can delete a board', () => {
+ //Given I navigate to a board
+ cy.get('[data-cy="board-item"]').filter(':contains("Portfolio Kanban")').click();
+ //When I click on the delete board button in the options menu
+ cy.get('[data-cy="board-options"]').click();
+ cy.get('[data-cy="delete-board"]').click();
+ //Then I should see the board is deleted
+ cy.notificationEquals('Board was deleted');
+ });
+
+ it('I can favorite a board', () => {
+ //Given I navigate to a board
+ cy.get('[data-cy="board-item"]').filter(':contains("Portfolio Kanban")').click();
+ //When I click on the favorite button
+ cy.get('[data-cy="star"]').click();
+ //Then I should see the board is favorited
+ cy.get('.text-yellow-300').should('exist');
+ cy.get('[data-cy="home"]').click();
+ cy.get('[data-cy="starred-section"]').filter(':contains("Portfolio Kanban")').should('exist');
+ });
+
+ it('I can unfavorite a board', () => {
+ //Given I have favorited a board
+ cy.log('Setting up the test')
+ cy.fixture('users').then((fixture) => {
+ cy.request('POST', '/api/login', fixture[0]).then(function (response) {
+ const auth = response.body.accessToken;
+ cy.request({
+ method: 'PATCH',
+ url: '/api/boards/1',
+ headers: { authorization: `Bearer ${auth}` },
+ body: { "starred": true },
+ })
+ });
+ });
+ cy.reload();
+ //And I navigate to the board
+ cy.get('[data-cy="starred-section"]').find('[data-cy="board-item"]').filter(':contains("Portfolio Kanban")').click();
+ //When I click on the favorite button
+ cy.get('[data-cy="star"]').click();
+ //Then I should see the board is unfavorited
+ cy.get('[data-cy="star"]').filter('.text-white').should('exist');
+ cy.get('[data-cy="home"]').click();
+ cy.get('[data-cy="starred-section"]').should('not.exist');
+ cy.get('[data-cy="all-boards"]').filter(':contains("Portfolio Kanban")').should('exist');
+ });
+
+ it('I can modify the name of a board', () => {
+ //Given I am on a board page
+ cy.get('[data-cy="board-item"]').filter(':contains("Portfolio Kanban")').click();
+ //When I make a change to the board name
+ cy.get('input[name="board-title"]').click().clear().type('RotaMaster Kanban').type('{enter}');
+ //Then I should see the board name is updated
+ cy.get('[data-cy="board-title"]').should('have.text', 'RotaMaster Kanban');
+ cy.get('[data-cy="home"]').click();
+ cy.get('[data-cy="board-item"]').filter(':contains("RotaMaster Kanban")').should('exist');
+ });
+});
\ No newline at end of file
diff --git a/cypress/e2e/specs/cards.spec.ts b/cypress/e2e/specs/cards.spec.ts
new file mode 100644
index 000000000..806ae881e
--- /dev/null
+++ b/cypress/e2e/specs/cards.spec.ts
@@ -0,0 +1,96 @@
+beforeEach(() => {
+ //seed the database with boards, lists and cards
+ cy.fixture('users').then((fixture: any) => {
+ cy.request('POST', '/api/signup', fixture[0]).then(function (response) {
+ const auth = response.body.accessToken;
+ cy.seedData('boards', undefined, auth);
+ cy.seedData('lists', undefined, auth);
+ cy.seedData('cards', undefined, auth);
+ });
+ });
+
+ // Given I am logged in as a valid user
+ cy.visit('/login');
+ cy.loginAs('Existinguser@test.com', 'Existinguser123');
+});
+
+describe('Cards: as a valid user', () => {
+ it('I can create a card', () => {
+ //Given I am on a board page
+ cy.visit('/board/1');
+ //And I Click on the new card button
+ cy.get('[data-cy="new-card"]').first().click();
+ //When I enter the name of the card in the title field
+ cy.get('[data-cy="new-card-input"]').type('New Card').type('{enter}');
+ //Then I should see the newly created card
+ cy.get('[data-cy="card"]').find('[data-cy="card-text"]').eq(1).should('have.text', 'New Card');
+ });
+
+ it('I can delete a card', () => {
+ //Given I am on a cards detail page
+ cy.visit('/board/1?card=1');
+ //When I click on the delete card button
+ cy.get('[data-cy="card-detail-delete"]').click();
+ //Then I should see the card is deleted
+ cy.get('[data-cy="card"]').contains('Create a Spec document').should('not.exist');
+ });
+
+ it('I can change the title of a card', () => {
+ //Given I am on a cards detail page
+ cy.visit('/board/1?card=1');
+ //When I change the title of the card
+ const newTitle = 'New Card Title';
+ cy.get('[data-cy="card-detail-title"]').click().clear().type(newTitle).type('{enter}');
+ //Then I should see the card has been renamed
+ cy.get('[data-cy="notification-message"]').should('have.text', 'Card was renamed');
+ cy.get('[data-cy="cancel"]').click();
+ cy.get('[data-cy="card-text"]').should('contain', newTitle);
+ });
+
+ it('I can add a description to a card', () => {
+ //Given I am on a cards detail page
+ cy.visit('/board/1?card=1');
+ //When I add a description to the card
+ cy.get('[data-cy="card-description"]').click().clear().type('This is a description').type('{enter}');
+ //Then I should see the description has been added
+ cy.notificationEquals('Description was changed');
+ });
+
+ it('I can see card has the correct details', () => {
+ //Given a detailed card exists
+ cy.fixture('cards').then((fixture) => {
+ cy.request('PATCH', '/api/cards/2', fixture[1]).then((response: any) => {
+ let card = response.body;
+ let boardId = parseInt(response.body.boardId);
+ let id = parseInt(response.body.id);
+ //When I view the card
+ cy.visit(`/board/${boardId}?card=${id}`);
+ //Then I should see the correct details
+ cy.get('[data-cy="card-detail-title"]').should('have.value', card.name);
+ cy.get('[data-cy="card-description"]').should('have.value', card.description);
+ });
+ });
+ });
+
+ it('I can move a card', () => {
+ //Given I am on a board page
+ cy.visit('/board/1');
+ //And I have two lists with cards
+ cy.get('[data-cy="card-list"]').first().find('[data-cy="card"]').should('exist');
+ cy.get('[data-cy="card-list"]').eq(0).find('[data-cy="card"]').as('firstCard')
+ cy.get('[data-cy="card-list"]').eq(1).as('secondList');
+ cy.get('@firstCard').should('exist');
+ //When I drag and drop a card from one list to another
+ cy.get('@firstCard').drag('@secondList');
+ //Then I should see the card has been moved
+ cy.get('@firstCard').should('not.exist');
+ cy.get('@secondList').find('[data-cy="card"]')
+ .should('contain', 'Create a Spec document')
+ .should('have.length', 2);
+ });
+
+ it('I can add an image to a card', () => {
+
+ });
+});
+
diff --git a/cypress/e2e/specs/lists.spec.ts b/cypress/e2e/specs/lists.spec.ts
new file mode 100644
index 000000000..18f2153f4
--- /dev/null
+++ b/cypress/e2e/specs/lists.spec.ts
@@ -0,0 +1,67 @@
+beforeEach(() => {
+ //seed the database with boards and lists
+ cy.fixture('users').then((fixture) => {
+ cy.request('POST', '/api/signup', fixture[0]).then(function (response) {
+ const auth = response.body.accessToken;
+ cy.seedData('boards', undefined, auth);
+ cy.seedData('lists');
+ });
+ });
+
+ //Given I am logged in as a valid user
+ cy.visit('/login');
+ cy.loginAs('Existinguser@test.com', 'Existinguser123');
+ //And I am on the board page
+ cy.visit('/board/1');
+});
+
+describe('Lists: as a valid user', () => {
+ it('I can create a list', () => {
+ //Given I click on the create list button
+ cy.get('[data-cy="create-list"]').click()
+ //When I enter the name of the list in the input field
+ cy.get('[data-cy="add-list-input"]').type('New List').type('{enter}');
+
+ //Then I should see the newly created list
+ cy.get('[data-cy="list-name"]').withValue('New List').should('exist');
+ });
+
+ it('I can delete a list', () => {
+ //Given I am on the board page
+ //When I click on the delete list button in the options menu
+ cy.get('[data-cy="list-name"]').withValue('Delete this list').siblings('[data-cy="list-options"]').click();
+ cy.get('[data-cy="delete-list"]').click();
+
+ //Then I should see the list is deleted
+ cy.get('[data-cy="list-name"]').withValue('Delete this list').should('not.exist');
+ });
+
+ it('I can modify the name of a list', () => {
+ //Given I am on the board page
+ //And I click on the name of the list
+ //When I enter the new name of the list in the input field
+ cy.get('[data-cy="list-name"]').withValue('Move this list').click()
+ .clear().type('List Renamed').type('{enter}');
+
+ //Then I should see the list is renamed
+ cy.get('[data-cy="list-name"]').withValue('List Renamed').should('exist');
+
+ });
+
+ it('I can drag and drop a list', () => {
+ //Given I am on the board page
+ //And I have two lists
+ cy.get('[data-cy="list-name"]').first().as('firstList');
+ cy.get('[data-cy="list-name"]').last().as('lastList');
+
+ cy.get('@firstList').should('have.value', 'Move this list');
+
+ //When I drag the first list to the right of the second list
+ cy.get('@firstList').drag('@lastList');
+
+ //Then I should see the lists are swapped
+ cy.get('@lastList').should('have.value', 'Move this list');
+ cy.get('@firstList').should('have.value', 'Delete this list');
+ });
+
+});
\ No newline at end of file
diff --git a/cypress/e2e/specs/login.spec.ts b/cypress/e2e/specs/login.spec.ts
new file mode 100644
index 000000000..95ef40573
--- /dev/null
+++ b/cypress/e2e/specs/login.spec.ts
@@ -0,0 +1,53 @@
+describe('Login :', () => {
+ it('as a valid user, I can login', () => {
+ // create a new user
+ cy.fixture('users').then((fixture) => { cy.request('POST', '/api/signup', fixture[0])});
+ //Given I am on the login page
+ cy.get('[data-cy="login-menu"').click();
+ //When I login with a valid email and password
+ cy.loginAs('Existinguser@test.com', 'Existinguser123');
+ //Then I be logged in yar
+ cy.notificationEquals('User is logged in');
+ });
+
+ it('as a invalid user, I can not login', () => {
+ //Given I am on the login page
+ cy.get('[data-cy="login-menu"').click();
+ //When I login with an invalid email and password
+ cy.loginAs('Notrealuser@test.com', 'Notrealuser123');
+ //Then I should the "Cannot find user" error message
+ cy.notificationEquals('Cannot find user');
+ });
+});
+
+describe('Register :', () => {
+ it('as a new user, I can register', () => {
+ //Given I am on the login page
+ cy.visit('/login');
+ //And I click on the "Sign up here" link
+ cy.get('a').contains('Sign up here').click();
+ //When I register with a new email and password
+ const newUser = `newuser${Math.floor(Math.random() * 1000)}`;
+ cy.get('input[name="email"]').type(newUser + '@test.com');
+ cy.get('input[name="password"]').type(newUser);
+ cy.get('[data-cy="signup-submit"]').click();
+ //Then I should see the "User is logged in" message
+ cy.notificationEquals('User is logged in');
+ //And my user is created
+ });
+
+ it('as a new user, I can not register with invalid password', () => {
+ //Given I am on the login page
+ cy.visit('/login');
+ //And I click on the "Sign up here" link
+ cy.get('a').contains('Sign up here').click();
+ //When I register with a invalid password
+ // create a new user with a random number
+ const newUser = `newuser${Math.floor(Math.random() * 1000)}`;
+ cy.get('input[name="email"]').type(newUser + '@test.com');
+ cy.get('input[name="password"]').type('a');
+ cy.get('[data-cy="signup-submit"]').click();
+ //Then I should see the "Password is too short" message
+ cy.notificationEquals('Password is too short');
+ });
+});
\ No newline at end of file
diff --git a/cypress/e2e/tools.spec.ts b/cypress/e2e/tools.spec.ts
deleted file mode 100644
index 3ca487a1d..000000000
--- a/cypress/e2e/tools.spec.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-describe('Tools', () => {
-
- const body = {
- email: 'filip@example.com', password: 'Asdf.1234#'
- }
-
- beforeEach(() => {
-
- cy.request('POST', '/api/reset')
- cy.signupApi(body)
- cy.addBoardApi('new board')
- cy.addListApi({name: 'new list'})
- cy.addCardApi({name: 'new card'})
-
- });
-
- it('show tools', function() {
-
- const boardId = this.board.id
- const { accessToken } = this.user
-
- cy.intercept('DELETE', '/api/boards').as('boards')
- cy.intercept('DELETE', '/api/lists').as('lists')
- cy.intercept('DELETE', '/api/cards').as('cards')
- cy.intercept('DELETE', '/api/users').as('users')
-
- cy.visit(`/board/${boardId}`)
-
- cy.getDataCy('card').should('be.visible')
- cy.getDataCy('list').should('be.visible')
-
- cy.window().trigger('keydown', { keyCode: 113, which: 113 })
-
- cy.getDataCy('api-tools')
- .should('be.visible')
-
- // deletes a user
- cy.contains('Users').click()
-
- cy.wait('@users')
-
- cy
- .request({
- body,
- failOnStatusCode: false,
- headers: {
- authorization: `Bearer ${accessToken}`
- },
- method: 'POST',
- url: '/api/login'
- }).its('body').should('eq', 'Cannot find user')
-
- // deletes cards
- cy.contains('Cards').click()
- cy.getDataCy('card').should('not.exist')
-
- cy.wait('@cards')
-
- // deletes lists
- cy.contains('Lists').click()
- cy.getDataCy('list').should('not.exist')
-
- cy.wait('@lists')
-
- // deletes boards
- cy.contains('Boards').click()
- cy.location('pathname').should('eq', '/')
-
- cy.wait('@boards')
-
- cy.getDataCy('first-board').should('be.visible')
-
- });
-
- it('resets all', function() {
-
- const boardId = this.board.id
- const { accessToken } = this.user
-
- cy.intercept('POST', '/api/reset').as('reset')
-
- cy.visit(`/board/${boardId}`)
-
- cy.window().invoke('store').invoke('toggleTools', true)
-
- cy.getDataCy('api-tools')
- .should('be.visible')
-
- // deletes a user
- cy.contains('All').click()
-
- cy.wait('@reset')
-
- cy.location('pathname').should('eq', '/')
-
- cy.getDataCy('first-board').should('be.visible')
-
- cy
- .request({
- body,
- failOnStatusCode: false,
- headers: {
- authorization: `Bearer ${accessToken}`
- },
- method: 'POST',
- url: '/api/login'
- }).its('body').should('eq', 'Cannot find user')
-
-
- cy
- .request({
- headers: {
- accept: 'application/json'
- },
- method: 'GET',
- url: '/api/lists'
- }).its('body').should('be.empty')
-
- cy
- .request({
- headers: {
- accept: 'application/json'
- },
- method: 'GET',
- url: '/api/cards'
- }).its('body').should('be.empty')
-
- })
-
-});
-
diff --git a/cypress/fixtures/boards.json b/cypress/fixtures/boards.json
new file mode 100644
index 000000000..fdce16898
--- /dev/null
+++ b/cypress/fixtures/boards.json
@@ -0,0 +1,8 @@
+[
+ {
+ "name": "Portfolio Kanban",
+ "user": 1,
+ "starred": false,
+ "id": 1
+ }
+]
\ No newline at end of file
diff --git a/cypress/fixtures/cards.json b/cypress/fixtures/cards.json
new file mode 100644
index 000000000..f6020d6e2
--- /dev/null
+++ b/cypress/fixtures/cards.json
@@ -0,0 +1,24 @@
+[
+ {
+ "order": 0,
+ "boardId": 1,
+ "listId": 1,
+ "name": "Create a Spec document",
+ "created": "2024-03-12",
+ "deadline": "2024-02-24",
+ "description": "Create a spec document in Obsidian with the following sections, Phase 1 and Phase 2",
+ "completed": true,
+ "id": 1
+ },
+ {
+ "order": 0,
+ "boardId": 1,
+ "listId": 2,
+ "name": "Detailed Design Document",
+ "created": "2024-03-12",
+ "deadline": "2024-02-24",
+ "description": "Create a detailed design document",
+ "completed": true,
+ "id": 2
+ }
+]
\ No newline at end of file
diff --git a/cypress/fixtures/cypressLogo.png b/cypress/fixtures/cypressLogo.png
deleted file mode 100755
index 10a014648..000000000
Binary files a/cypress/fixtures/cypressLogo.png and /dev/null differ
diff --git a/cypress/fixtures/lists.json b/cypress/fixtures/lists.json
new file mode 100644
index 000000000..d1b64d01b
--- /dev/null
+++ b/cypress/fixtures/lists.json
@@ -0,0 +1,16 @@
+ [
+ {
+ "boardId": 1,
+ "name": "Move this list",
+ "order": 0,
+ "created": "2024-03-12",
+ "id": 1
+ },
+ {
+ "boardId": 1,
+ "name": "Delete this list",
+ "order": 1,
+ "created": "2024-03-12",
+ "id": 2
+ }
+ ]
\ No newline at end of file
diff --git a/cypress/fixtures/users.json b/cypress/fixtures/users.json
new file mode 100644
index 000000000..9e54f31f6
--- /dev/null
+++ b/cypress/fixtures/users.json
@@ -0,0 +1,6 @@
+[
+ {
+ "email": "Existinguser@test.com",
+ "password": "Existinguser123"
+ }
+]
\ No newline at end of file
diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts
deleted file mode 100644
index f8f9407cd..000000000
--- a/cypress/plugins/index.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import 'dotenv/config'
-
-module.exports = (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
-
-
- require('@cypress/code-coverage/task')(on, config);
-
- config.env.googleEnabled = process.env.VUE_APP_GOOGLE_ENABLED
- config.env.googleRefreshToken = process.env.GOOGLE_REFRESH_TOKEN
- config.env.googleClientId = process.env.VUE_APP_GOOGLE_CLIENT_ID
- config.env.googleClientSecret = process.env.VUE_APP_GOOGLE_CLIENT_SECRET
-
- return config;
-};
\ No newline at end of file
diff --git a/cypress/support/@types/selectors.d.ts b/cypress/support/@types/selectors.d.ts
deleted file mode 100644
index 7bc53b4cc..000000000
--- a/cypress/support/@types/selectors.d.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-export type Selectors =
-| '404'
-| 'add-list-input'
-| 'api-tools'
-| 'board-detail'
-| 'board-dropdown'
-| 'board-item'
-| 'board-list'
-| 'board-list-error-message'
-| 'board-options'
-| 'board-title'
-| 'calendar-button'
-| 'calendar-dropdown'
-| 'cancel'
-| 'card'
-| 'card-add'
-| 'card-checkbox'
-| 'card-description'
-| 'card-detail'
-| 'card-detail-backdrop'
-| 'card-detail-deadline'
-| 'card-detail-delete'
-| 'card-detail-title'
-| 'card-edit'
-| 'card-list'
-| 'card-list-name'
-| 'card-text'
-| 'copy-properties'
-| 'create-board'
-| 'create-list'
-| 'day'
-| 'delete-board'
-| 'delete-list'
-| 'discount'
-| 'due-date'
-| 'error-icon'
-| 'find-location'
-| 'first-board'
-| 'footer-link'
-| 'google-button'
-| 'header-month'
-| 'header-year'
-| 'home'
-| 'image-attachment'
-| 'image-delete'
-| 'info-icon'
-| 'list'
-| 'list-dropdown'
-| 'list-name'
-| 'list-options'
-| 'list-placeholder'
-| 'loading'
-| 'logged-user'
-| 'login-email'
-| 'login-menu'
-| 'login-password'
-| 'login-submit'
-| 'month'
-| 'new-board-create'
-| 'new-board-input'
-| 'new-card'
-| 'new-card-input'
-| 'notification-message'
-| 'plan-item'
-| 'plan-price'
-| 'result-item'
-| 'search-input'
-| 'signup-email'
-| 'signup-password'
-| 'signup-submit'
-| 'star'
-| 'starred-boards'
-| 'trello-logo'
-| 'upload-image'
-| 'year'
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
new file mode 100644
index 000000000..1e974a960
--- /dev/null
+++ b/cypress/support/commands.ts
@@ -0,0 +1,77 @@
+Cypress.Commands.add('loginAs', (email: string, password: string) => {
+ cy.log(`Logging in as ${email} with password ${password}`);
+ cy.get('input[name="email"]').type(email);
+ cy.get('input[name="password"]').type(password);
+ cy.get('[data-cy="login-submit"]').click();
+});
+
+Cypress.Commands.add('withValue', { prevSubject: true }, (element, value) => {
+ return element.filter((_:number, el:any) => {
+ return Cypress.$(el).val() === value;
+ });
+ });
+
+Cypress.Commands.add('notificationEquals', (value) => {cy.get('[data-cy="notification-message"]').should('have.text', value)});
+
+Cypress.Commands.add('seedData', (fixtureName: string, index?: number, auth?: string) => {
+ cy.log(`Seeding data from ${fixtureName}`);
+ if (!auth) {
+ cy.log('No auth token provided, seeding data as guest');
+ if (index == undefined) {
+ cy.log('Seeding all data from fixture');
+ cy.fixture(fixtureName).then((fixture) => {
+ for (let i = 0; i < fixture.length; i++) {
+ cy.request({
+ method: 'POST',
+ url: `/api/${fixtureName}`,
+ body: fixture[i]
+ });
+ }
+ });
+ } else {
+ cy.log(`Seeding data from fixture at index ${index}`);
+ cy.fixture(fixtureName).then((fixture) => {
+ cy.request({
+ method: 'POST',
+ url: `/api/${fixtureName}`,
+ body: fixture[index]
+ });
+ });
+ }
+ }
+ else {
+ cy.log('Auth token provided, seeding data as user');
+ cy.fixture(fixtureName).then((fixture) => {
+ if (index == undefined) {
+ cy.log('Seeding all data from fixture');
+ for (let i = 0; i < fixture.length; i++) {
+ cy.request({
+ method: 'POST',
+ url: `/api/${fixtureName}`,
+ headers: { authorization: `Bearer ${auth}` },
+ body: fixture[i]
+ });
+ }
+ } else {
+ cy.log(`Seeding data from fixture at index ${index}`);
+ cy.request({
+ method: 'POST',
+ url: `/api/${fixtureName}`,
+ headers: { authorization: `Bearer ${auth}` },
+ body: fixture[index]
+ });
+ }
+ });
+ };
+});
+
+
+
+declare namespace Cypress {
+ interface Chainable {
+ loginAs(email: string, password: string): Chainable
+ seedData(fixtureName: string, index?: number, auth?: string): Chainable
+ withValue(value: string): Chainable
+ notificationEquals(value: string): Chainable
+ }
+}
\ No newline at end of file
diff --git a/cypress/support/commands/addBoardApi.ts b/cypress/support/commands/addBoardApi.ts
deleted file mode 100644
index 79faa1d2c..000000000
--- a/cypress/support/commands/addBoardApi.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-export {}
-declare global {
- namespace Cypress {
- interface Chainable {
- addBoardApi: typeof addBoardApi;
- }
- }
-}
-
-/**
- * Creates a new board using the API
- * @param name name of the board
- * @example
- * cy.addBoardApi('new board')
- *
- */
-
-export const addBoardApi = function(this: any, name: string): Cypress.Chainable {
-
- return cy
- .request('POST', '/api/boards', { name })
- .its('body', { log: false }).as('board');
-
-};
\ No newline at end of file
diff --git a/cypress/support/commands/addCardApi.ts b/cypress/support/commands/addCardApi.ts
deleted file mode 100644
index 36b19701a..000000000
--- a/cypress/support/commands/addCardApi.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export {}
-declare global {
- namespace Cypress {
- interface Chainable {
- addCardApi: typeof addCardApi;
- }
- }
-}
-
-/**
- * Creates a new card using the API. By default, the card is added to the first list of the first board.
- * @param name name of the card
- * @param boardIndex index number from this.boards
- * @param listIndex index number from this.lists
- * @example
- * cy.addCardApi({ name: 'new card', boardIndex: 0, listIndex: 0 })
- */
-export const addCardApi = function(this: any, { name, boardAlias = 'board', listAlias = 'list', cardAlias = 'card' }: { name: string, boardAlias?: string, listAlias?: string, cardAlias?: string }): Cypress.Chainable {
-
- return cy
- .request('POST', '/api/cards', {
- boardId: this[boardAlias].id,
- listId: this[listAlias].id,
- name,
- order: 0
- })
- .its('body', { log: false }).as(cardAlias);
-
-}
\ No newline at end of file
diff --git a/cypress/support/commands/addListApi.ts b/cypress/support/commands/addListApi.ts
deleted file mode 100644
index 659ffc178..000000000
--- a/cypress/support/commands/addListApi.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-export {}
-declare global {
- namespace Cypress {
- interface Chainable {
- addListApi: typeof addListApi;
- }
- }
-}
-
-/**
- * Creates a new list using the API. By default, the card is added to the first board.
- * @param name name of the card
- * @param boardIndex index number from this.boards
- * @example
- * cy.addListApi({ name: 'new card', boardIndex: 0 })
- */
-export const addListApi = function(this: any, { name, boardAlias = 'board', listAlias = 'list' }: { name: string, boardAlias?: string, listAlias?: string}): Cypress.Chainable {
-
- return cy.request('POST', '/api/lists', {
- boardId: this[boardAlias].id,
- name,
- }).its('body', { log: false }).as(listAlias);
-
-}
\ No newline at end of file
diff --git a/cypress/support/commands/getDataCy.ts b/cypress/support/commands/getDataCy.ts
deleted file mode 100644
index 017ccd8fb..000000000
--- a/cypress/support/commands/getDataCy.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Selectors } from '../@types/selectors';
-
-declare global {
- namespace Cypress {
- interface Chainable {
- getDataCy: typeof getDataCy
- }
- }
-}
-
-/**
- * Gets element using data-cy selector
- * @param input data-cy attribute value
- * @example
- * // this command
- * cy.getDataCy('header')
- * // will select this element
- *
- *
- *
- */
-export const getDataCy = function(
- input: Selectors
-) {
-
- Cypress.log({
- consoleProps() {
- return {
- selector: input,
- };
- },
- displayName: 'getDataCy',
- name: 'Get by [data-cy] attribute',
- });
-
- return cy.get(`[data-cy='${input}']`);
-
-};
\ No newline at end of file
diff --git a/cypress/support/commands/googleLogin.ts b/cypress/support/commands/googleLogin.ts
deleted file mode 100644
index e430f72ea..000000000
--- a/cypress/support/commands/googleLogin.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-export { }
-declare global {
- namespace Cypress {
- interface Chainable {
- googleLogin: typeof googleLogin;
- }
- }
-}
-
-/**
- * Performs a Google SSO login
- * @example
- * cy.googleLogin()
- *
- */
-
-export const googleLogin = function (this: any): Cypress.Chainable {
-
- return cy.request({
- method: 'POST',
- url: 'https://www.googleapis.com/oauth2/v4/token',
- body: {
- grant_type: 'refresh_token',
- client_id: Cypress.env('googleClientId'),
- client_secret: Cypress.env('googleClientSecret'),
- refresh_token: Cypress.env('googleRefreshToken'),
- },
- }).then(({ body }) => {
- const { id_token } = body
- cy.request('POST', '/api/login', { jwt: id_token })
- .then(({ body: { accessToken } }) => {
- cy.setCookie('auth_token', accessToken)
- })
- })
-}
\ No newline at end of file
diff --git a/cypress/support/commands/googleSignup.ts b/cypress/support/commands/googleSignup.ts
deleted file mode 100644
index 0250936ff..000000000
--- a/cypress/support/commands/googleSignup.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-export { }
-declare global {
- namespace Cypress {
- interface Chainable {
- googleSignup: typeof googleSignup;
- }
- }
-}
-
-/**
- * Performs a Google SSO login
- * @example
- * cy.googleSignup()
- *
- */
-
-export const googleSignup = function (this: any): Cypress.Chainable {
-
- return cy.request({
- method: 'POST',
- url: 'https://www.googleapis.com/oauth2/v4/token',
- body: {
- grant_type: 'refresh_token',
- client_id: Cypress.env('googleClientId'),
- client_secret: Cypress.env('googleClientSecret'),
- refresh_token: Cypress.env('googleRefreshToken'),
- },
- }).then(({ body }) => {
- const { id_token } = body
- cy.request('POST', '/api/signup', { jwt: id_token })
- .then(({ body: { accessToken } }) => {
- cy.setCookie('auth_token', accessToken)
- })
- })
-}
\ No newline at end of file
diff --git a/cypress/support/commands/signupApi.ts b/cypress/support/commands/signupApi.ts
deleted file mode 100644
index 3991cb55b..000000000
--- a/cypress/support/commands/signupApi.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-export { }
-declare global {
- namespace Cypress {
- interface Chainable {
- signupApi: typeof signupApi;
- }
- }
-}
-
-/**
- * Creates a new user using the API
- * @param email user email
- * @param password user password
- * @param login defaults to true, logs in the user
- * @example
- * cy.signupApi({ email: 'filip@example.com', password: 'nbusr123', login: false })
- */
-export const signupApi = function (this: any, { email, password, login = true }: { email: string, password: string, login?: boolean }) {
-
- cy
- .request('POST', '/api/signup', {
- email, password
- }).then(({ body }) => {
- if (login) cy.setCookie('auth_token', body.accessToken)
- cy.wrap(body).as('user');
- });
-
-};
\ No newline at end of file
diff --git a/cypress/support/commands/step.ts b/cypress/support/commands/step.ts
deleted file mode 100644
index 2e0197c25..000000000
--- a/cypress/support/commands/step.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export {}
-declare global {
- namespace Cypress {
- interface Chainable {
- step: typeof step;
- }
- }
-}
-
-/**
- * Creates a test step
- */
-export const step = (msg: string, options?: { section: boolean }) => {
-
- let logMessage = `${window.logCalls}. ${msg}`;
-
- if (options?.section) {
- window.logCalls = 0;
- logMessage = `\n--- ${msg} ---\n`;
- }
-
- Cypress.log({
- displayName: logMessage.toUpperCase(),
- message: '\n',
- });
-
- window.testFlow.push(logMessage);
- window.logCalls++;
-};
diff --git a/cypress/support/common.ts b/cypress/support/common.ts
deleted file mode 100644
index c244f196a..000000000
--- a/cypress/support/common.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { getDataCy } from '@commands/getDataCy'
-
-Cypress.Commands.add('getDataCy', getDataCy);
\ No newline at end of file
diff --git a/cypress/support/component-index.html b/cypress/support/component-index.html
deleted file mode 100644
index ac6e79fd8..000000000
--- a/cypress/support/component-index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- Components App
-
-
-
-
-
\ No newline at end of file
diff --git a/cypress/support/component.ts b/cypress/support/component.ts
deleted file mode 100644
index b27a3cb44..000000000
--- a/cypress/support/component.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { mount } from 'cypress/vue'
-import { createPinia } from 'pinia'
-import { createMemoryHistory, createRouter } from 'vue-router'
-import { routes } from '@/router/routes';
-import { useStore } from '@/store/store';
-import VueClickAway from 'vue3-click-away';
-import './common'
-import '@/index.css';
-
-type MountParams = Parameters
-type OptionsParam = MountParams[1]
-
-declare global {
- namespace Cypress {
- interface Chainable {
- mount(
- component: any,
- options?: OptionsParam & { store?: any }
- ): Chainable
- }
- }
-}
-
-// solution #1 👇 - does not throw error, but doesn’t show component
-Cypress.Commands.add('mount', (component, options = {}) => {
-
- let pinia = createPinia()
- let router = createRouter({
- routes,
- history: createMemoryHistory()
- })
-
- // define default route
- router.push('/')
-
- let store = options.store || useStore(pinia)
-
- options = {
- global: {
- plugins: [store, router, VueClickAway]
- },
- ...options
- }
-
- return mount(component, options)
-})
-
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
index 498be3e8a..e0ab74b65 100644
--- a/cypress/support/e2e.ts
+++ b/cypress/support/e2e.ts
@@ -1,41 +1,40 @@
-import '@4tw/cypress-drag-drop';
-import '@cypress/code-coverage/support';
-import 'cypress-real-events/support';
+import './commands'
+import '@4tw/cypress-drag-drop'
+import '@cypress/grep'
-import './common'
-
-import { addBoardApi } from '@commands/addBoardApi'
-import { addCardApi } from '@commands/addCardApi'
-import { addListApi } from '@commands/addListApi'
-import { googleLogin } from '@commands/googleLogin'
-import { googleSignup } from '@commands/googleSignup'
-import { signupApi } from '@commands/signupApi'
-import { step } from '@commands/step'
+before(() => {
+// cy.log('clearing the database')
+// cy.request('POST', '/api/reset')
+//
+// cy.log('Seeding the database')
+// cy.request('POST', '/api/reset')
+// cy.fixture('users').then((fixture) => {
+// cy.request('POST', '/api/signup', fixture[0]).then(function (response) {
+// const auth = response.body.accessToken;
+// cy.seedData('boards', undefined, auth);
+// cy.seedData('lists');
+// cy.seedData('cards');
+// });
+// });
+// cy.log('Starting E2E tests')
+});
-Cypress.Commands.add('addBoardApi', addBoardApi);
-Cypress.Commands.add('addCardApi', addCardApi);
-Cypress.Commands.add('addListApi', addListApi);
-Cypress.Commands.add('googleLogin', googleLogin);
-Cypress.Commands.add('googleSignup', googleSignup);
-Cypress.Commands.add('signupApi', signupApi);
-Cypress.Commands.add('step', step);
+beforeEach(() => {
+ // clear the database
+ cy.request('POST', '/api/reset')
+ cy.visit('')
-declare global {
- interface Window {
- logCalls: number;
- testFlow: string[];
- }
-}
-beforeEach(function () {
- window.logCalls = 1;
- window.testFlow = [];
-});
-Cypress.on('fail', (err) => {
- if (window.testFlow.length) {
- err.message += `${'\n\n' + 'Test steps were:\n\n'}${window.testFlow.join('\n')}`;
- }
- throw err;
-});
+// cy.log('Setting up the test')
+// cy.request('POST', '/api/reset')
+// cy.fixture('users').then((fixture) => {
+// cy.request('POST', '/api/signup', fixture[0]).then(function (response) {
+// const auth = response.body.accessToken;
+// cy.seedData('boards', 0, auth);
+// cy.seedData('lists');
+// cy.seedData('cards');
+// });
+// });
+})
diff --git a/package-lock.json b/package-lock.json
index 8b6639642..50cc3f16b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,6 @@
"version": "1.0.0",
"hasInstallScript": true,
"dependencies": {
- "@4tw/cypress-drag-drop": "^2.1.0",
"@cypress/code-coverage": "^3.10.0",
"@cypress/vite-dev-server": "^2.2.1",
"@cypress/vue": "^3.0.5",
@@ -66,9 +65,11 @@
"vuedraggable": "^4.1.0"
},
"devDependencies": {
+ "@4tw/cypress-drag-drop": "^2.2.5",
+ "@cypress/grep": "^4.0.1",
"@cypress/skip-test": "^2.6.1",
"@types/leaflet": "^1.7.11",
- "cypress": "^10.4.0",
+ "cypress": "^13.7.0",
"eslint": "^8.5.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-no-only-tests": "^2.6.0",
@@ -83,11 +84,12 @@
}
},
"node_modules/@4tw/cypress-drag-drop": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@4tw/cypress-drag-drop/-/cypress-drag-drop-2.1.0.tgz",
- "integrity": "sha512-HbPBcx2KBdxL3hhyTlZYsF7XSkHkEKAcmDGfvzXp0sBs2sA/NkHE9CMqHz52liLnnVgKEkVkzcoVnyatCc9J5w==",
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/@4tw/cypress-drag-drop/-/cypress-drag-drop-2.2.5.tgz",
+ "integrity": "sha512-3ghTmzhOmUqeN6U3QmUnKRUxI7OMLbJA4hHUY/eS/FhWJgxbiGgcaELbolWnBAOpajPXcsNQGYEj9brd59WH6A==",
+ "dev": true,
"peerDependencies": {
- "cypress": "^2.1.0 || ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+ "cypress": "2 - 13"
}
},
"node_modules/@achrinza/node-ipc": {
@@ -293,6 +295,15 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+ "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-simple-access": {
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz",
@@ -422,9 +433,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.18.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz",
- "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+ "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -432,6 +443,21 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
+ "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
@@ -519,15 +545,29 @@
"cypress": "*"
}
},
+ "node_modules/@cypress/grep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@cypress/grep/-/grep-4.0.1.tgz",
+ "integrity": "sha512-i3mWy4mG6nxF7m93W0nzsMZkl0PflGa4+SygA9P92tELayYYAaRKlr07I4fo5PnwoPk1H9IEbXoMFJkhfTMxtg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "find-test-names": "^1.19.0",
+ "globby": "^11.0.4"
+ },
+ "peerDependencies": {
+ "cypress": ">=10"
+ }
+ },
"node_modules/@cypress/mount-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@cypress/mount-utils/-/mount-utils-1.0.2.tgz",
"integrity": "sha512-Fn3fdTiyayHoy8Ol0RSu4MlBH2maQ2ZEXeEVKl/zHHXEQpld5HX3vdNLhK5YLij8cLynA4DxOT/nO9iEnIiOXw=="
},
"node_modules/@cypress/request": {
- "version": "2.88.10",
- "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz",
- "integrity": "sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz",
+ "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==",
"dev": true,
"dependencies": {
"aws-sign2": "~0.7.0",
@@ -543,9 +583,9 @@
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"performance-now": "^2.1.0",
- "qs": "~6.5.2",
+ "qs": "6.10.4",
"safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
+ "tough-cookie": "^4.1.3",
"tunnel-agent": "^0.6.0",
"uuid": "^8.3.2"
},
@@ -1679,6 +1719,15 @@
"node": ">=0.4.0"
}
},
+ "node_modules/acorn-walk": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
+ "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/addressparser": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
@@ -1987,9 +2036,9 @@
}
},
"node_modules/aws4": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
- "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
+ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
"dev": true
},
"node_modules/axios": {
@@ -2662,9 +2711,9 @@
}
},
"node_modules/commander": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
- "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"dev": true,
"engines": {
"node": ">= 6"
@@ -3027,30 +3076,29 @@
"dev": true
},
"node_modules/cypress": {
- "version": "10.11.0",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz",
- "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==",
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.7.0.tgz",
+ "integrity": "sha512-UimjRSJJYdTlvkChcdcfywKJ6tUYuwYuk/n1uMMglrvi+ZthNhoRYcxnWgTqUtkl17fXrPAsD5XT2rcQYN1xKA==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
- "@cypress/request": "^2.88.10",
+ "@cypress/request": "^3.0.0",
"@cypress/xvfb": "^1.2.4",
- "@types/node": "^14.14.31",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
"blob-util": "^2.0.2",
"bluebird": "^3.7.2",
- "buffer": "^5.6.0",
+ "buffer": "^5.7.1",
"cachedir": "^2.3.0",
"chalk": "^4.1.0",
"check-more-types": "^2.24.0",
"cli-cursor": "^3.1.0",
"cli-table3": "~0.6.1",
- "commander": "^5.1.0",
+ "commander": "^6.2.1",
"common-tags": "^1.8.0",
"dayjs": "^1.10.4",
- "debug": "^4.3.2",
+ "debug": "^4.3.4",
"enquirer": "^2.3.6",
"eventemitter2": "6.4.7",
"execa": "4.1.0",
@@ -3059,18 +3107,19 @@
"figures": "^3.2.0",
"fs-extra": "^9.1.0",
"getos": "^3.2.1",
- "is-ci": "^3.0.0",
+ "is-ci": "^3.0.1",
"is-installed-globally": "~0.4.0",
"lazy-ass": "^1.6.0",
"listr2": "^3.8.3",
"lodash": "^4.17.21",
"log-symbols": "^4.0.0",
- "minimist": "^1.2.6",
+ "minimist": "^1.2.8",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
+ "process": "^0.11.10",
"proxy-from-env": "1.0.0",
"request-progress": "^3.0.0",
- "semver": "^7.3.2",
+ "semver": "^7.5.3",
"supports-color": "^8.1.1",
"tmp": "~0.2.1",
"untildify": "^4.0.0",
@@ -3080,7 +3129,7 @@
"cypress": "bin/cypress"
},
"engines": {
- "node": ">=12.0.0"
+ "node": "^16.0.0 || ^18.0.0 || >=20.0.0"
}
},
"node_modules/cypress-real-events": {
@@ -5452,6 +5501,25 @@
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
+ "node_modules/find-test-names": {
+ "version": "1.28.18",
+ "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.18.tgz",
+ "integrity": "sha512-hhnGdkWK+qEA5Z02Tu0OqGQIUjFZNyOCE4WaJpbhW4hAF1+NZ7OCr0Bss9RCaj7BBtjoIjkU93utobQ8pg2iVg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.23.0",
+ "@babel/plugin-syntax-jsx": "^7.22.5",
+ "acorn-walk": "^8.2.0",
+ "debug": "^4.3.3",
+ "globby": "^11.0.4",
+ "simple-bin-help": "^1.8.0"
+ },
+ "bin": {
+ "find-test-names": "bin/find-test-names.js",
+ "print-tests": "bin/print-tests.js",
+ "update-test-count": "bin/update-test-count.js"
+ }
+ },
"node_modules/find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@@ -7745,9 +7813,12 @@
}
},
"node_modules/minimist": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/mkdirp": {
"version": "0.5.6",
@@ -8855,6 +8926,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
"node_modules/process-on-spawn": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
@@ -8894,9 +8974,9 @@
"dev": true
},
"node_modules/psl": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
- "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
"dev": true
},
"node_modules/pump": {
@@ -8929,14 +9009,26 @@
}
},
"node_modules/qs": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
- "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz",
+ "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==",
"dev": true,
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
"engines": {
"node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -9169,6 +9261,12 @@
"node": ">=0.10.5"
}
},
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true
+ },
"node_modules/resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
@@ -9326,9 +9424,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -9490,6 +9588,15 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
+ "node_modules/simple-bin-help": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/simple-bin-help/-/simple-bin-help-1.8.0.tgz",
+ "integrity": "sha512-0LxHn+P1lF5r2WwVB/za3hLRIsYoLaNq1CXqjbrs3ZvLuvlWnRKrUjEWzV7umZL7hpQ7xULiQMV+0iXdRa5iFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -9648,9 +9755,9 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
},
"node_modules/sshpk": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
- "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
+ "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
"dev": true,
"dependencies": {
"asn1": "~0.2.3",
@@ -10092,16 +10199,27 @@
}
},
"node_modules/tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"dev": true,
"dependencies": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
},
"engines": {
- "node": ">=0.8"
+ "node": ">=6"
+ }
+ },
+ "node_modules/tough-cookie/node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.0.0"
}
},
"node_modules/tr46": {
@@ -10166,7 +10284,7 @@
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
"dependencies": {
"safe-buffer": "^5.0.1"
@@ -10178,7 +10296,7 @@
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
"dev": true
},
"node_modules/type-check": {
@@ -10363,6 +10481,16 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
"node_modules/url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
@@ -10415,7 +10543,7 @@
"node_modules/verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
"dev": true,
"engines": [
"node >=0.6.0"
@@ -11082,9 +11210,10 @@
},
"dependencies": {
"@4tw/cypress-drag-drop": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@4tw/cypress-drag-drop/-/cypress-drag-drop-2.1.0.tgz",
- "integrity": "sha512-HbPBcx2KBdxL3hhyTlZYsF7XSkHkEKAcmDGfvzXp0sBs2sA/NkHE9CMqHz52liLnnVgKEkVkzcoVnyatCc9J5w=="
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/@4tw/cypress-drag-drop/-/cypress-drag-drop-2.2.5.tgz",
+ "integrity": "sha512-3ghTmzhOmUqeN6U3QmUnKRUxI7OMLbJA4hHUY/eS/FhWJgxbiGgcaELbolWnBAOpajPXcsNQGYEj9brd59WH6A==",
+ "dev": true
},
"@achrinza/node-ipc": {
"version": "9.2.6",
@@ -11237,6 +11366,12 @@
"@babel/types": "^7.18.0"
}
},
+ "@babel/helper-plugin-utils": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+ "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
+ "dev": true
+ },
"@babel/helper-simple-access": {
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz",
@@ -11335,9 +11470,18 @@
}
},
"@babel/parser": {
- "version": "7.18.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz",
- "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow=="
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+ "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg=="
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
+ "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ }
},
"@babel/template": {
"version": "7.16.7",
@@ -11410,15 +11554,26 @@
"nyc": "15.1.0"
}
},
+ "@cypress/grep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@cypress/grep/-/grep-4.0.1.tgz",
+ "integrity": "sha512-i3mWy4mG6nxF7m93W0nzsMZkl0PflGa4+SygA9P92tELayYYAaRKlr07I4fo5PnwoPk1H9IEbXoMFJkhfTMxtg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.3.4",
+ "find-test-names": "^1.19.0",
+ "globby": "^11.0.4"
+ }
+ },
"@cypress/mount-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@cypress/mount-utils/-/mount-utils-1.0.2.tgz",
"integrity": "sha512-Fn3fdTiyayHoy8Ol0RSu4MlBH2maQ2ZEXeEVKl/zHHXEQpld5HX3vdNLhK5YLij8cLynA4DxOT/nO9iEnIiOXw=="
},
"@cypress/request": {
- "version": "2.88.10",
- "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz",
- "integrity": "sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz",
+ "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
@@ -11434,9 +11589,9 @@
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"performance-now": "^2.1.0",
- "qs": "~6.5.2",
+ "qs": "6.10.4",
"safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
+ "tough-cookie": "^4.1.3",
"tunnel-agent": "^0.6.0",
"uuid": "^8.3.2"
},
@@ -12290,6 +12445,12 @@
}
}
},
+ "acorn-walk": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
+ "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
+ "dev": true
+ },
"addressparser": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
@@ -12503,9 +12664,9 @@
"dev": true
},
"aws4": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
- "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
+ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
"dev": true
},
"axios": {
@@ -12998,9 +13159,9 @@
}
},
"commander": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
- "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"dev": true
},
"common-tags": {
@@ -13279,29 +13440,28 @@
"dev": true
},
"cypress": {
- "version": "10.11.0",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz",
- "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==",
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.7.0.tgz",
+ "integrity": "sha512-UimjRSJJYdTlvkChcdcfywKJ6tUYuwYuk/n1uMMglrvi+ZthNhoRYcxnWgTqUtkl17fXrPAsD5XT2rcQYN1xKA==",
"dev": true,
"requires": {
- "@cypress/request": "^2.88.10",
+ "@cypress/request": "^3.0.0",
"@cypress/xvfb": "^1.2.4",
- "@types/node": "^14.14.31",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
"blob-util": "^2.0.2",
"bluebird": "^3.7.2",
- "buffer": "^5.6.0",
+ "buffer": "^5.7.1",
"cachedir": "^2.3.0",
"chalk": "^4.1.0",
"check-more-types": "^2.24.0",
"cli-cursor": "^3.1.0",
"cli-table3": "~0.6.1",
- "commander": "^5.1.0",
+ "commander": "^6.2.1",
"common-tags": "^1.8.0",
"dayjs": "^1.10.4",
- "debug": "^4.3.2",
+ "debug": "^4.3.4",
"enquirer": "^2.3.6",
"eventemitter2": "6.4.7",
"execa": "4.1.0",
@@ -13310,18 +13470,19 @@
"figures": "^3.2.0",
"fs-extra": "^9.1.0",
"getos": "^3.2.1",
- "is-ci": "^3.0.0",
+ "is-ci": "^3.0.1",
"is-installed-globally": "~0.4.0",
"lazy-ass": "^1.6.0",
"listr2": "^3.8.3",
"lodash": "^4.17.21",
"log-symbols": "^4.0.0",
- "minimist": "^1.2.6",
+ "minimist": "^1.2.8",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
+ "process": "^0.11.10",
"proxy-from-env": "1.0.0",
"request-progress": "^3.0.0",
- "semver": "^7.3.2",
+ "semver": "^7.5.3",
"supports-color": "^8.1.1",
"tmp": "~0.2.1",
"untildify": "^4.0.0",
@@ -15032,6 +15193,20 @@
"pkg-dir": "^4.1.0"
}
},
+ "find-test-names": {
+ "version": "1.28.18",
+ "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.18.tgz",
+ "integrity": "sha512-hhnGdkWK+qEA5Z02Tu0OqGQIUjFZNyOCE4WaJpbhW4hAF1+NZ7OCr0Bss9RCaj7BBtjoIjkU93utobQ8pg2iVg==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.23.0",
+ "@babel/plugin-syntax-jsx": "^7.22.5",
+ "acorn-walk": "^8.2.0",
+ "debug": "^4.3.3",
+ "globby": "^11.0.4",
+ "simple-bin-help": "^1.8.0"
+ }
+ },
"find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@@ -16741,9 +16916,9 @@
}
},
"minimist": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
},
"mkdirp": {
"version": "0.5.6",
@@ -17526,6 +17701,12 @@
"integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
"dev": true
},
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true
+ },
"process-on-spawn": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
@@ -17556,9 +17737,9 @@
"dev": true
},
"psl": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
- "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
"dev": true
},
"pump": {
@@ -17585,9 +17766,18 @@
}
},
"qs": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
- "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz",
+ "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
+ "querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
"dev": true
},
"queue-microtask": {
@@ -17757,6 +17947,12 @@
"integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
"dev": true
},
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true
+ },
"resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
@@ -17855,9 +18051,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"requires": {
"lru-cache": "^6.0.0"
}
@@ -17992,6 +18188,12 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
+ "simple-bin-help": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/simple-bin-help/-/simple-bin-help-1.8.0.tgz",
+ "integrity": "sha512-0LxHn+P1lF5r2WwVB/za3hLRIsYoLaNq1CXqjbrs3ZvLuvlWnRKrUjEWzV7umZL7hpQ7xULiQMV+0iXdRa5iFg==",
+ "dev": true
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -18125,9 +18327,9 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
},
"sshpk": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
- "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
+ "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
"dev": true,
"requires": {
"asn1": "~0.2.3",
@@ -18458,13 +18660,23 @@
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"dev": true,
"requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "dependencies": {
+ "universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true
+ }
}
},
"tr46": {
@@ -18524,7 +18736,7 @@
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
"requires": {
"safe-buffer": "^5.0.1"
@@ -18533,7 +18745,7 @@
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
"dev": true
},
"type-check": {
@@ -18661,6 +18873,16 @@
"punycode": "^2.1.0"
}
},
+ "url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
"url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
@@ -18701,7 +18923,7 @@
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
"dev": true,
"requires": {
"assert-plus": "^1.0.0",
diff --git a/package.json b/package.json
index 0859c5758..075687bb2 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,6 @@
"postinstall": "echo \"Trello app was installed sucessfully ✅\nYou can now run it by typing:\nnpm start\""
},
"dependencies": {
- "@4tw/cypress-drag-drop": "^2.1.0",
"@cypress/code-coverage": "^3.10.0",
"@cypress/vite-dev-server": "^2.2.1",
"@cypress/vue": "^3.0.5",
@@ -66,9 +65,11 @@
"vuedraggable": "^4.1.0"
},
"devDependencies": {
+ "@4tw/cypress-drag-drop": "^2.2.5",
+ "@cypress/grep": "^4.0.1",
"@cypress/skip-test": "^2.6.1",
"@types/leaflet": "^1.7.11",
- "cypress": "^10.4.0",
+ "cypress": "^13.7.0",
"eslint": "^8.5.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-no-only-tests": "^2.6.0",
diff --git a/src/components/board/BoardDetail.vue b/src/components/board/BoardDetail.vue
index 93c883542..708d3f830 100644
--- a/src/components/board/BoardDetail.vue
+++ b/src/components/board/BoardDetail.vue
@@ -35,14 +35,14 @@
>
-
- {{ state.board.name }}
+
+ {{ state.board.name }}
+
-
+
Starred
@@ -31,7 +31,7 @@
-
+
My Boards
diff --git a/tsconfig.json b/tsconfig.json
index f062797c0..7c30fb9e3 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -34,11 +34,13 @@
"types": [
"cypress-real-events",
"node",
- "cypress"
+ "cypress",
+ "@4tw/cypress-drag-drop"
],
},
"include": [
"cypress/**/*.ts",
"src/**/*"
]
+
}
\ No newline at end of file