diff --git a/docs/config/index.md b/docs/config/index.md index 7151d1c3b311..eac8c6c1004d 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -1126,6 +1126,8 @@ Clean coverage report on watch rerun Directory to write coverage report to. +To preview the coverage report in the output of [HTML reporter](/guide/reporters.html#html-reporter), this option must be set as a sub-directory of the html report directory (for example `./html/coverage`). + #### coverage.reporter - **Type:** `string | string[] | [string, {}][]` diff --git a/packages/ui/client/composables/navigation.ts b/packages/ui/client/composables/navigation.ts index d4229407efb9..1054c1790abc 100644 --- a/packages/ui/client/composables/navigation.ts +++ b/packages/ui/client/composables/navigation.ts @@ -7,19 +7,16 @@ export const dashboardVisible = ref(true) export const coverageVisible = ref(false) export const disableCoverage = ref(true) export const coverage = computed(() => config.value?.coverage) -export const coverageConfigured = computed(() => { - if (!config.value?.api?.port) - return false - - return coverage.value?.enabled -}) +export const coverageConfigured = computed(() => coverage.value?.enabled) export const coverageEnabled = computed(() => { return coverageConfigured.value && coverage.value.reporter.map(([reporterName]) => reporterName).includes('html') }) +// TODO +// For html report preview, "coverage.reportsDirectory" must be explicitly set as a subdirectory of html report. +// Handling other cases seems difficult, so this limitation is mentioned in the documentation for now. export const coverageUrl = computed(() => { if (coverageEnabled.value) { - const url = `${window.location.protocol}//${window.location.hostname}:${config.value!.api!.port!}` const idx = coverage.value!.reportsDirectory.lastIndexOf('/') const htmlReporter = coverage.value!.reporter.find((reporter) => { if (reporter[0] !== 'html') @@ -28,8 +25,8 @@ export const coverageUrl = computed(() => { return reporter }) return htmlReporter && 'subdir' in htmlReporter[1] - ? `${url}/${coverage.value!.reportsDirectory.slice(idx + 1)}/${htmlReporter[1].subdir}/index.html` - : `${url}/${coverage.value!.reportsDirectory.slice(idx + 1)}/index.html` + ? `/${coverage.value!.reportsDirectory.slice(idx + 1)}/${htmlReporter[1].subdir}/index.html` + : `/${coverage.value!.reportsDirectory.slice(idx + 1)}/index.html` } return undefined diff --git a/test/ui/fixtures/coverage.test.ts b/test/ui/fixtures/coverage.test.ts new file mode 100644 index 000000000000..802168139d65 --- /dev/null +++ b/test/ui/fixtures/coverage.test.ts @@ -0,0 +1,6 @@ +import { expect, it } from 'vitest' +import { multiply } from './coverage' + +it(multiply, () => { + expect(multiply(2, 3)).toEqual(6) +}) diff --git a/test/ui/fixtures/coverage.ts b/test/ui/fixtures/coverage.ts new file mode 100644 index 000000000000..1f2e9649ed2f --- /dev/null +++ b/test/ui/fixtures/coverage.ts @@ -0,0 +1,3 @@ +export function multiply(n: number, m: number) { + return n * m; +} diff --git a/test/ui/test/html-report.spec.ts b/test/ui/test/html-report.spec.ts index 062dd1f98796..8c2e094d6525 100644 --- a/test/ui/test/html-report.spec.ts +++ b/test/ui/test/html-report.spec.ts @@ -11,7 +11,7 @@ test.describe('html report', () => { test.beforeAll(async () => { // generate vitest html report - await startVitest('test', [], { run: true, reporters: 'html' }) + await startVitest('test', [], { run: true, reporters: 'html', coverage: { enabled: true, reportsDirectory: 'html/coverage' } }) // run vite preview server previewServer = await preview({ build: { outDir: 'html' }, preview: { port, strictPort: true } }) @@ -32,7 +32,7 @@ test.describe('html report', () => { await page.goto(pageUrl) // dashbaord - await expect(page.locator('[aria-labelledby=tests]')).toContainText('4 Pass 0 Fail 4 Total') + await expect(page.locator('[aria-labelledby=tests]')).toContainText('5 Pass 0 Fail 5 Total') // report await page.getByText('sample.test.ts').click() @@ -49,4 +49,10 @@ test.describe('html report', () => { expect(pageErrors).toEqual([]) }) + + test('coverage', async ({ page }) => { + await page.goto(pageUrl) + await page.getByLabel('Show coverage').click() + await page.frameLocator('#vitest-ui-coverage').getByRole('heading', { name: 'All files' }).click() + }) }) diff --git a/test/ui/test/ui.spec.ts b/test/ui/test/ui.spec.ts index 69a3bdb73bb1..440009312135 100644 --- a/test/ui/test/ui.spec.ts +++ b/test/ui/test/ui.spec.ts @@ -8,7 +8,7 @@ test.describe('ui', () => { let vitest: Vitest | undefined test.beforeAll(async () => { - vitest = await startVitest('test', [], { watch: true, ui: true, open: false, api: { port } }) + vitest = await startVitest('test', [], { watch: true, ui: true, open: false, api: { port }, coverage: { enabled: true } }) expect(vitest).toBeDefined() }) @@ -23,7 +23,7 @@ test.describe('ui', () => { await page.goto(pageUrl) // dashbaord - await expect(page.locator('[aria-labelledby=tests]')).toContainText('4 Pass 0 Fail 4 Total') + await expect(page.locator('[aria-labelledby=tests]')).toContainText('5 Pass 0 Fail 5 Total') // report await page.getByText('sample.test.ts').click() @@ -41,6 +41,12 @@ test.describe('ui', () => { expect(pageErrors).toEqual([]) }) + test('coverage', async ({ page }) => { + await page.goto(pageUrl) + await page.getByLabel('Show coverage').click() + await page.frameLocator('#vitest-ui-coverage').getByRole('heading', { name: 'All files' }).click() + }) + test('console', async ({ page }) => { await page.goto(pageUrl) await page.getByText('fixtures/console.test.ts').click()