Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/vitest-dev/vscode. VS Code extension for Vitest vitest.dev/vscode
testing vitest vscode
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120import { expect } from '@playwright/test'import type { TesterTestItem } from './tester'
type TestState = 'passed' | 'failed' | 'skipped' | 'waiting'interface TestsTree { [test: string]: TestState | TestsTree}
function getTitleFromState(state: TestState) { switch (state) { case 'passed': return '(Passed)' case 'failed': return '(Failed)' case 'skipped': return '(Skipped)' case 'waiting': return '(Not yet run)' }}
expect.extend({ async toHaveState(item: TesterTestItem, state: TestState) { const title = await item.locator.getAttribute('aria-label') const pass = !!(title && title.includes(getTitleFromState(state)))
return { pass, message: () => `${this.utils.matcherHint('toHaveState', title, state, { isNot: this.isNot })}\n\n` + `Locator: ${item.locator}\n` + `Expected: ${this.isNot ? 'not ' : ''}to have state: ${this.utils.printExpected(state)}\n` + `Received: ${this.utils.printReceived(title)}\n`, name: 'toHaveState', } }, async toHaveError(item: TesterTestItem, error: string) { const page = item.page const depth = Number(await item.locator.getAttribute('aria-level'))
await expect(page.locator(`[aria-label*="${error}"][aria-level="${depth + 1}"]`)).toBeVisible()
return { pass: true, message: () => '', } }, async toHaveTests(item: TesterTestItem, tests: TestsTree) { const page = item.page // the "Resolving Vitest..." item stays in the tree until every config is // resolved, but roots are added as soon as their own config is resolved. // Wait for it to go away, otherwise every row index shifts by one later. await expect(page.locator('[aria-label*="Resolving Vitest..."]')).not.toBeAttached({ timeout: 10_000, }) const depth = Number(await item.locator.getAttribute('aria-level')) const currentIndex = Number(await item.locator.getAttribute('data-index'))
async function assert(test: string, level: number, state: TestState, itemIndex: number) { const [name, index = itemIndex] = test.split('|') let locator = `[aria-label*="${name} ${getTitleFromState(state)}"][aria-level="${level}"]` if (index) { locator += `[data-index="${index}"]` } await expect(page.locator(locator)).toBeAttached({ timeout: 10_000 }) }
const counter = { index: currentIndex }
async function traverse(tests: TestsTree, level = depth + 1) { for (const test in tests) { counter.index++
const item = tests[test] if (typeof item === 'string') { await assert(test, level, item, counter.index) } else { const [name, index = counter.index] = test.split('|') let locator = `[aria-label*="${name}"][aria-level="${level}"]` if (index) { locator += `[data-index="${index}"]` } await expect(page.locator(locator)).toBeAttached()
await traverse(item, level + 1) } } }
await traverse(tests)
return { pass: true, message: () => '', } },})
declare global { // eslint-disable-next-line ts/no-namespace export namespace PlaywrightTest { // eslint-disable-next-line unused-imports/no-unused-vars export interface Matchers<R, T = unknown> { toHaveState: (state: TestState) => Promise<R> /** * @example * expect(tester.tree.getFileItem('no-import.test.ts')).toHaveTests({ * multiply: 'waiting', * divide: 'waiting', * suite: { * 'some old test name': 'waiting', * }, * }) */ toHaveTests: (tests: TestsTree) => Promise<R> toHaveError: (error: string) => Promise<R> } }}