mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
553 lines
21 KiB
TypeScript
553 lines
21 KiB
TypeScript
import type { TestBenchmark } from 'vitest'
|
||
import type { JsonTestResult, JsonTestResults, Vitest } from 'vitest/node'
|
||
import { readdirSync } from 'node:fs'
|
||
import { readFile } from 'node:fs/promises'
|
||
import { beforeAll, describe, expect, onTestFailed, test } from 'vitest'
|
||
import { buildTestTree } from '../../test-utils'
|
||
import { instances, provider, runBrowserTests } from './utils'
|
||
|
||
function noop() {}
|
||
|
||
describe('running browser tests', async () => {
|
||
let stderr: string
|
||
let stdout: string
|
||
let browserResultJson: JsonTestResults
|
||
let passedTests: JsonTestResult[]
|
||
let failedTests: JsonTestResult[]
|
||
let vitest: Vitest
|
||
const events: string[] = []
|
||
const emittedBenchmarks: Array<{ projectName: string; testName: string; benchmark: TestBenchmark }> = []
|
||
|
||
beforeAll(async () => {
|
||
({
|
||
stderr,
|
||
stdout,
|
||
ctx: vitest,
|
||
} = await runBrowserTests({
|
||
allowOnly: true,
|
||
reporters: [
|
||
{
|
||
onBrowserInit(project) {
|
||
events.push(`onBrowserInit ${project.name}`)
|
||
},
|
||
onTestCaseBenchmark(testCase, benchmark) {
|
||
emittedBenchmarks.push({
|
||
projectName: testCase.project.name || '',
|
||
testName: testCase.fullName,
|
||
benchmark,
|
||
})
|
||
},
|
||
},
|
||
'json',
|
||
{
|
||
onInit: noop,
|
||
onTestRunStart: noop,
|
||
onTestModuleCollected: noop,
|
||
onTestRunEnd: noop,
|
||
onTestRemoved: noop,
|
||
onWatcherStart: noop,
|
||
onWatcherRerun: noop,
|
||
onServerRestart: noop,
|
||
onUserConsoleLog: noop,
|
||
},
|
||
'default',
|
||
],
|
||
}))
|
||
|
||
const browserResult = await readFile('./browser.json', 'utf-8')
|
||
browserResultJson = JSON.parse(browserResult) as JsonTestResults
|
||
const getPassed = (results: JsonTestResult[]) => results.filter(result => result.status === 'passed' && !result.message)
|
||
const getFailed = (results: JsonTestResult[]) => results.filter(result => result.status === 'failed')
|
||
passedTests = getPassed(browserResultJson.testResults)
|
||
failedTests = getFailed(browserResultJson.testResults)
|
||
})
|
||
|
||
test('tests are actually running', () => {
|
||
expect(stderr).toBe('')
|
||
|
||
const testFiles = Array.from(new Set(browserResultJson.testResults.map(t => t.name)))
|
||
|
||
vitest.projects.forEach((project) => {
|
||
// the order is non-deterministic
|
||
expect(events).toContain(`onBrowserInit ${project.name}`)
|
||
})
|
||
|
||
// test files are optimized automatically (type-check-only files are excluded)
|
||
const runtimeTestFiles = testFiles.filter(f => !f.endsWith('.test-d.ts'))
|
||
expect(vitest.projects.map(p => p.vite.config.optimizeDeps.entries))
|
||
.toEqual(vitest.projects.map(() => expect.arrayContaining(runtimeTestFiles)))
|
||
|
||
const testFilesCount = readdirSync('./test')
|
||
.filter(n => n.includes('.test.') || n.includes('.test-d.') || n.includes('.bench.'))
|
||
.length + 1 // 1 is in-source-test
|
||
|
||
expect(browserResultJson.testResults).toHaveLength(testFilesCount * instances.length)
|
||
expect(passedTests).toHaveLength(browserResultJson.testResults.length)
|
||
expect(failedTests).toHaveLength(0)
|
||
})
|
||
|
||
test('benchmarks run in a dedicated `(bench)` project per browser instance', () => {
|
||
const benchProjects = vitest.projects.filter(p => p.name.endsWith('(bench)'))
|
||
expect(benchProjects.map(p => p.name).sort()).toEqual(
|
||
instances.map(({ browser }) => `${browser} (bench)`).sort(),
|
||
)
|
||
})
|
||
|
||
test('perProject benchmarks emit tasks with the perProject flag in every browser', () => {
|
||
const records = emittedBenchmarks.filter(e =>
|
||
e.testName === 'perProject registrations flow through the browser RPC (onTestBenchmark)',
|
||
)
|
||
// the test calls `.run()` twice, so each browser produces 2 benchmark records
|
||
expect(records.length, `perProject emitted: ${records.length}`).toBe(2 * instances.length)
|
||
for (const record of records) {
|
||
expect(record.benchmark.tasks, `empty tasks for ${record.projectName}`).toHaveLength(1)
|
||
const [task] = record.benchmark.tasks
|
||
expect(task.perProject, `missing perProject flag on ${record.projectName}/${task.name}`).toBe(true)
|
||
expect(task.fromStore).toBeUndefined()
|
||
}
|
||
})
|
||
|
||
test('bench.compare emits one benchmark with both registrations ranked', () => {
|
||
const records = emittedBenchmarks.filter(e =>
|
||
e.testName === 'bench.compare resolves a BenchStorage in the browser',
|
||
)
|
||
expect(records.length).toBe(instances.length)
|
||
for (const record of records) {
|
||
expect(record.benchmark.tasks.map(t => t.name).sort(), `unexpected tasks for ${record.projectName}`).toEqual(['a', 'b'])
|
||
expect(record.benchmark.tasks.map(t => t.rank).sort()).toEqual([1, 2])
|
||
}
|
||
})
|
||
|
||
test('writeResult flows through the write-artifact RPC in every browser', () => {
|
||
const records = emittedBenchmarks.filter(e =>
|
||
e.testName === 'writeResult exercises the writeBenchmarkResult RPC round-trip',
|
||
)
|
||
expect(records.length).toBe(instances.length)
|
||
for (const record of records) {
|
||
expect(record.benchmark.tasks, `empty tasks for ${record.projectName}`).toHaveLength(1)
|
||
const [task] = record.benchmark.tasks
|
||
expect(task.name).toBe('with-write')
|
||
}
|
||
})
|
||
|
||
test('tags are collected', () => {
|
||
expect(vitest.config.tags).toEqual([
|
||
{ name: 'e2e', priority: 10 },
|
||
{ name: 'test', priority: 5 },
|
||
{ name: 'browser', priority: 1 },
|
||
])
|
||
|
||
const testModule = vitest.state.getTestModules().find(m => m.moduleId.includes('tags.test.ts'))
|
||
expect.assert(testModule)
|
||
expect(buildTestTree([testModule], t => t.tags)).toMatchInlineSnapshot(`
|
||
{
|
||
"test/tags.test.ts": {
|
||
"suite 1": {
|
||
"suite 2": {
|
||
"test 2": [
|
||
"browser",
|
||
"e2e",
|
||
],
|
||
},
|
||
"test 1": [
|
||
"browser",
|
||
"test",
|
||
],
|
||
},
|
||
},
|
||
}
|
||
`)
|
||
})
|
||
|
||
test('runs in-source tests', () => {
|
||
expect(stdout).toContain('src/actions.ts')
|
||
const actionsTest = passedTests.find(t => t.name.includes('/actions.ts'))
|
||
expect.assert(actionsTest)
|
||
expect(actionsTest.assertionResults).toHaveLength(1)
|
||
})
|
||
|
||
test('unsubscribes cancel listeners after run', async () => {
|
||
// should not throw birpc closing errors
|
||
await expect(vitest.cancelCurrentRun('keyboard-input')).resolves.not.toThrow()
|
||
})
|
||
})
|
||
|
||
describe('console logging tests', async () => {
|
||
let stderr: string
|
||
let stdout: string
|
||
beforeAll(async () => {
|
||
({
|
||
stderr,
|
||
stdout,
|
||
} = await runBrowserTests({
|
||
root: './fixtures/print-logs',
|
||
// assert on Vitest's own console forwarding rather than Vite's client
|
||
// relay, which does not run when the tester loads the stubbed @vite/client
|
||
reporters: ['default'],
|
||
}))
|
||
})
|
||
|
||
test('logs are redirected to stdout', () => {
|
||
expect(stdout).toContain('stdout | test/logs.test.ts > logging to stdout')
|
||
expect(stdout).toContain('hello from console.log')
|
||
expect(stdout).toContain('hello from console.info')
|
||
expect(stdout).toContain('hello from console.debug')
|
||
expect(stdout).toContain(`
|
||
{
|
||
hello: 'from dir',
|
||
}
|
||
`.trim())
|
||
expect(stdout).toContain(`
|
||
{
|
||
hello: 'from dirxml',
|
||
}
|
||
`.trim())
|
||
expect(stdout).toContain('dom <div />')
|
||
expect(stdout).toContain('default: 1')
|
||
expect(stdout).toContain('default: 2')
|
||
expect(stdout).toContain('default: 3')
|
||
expect(stdout).toContain('count: 1')
|
||
expect(stdout).toContain('count: 2')
|
||
expect(stdout).toContain('count: 3')
|
||
expect(stdout).toMatch(/default: [\d.]+ ms/)
|
||
expect(stdout).toMatch(/time: [\d.]+ ms/)
|
||
expect(stdout).toMatch(/\[console-time-fake\]: [\d.]+ ms/)
|
||
expect(stdout).not.toContain('[console-time-fake]: 0 ms')
|
||
expect(stdout).toContain('hello from one')
|
||
expect(stdout).toContain(`hello from two {
|
||
hello: 'object',
|
||
}`)
|
||
})
|
||
|
||
test('logs are redirected to stderr', () => {
|
||
expect(stderr).toContain('stderr | test/logs.test.ts > logging to stderr')
|
||
expect(stderr).toContain('hello from console.error')
|
||
expect(stderr).toContain('hello from console.warn')
|
||
expect(stderr).toContain('Timer "invalid timeLog" does not exist')
|
||
expect(stderr).toContain('Timer "invalid timeEnd" does not exist')
|
||
// safari logs the stack files with @https://...
|
||
expect(stderr).toMatch(/hello from console.trace\s+(\w+|@)/)
|
||
})
|
||
|
||
test(`logs have stack traces`, () => {
|
||
expect(stdout).toMatch(`
|
||
log with a stack
|
||
❯ test/logs.test.ts:58:11
|
||
`.trim())
|
||
expect(stderr).toMatch(`
|
||
error with a stack
|
||
❯ test/logs.test.ts:59:11
|
||
`.trim())
|
||
// console.trace processes the stack trace correctly
|
||
expect(stderr).toMatch('test/logs.test.ts:60:11')
|
||
})
|
||
|
||
test('popup apis should log a warning', () => {
|
||
expect(stderr).toContain('Vitest encountered a `alert("test")`')
|
||
expect(stderr).toContain('Vitest encountered a `confirm("test")`')
|
||
expect(stderr).toContain('Vitest encountered a `print()`')
|
||
expect(stderr).toContain('Vitest encountered a `prompt("test")`')
|
||
})
|
||
})
|
||
|
||
test('disableConsoleIntercept', async () => {
|
||
const result = await runBrowserTests({
|
||
root: './fixtures/print-logs',
|
||
project: [instances[0].browser],
|
||
disableConsoleIntercept: true,
|
||
})
|
||
expect(result.stderr).toBe('')
|
||
expect(result.stdout).not.toContain('logging to stdout')
|
||
expect(result.stdout).not.toContain('hello from console.log')
|
||
})
|
||
|
||
test(`stack trace points to correct file in every browser when failed`, async () => {
|
||
expect.assertions(30)
|
||
const { stderr } = await runBrowserTests({
|
||
root: './fixtures/failing',
|
||
reporters: [
|
||
'default',
|
||
{
|
||
onTestCaseReady(testCase) {
|
||
if (testCase.name !== 'correctly fails and prints a diff') {
|
||
return
|
||
}
|
||
if (testCase.project.name === 'chromium' || testCase.project.name === 'chrome') {
|
||
expect(testCase.result().errors?.[0].stacks).toEqual([
|
||
{
|
||
line: 11,
|
||
column: 13,
|
||
file: testCase.module.moduleId,
|
||
method: '',
|
||
},
|
||
])
|
||
}
|
||
},
|
||
},
|
||
],
|
||
})
|
||
|
||
expect(stderr).toContain('expected 1 to be 2')
|
||
expect(stderr).toMatch(/- 2\s+\+ 1/)
|
||
// expect(stderr).toContain('Expected to be')
|
||
// expect(stderr).toContain('But got')
|
||
expect(stderr).toContain('Failure screenshot')
|
||
expect(stderr).toContain('__screenshots__/failing')
|
||
|
||
expect(stderr).toContain('Access denied to "/inaccessible/path".')
|
||
|
||
expect(stderr).toMatch(/failing.test.ts:11:13/)
|
||
|
||
// column is 13 in safari, 9 in others
|
||
expect(stderr).toMatch(/throwError src\/error.ts:8:(13|9)/)
|
||
|
||
expect(stderr).toContain('The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.')
|
||
expect(stderr).toMatch(/failing.test.ts:19:28/)
|
||
expect(stderr).toMatch(/failing.test.ts:20:28/)
|
||
expect(stderr).toMatch(/failing.test.ts:21:28/)
|
||
expect(stderr).toMatch(/failing.test.ts:22:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:23:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:24:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:25:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:26:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:27:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:28:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:29:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:30:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:31:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:32:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:33:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:34:13/)
|
||
expect(stderr).toMatch(/failing.test.ts:35:13/)
|
||
|
||
expect(stderr).toMatch(/bundled-lib\/src\/b.js:2:(9|18)/)
|
||
expect(stderr).toMatch(/bundled-lib\/src\/index.js:5:(16|17)/)
|
||
|
||
// index() is called from a bundled file
|
||
expect(stderr).toMatch(/failing.test.ts:39:3/)
|
||
|
||
// "not awaited but with then/catch/finally" test should not produce warnings
|
||
expect(stderr).not.toMatch(/failing.test.ts:4[3-8]/)
|
||
})
|
||
|
||
test('user-event', async () => {
|
||
const { stdout, stderr } = await runBrowserTests({
|
||
root: './fixtures/user-event',
|
||
})
|
||
expect(stderr).toBe('')
|
||
onTestFailed(() => console.error(stderr))
|
||
instances.forEach(({ browser }) => {
|
||
expect(stdout).toReportPassedTest('cleanup-retry.test.ts', browser)
|
||
expect(stdout).toReportPassedTest('cleanup1.test.ts', browser)
|
||
expect(stdout).toReportPassedTest('cleanup2.test.ts', browser)
|
||
expect(stdout).toReportPassedTest('keyboard.test.ts', browser)
|
||
expect(stdout).toReportPassedTest('clipboard.test.ts', browser)
|
||
})
|
||
})
|
||
|
||
test('timeout settings', async () => {
|
||
const { stderr } = await runBrowserTests({
|
||
root: './fixtures/timeout',
|
||
})
|
||
expect(stderr).toContain('Matcher did not succeed in time.')
|
||
if (provider.name === 'playwright') {
|
||
expect(stderr).toContain('locator.click: Timeout 500ms exceeded.')
|
||
expect(stderr).toContain('locator.click: Timeout 345ms exceeded.')
|
||
}
|
||
})
|
||
|
||
test('viewport', async () => {
|
||
const { stdout, stderr } = await runBrowserTests({
|
||
root: './fixtures/viewport',
|
||
})
|
||
expect(stderr).toBe('')
|
||
instances.forEach(({ browser }) => {
|
||
expect(stdout).toReportPassedTest('basic.test.ts', browser)
|
||
})
|
||
})
|
||
|
||
test('in-source tests don\'t run when the module is imported by the test', async () => {
|
||
const { stderr, stdout } = await runBrowserTests({}, ['mocking.test.ts'])
|
||
expect(stderr).toBe('')
|
||
|
||
instances.forEach(({ browser }) => {
|
||
expect(stdout).toReportPassedTest('test/mocking.test.ts', browser)
|
||
})
|
||
|
||
// there is only one file with one test inside
|
||
// if this stops working, it will report twice as much tests
|
||
expect(stdout).toContain(`Test Files ${instances.length} passed`)
|
||
expect(stdout).toContain(`Tests ${instances.length} passed`)
|
||
})
|
||
|
||
test('in-source tests run correctly when filtered', async () => {
|
||
const { stderr, stdout } = await runBrowserTests({}, ['actions.ts'])
|
||
expect(stderr).toBe('')
|
||
|
||
instances.forEach(({ browser }) => {
|
||
expect(stdout).toReportPassedTest('src/actions.ts', browser)
|
||
})
|
||
|
||
// there is only one file with one test inside
|
||
expect(stdout).toContain(`Test Files ${instances.length} passed`)
|
||
expect(stdout).toContain(`Tests ${instances.length} passed`)
|
||
})
|
||
|
||
test('re-evaluate setupFiles on each test run even when isolate is false', async () => {
|
||
const { exitCode, stderr, stdout } = await runBrowserTests({
|
||
root: './fixtures/isolate-and-setup-file',
|
||
})
|
||
|
||
expect(stderr).toBe('')
|
||
expect(exitCode).toBe(0)
|
||
instances.forEach(({ browser }) => {
|
||
expect(stdout).toReportPassedTest('a.test.ts', browser)
|
||
expect(stdout).toReportPassedTest('b.test.ts', browser)
|
||
})
|
||
})
|
||
|
||
test.runIf(provider.name === 'playwright')('timeout hooks', async ({ onTestFailed }) => {
|
||
const { stderr } = await runBrowserTests({
|
||
root: './fixtures/timeout-hooks',
|
||
})
|
||
|
||
onTestFailed(() => {
|
||
console.error(stderr)
|
||
})
|
||
|
||
const lines = stderr.split('\n')
|
||
const timeoutErrorsIndexes: number[] = []
|
||
lines.forEach((line, index) => {
|
||
if (line.includes('TimeoutError:')) {
|
||
timeoutErrorsIndexes.push(index)
|
||
}
|
||
})
|
||
|
||
const snapshot = timeoutErrorsIndexes.map((index) => {
|
||
return [
|
||
lines[index - 1],
|
||
lines[index].replace(/Timeout \d+ms exceeded/, 'Timeout <ms> exceeded'),
|
||
lines[index + 4],
|
||
].join('\n')
|
||
}).sort().join('\n\n')
|
||
|
||
expect(snapshot).toMatchInlineSnapshot(`
|
||
" FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > afterAll
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:39:46
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:23:46
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:31:46
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:15:46
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:6:34
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:62:48
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:70:48
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:48:48
|
||
|
||
FAIL |chromium| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:54:48
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > afterAll
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:39:46
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:23:46
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:31:46
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:15:46
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:6:34
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:62:48
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:70:48
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:48:48
|
||
|
||
FAIL |firefox| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:54:48
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > afterAll
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:39:46
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > afterEach > skipped
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:23:46
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > beforeAll
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:31:46
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > beforeEach > skipped
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:15:46
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > click on non-existing element fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:6:34
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:62:48
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFailed > fails global
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:70:48
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:48:48
|
||
|
||
FAIL |webkit| hooks-timeout.test.ts > timeouts are failing correctly > onTestFinished > fails global
|
||
TimeoutError: locator.click: Timeout <ms> exceeded.
|
||
❯ hooks-timeout.test.ts:54:48"
|
||
`)
|
||
|
||
// page.getByRole('code').click()
|
||
expect(stderr).toContain('locator.click: Timeout')
|
||
// playwright error is proxied from the server to the client and back correctly
|
||
expect(stderr).toContain('waiting for locator(\'[data-vitest="true"]\').contentFrame().getByRole(\'code\')')
|
||
expect(stderr).toMatch(/hooks-timeout.test.ts:6:34/)
|
||
// await expect.element().toBeVisible()
|
||
expect(stderr).toContain('Cannot find element with locator: getByRole(\'code\')')
|
||
expect(stderr).toMatch(/hooks-timeout.test.ts:10:50/)
|
||
}, 120_000 * 3)
|