Merge branch 'webapp_unit_testing' into 'v3'
ui_migration feature(unit-testing) Add isolated component testing, coverage and configurations. Closes #733 See merge request openflexure/openflexure-microscope-server!588
This commit is contained in:
commit
9fcd52ce76
13 changed files with 8237 additions and 306 deletions
|
|
@ -16,8 +16,8 @@ skip = node_modules,
|
||||||
./src/openflexure_microscope_server/static,
|
./src/openflexure_microscope_server/static,
|
||||||
.venv,
|
.venv,
|
||||||
*.egg-info,
|
*.egg-info,
|
||||||
report.xml
|
src/tests/unit,
|
||||||
|
./webapp/coverage/*,
|
||||||
|
|
||||||
regex = [a-zA-Z0-9\-'’]+
|
regex = [a-zA-Z0-9\-'’]+
|
||||||
ignore-words-list = fom
|
ignore-words-list = fom, afterAll
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[codespell]
|
[codespell]
|
||||||
# A separate RC file for detecting camelCase, PascalCase, and kebab-case errors
|
# A separate RC file for detecting camelCase, PascalCase, and kebab-case errors
|
||||||
# A little more prone to false positives than our standard regex, also fails to detect
|
# A little more prone to false positives than our standard regex, also fails to detect
|
||||||
# hyphenated words in the dictonary.
|
# hyphenated words in the dictionary.
|
||||||
|
|
||||||
# Same as the main RC-file except it also excludes CHANGELOG as this is well covered
|
# Same as the main RC-file except it also excludes CHANGELOG as this is well covered
|
||||||
# by the normal RC file, and we get false positives from git hashes.
|
# by the normal RC file, and we get false positives from git hashes.
|
||||||
|
|
@ -19,7 +19,9 @@ skip = node_modules,
|
||||||
.venv,
|
.venv,
|
||||||
*.egg-info,
|
*.egg-info,
|
||||||
report.xml,
|
report.xml,
|
||||||
CHANGELOG.md
|
CHANGELOG.md,
|
||||||
|
./webapp/src/tests/fixtures/*,
|
||||||
|
./webapp/coverage/*,
|
||||||
|
|
||||||
# Ignores split by |
|
# Ignores split by |
|
||||||
# Ignore hexadecimal numbers preceded by #
|
# Ignore hexadecimal numbers preceded by #
|
||||||
|
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -94,7 +94,7 @@ openflexure_settings/
|
||||||
# Files created by test utilities
|
# Files created by test utilities
|
||||||
/tests/unit_tests/utilities/*.pstats
|
/tests/unit_tests/utilities/*.pstats
|
||||||
/tests/unit_tests/utilities/*.png
|
/tests/unit_tests/utilities/*.png
|
||||||
|
coverage/
|
||||||
# Files created by simulator
|
# Files created by simulator
|
||||||
openflexure/
|
openflexure/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,14 +150,29 @@ combined-tests:
|
||||||
coverage_format: cobertura
|
coverage_format: cobertura
|
||||||
path: coverage.xml
|
path: coverage.xml
|
||||||
|
|
||||||
# JavaScript linting with ESLint (via Vue CLI)
|
# JavaScript linting and testing
|
||||||
|
# ESLint, StyleLint and ViTest
|
||||||
# Only runs when a .js or .vue file is edited
|
# Only runs when a .js or .vue file is edited
|
||||||
eslint:
|
javascript-lint-and-test:
|
||||||
stage: analysis
|
stage: testing
|
||||||
extends: .javascript_webapp
|
extends: .javascript_webapp
|
||||||
script:
|
script:
|
||||||
- npm run lint
|
- npm run lint
|
||||||
- npm run lint:style
|
- npm run lint:style
|
||||||
|
# The test runs only if a test spec file has changed
|
||||||
|
- npm run test:unit
|
||||||
|
artifacts:
|
||||||
|
name: "vitest-coverage-$CI_COMMIT_REF_SLUG"
|
||||||
|
when: always
|
||||||
|
expire_in: 1 week
|
||||||
|
paths:
|
||||||
|
- webapp/coverage/
|
||||||
|
reports:
|
||||||
|
# Tells GitLab where to find the Cobertura file for MR integration
|
||||||
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: webapp/coverage/cobertura-coverage.xml
|
||||||
|
|
||||||
|
|
||||||
# Build JS app
|
# Build JS app
|
||||||
build:
|
build:
|
||||||
|
|
|
||||||
1
webapp/.prettierignore
Normal file
1
webapp/.prettierignore
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
coverage/
|
||||||
|
|
@ -9,7 +9,13 @@ const isDev = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
ignores: ["dist/**/*", "lib/**/*", "**/*.min.js", "tools/architecture_dashboard/**/*"],
|
ignores: [
|
||||||
|
"dist/**/*",
|
||||||
|
"lib/**/*",
|
||||||
|
"**/*.min.js",
|
||||||
|
"tools/architecture_dashboard/**/*",
|
||||||
|
"coverage/",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
js.configs.recommended,
|
js.configs.recommended,
|
||||||
|
|
@ -17,7 +23,7 @@ export default [
|
||||||
...vue.configs["flat/recommended"],
|
...vue.configs["flat/recommended"],
|
||||||
|
|
||||||
{
|
{
|
||||||
files: ["**/*.vue", "**/*.js", "**/*.jsx", "**/*.cjs", "**/*.mjs"],
|
files: ["**/*.vue", "**/*.js", "**/*.jsx", "**/*.cjs", "**/*.mjs", "**/*.spec.js"],
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
ecmaVersion: 2021,
|
ecmaVersion: 2021,
|
||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
|
|
@ -73,5 +79,22 @@ export default [
|
||||||
"pinia/require-setup-store-properties-export": "warn",
|
"pinia/require-setup-store-properties-export": "warn",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: ["src/tests/unit/**/*.spec.js"],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
describe: "readonly",
|
||||||
|
it: "readonly",
|
||||||
|
expect: "readonly",
|
||||||
|
vi: "readonly",
|
||||||
|
beforeEach: "readonly",
|
||||||
|
afterEach: "readonly",
|
||||||
|
mockLogData: "readonly", // Prevents unused global mock variable warnings
|
||||||
|
afterAll: "readonly",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
prettierConfig,
|
prettierConfig,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
2564
webapp/package-lock.json
generated
2564
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -15,7 +15,8 @@
|
||||||
"lint": "eslint . --ignore-pattern .gitignore --max-warnings=0",
|
"lint": "eslint . --ignore-pattern .gitignore --max-warnings=0",
|
||||||
"lint:fix": "eslint . --fix --ignore-pattern .gitignore",
|
"lint:fix": "eslint . --fix --ignore-pattern .gitignore",
|
||||||
"lint:style": "stylelint \"src/**/*.{vue,less,css}\" --max-warnings=0",
|
"lint:style": "stylelint \"src/**/*.{vue,less,css}\" --max-warnings=0",
|
||||||
"lint:style:fix": "stylelint \"src/**/*.{vue,less,css}\" --fix"
|
"lint:style:fix": "stylelint \"src/**/*.{vue,less,css}\" --fix",
|
||||||
|
"test:unit": "NODE_OPTIONS=--expose-gc vitest run src/tests/unit/ --no-cache --mode test --detectAsyncLeaks --coverage --isolate=true --pool=forks --silent --logHeapUsage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vueuse/core": "^14.1.0",
|
"@vueuse/core": "^14.1.0",
|
||||||
|
|
@ -31,15 +32,20 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/eslint-parser": "^7.28.5",
|
"@babel/eslint-parser": "^7.28.5",
|
||||||
|
"@pinia/testing": "^1.0.3",
|
||||||
"@vitejs/plugin-vue": "^6.0.6",
|
"@vitejs/plugin-vue": "^6.0.6",
|
||||||
|
"@vitest/coverage-v8": "^4.1.6",
|
||||||
"@vue/eslint-config-prettier": "9.0.0",
|
"@vue/eslint-config-prettier": "9.0.0",
|
||||||
|
"@vue/test-utils": "^2.4.10",
|
||||||
"autoprefixer": "^10.4.24",
|
"autoprefixer": "^10.4.24",
|
||||||
"core-js": "^3.46.0",
|
"core-js": "^3.46.0",
|
||||||
"cross-env": "^10.1.0",
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "^9.39.2",
|
"eslint": "^9.39.2",
|
||||||
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-pinia": "^0.4.2",
|
"eslint-plugin-pinia": "^0.4.2",
|
||||||
"eslint-plugin-prettier": "^5.1.0",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"eslint-plugin-vue": "^9.20.0",
|
"eslint-plugin-vue": "^9.20.0",
|
||||||
|
"happy-dom": "^20.9.0",
|
||||||
"less": "^4.5.1",
|
"less": "^4.5.1",
|
||||||
"material-symbols": "^0.39.1",
|
"material-symbols": "^0.39.1",
|
||||||
"postcss-html": "^1.8.1",
|
"postcss-html": "^1.8.1",
|
||||||
|
|
@ -49,7 +55,8 @@
|
||||||
"stylelint-config-standard": "^40.0.0",
|
"stylelint-config-standard": "^40.0.0",
|
||||||
"stylelint-config-standard-less": "^4.1.0",
|
"stylelint-config-standard-less": "^4.1.0",
|
||||||
"typescript-eslint": "^8.59.0",
|
"typescript-eslint": "^8.59.0",
|
||||||
"vite": "^7.3.1"
|
"vite": "^7.3.1",
|
||||||
|
"vitest": "^4.1.6"
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"plugins": {
|
"plugins": {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-default uk-width-1-1"
|
class="uk-button uk-button-default uk-width-1-1"
|
||||||
type="button"
|
type="button"
|
||||||
|
data-test-id="update-btn"
|
||||||
@click="updateLogs()"
|
@click="updateLogs()"
|
||||||
>
|
>
|
||||||
Refresh Logs
|
Refresh Logs
|
||||||
|
|
@ -27,6 +28,7 @@
|
||||||
:url="logFileURI"
|
:url="logFileURI"
|
||||||
button-label="Download Log File"
|
button-label="Download Log File"
|
||||||
:button-primary="false"
|
:button-primary="false"
|
||||||
|
data-test-id="download-btn"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -225,7 +227,7 @@ export default {
|
||||||
},
|
},
|
||||||
escapeText: function (unsafeText) {
|
escapeText: function (unsafeText) {
|
||||||
let div = document.createElement("div");
|
let div = document.createElement("div");
|
||||||
div.innerText = unsafeText;
|
div.textContent = unsafeText;
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
5618
webapp/src/tests/fixtures/realLog.txt
vendored
Normal file
5618
webapp/src/tests/fixtures/realLog.txt
vendored
Normal file
File diff suppressed because it is too large
Load diff
163
webapp/src/tests/unit/LoggingContent.spec.js
Normal file
163
webapp/src/tests/unit/LoggingContent.spec.js
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
import { shallowMount, flushPromises } from "@vue/test-utils";
|
||||||
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||||
|
import { createTestingPinia } from "@pinia/testing";
|
||||||
|
import { setActivePinia } from "pinia";
|
||||||
|
import axios from "axios";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import LoggingContent from "../../components/tabContentComponents/loggingContent.vue";
|
||||||
|
|
||||||
|
// Mock Axios
|
||||||
|
vi.mock("axios", () => {
|
||||||
|
return {
|
||||||
|
default: {
|
||||||
|
get: vi.fn(),
|
||||||
|
post: vi.fn(),
|
||||||
|
put: vi.fn(),
|
||||||
|
delete: vi.fn(),
|
||||||
|
patch: vi.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mock VueUse to prevent IntersectionObserver crashes in JSDOM
|
||||||
|
// This will be removed once vue-route is implemented
|
||||||
|
vi.mock("@vueuse/core", () => ({
|
||||||
|
useIntersectionObserver: vi.fn(() => ({
|
||||||
|
stop: vi.fn(),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Test Description
|
||||||
|
describe("Test LoggingContent.vue", () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
// Define path to a real log file and read it
|
||||||
|
const logFilePath = path.resolve(__dirname, "../fixtures/realLog.txt");
|
||||||
|
const mockLogData = fs.readFileSync(logFilePath, "utf-8");
|
||||||
|
|
||||||
|
// Things to do before each test
|
||||||
|
beforeEach(async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
// Reset mocks before each test
|
||||||
|
vi.resetAllMocks();
|
||||||
|
|
||||||
|
// Set axios to return our fake logs
|
||||||
|
axios.get.mockResolvedValue({ data: mockLogData });
|
||||||
|
|
||||||
|
// Mount the component with a fake Pinia store
|
||||||
|
wrapper = shallowMount(LoggingContent, {
|
||||||
|
attachTo: document.body,
|
||||||
|
global: {
|
||||||
|
plugins: [
|
||||||
|
createTestingPinia({
|
||||||
|
createSpy: vi.fn,
|
||||||
|
initialState: {
|
||||||
|
settings: { origin: "http://microscope.local:5000/api/v3" },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
// Simplify child components
|
||||||
|
stubs: {
|
||||||
|
PaginateLinks: true,
|
||||||
|
EndpointButton: true,
|
||||||
|
transition: true,
|
||||||
|
teleport: true,
|
||||||
|
settings: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// flush so we avoid leaving uncompleted processes running on background
|
||||||
|
await flushPromises();
|
||||||
|
vi.advanceTimersByTime(1000);
|
||||||
|
vi.useRealTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tear down wrapper, unmount testing component
|
||||||
|
afterEach(() => {
|
||||||
|
if (wrapper) {
|
||||||
|
wrapper.unmount(); // Clean up virtual DOM and memory bindings
|
||||||
|
}
|
||||||
|
setActivePinia(undefined);
|
||||||
|
document.body.innerHTML = "";
|
||||||
|
|
||||||
|
if (global.gc) {
|
||||||
|
global.gc(); // Forces V8 engine to immediately run Garbage Collection
|
||||||
|
}
|
||||||
|
vi.clearAllTimers();
|
||||||
|
vi.useRealTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 1: Render check, if things do exist in the page as intended
|
||||||
|
it("renders the component correctly", async () => {
|
||||||
|
// Check if component is been loaded and it is rendered
|
||||||
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
// Check if navbar exists
|
||||||
|
expect(wrapper.find(".logging-navbar").exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 2: Check log parsing to see if specific INFO exists
|
||||||
|
it("fetches logs and parses them correctly when updateLogs is called", async () => {
|
||||||
|
// Trigger the method
|
||||||
|
await wrapper.vm.updateLogs();
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// Verify Axios was called with the correct URI from the Pinia store
|
||||||
|
expect(axios.get).toHaveBeenCalledWith("http://microscope.local:5000/api/v3/log/");
|
||||||
|
|
||||||
|
// Verify the logs have correct file length
|
||||||
|
// Helps validate formatting, etc
|
||||||
|
expect(wrapper.vm.logs.length).toBe(5491);
|
||||||
|
|
||||||
|
// Check the most recent log
|
||||||
|
expect(wrapper.vm.logs[0].level).toBe("INFO");
|
||||||
|
|
||||||
|
// Check if the multi-line file has real first connection information
|
||||||
|
expect(wrapper.vm.logs[0].message).toContain("uvicorn");
|
||||||
|
expect(wrapper.vm.logs[0].summary).toContain("http://0.0.0.0:5000");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 3: Filter logging file information
|
||||||
|
it("filters logs based on the selected level", async () => {
|
||||||
|
await wrapper.vm.updateLogs();
|
||||||
|
|
||||||
|
// Set filter to WARNING wait and compare expected length
|
||||||
|
wrapper.vm.filterLevel = "WARNING";
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
expect(wrapper.vm.filteredItems.length).toBe(1449);
|
||||||
|
expect(wrapper.vm.filteredItems[0].level).toBe("WARNING");
|
||||||
|
|
||||||
|
// Set filter to INFO wait and compare expected length
|
||||||
|
wrapper.vm.filterLevel = "INFO";
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
expect(wrapper.vm.filteredItems.length).toBe(5491);
|
||||||
|
expect(wrapper.vm.filteredItems[0].level).toBe("INFO");
|
||||||
|
|
||||||
|
// Set filter to ERROR wait and compare expected length
|
||||||
|
wrapper.vm.filterLevel = "ERROR";
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
expect(wrapper.vm.filteredItems.length).toBe(7);
|
||||||
|
expect(wrapper.vm.filteredItems[0].level).toBe("ERROR");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 4: Click buttons
|
||||||
|
// This required the component file to be modified by adding data-test-id flags.
|
||||||
|
// Flags are needed as classes and text content may change by translation or style change.
|
||||||
|
it("click buttons", async () => {
|
||||||
|
// Click download button
|
||||||
|
const downloadButton = wrapper.find('[data-test-id="download-btn"]');
|
||||||
|
expect(downloadButton.exists()).toBe(true);
|
||||||
|
await downloadButton.trigger("click");
|
||||||
|
|
||||||
|
// Click update button
|
||||||
|
const updateButton = wrapper.find('[data-test-id="update-btn"]');
|
||||||
|
expect(updateButton.exists()).toBe(true);
|
||||||
|
await updateButton.trigger("click");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevents Vitest "Async Leak" errors by giving Vue's internal
|
||||||
|
// DevTools timer a few milliseconds to finish before teardown.
|
||||||
|
afterAll(async () => {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 15));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -10,6 +10,7 @@ import vue from "@vitejs/plugin-vue";
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({ command, mode }) => {
|
export default defineConfig(({ command, mode }) => {
|
||||||
const env = loadEnv(mode, process.cwd(), "");
|
const env = loadEnv(mode, process.cwd(), "");
|
||||||
|
const isProduction = mode === "production";
|
||||||
|
|
||||||
var target;
|
var target;
|
||||||
|
|
||||||
|
|
@ -27,7 +28,29 @@ export default defineConfig(({ command, mode }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plugins: [vue()],
|
plugins: [
|
||||||
|
vue({
|
||||||
|
// Strip "data-test-id" attributes (used by Vitest) from the production build.
|
||||||
|
// This enforces separation of concerns and prevents developers from relying on
|
||||||
|
// test IDs for styling or core application logic.
|
||||||
|
template: {
|
||||||
|
compilerOptions: {
|
||||||
|
// Only apply this AST transformation during production builds
|
||||||
|
nodeTransforms: isProduction
|
||||||
|
? [
|
||||||
|
(node) => {
|
||||||
|
// Check if the current AST node is an HTML element
|
||||||
|
if (node.type === 1) {
|
||||||
|
// Filter out any property named "data-test-id"
|
||||||
|
node.props = node.props.filter((prop) => prop.name !== "data-test-id");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
// Output directory for production builds
|
// Output directory for production builds
|
||||||
|
|
|
||||||
93
webapp/vitest.config.js
Normal file
93
webapp/vitest.config.js
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
// OFM unit testing configuration file.
|
||||||
|
|
||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
import vue from "@vitejs/plugin-vue";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue({
|
||||||
|
template: {
|
||||||
|
compilerOptions: {
|
||||||
|
// This configuration is set to avoid vue warns about missing refs.
|
||||||
|
// Forces the test to render all html as dynamic, and avoid hoisting.
|
||||||
|
hoistStatic: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
test: {
|
||||||
|
// CSS is disabled for now, the test loads the DOM without styles.
|
||||||
|
css: false,
|
||||||
|
pool: "forks",
|
||||||
|
// Runs in a single thread to avoid CI pipeline crashing.
|
||||||
|
singleThread: true,
|
||||||
|
|
||||||
|
// Switch loading vue features
|
||||||
|
define: {
|
||||||
|
// Feature not needed for current testing
|
||||||
|
__VUE_PROD_DEVTOOLS__: false,
|
||||||
|
// We use and enforce VUE optionsAPI
|
||||||
|
__VUE_OPTIONS_API__: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Coverage analysis tools setup
|
||||||
|
coverage: {
|
||||||
|
enabled: true,
|
||||||
|
provider: "v8",
|
||||||
|
clean: true,
|
||||||
|
cleanOnStart: true,
|
||||||
|
// text gives output on STOUT and html creates an artifact
|
||||||
|
reporter: ["text", "html", "cobertura"],
|
||||||
|
all: true,
|
||||||
|
// Files to include or exclude in coverage
|
||||||
|
include: ["src/**/*.vue", "src/**/*.js"],
|
||||||
|
exclude: [],
|
||||||
|
// These thresholds raise ERROR if the coverage it's under the provided percentages.
|
||||||
|
// As the coverage is low we set the limit low, as testing spec files increase,
|
||||||
|
// these thresholds need to increase accordingly.
|
||||||
|
thresholds: {
|
||||||
|
lines: 4,
|
||||||
|
statements: 3,
|
||||||
|
functions: 3,
|
||||||
|
branches: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Add largest component dependencies here
|
||||||
|
// This chunks together the largest libraries to avoid recurrent parsing and loading
|
||||||
|
// and increasing memory overhead. Good for CI.
|
||||||
|
deps: {
|
||||||
|
optimizer: {
|
||||||
|
web: {
|
||||||
|
enabled: true,
|
||||||
|
include: ["uikit", "openseadragon", "material-design-icons"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// This is the package responsible for simulating the DOM the other option is JSDOM
|
||||||
|
// Happy-dom is the most efficient in memory and its future proof for later node versions.
|
||||||
|
environment: "happy-dom",
|
||||||
|
|
||||||
|
globals: true, // Probably good for Mixins
|
||||||
|
|
||||||
|
// This tells vitest to not skip loading these packages,
|
||||||
|
// and load them from the local node_modules at run time.
|
||||||
|
server: {
|
||||||
|
deps: {
|
||||||
|
inline: ["vue", "@vue/test-utils", "pinia", "@pinia/testing"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// This is to enforce the use of specific packages versions on the testing.
|
||||||
|
// This one for example says to load explicitly the vue package at the project's level,
|
||||||
|
// and not the global vue if existing.
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
vue: path.resolve(__dirname, "./node_modules/vue"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue