Use vitest
This commit is contained in:
parent
b46de85926
commit
cca5e31f56
15 changed files with 825 additions and 96 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,3 +9,4 @@ selenium-debug.log
|
||||||
config/local.json
|
config/local.json
|
||||||
src/assets/emoji.json
|
src/assets/emoji.json
|
||||||
logs/
|
logs/
|
||||||
|
__screenshots__/
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,15 @@ test:
|
||||||
APT_CACHE_DIR: apt-cache
|
APT_CACHE_DIR: apt-cache
|
||||||
script:
|
script:
|
||||||
- mkdir -pv $APT_CACHE_DIR && apt-get -qq update
|
- mkdir -pv $APT_CACHE_DIR && apt-get -qq update
|
||||||
- apt install firefox-esr -y --no-install-recommends
|
|
||||||
- firefox --version
|
|
||||||
- yarn
|
- yarn
|
||||||
- yarn unit
|
- yarn playwright install firefox
|
||||||
|
- yarn playwright install-deps
|
||||||
|
- yarn unit-ci
|
||||||
|
artifacts:
|
||||||
|
# When the test fails, upload screenshots for better context on why it fails
|
||||||
|
paths:
|
||||||
|
- test/**/__screenshots__
|
||||||
|
when: on_failure
|
||||||
|
|
||||||
build:
|
build:
|
||||||
stage: build
|
stage: build
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export default [
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
...globals.browser,
|
...globals.browser,
|
||||||
|
...globals.vitest,
|
||||||
...globals.mocha,
|
...globals.mocha,
|
||||||
...globals.chai,
|
...globals.chai,
|
||||||
...globals.commonjs,
|
...globals.commonjs,
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node build/update-emoji.js && vite dev",
|
"dev": "node build/update-emoji.js && vite dev",
|
||||||
"build": "node build/update-emoji.js && vite build",
|
"build": "node build/update-emoji.js && vite build",
|
||||||
"unit": "karma start test/unit/karma.conf.js --single-run",
|
"unit": "node build/update-emoji.js && vitest --run",
|
||||||
"unit:watch": "karma start test/unit/karma.conf.js --single-run=false",
|
"unit-ci": "node build/update-emoji.js && vitest --run --browser.headless",
|
||||||
|
"unit:watch": "node build/update-emoji.js && vitest",
|
||||||
"e2e": "node test/e2e/runner.js",
|
"e2e": "node test/e2e/runner.js",
|
||||||
"test": "yarn run unit && yarn run e2e",
|
"test": "yarn run unit && yarn run e2e",
|
||||||
"stylelint": "yarn exec stylelint '**/*.scss' '**/*.vue'",
|
"stylelint": "yarn exec stylelint '**/*.scss' '**/*.vue'",
|
||||||
|
|
@ -61,6 +62,8 @@
|
||||||
"@ungap/event-target": "0.2.4",
|
"@ungap/event-target": "0.2.4",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||||
|
"@vitest/browser": "^3.0.7",
|
||||||
|
"@vitest/ui": "^3.0.7",
|
||||||
"@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
|
"@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
|
||||||
"@vue/babel-plugin-jsx": "1.2.5",
|
"@vue/babel-plugin-jsx": "1.2.5",
|
||||||
"@vue/compiler-sfc": "3.5.13",
|
"@vue/compiler-sfc": "3.5.13",
|
||||||
|
|
@ -107,6 +110,7 @@
|
||||||
"nightwatch": "2.6.25",
|
"nightwatch": "2.6.25",
|
||||||
"opn": "5.5.0",
|
"opn": "5.5.0",
|
||||||
"ora": "0.4.1",
|
"ora": "0.4.1",
|
||||||
|
"playwright": "1.49.1",
|
||||||
"postcss": "8.5.2",
|
"postcss": "8.5.2",
|
||||||
"postcss-html": "^1.5.0",
|
"postcss-html": "^1.5.0",
|
||||||
"postcss-loader": "7.3.4",
|
"postcss-loader": "7.3.4",
|
||||||
|
|
@ -129,6 +133,7 @@
|
||||||
"stylelint-webpack-plugin": "^3.3.0",
|
"stylelint-webpack-plugin": "^3.3.0",
|
||||||
"vite": "^6.1.0",
|
"vite": "^6.1.0",
|
||||||
"vite-plugin-pwa": "^0.21.1",
|
"vite-plugin-pwa": "^0.21.1",
|
||||||
|
"vitest": "^3.0.7",
|
||||||
"vue-loader": "17.4.2",
|
"vue-loader": "17.4.2",
|
||||||
"vue-style-loader": "4.1.3",
|
"vue-style-loader": "4.1.3",
|
||||||
"webpack": "5.97.1",
|
"webpack": "5.97.1",
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,8 @@ const getLatestScrobble = (state, user) => {
|
||||||
|
|
||||||
state.scrobblesNextFetch[user.id] = Date.now() + 60 * 1000
|
state.scrobblesNextFetch[user.id] = Date.now() + 60 * 1000
|
||||||
}
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.warn('cannot fetch scrobbles', e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* global process */
|
||||||
function urlBase64ToUint8Array (base64String) {
|
function urlBase64ToUint8Array (base64String) {
|
||||||
const padding = '='.repeat((4 - base64String.length % 4) % 4)
|
const padding = '='.repeat((4 - base64String.length % 4) % 4)
|
||||||
const base64 = (base64String + padding)
|
const base64 = (base64String + padding)
|
||||||
|
|
|
||||||
21
test/fixtures/setup_test.js
vendored
21
test/fixtures/setup_test.js
vendored
|
|
@ -109,23 +109,18 @@ export const waitForEvent = (wrapper, event, {
|
||||||
timesEmitted = 1
|
timesEmitted = 1
|
||||||
} = {}) => {
|
} = {}) => {
|
||||||
const tick = 10
|
const tick = 10
|
||||||
const totalTries = timeout / tick
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return vi.waitFor(
|
||||||
let currentTries = 0
|
() => {
|
||||||
const wait = () => {
|
|
||||||
const e = wrapper.emitted(event)
|
const e = wrapper.emitted(event)
|
||||||
if (e && e.length >= timesEmitted) {
|
if (e && e.length >= timesEmitted) {
|
||||||
resolve()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (currentTries >= totalTries) {
|
throw new Error('event is not emitted')
|
||||||
reject(new Error('Event did not fire'))
|
},
|
||||||
return
|
{
|
||||||
}
|
timeout,
|
||||||
++currentTries
|
interval: tick
|
||||||
setTimeout(wait, tick)
|
|
||||||
}
|
}
|
||||||
wait()
|
)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { mount, flushPromises } from '@vue/test-utils'
|
import { mount, flushPromises } from '@vue/test-utils'
|
||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
import sinon from 'sinon'
|
|
||||||
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
|
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
|
||||||
import { mountOpts, waitForEvent, $t } from '../../../fixtures/setup_test'
|
import { mountOpts, waitForEvent, $t } from '../../../fixtures/setup_test'
|
||||||
|
|
||||||
|
|
@ -25,7 +24,7 @@ const saveManually = async (wrapper) => {
|
||||||
const waitSaveTime = 4000
|
const waitSaveTime = 4000
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
sinon.restore()
|
vi.useRealTimers()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Draft saving', () => {
|
describe('Draft saving', () => {
|
||||||
|
|
@ -43,12 +42,10 @@ describe('Draft saving', () => {
|
||||||
await saveManually(wrapper)
|
await saveManually(wrapper)
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
||||||
expect(wrapper.vm.$store.getters.draftsArray[0].status).to.equal('mew mew')
|
expect(wrapper.vm.$store.getters.draftsArray[0].status).to.equal('mew mew')
|
||||||
console.log('done')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should auto-save if it is enabled', async function () {
|
it('should auto-save if it is enabled', async function () {
|
||||||
this.timeout(5000)
|
vi.useFakeTimers()
|
||||||
const clock = sinon.useFakeTimers(Date.now())
|
|
||||||
const wrapper = mount(PostStatusForm, mountOpts())
|
const wrapper = mount(PostStatusForm, mountOpts())
|
||||||
await wrapper.vm.$store.dispatch('setOption', {
|
await wrapper.vm.$store.dispatch('setOption', {
|
||||||
name: 'autoSaveDraft',
|
name: 'autoSaveDraft',
|
||||||
|
|
@ -59,10 +56,9 @@ describe('Draft saving', () => {
|
||||||
await textarea.setValue('mew mew')
|
await textarea.setValue('mew mew')
|
||||||
|
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
|
||||||
await clock.tickAsync(waitSaveTime)
|
await vi.advanceTimersByTimeAsync(waitSaveTime)
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
||||||
expect(wrapper.vm.$store.getters.draftsArray[0].status).to.equal('mew mew')
|
expect(wrapper.vm.$store.getters.draftsArray[0].status).to.equal('mew mew')
|
||||||
clock.restore()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should auto-save when close if auto-save is on', async () => {
|
it('should auto-save when close if auto-save is on', async () => {
|
||||||
|
|
@ -81,7 +77,6 @@ describe('Draft saving', () => {
|
||||||
wrapper.vm.requestClose()
|
wrapper.vm.requestClose()
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
||||||
await waitForEvent(wrapper, 'can-close')
|
await waitForEvent(wrapper, 'can-close')
|
||||||
console.log('done')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should save when close if auto-save is off, and unsavedPostAction is save', async () => {
|
it('should save when close if auto-save is off, and unsavedPostAction is save', async () => {
|
||||||
|
|
@ -104,7 +99,6 @@ describe('Draft saving', () => {
|
||||||
wrapper.vm.requestClose()
|
wrapper.vm.requestClose()
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
||||||
await waitForEvent(wrapper, 'can-close')
|
await waitForEvent(wrapper, 'can-close')
|
||||||
console.log('done')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should discard when close if auto-save is off, and unsavedPostAction is discard', async () => {
|
it('should discard when close if auto-save is off, and unsavedPostAction is discard', async () => {
|
||||||
|
|
@ -127,40 +121,33 @@ describe('Draft saving', () => {
|
||||||
wrapper.vm.requestClose()
|
wrapper.vm.requestClose()
|
||||||
await waitForEvent(wrapper, 'can-close')
|
await waitForEvent(wrapper, 'can-close')
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
|
||||||
console.log('done')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should confirm when close if auto-save is off, and unsavedPostAction is confirm', async () => {
|
it('should confirm when close if auto-save is off, and unsavedPostAction is confirm', async () => {
|
||||||
try {
|
const wrapper = mount(PostStatusForm, mountOpts({
|
||||||
const wrapper = mount(PostStatusForm, mountOpts({
|
props: {
|
||||||
props: {
|
closeable: true
|
||||||
closeable: true
|
}
|
||||||
}
|
}))
|
||||||
}))
|
await wrapper.vm.$store.dispatch('setOption', {
|
||||||
await wrapper.vm.$store.dispatch('setOption', {
|
name: 'autoSaveDraft',
|
||||||
name: 'autoSaveDraft',
|
value: false
|
||||||
value: false
|
})
|
||||||
})
|
await wrapper.vm.$store.dispatch('setOption', {
|
||||||
await wrapper.vm.$store.dispatch('setOption', {
|
name: 'unsavedPostAction',
|
||||||
name: 'unsavedPostAction',
|
value: 'confirm'
|
||||||
value: 'confirm'
|
})
|
||||||
})
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
|
const textarea = wrapper.get('textarea')
|
||||||
const textarea = wrapper.get('textarea')
|
await textarea.setValue('mew mew')
|
||||||
await textarea.setValue('mew mew')
|
wrapper.vm.requestClose()
|
||||||
wrapper.vm.requestClose()
|
await nextTick()
|
||||||
await nextTick()
|
const saveButton = wrapper.findByText('button', $t('post_status.close_confirm_save_button'))
|
||||||
const saveButton = wrapper.findByText('button', $t('post_status.close_confirm_save_button'))
|
expect(saveButton).to.be.ok
|
||||||
expect(saveButton).to.be.ok
|
await saveButton.trigger('click')
|
||||||
await saveButton.trigger('click')
|
console.log('clicked')
|
||||||
console.log('clicked')
|
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
||||||
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
|
await flushPromises()
|
||||||
await flushPromises()
|
await waitForEvent(wrapper, 'can-close')
|
||||||
await waitForEvent(wrapper, 'can-close')
|
|
||||||
console.log('done')
|
|
||||||
} catch (e) {
|
|
||||||
console.log('error:', e)
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,13 @@ const generateInput = (value, padEmoji = true) => {
|
||||||
$t: (msg) => msg
|
$t: (msg) => msg
|
||||||
},
|
},
|
||||||
stubs: {
|
stubs: {
|
||||||
FAIcon: true
|
FAIcon: true,
|
||||||
|
Popover: {
|
||||||
|
template: `<div><slot trigger /></div>`,
|
||||||
|
methods: {
|
||||||
|
updateStyles () {}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'click-outside': vClickOutside
|
'click-outside': vClickOutside
|
||||||
|
|
@ -104,43 +110,37 @@ describe('EmojiInput', () => {
|
||||||
expect(inputEvents[inputEvents.length - 1][0]).to.eql('Eat some spam!:spam:')
|
expect(inputEvents[inputEvents.length - 1][0]).to.eql('Eat some spam!:spam:')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('correctly sets caret after insertion at beginning', (done) => {
|
it('correctly sets caret after insertion at beginning', async () => {
|
||||||
const initialString = '1234'
|
const initialString = '1234'
|
||||||
const wrapper = generateInput(initialString)
|
const wrapper = generateInput(initialString)
|
||||||
const input = wrapper.find('input')
|
const input = wrapper.find('input')
|
||||||
input.setValue(initialString)
|
input.setValue(initialString)
|
||||||
wrapper.setData({ caret: 0 })
|
wrapper.setData({ caret: 0 })
|
||||||
wrapper.vm.insert({ insertion: '1234', keepOpen: false })
|
wrapper.vm.insert({ insertion: '1234', keepOpen: false })
|
||||||
wrapper.vm.$nextTick(() => {
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.vm.caret).to.eql(5)
|
expect(wrapper.vm.caret).to.eql(5)
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('correctly sets caret after insertion at end', (done) => {
|
it('correctly sets caret after insertion at end', async () => {
|
||||||
const initialString = '1234'
|
const initialString = '1234'
|
||||||
const wrapper = generateInput(initialString)
|
const wrapper = generateInput(initialString)
|
||||||
const input = wrapper.find('input')
|
const input = wrapper.find('input')
|
||||||
input.setValue(initialString)
|
input.setValue(initialString)
|
||||||
wrapper.setData({ caret: initialString.length })
|
wrapper.setData({ caret: initialString.length })
|
||||||
wrapper.vm.insert({ insertion: '1234', keepOpen: false })
|
wrapper.vm.insert({ insertion: '1234', keepOpen: false })
|
||||||
wrapper.vm.$nextTick(() => {
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.vm.caret).to.eql(10)
|
expect(wrapper.vm.caret).to.eql(10)
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('correctly sets caret after insertion if padEmoji setting is set to false', (done) => {
|
it('correctly sets caret after insertion if padEmoji setting is set to false', async () => {
|
||||||
const initialString = '1234'
|
const initialString = '1234'
|
||||||
const wrapper = generateInput(initialString, false)
|
const wrapper = generateInput(initialString, false)
|
||||||
const input = wrapper.find('input')
|
const input = wrapper.find('input')
|
||||||
input.setValue(initialString)
|
input.setValue(initialString)
|
||||||
wrapper.setData({ caret: initialString.length })
|
wrapper.setData({ caret: initialString.length })
|
||||||
wrapper.vm.insert({ insertion: '1234', keepOpen: false })
|
wrapper.vm.insert({ insertion: '1234', keepOpen: false })
|
||||||
wrapper.vm.$nextTick(() => {
|
await wrapper.vm.$nextTick()
|
||||||
expect(wrapper.vm.caret).to.eql(8)
|
expect(wrapper.vm.caret).to.eql(8)
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import * as DateUtils from 'src/services/date_utils/date_utils.js'
|
import * as DateUtils from 'src/services/date_utils/date_utils.js'
|
||||||
|
|
||||||
|
beforeEach(() => { vi.useFakeTimers() })
|
||||||
|
afterEach(() => { vi.useRealTimers() })
|
||||||
|
|
||||||
describe('DateUtils', () => {
|
describe('DateUtils', () => {
|
||||||
describe('relativeTime', () => {
|
describe('relativeTime', () => {
|
||||||
it('returns now with low enough amount of seconds', () => {
|
it('returns now with low enough amount of seconds', () => {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
||||||
import { serialize } from 'src/services/theme_data/iss_serializer.js'
|
import { serialize } from 'src/services/theme_data/iss_serializer.js'
|
||||||
const componentsContext = require.context('src', true, /\.style.js(on)?$/)
|
const componentsContext = import.meta.glob(
|
||||||
|
['/src/**/*.style.js', '/src/**/*.style.json'],
|
||||||
|
{ eager: true }
|
||||||
|
)
|
||||||
|
|
||||||
describe('ISS (de)serialization', () => {
|
describe('ISS (de)serialization', () => {
|
||||||
componentsContext.keys().forEach(key => {
|
Object.keys(componentsContext).forEach(key => {
|
||||||
const component = componentsContext(key).default
|
const component = componentsContext[key].default
|
||||||
|
|
||||||
it(`(De)serialization of component ${component.name} works`, () => {
|
it(`(De)serialization of component ${component.name} works`, () => {
|
||||||
const normalized = component.defaultRules.map(x => ({ component: component.name, ...x }))
|
const normalized = component.defaultRules.map(x => ({ component: component.name, ...x }))
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ const checkColors = (output) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Theme Data utility functions', () => {
|
describe('Theme Data utility functions', () => {
|
||||||
const context = require.context('static/themes/', false, /\.json$/)
|
const context = import.meta.glob('/public/static/themes/*.json', { import: 'default', eager: true })
|
||||||
context.keys().forEach((key) => {
|
Object.keys(context).forEach((key) => {
|
||||||
it(`Should render all colors for ${key} properly`, () => {
|
it(`Should render all colors for ${key} properly`, () => {
|
||||||
const { theme, source } = context(key)
|
const { theme, source } = context[key]
|
||||||
const data = source || theme
|
const data = source || theme
|
||||||
const colors = getColors(data.colors, data.opacity, 1)
|
const colors = getColors(data.colors, data.opacity, 1)
|
||||||
checkColors(colors)
|
checkColors(colors)
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,6 @@ describe('Theme Data 3', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('init', function () {
|
describe('init', function () {
|
||||||
this.timeout(5000)
|
|
||||||
|
|
||||||
it('Test initialization without anything', () => {
|
it('Test initialization without anything', () => {
|
||||||
const out = init({ inputRuleset: [], ultimateBackgroundColor: '#DEADAF' })
|
const out = init({ inputRuleset: [], ultimateBackgroundColor: '#DEADAF' })
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ const getLocalDevSettings = async () => {
|
||||||
|
|
||||||
const projectRoot = dirname(fileURLToPath(import.meta.url))
|
const projectRoot = dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
export default defineConfig(async ({ command }) => {
|
export default defineConfig(async ({ mode, command }) => {
|
||||||
const settings = await getLocalDevSettings()
|
const settings = await getLocalDevSettings()
|
||||||
const target = settings.target || 'http://localhost:4000/'
|
const target = settings.target || 'http://localhost:4000/'
|
||||||
const proxy = {
|
const proxy = {
|
||||||
|
|
@ -87,7 +87,8 @@ export default defineConfig(async ({ command }) => {
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
src: '/src',
|
src: '/src',
|
||||||
components: '/src/components'
|
components: '/src/components',
|
||||||
|
...(mode === 'test' ? { vue: 'vue/dist/vue.esm-bundler.js' } : {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
define: {
|
define: {
|
||||||
|
|
@ -131,11 +132,21 @@ export default defineConfig(async ({ command }) => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
proxy,
|
...(mode === 'test' ? {} : { proxy }),
|
||||||
port: Number(process.env.PORT) || 8080
|
port: Number(process.env.PORT) || 8080
|
||||||
},
|
},
|
||||||
preview: {
|
preview: {
|
||||||
proxy
|
proxy
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
browser: {
|
||||||
|
enabled: true,
|
||||||
|
provider: 'playwright',
|
||||||
|
instances: [
|
||||||
|
{ browser: 'firefox' }
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue