forked from vikunja/frontend
feat(cypress): use cy.session
Also align repo closer to `create-vue` template and improve cypress integration
This commit is contained in:
parent
6ddfba4f1f
commit
4908469d49
@ -96,7 +96,7 @@ steps:
|
||||
- dependencies
|
||||
|
||||
- name: test-frontend
|
||||
image: cypress/browsers:node18.12.0-chrome106-ff106
|
||||
image: cypress/browsers:node18.12.0-chrome107
|
||||
pull: always
|
||||
environment:
|
||||
CYPRESS_API_URL: http://api:3456/api/v1
|
||||
@ -110,8 +110,7 @@ steps:
|
||||
- sed -i 's/localhost/api/g' dist/index.html
|
||||
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||
- pnpm cypress install
|
||||
- pnpm run serve:dist & npx wait-on http://localhost:4173
|
||||
- pnpm run test:frontend --browser chrome --record
|
||||
- pnpm run test:e2e-record
|
||||
depends_on:
|
||||
- build-prod
|
||||
|
||||
|
34
.gitignore
vendored
34
.gitignore
vendored
@ -1,26 +1,31 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist*
|
||||
*.zip
|
||||
.direnv/
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
stats.html
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
stats.html
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
/dist*
|
||||
coverage
|
||||
*.zip
|
||||
.direnv/
|
||||
|
||||
# Test files
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
@ -28,9 +33,6 @@ lerna-debug.log*
|
||||
*.sw*
|
||||
!rollup.sw.js
|
||||
|
||||
# Test files
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
|
@ -11,8 +11,10 @@ export default defineConfig({
|
||||
},
|
||||
projectId: '181c7x',
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:4173',
|
||||
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
|
||||
specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
|
||||
baseUrl: 'http://127.0.0.1:4173',
|
||||
experimentalRunAllSpecs: true,
|
||||
// testIsolation: false,
|
||||
},
|
||||
component: {
|
||||
devServer: {
|
||||
|
@ -36,7 +36,7 @@ to get a shell inside the cypress container.
|
||||
In that shell you can then execute the tests with
|
||||
|
||||
```shell
|
||||
pnpm run test:frontend
|
||||
pnpm run test:e2e
|
||||
```
|
||||
|
||||
### Using The Cypress Dashboard
|
||||
@ -44,5 +44,5 @@ pnpm run test:frontend
|
||||
To open the Cypress Dashboard and run tests from there, run
|
||||
|
||||
```shell
|
||||
pnpm run cypress:open
|
||||
pnpm run test:e2e:dev
|
||||
```
|
||||
|
@ -9,7 +9,7 @@ services:
|
||||
ports:
|
||||
- 3456:3456
|
||||
cypress:
|
||||
image: cypress/browsers:node16.14.0-chrome99-ff97
|
||||
image: cypress/browsers:node18.12.0-chrome107
|
||||
volumes:
|
||||
- ..:/project
|
||||
- $HOME/.cache:/home/node/.cache/
|
||||
|
@ -1,9 +1,10 @@
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {prepareLists} from './prepareLists'
|
||||
|
||||
describe('List History', () => {
|
||||
createFakeUserAndLogin()
|
||||
prepareLists()
|
||||
|
||||
it('should show a list history on the home page', () => {
|
||||
|
@ -1,10 +1,12 @@
|
||||
import {formatISO, format} from 'date-fns'
|
||||
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {prepareLists} from './prepareLists'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('List View Gantt', () => {
|
||||
createFakeUserAndLogin()
|
||||
prepareLists()
|
||||
|
||||
it('Hides tasks with no dates', () => {
|
||||
@ -33,8 +35,8 @@ describe('List View Gantt', () => {
|
||||
it('Shows tasks with dates', () => {
|
||||
const now = new Date()
|
||||
const tasks = TaskFactory.create(1, {
|
||||
start_date: formatISO(now),
|
||||
end_date: formatISO(now.setDate(now.getDate() + 4)),
|
||||
start_date: now.toISOString(),
|
||||
end_date: new Date(new Date(now).setDate(now.getDate() + 4)).toISOString(),
|
||||
})
|
||||
cy.visit('/lists/1/gantt')
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {BucketFactory} from '../../factories/bucket'
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {prepareLists} from './prepareLists'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('List View Kanban', () => {
|
||||
let buckets
|
||||
createFakeUserAndLogin()
|
||||
prepareLists()
|
||||
|
||||
|
||||
let buckets
|
||||
beforeEach(() => {
|
||||
buckets = BucketFactory.create(2)
|
||||
})
|
||||
|
@ -1,12 +1,13 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {UserListFactory} from '../../factories/users_list'
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {UserFactory} from '../../factories/user'
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {prepareLists} from './prepareLists'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('List View List', () => {
|
||||
createFakeUserAndLogin()
|
||||
prepareLists()
|
||||
|
||||
it('Should be an empty list', () => {
|
||||
|
@ -1,8 +1,10 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('List View Table', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
it('Should show a table with tasks', () => {
|
||||
const tasks = TaskFactory.create(1)
|
||||
cy.visit('/lists/1/table')
|
||||
|
@ -1,9 +1,11 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {prepareLists} from './prepareLists'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('Lists', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
let lists
|
||||
prepareLists((newLists) => (lists = newLists))
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
import {UserFactory} from '../../factories/user'
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {NamespaceFactory} from '../../factories/namespace'
|
||||
|
||||
describe('Namepaces', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
let namespaces
|
||||
|
||||
beforeEach(() => {
|
||||
UserFactory.create(1)
|
||||
namespaces = NamespaceFactory.create(1)
|
||||
ListFactory.create(1)
|
||||
})
|
||||
|
@ -1,10 +1,8 @@
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {UserFactory} from '../../factories/user'
|
||||
import {NamespaceFactory} from '../../factories/namespace'
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
|
||||
export function createLists() {
|
||||
UserFactory.create(1)
|
||||
NamespaceFactory.create(1)
|
||||
const lists = ListFactory.create(1, {
|
||||
title: 'First List'
|
||||
|
@ -1,14 +1,16 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {NamespaceFactory} from '../../factories/namespace'
|
||||
import {UserListFactory} from '../../factories/users_list'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('Editor', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
beforeEach(() => {
|
||||
NamespaceFactory.create(1)
|
||||
const lists = ListFactory.create(1)
|
||||
ListFactory.create(1)
|
||||
TaskFactory.truncate()
|
||||
UserListFactory.truncate()
|
||||
})
|
||||
|
@ -1,6 +1,12 @@
|
||||
import '../../support/authenticateUser'
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
describe('The Menu', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/')
|
||||
})
|
||||
|
||||
it('Is visible by default on desktop', () => {
|
||||
cy.get('.namespace-container')
|
||||
.should('have.class', 'is-active')
|
||||
|
@ -1,9 +1,12 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {TeamFactory} from '../../factories/team'
|
||||
import {TeamMemberFactory} from '../../factories/team_member'
|
||||
import {UserFactory} from '../../factories/user'
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
describe('Team', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
it('Creates a new team', () => {
|
||||
TeamFactory.truncate()
|
||||
cy.visit('/teams')
|
||||
|
@ -1,16 +1,13 @@
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {ListFactory} from '../../factories/list'
|
||||
import {seed} from '../../support/seed'
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {formatISO} from 'date-fns'
|
||||
import {UserFactory} from '../../factories/user'
|
||||
import {NamespaceFactory} from '../../factories/namespace'
|
||||
import {BucketFactory} from '../../factories/bucket'
|
||||
import {updateUserSettings} from '../../support/updateUserSettings'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
|
||||
function seedTasks(numberOfTasks = 100, startDueDate = new Date()) {
|
||||
UserFactory.create(1)
|
||||
function seedTasks(numberOfTasks = 50, startDueDate = new Date()) {
|
||||
NamespaceFactory.create(1)
|
||||
const list = ListFactory.create()[0]
|
||||
BucketFactory.create(1, {
|
||||
@ -20,7 +17,7 @@ function seedTasks(numberOfTasks = 100, startDueDate = new Date()) {
|
||||
let dueDate = startDueDate
|
||||
for (let i = 0; i < numberOfTasks; i++) {
|
||||
const now = new Date()
|
||||
dueDate = (new Date(dueDate.valueOf())).setDate((new Date(dueDate.valueOf())).getDate() + 2)
|
||||
dueDate = new Date(new Date(dueDate).setDate(dueDate.getDate() + 2))
|
||||
tasks.push({
|
||||
id: i + 1,
|
||||
list_id: list.id,
|
||||
@ -28,9 +25,9 @@ function seedTasks(numberOfTasks = 100, startDueDate = new Date()) {
|
||||
created_by_id: 1,
|
||||
title: 'Test Task ' + i,
|
||||
index: i + 1,
|
||||
due_date: formatISO(dueDate),
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now),
|
||||
due_date: dueDate.toISOString(),
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
})
|
||||
}
|
||||
seed(TaskFactory.table, tasks)
|
||||
@ -38,8 +35,11 @@ function seedTasks(numberOfTasks = 100, startDueDate = new Date()) {
|
||||
}
|
||||
|
||||
describe('Home Page Task Overview', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
it('Should show tasks with a near due date first on the home page overview', () => {
|
||||
const {tasks} = seedTasks()
|
||||
const taskCount = 50
|
||||
const {tasks} = seedTasks(taskCount)
|
||||
|
||||
cy.visit('/')
|
||||
cy.get('[data-cy="showTasks"] .card .task')
|
||||
@ -49,8 +49,10 @@ describe('Home Page Task Overview', () => {
|
||||
})
|
||||
|
||||
it('Should show overdue tasks first, then show other tasks', () => {
|
||||
const oldDate = (new Date()).setDate((new Date()).getDate() - 14)
|
||||
const {tasks} = seedTasks(100, oldDate)
|
||||
const now = new Date()
|
||||
const oldDate = new Date(new Date(now).setDate(now.getDate() - 14))
|
||||
const taskCount = 50
|
||||
const {tasks} = seedTasks(taskCount, oldDate)
|
||||
|
||||
cy.visit('/')
|
||||
cy.get('[data-cy="showTasks"] .card .task')
|
||||
@ -68,7 +70,7 @@ describe('Home Page Task Overview', () => {
|
||||
TaskFactory.create(1, {
|
||||
id: 999,
|
||||
title: newTaskTitle,
|
||||
due_date: formatISO(new Date()),
|
||||
due_date: new Date().toISOString(),
|
||||
}, false)
|
||||
|
||||
cy.visit(`/lists/${tasks[0].list_id}/list`)
|
||||
@ -83,7 +85,7 @@ describe('Home Page Task Overview', () => {
|
||||
|
||||
it('Should not show a new task without a date at the bottom when there are > 50 tasks', () => {
|
||||
// We're not using the api here to create the task in order to verify the flow
|
||||
const {tasks} = seedTasks()
|
||||
const {tasks} = seedTasks(100)
|
||||
const newTaskTitle = 'New Task'
|
||||
|
||||
cy.visit('/')
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {formatISO} from 'date-fns'
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
import {TaskFactory} from '../../factories/task'
|
||||
import {ListFactory} from '../../factories/list'
|
||||
@ -11,7 +11,6 @@ import {LabelFactory} from '../../factories/labels'
|
||||
import {LabelTaskFactory} from '../../factories/label_task'
|
||||
import {BucketFactory} from '../../factories/bucket'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
import {TaskAttachmentFactory} from '../../factories/task_attachments'
|
||||
|
||||
function addLabelToTaskAndVerify(labelTitle: string) {
|
||||
@ -46,12 +45,14 @@ function uploadAttachmentAndVerify(taskId: number) {
|
||||
}
|
||||
|
||||
describe('Task', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
let namespaces
|
||||
let lists
|
||||
let buckets
|
||||
|
||||
beforeEach(() => {
|
||||
UserFactory.create(1)
|
||||
// UserFactory.create(1)
|
||||
namespaces = NamespaceFactory.create(1)
|
||||
lists = ListFactory.create(1)
|
||||
buckets = BucketFactory.create(1, {
|
||||
@ -145,7 +146,7 @@ describe('Task', () => {
|
||||
id: 1,
|
||||
index: 1,
|
||||
done: true,
|
||||
done_at: formatISO(new Date())
|
||||
done_at: new Date().toISOString()
|
||||
})
|
||||
cy.visit(`/tasks/${tasks[0].id}`)
|
||||
|
||||
|
11
cypress/e2e/tsconfig.json
Normal file
11
cypress/e2e/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
||||
"include": ["./**/*", "../support/**/*", "../factories/**/*"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": false,
|
||||
"target": "ES2015",
|
||||
"lib": ["ESNext", "dom"],
|
||||
"types": ["cypress"]
|
||||
}
|
||||
}
|
@ -11,16 +11,11 @@ const testAndAssertFailed = fixture => {
|
||||
cy.get('div.message.danger').contains('Wrong username or password.')
|
||||
}
|
||||
|
||||
const username = 'test'
|
||||
|
||||
context('Login', () => {
|
||||
beforeEach(() => {
|
||||
UserFactory.create(1, {
|
||||
username: 'test',
|
||||
})
|
||||
cy.visit('/', {
|
||||
onBeforeLoad(win) {
|
||||
win.localStorage.removeItem('token')
|
||||
},
|
||||
})
|
||||
UserFactory.create(1, {username})
|
||||
})
|
||||
|
||||
it('Should log in with the right credentials', () => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import '../../support/authenticateUser'
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
import {createLists} from '../list/prepareLists'
|
||||
|
||||
function logout() {
|
||||
@ -10,6 +10,8 @@ function logout() {
|
||||
}
|
||||
|
||||
describe('Log out', () => {
|
||||
createFakeUserAndLogin()
|
||||
|
||||
it('Logs the user out', () => {
|
||||
cy.visit('/')
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
import {UserFactory} from '../../factories/user'
|
||||
|
||||
import '../../support/authenticateUser'
|
||||
import {createFakeUserAndLogin} from '../../support/authenticateUser'
|
||||
|
||||
describe('User Settings', () => {
|
||||
beforeEach(() => {
|
||||
UserFactory.create(1)
|
||||
})
|
||||
createFakeUserAndLogin()
|
||||
|
||||
it('Changes the user avatar', () => {
|
||||
cy.intercept(`${Cypress.env('API_URL')}/user/settings/avatar/upload`).as('uploadAvatar')
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class BucketFactory extends Factory {
|
||||
static table = 'buckets'
|
||||
@ -13,8 +12,8 @@ export class BucketFactory extends Factory {
|
||||
title: faker.lorem.words(3),
|
||||
list_id: 1,
|
||||
created_by_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class LabelTaskFactory extends Factory {
|
||||
static table = 'label_tasks'
|
||||
@ -11,7 +10,7 @@ export class LabelTaskFactory extends Factory {
|
||||
id: '{increment}',
|
||||
task_id: 1,
|
||||
label_id: 1,
|
||||
created: formatISO(now),
|
||||
created: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class LabelFactory extends Factory {
|
||||
static table = 'labels'
|
||||
@ -15,8 +14,8 @@ export class LabelFactory extends Factory {
|
||||
description: faker.lorem.text(10),
|
||||
hex_color: (Math.random()*0xFFFFFF<<0).toString(16), // random 6-digit hex number
|
||||
created_by_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now),
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from "date-fns"
|
||||
import {faker} from '@faker-js/faker'
|
||||
|
||||
export class LinkShareFactory extends Factory {
|
||||
@ -15,8 +14,8 @@ export class LinkShareFactory extends Factory {
|
||||
right: 0,
|
||||
sharing_type: 0,
|
||||
shared_by_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from "date-fns"
|
||||
import {faker} from '@faker-js/faker'
|
||||
|
||||
export class ListFactory extends Factory {
|
||||
@ -13,8 +12,8 @@ export class ListFactory extends Factory {
|
||||
title: faker.lorem.words(3),
|
||||
owner_id: 1,
|
||||
namespace_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class NamespaceFactory extends Factory {
|
||||
static table = 'namespaces'
|
||||
@ -12,8 +11,8 @@ export class NamespaceFactory extends Factory {
|
||||
id: '{increment}',
|
||||
title: faker.lorem.words(3),
|
||||
owner_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class TaskFactory extends Factory {
|
||||
static table = 'tasks'
|
||||
@ -16,8 +15,8 @@ export class TaskFactory extends Factory {
|
||||
created_by_id: 1,
|
||||
index: '{increment}',
|
||||
position: '{increment}',
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class TaskAssigneeFactory extends Factory {
|
||||
static table = 'task_assignees'
|
||||
@ -11,7 +10,7 @@ export class TaskAssigneeFactory extends Factory {
|
||||
id: '{increment}',
|
||||
task_id: 1,
|
||||
user_id: 1,
|
||||
created: formatISO(now),
|
||||
created: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class TaskAttachmentFactory extends Factory {
|
||||
static table = 'task_attachments'
|
||||
@ -11,7 +10,7 @@ export class TaskAttachmentFactory extends Factory {
|
||||
id: '{increment}',
|
||||
task_id: 1,
|
||||
file_id: 1,
|
||||
created: formatISO(now),
|
||||
created: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from "date-fns"
|
||||
|
||||
export class TaskCommentFactory extends Factory {
|
||||
static table = 'task_comments'
|
||||
@ -14,8 +13,8 @@ export class TaskCommentFactory extends Factory {
|
||||
comment: faker.lorem.text(3),
|
||||
author_id: 1,
|
||||
task_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class TeamFactory extends Factory {
|
||||
static table = 'teams'
|
||||
@ -11,8 +10,8 @@ export class TeamFactory extends Factory {
|
||||
return {
|
||||
name: faker.lorem.words(3),
|
||||
created_by_id: 1,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from 'date-fns'
|
||||
|
||||
export class TeamMemberFactory extends Factory {
|
||||
static table = 'team_members'
|
||||
@ -9,7 +8,7 @@ export class TeamMemberFactory extends Factory {
|
||||
team_id: 1,
|
||||
user_id: 1,
|
||||
admin: false,
|
||||
created: formatISO(new Date()),
|
||||
created: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import {faker} from '@faker-js/faker'
|
||||
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from "date-fns"
|
||||
|
||||
export class UserFactory extends Factory {
|
||||
static table = 'users'
|
||||
@ -15,8 +14,8 @@ export class UserFactory extends Factory {
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.', // 1234
|
||||
status: 0,
|
||||
issuer: 'local',
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import {Factory} from '../support/factory'
|
||||
import {formatISO} from "date-fns"
|
||||
|
||||
export class UserListFactory extends Factory {
|
||||
static table = 'users_lists'
|
||||
@ -12,8 +11,8 @@ export class UserListFactory extends Factory {
|
||||
list_id: 1,
|
||||
user_id: 1,
|
||||
right: 0,
|
||||
created: formatISO(now),
|
||||
updated: formatISO(now)
|
||||
created: now.toISOString(),
|
||||
updated: now.toISOString(),
|
||||
}
|
||||
}
|
||||
}
|
@ -4,26 +4,32 @@
|
||||
|
||||
import {UserFactory} from '../factories/user'
|
||||
|
||||
let token
|
||||
|
||||
before(() => {
|
||||
const users = UserFactory.create(1)
|
||||
|
||||
cy.request('POST', `${Cypress.env('API_URL')}/login`, {
|
||||
username: users[0].username,
|
||||
password: '1234',
|
||||
})
|
||||
.its('body')
|
||||
.then(r => {
|
||||
token = r.token
|
||||
export function login(user, cacheAcrossSpecs = false) {
|
||||
if (!user) {
|
||||
throw new Error('Needs user')
|
||||
}
|
||||
// Caching session when logging in via page visit
|
||||
cy.session(`user__${user.username}`, () => {
|
||||
cy.request('POST', `${Cypress.env('API_URL')}/login`, {
|
||||
username: user.username,
|
||||
password: '1234',
|
||||
}).then(({ body }) => {
|
||||
window.localStorage.setItem('token', body.token)
|
||||
})
|
||||
})
|
||||
}, {
|
||||
cacheAcrossSpecs,
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cy.log(`Using token ${token} to make authenticated requests`)
|
||||
cy.visit('/', {
|
||||
onBeforeLoad(win) {
|
||||
win.localStorage.setItem('token', token)
|
||||
},
|
||||
export function createFakeUserAndLogin() {
|
||||
let user
|
||||
before(() => {
|
||||
user = UserFactory.create(1)[0]
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
login(user, true)
|
||||
})
|
||||
|
||||
return user
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
||||
"include": ["./integration/**/*", "./support/**/*"],
|
||||
"compilerOptions": {
|
||||
"isolatedModules": false,
|
||||
"target": "es5",
|
||||
"lib": ["es5", "dom"],
|
||||
"types": ["cypress"]
|
||||
}
|
||||
}
|
14
package.json
14
package.json
@ -4,16 +4,17 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vite",
|
||||
"serve:dist": "vite preview --port 4173",
|
||||
"serve:dist:dev": "vite preview --mode development --port 4173",
|
||||
"preview": "vite preview --port 4173",
|
||||
"preview:dev": "vite preview --outDir dist-dev --mode development --port 4173",
|
||||
"build": "vite build && workbox copyLibraries dist/",
|
||||
"build:modern-only": "BUILD_MODERN_ONLY=true vite build && workbox copyLibraries dist/",
|
||||
"build:dev": "vite build --mode development --outDir dist-dev/",
|
||||
"lint": "eslint --ignore-pattern '*.test.*' ./src --ext .vue,.js,.ts",
|
||||
"cypress:open": "cypress open",
|
||||
"test:unit": "vitest --run",
|
||||
"test:unit-watch": "vitest watch",
|
||||
"test:frontend": "cypress run",
|
||||
"test:e2e": "start-server-and-test preview http://127.0.0.1:4173 'cypress run --e2e --browser chrome'",
|
||||
"test:e2e-record": "start-server-and-test preview http://127.0.0.1:4173 'cypress run --e2e --browser chrome --record'",
|
||||
"test:e2e-dev-dev": "start-server-and-test preview:dev http://127.0.0.1:4173 'cypress open --e2e'",
|
||||
"test:e2e-dev": "start-server-and-test preview http://127.0.0.1:4173 'cypress open --e2e'",
|
||||
"test:unit": "vitest",
|
||||
"typecheck": "vue-tsc --noEmit && vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||
"browserslist:update": "npx browserslist@latest --update-db",
|
||||
"fonts:update": "pnpm run fonts:download && pnpm run fonts:subset",
|
||||
@ -102,6 +103,7 @@
|
||||
"rollup": "3.9.0",
|
||||
"rollup-plugin-visualizer": "5.9.0",
|
||||
"sass": "1.57.1",
|
||||
"start-server-and-test": "1.15.2",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "4.0.3",
|
||||
"vite-plugin-pwa": "0.14.0",
|
||||
|
169
pnpm-lock.yaml
generated
169
pnpm-lock.yaml
generated
@ -72,6 +72,7 @@ specifiers:
|
||||
sass: 1.57.1
|
||||
snake-case: 3.0.4
|
||||
sortablejs: 1.15.0
|
||||
start-server-and-test: 1.15.2
|
||||
typescript: 4.9.4
|
||||
ufo: 1.0.1
|
||||
vite: 4.0.3
|
||||
@ -171,6 +172,7 @@ devDependencies:
|
||||
rollup: 3.9.0
|
||||
rollup-plugin-visualizer: 5.9.0_rollup@3.9.0
|
||||
sass: 1.57.1
|
||||
start-server-and-test: 1.15.2
|
||||
typescript: 4.9.4
|
||||
vite: 4.0.3_4ljv3kzetn75ixk7nciffo2yk4
|
||||
vite-plugin-pwa: 0.14.0_d6hwg7klbxt3x5xmvc2y355a7m
|
||||
@ -2159,7 +2161,7 @@ packages:
|
||||
'@netlify/edge-bundler': 8.0.0
|
||||
'@netlify/functions-utils': 5.1.1_supports-color@9.2.1
|
||||
'@netlify/git-utils': 5.1.0
|
||||
'@netlify/plugins-list': 6.59.0
|
||||
'@netlify/plugins-list': 6.61.0
|
||||
'@netlify/run-utils': 5.1.0
|
||||
'@netlify/zip-it-and-ship-it': 8.2.0_supports-color@9.2.1
|
||||
'@sindresorhus/slugify': 2.1.0
|
||||
@ -2665,8 +2667,8 @@ packages:
|
||||
resolution: {integrity: sha512-1n9VvO/9qM7cRB5f7NgSNqeUrovM7j9WVAY7ZQ4LtQuXSquFmO9Fku7WrV3zAUC6v2Y62fxGyJ0fRllYz5uXLw==}
|
||||
dev: true
|
||||
|
||||
/@netlify/plugins-list/6.59.0:
|
||||
resolution: {integrity: sha512-QLS3j9jf/5Jmu9x6OY+qp8i1mSCftBgq9SmE797mHP/TRD6+00C93pIdZN9KZJRUdyy8gts9K3XSXiS23LJJWA==}
|
||||
/@netlify/plugins-list/6.61.0:
|
||||
resolution: {integrity: sha512-76pkuMxDdRQcAKu5WXBl24fFCzjV8rQyBS2xh/xphAntPn57uLBtQYasncTzsgGjckWwDPjwoIkmxOzi3OeqFQ==}
|
||||
engines: {node: ^14.14.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
@ -2701,7 +2703,7 @@ packages:
|
||||
junk: 4.0.0
|
||||
locate-path: 7.1.0
|
||||
merge-options: 3.0.4
|
||||
minimatch: 5.1.1
|
||||
minimatch: 5.1.2
|
||||
normalize-path: 3.0.0
|
||||
p-map: 5.5.0
|
||||
path-exists: 5.0.0
|
||||
@ -2742,7 +2744,7 @@ packages:
|
||||
junk: 4.0.0
|
||||
locate-path: 7.1.0
|
||||
merge-options: 3.0.4
|
||||
minimatch: 5.1.1
|
||||
minimatch: 5.1.2
|
||||
normalize-path: 3.0.0
|
||||
p-map: 5.5.0
|
||||
path-exists: 5.0.0
|
||||
@ -3682,7 +3684,7 @@ packages:
|
||||
'@vue/compiler-sfc': 3.2.45
|
||||
'@vue/reactivity': 3.2.45
|
||||
'@vue/shared': 3.2.45
|
||||
minimatch: 5.1.1
|
||||
minimatch: 5.1.2
|
||||
vue-template-compiler: 2.7.14
|
||||
dev: true
|
||||
|
||||
@ -4136,6 +4138,10 @@ packages:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
dev: true
|
||||
|
||||
/arg/5.0.2:
|
||||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||
dev: true
|
||||
|
||||
/argparse/2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
@ -4191,7 +4197,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/ascii-table/0.0.9:
|
||||
resolution: {integrity: sha512-xpkr6sCDIYTPqzvjG8M3ncw1YOTaloWZOyrUmicoEifBEKzQzt+ooUpRpQ/AbOoJfO/p2ZKiyp79qHThzJDulQ==}
|
||||
resolution: {integrity: sha1-BqZgTWpV1L9BqaR9mHLXp42jHnM=}
|
||||
dev: true
|
||||
|
||||
/asn1/0.2.6:
|
||||
@ -4278,6 +4284,14 @@ packages:
|
||||
resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==}
|
||||
dev: true
|
||||
|
||||
/axios/0.25.0_debug@4.3.4:
|
||||
resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.1_debug@4.3.4
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: true
|
||||
|
||||
/axios/0.27.2:
|
||||
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
|
||||
dependencies:
|
||||
@ -4576,7 +4590,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/buffer-equal-constant-time/1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
resolution: {integrity: sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=}
|
||||
dev: true
|
||||
|
||||
/buffer-fill/1.0.0:
|
||||
@ -5143,7 +5157,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/concat-map/0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
dev: true
|
||||
|
||||
/concordance/5.0.4:
|
||||
@ -5213,7 +5227,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/cookie-signature/1.0.6:
|
||||
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
|
||||
resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
|
||||
dev: true
|
||||
|
||||
/cookie/0.5.0:
|
||||
@ -5978,7 +5992,7 @@ packages:
|
||||
/dom-serializer/1.3.2:
|
||||
resolution: {integrity: sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==}
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domelementtype: 2.2.0
|
||||
domhandler: 4.3.0
|
||||
entities: 2.2.0
|
||||
dev: true
|
||||
@ -5991,6 +6005,10 @@ packages:
|
||||
entities: 4.4.0
|
||||
dev: true
|
||||
|
||||
/domelementtype/2.2.0:
|
||||
resolution: {integrity: sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==}
|
||||
dev: true
|
||||
|
||||
/domelementtype/2.3.0:
|
||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||
dev: true
|
||||
@ -5999,7 +6017,7 @@ packages:
|
||||
resolution: {integrity: sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==}
|
||||
engines: {node: '>= 4'}
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domelementtype: 2.2.0
|
||||
dev: true
|
||||
|
||||
/domhandler/5.0.3:
|
||||
@ -6017,7 +6035,7 @@ packages:
|
||||
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
|
||||
dependencies:
|
||||
dom-serializer: 1.3.2
|
||||
domelementtype: 2.3.0
|
||||
domelementtype: 2.2.0
|
||||
domhandler: 4.3.0
|
||||
dev: true
|
||||
|
||||
@ -6084,6 +6102,10 @@ packages:
|
||||
pify: 4.0.1
|
||||
dev: true
|
||||
|
||||
/duplexer/0.1.2:
|
||||
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
|
||||
dev: true
|
||||
|
||||
/duplexer3/0.1.4:
|
||||
resolution: {integrity: sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==}
|
||||
dev: true
|
||||
@ -6120,7 +6142,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/ee-first/1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
|
||||
dev: true
|
||||
|
||||
/ejs/3.1.6:
|
||||
@ -6510,6 +6532,18 @@ packages:
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/event-stream/3.3.4:
|
||||
resolution: {integrity: sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=}
|
||||
dependencies:
|
||||
duplexer: 0.1.2
|
||||
from: 0.1.7
|
||||
map-stream: 0.1.0
|
||||
pause-stream: 0.0.11
|
||||
split: 0.3.3
|
||||
stream-combiner: 0.0.4
|
||||
through: 2.3.8
|
||||
dev: true
|
||||
|
||||
/eventemitter2/6.4.7:
|
||||
resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==}
|
||||
dev: true
|
||||
@ -6877,7 +6911,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/file-size/0.0.5:
|
||||
resolution: {integrity: sha512-ZW056dw8Ta1RWHVOQue3LMZe+mSOnHkcM7AN9is8JoHSIHRiLD5szwPAHM3fM7P5SGJ1bkAmCv3PvUTGoluDqA==}
|
||||
resolution: {integrity: sha1-BX1Dw6Ptc12j+Q1gUqs4Dx5tXjs=}
|
||||
dev: true
|
||||
|
||||
/file-type/11.1.0:
|
||||
@ -7131,10 +7165,14 @@ packages:
|
||||
dev: true
|
||||
|
||||
/fresh/0.5.2:
|
||||
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
|
||||
resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/from/0.1.7:
|
||||
resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
|
||||
dev: true
|
||||
|
||||
/from2-array/0.0.4:
|
||||
resolution: {integrity: sha512-0G0cAp7sYLobH7ALsr835x98PU/YeVF7wlwxdWbCUaea7wsa7lJfKZUAo6p2YZGZ8F94luCuqHZS3JtFER6uPg==}
|
||||
dependencies:
|
||||
@ -7385,7 +7423,7 @@ packages:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 5.1.1
|
||||
minimatch: 5.1.2
|
||||
once: 1.4.0
|
||||
dev: true
|
||||
|
||||
@ -8531,6 +8569,16 @@ packages:
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/joi/17.6.0:
|
||||
resolution: {integrity: sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.2.1
|
||||
'@hapi/topo': 5.1.0
|
||||
'@sideway/address': 4.1.3
|
||||
'@sideway/formula': 3.0.0
|
||||
'@sideway/pinpoint': 2.0.0
|
||||
dev: true
|
||||
|
||||
/joi/17.7.0:
|
||||
resolution: {integrity: sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==}
|
||||
dependencies:
|
||||
@ -8576,7 +8624,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/json-buffer/3.0.0:
|
||||
resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==}
|
||||
resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=}
|
||||
dev: true
|
||||
|
||||
/json-buffer/3.0.1:
|
||||
@ -9165,6 +9213,10 @@ packages:
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/map-stream/0.1.0:
|
||||
resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
|
||||
dev: true
|
||||
|
||||
/map-visit/1.0.0:
|
||||
resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -9207,7 +9259,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/media-typer/0.3.0:
|
||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
@ -9233,7 +9285,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/merge-descriptors/1.0.1:
|
||||
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
|
||||
resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=}
|
||||
dev: true
|
||||
|
||||
/merge-options/3.0.4:
|
||||
@ -9375,8 +9427,8 @@ packages:
|
||||
brace-expansion: 1.1.11
|
||||
dev: true
|
||||
|
||||
/minimatch/5.1.1:
|
||||
resolution: {integrity: sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==}
|
||||
/minimatch/5.1.2:
|
||||
resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
@ -9487,7 +9539,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/mute-stream/0.0.7:
|
||||
resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==}
|
||||
resolution: {integrity: sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=}
|
||||
dev: true
|
||||
|
||||
/mute-stream/0.0.8:
|
||||