diff --git a/.drone.yml b/.drone.yml index 8a7c18c02..4090e6a8f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -98,6 +98,15 @@ steps: depends_on: - dependencies + - name: typecheck + failure: ignore + image: node:16 + pull: true + commands: + - yarn typecheck + depends_on: + - dependencies + - name: test-frontend image: cypress/browsers:node16.5.0-chrome94-ff93 pull: true diff --git a/cypress/integration/list/list.spec.js b/cypress/integration/list/list.spec.js index 1d1c03585..55afcc7b2 100644 --- a/cypress/integration/list/list.spec.js +++ b/cypress/integration/list/list.spec.js @@ -31,7 +31,7 @@ describe('Lists', () => { cy.url() .should('contain', '/namespaces/1/list') cy.get('.card-header-title') - .contains('Create a new list') + .contains('New list') cy.get('input.input') .type('New List') cy.get('.button') @@ -101,7 +101,7 @@ describe('Lists', () => { .click() cy.url() .should('contain', '/settings/delete') - cy.get('.modal-mask .modal-container .modal-content .actions a.button') + cy.get('[data-cy="modalPrimary"]') .contains('Do it') .click() @@ -392,7 +392,7 @@ describe('Lists', () => { cy.get('.kanban .bucket .bucket-header .dropdown.options .dropdown-menu .dropdown-item .field input.input') .first() .type(3) - cy.get('.kanban .bucket .bucket-header .dropdown.options .dropdown-menu .dropdown-item .field a.button.is-primary') + cy.get('[data-cy="setBucketLimit"]') .first() .click() diff --git a/cypress/integration/list/namespaces.spec.js b/cypress/integration/list/namespaces.spec.js index 7d092113a..2ede493f5 100644 --- a/cypress/integration/list/namespaces.spec.js +++ b/cypress/integration/list/namespaces.spec.js @@ -15,7 +15,7 @@ describe('Namepaces', () => { it('Should be all there', () => { cy.visit('/namespaces') - cy.get('.namespace h1 span') + cy.get('[data-cy="namespace-title"]') .should('contain', namespaces[0].title) }) @@ -23,14 +23,14 @@ describe('Namepaces', () => { const newNamespaceTitle = 'New Namespace' cy.visit('/namespaces') - cy.get('a.button') - .contains('Create a new namespace') + cy.get('[data-cy="new-namespace"]') + .should('contain', 'New namespace') .click() cy.url() .should('contain', '/namespaces/new') cy.get('.card-header-title') - .should('contain', 'Create a new namespace') + .should('contain', 'New namespace') cy.get('input.input') .type(newNamespaceTitle) cy.get('.button') @@ -72,7 +72,7 @@ describe('Namepaces', () => { cy.get('.namespace-container .menu.namespaces-lists') .should('contain', newNamespaceName) .should('not.contain', newNamespaces[0].title) - cy.get('.content.namespaces-list') + cy.get('[data-cy="namespaces-list"]') .should('contain', newNamespaceName) .should('not.contain', newNamespaces[0].title) }) @@ -89,7 +89,7 @@ describe('Namepaces', () => { .click() cy.url() .should('contain', '/settings/delete') - cy.get('.modal-mask .modal-container .modal-content .actions a.button') + cy.get('[data-cy="modalPrimary"]') .contains('Do it') .click() @@ -116,30 +116,30 @@ describe('Namepaces', () => { // Initial cy.visit('/namespaces') - cy.get('.namespaces-list .namespace') + cy.get('.namespace') .should('not.contain', 'Archived') // Show archived - cy.get('.namespaces-list .fancycheckbox.show-archived-check label.check span') + cy.get('[data-cy="show-archived-check"] label.check span') .should('be.visible') .click() - cy.get('.namespaces-list .fancycheckbox.show-archived-check input') + cy.get('[data-cy="show-archived-check"] input') .should('be.checked') - cy.get('.namespaces-list .namespace') + cy.get('.namespace') .should('contain', 'Archived') // Don't show archived - cy.get('.namespaces-list .fancycheckbox.show-archived-check label.check span') + cy.get('[data-cy="show-archived-check"] label.check span') .should('be.visible') .click() - cy.get('.namespaces-list .fancycheckbox.show-archived-check input') + cy.get('[data-cy="show-archived-check"] input') .should('not.be.checked') // Second time visiting after unchecking cy.visit('/namespaces') - cy.get('.namespaces-list .fancycheckbox.show-archived-check input') + cy.get('[data-cy="show-archived-check"] input') .should('not.be.checked') - cy.get('.namespaces-list .namespace') + cy.get('.namespace') .should('not.contain', 'Archived') }) }) diff --git a/cypress/integration/misc/home.spec.js b/cypress/integration/misc/home.spec.js deleted file mode 100644 index 82cbeed22..000000000 --- a/cypress/integration/misc/home.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import '../../support/authenticateUser' - -const setHours = hours => { - const date = new Date() - date.setHours(hours) - cy.clock(+date) -} - -describe('Home Page', () => { - it('shows the right salutation in the night', () => { - setHours(4) - cy.visit('/') - cy.get('h2').should('contain', 'Good Night') - }) - it('shows the right salutation in the morning', () => { - setHours(8) - cy.visit('/') - cy.get('h2').should('contain', 'Good Morning') - }) - it('shows the right salutation in the day', () => { - setHours(13) - cy.visit('/') - cy.get('h2').should('contain', 'Hi') - }) - it('shows the right salutation in the night', () => { - setHours(20) - cy.visit('/') - cy.get('h2').should('contain', 'Good Evening') - }) - it('shows the right salutation in the night again', () => { - setHours(23) - cy.visit('/') - cy.get('h2').should('contain', 'Good Night') - }) -}) \ No newline at end of file diff --git a/cypress/integration/task/task.spec.js b/cypress/integration/task/task.spec.js index 68027e3d8..1b85e9921 100644 --- a/cypress/integration/task/task.spec.js +++ b/cypress/integration/task/task.spec.js @@ -128,7 +128,7 @@ describe('Task', () => { cy.visit(`/tasks/${tasks[0].id}`) cy.get('.task-view .action-buttons .button') - .contains('Done!') + .contains('Mark task done!') .click() cy.get('.task-view .heading .is-done') @@ -168,7 +168,7 @@ describe('Task', () => { .click() cy.get('.task-view .details.content.description .editor .vue-easymde .EasyMDEContainer .CodeMirror-scroll') .type('{selectall}New Description') - cy.get('.task-view .details.content.description .editor a') + cy.get('[data-cy="saveEditor"]') .contains('Save') .click() @@ -404,7 +404,7 @@ describe('Task', () => { cy.get('.datepicker .datepicker-popup a') .contains('Tomorrow') .click() - cy.get('.datepicker .datepicker-popup a.button') + cy.get('[data-cy="closeDatepicker"]') .contains('Confirm') .click() diff --git a/cypress/integration/user/settings.spec.js b/cypress/integration/user/settings.spec.js index 29cb1ad03..c6a645d59 100644 --- a/cypress/integration/user/settings.spec.js +++ b/cypress/integration/user/settings.spec.js @@ -18,7 +18,7 @@ describe('User Settings', () => { .trigger('mousedown', {which: 1}) .trigger('mousemove', {clientY: 100}) .trigger('mouseup') - cy.get('a.button.is-primary') + cy.get('[data-cy="uploadAvatar"]') .contains('Upload Avatar') .click() @@ -33,7 +33,7 @@ describe('User Settings', () => { cy.get('.general-settings .control input.input') .first() .type('Lorem Ipsum') - cy.get('.card.general-settings .button.is-primary') + cy.get('[data-cy="saveGeneralSettings"]') .contains('Save') .click() diff --git a/package.json b/package.json index 538de3ac5..9ab35adb2 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,11 @@ "build": "vite build && workbox copyLibraries dist/", "build:modern-only": "BUILD_MODERN_ONLY=true vite build && workbox copyLibraries dist/", "build:dev": "vite build -m development --outDir dist-dev/", + "typecheck": "vue-tsc --noEmit", "lint": "eslint --ignore-pattern '*.test.*' ./src --ext .vue,.js,.ts", - "lint:markup": "vue-tsc --noEmit", "cypress:open": "cypress open", - "test:unit": "jest", + "test:unit": "vitest run", + "test:unit-watch": "vitest watch", "test:frontend": "cypress run", "browserslist:update": "npx browserslist@latest --update-db" }, @@ -21,32 +22,33 @@ "@kyvg/vue3-notification": "2.3.4", "@sentry/tracing": "6.16.1", "@sentry/vue": "6.16.1", + "@types/is-touch-device": "1.0.0", "@vue/compat": "3.2.26", - "@vueuse/core": "7.4.1", - "@vueuse/router": "7.4.1", + "@vueuse/core": "7.5.2", + "@vueuse/router": "7.5.3", "bulma-css-variables": "0.9.33", "camel-case": "4.1.2", "codemirror": "5.65.0", "copy-to-clipboard": "3.3.1", - "date-fns": "2.27.0", + "date-fns": "2.28.0", "dompurify": "2.3.4", "easymde": "2.15.0", "flatpickr": "4.6.9", "flexsearch": "0.7.21", - "highlight.js": "11.3.1", + "highlight.js": "11.4.0", "is-touch-device": "1.0.1", "lodash.clonedeep": "4.5.0", "lodash.debounce": "4.0.8", - "marked": "4.0.8", + "marked": "4.0.9", "register-service-worker": "1.7.2", "snake-case": "3.0.4", "ufo": "0.7.9", - "v-tooltip": "4.0.0-beta.2", + "v-tooltip": "4.0.0-beta.13", "vue": "3.2.26", - "vue-advanced-cropper": "2.7.0", + "vue-advanced-cropper": "2.7.1", "vue-drag-resize": "2.0.3", "vue-flatpickr-component": "9.0.5", - "vue-i18n": "9.2.0-beta.25", + "vue-i18n": "9.2.0-beta.26", "vue-router": "4.0.12", "vuedraggable": "4.1.0", "vuex": "4.0.2", @@ -59,37 +61,36 @@ "@fortawesome/free-solid-svg-icons": "5.15.4", "@fortawesome/vue-fontawesome": "3.0.0-5", "@types/flexsearch": "0.7.2", - "@types/jest": "27.0.3", - "@typescript-eslint/eslint-plugin": "5.8.0", - "@typescript-eslint/parser": "5.8.0", + "@typescript-eslint/eslint-plugin": "5.9.0", + "@typescript-eslint/parser": "5.9.0", "@vitejs/plugin-legacy": "1.6.4", "@vitejs/plugin-vue": "2.0.1", - "@vue/eslint-config-typescript": "9.1.0", - "autoprefixer": "10.4.0", + "@vue/eslint-config-typescript": "10.0.0", + "autoprefixer": "10.4.2", "axios": "0.24.0", "browserslist": "4.19.1", - "caniuse-lite": "1.0.30001292", + "caniuse-lite": "1.0.30001298", "cypress": "9.2.0", "cypress-file-upload": "5.0.8", - "esbuild": "0.14.8", - "eslint": "8.5.0", + "esbuild": "0.14.11", + "eslint": "8.6.0", "eslint-plugin-vue": "8.2.0", "express": "4.17.2", "faker": "5.5.3", - "jest": "27.4.5", - "netlify-cli": "8.4.2", + "netlify-cli": "8.6.15", + "happy-dom": "2.25.1", "postcss": "8.4.5", - "postcss-preset-env": "7.1.0", - "rollup": "2.61.1", + "postcss-preset-env": "7.2.0", + "rollup": "2.63.0", "rollup-plugin-visualizer": "5.5.2", - "sass": "1.45.1", - "slugify": "1.6.4", - "ts-jest": "27.1.2", + "sass": "1.47.0", + "slugify": "1.6.5", "typescript": "4.5.4", - "vite": "2.7.7", + "vite": "2.7.10", "vite-plugin-pwa": "0.11.12", "vite-svg-loader": "3.1.1", - "vue-tsc": "0.30.0", + "vitest": "0.0.139", + "vue-tsc": "0.30.2", "wait-on": "6.0.0", "workbox-cli": "6.4.2" }, @@ -144,24 +145,6 @@ "autoprefixer": {} } }, - "jest": { - "testPathIgnorePatterns": [ - "cypress" - ], - "testEnvironment": "jsdom", - "preset": "ts-jest", - "roots": [ - "/src" - ], - "transform": { - "^.+\\.(js|tsx?)$": "ts-jest" - }, - "moduleFileExtensions": [ - "ts", - "js", - "json" - ] - }, "license": "AGPL-3.0-or-later", "packageManager": "yarn@1.22.17" } diff --git a/src/App.vue b/src/App.vue index e0b53d243..06a818506 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,16 +1,14 @@ + + + + diff --git a/src/components/home/contentLinkShare.vue b/src/components/home/contentLinkShare.vue index 1ae53c151..97648a09d 100644 --- a/src/components/home/contentLinkShare.vue +++ b/src/components/home/contentLinkShare.vue @@ -1,6 +1,6 @@