Skip to content

Commit

Permalink
Merge branch 'main' into fix-restrict-file-for-screenshot-error
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa committed Jan 23, 2025
2 parents b6ceccb + 45085cf commit 85e0df7
Show file tree
Hide file tree
Showing 54 changed files with 668 additions and 581 deletions.
6 changes: 3 additions & 3 deletions docs/guide/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ Run tests on different machines using [`--shard`](/guide/cli#shard) and [`--repo
All test and coverage results can be merged at the end of your CI pipeline using `--merge-reports` command:

```bash
vitest --shard=1/2 --reporter=blob
vitest --shard=2/2 --reporter=blob
vitest --merge-reports --reporter=junit --coverage.reporter=text
vitest --shard=1/2 --reporter=blob --coverage
vitest --shard=2/2 --reporter=blob --coverage
vitest --merge-reports --reporter=junit --coverage
```

See [`Improving Performance | Sharding`](/guide/improving-performance#sharding) for more information.
Expand Down
80 changes: 69 additions & 11 deletions docs/guide/mocking.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,17 +430,20 @@ it('can return a value multiple times', () => {

## Requests

Because Vitest runs in Node, mocking network requests is tricky; web APIs are not available, so we need something that will mimic network behavior for us. We recommend [Mock Service Worker](https://mswjs.io/) to accomplish this. It will let you mock both `REST` and `GraphQL` network requests, and is framework agnostic.
Because Vitest runs in Node, mocking network requests is tricky; web APIs are not available, so we need something that will mimic network behavior for us. We recommend [Mock Service Worker](https://mswjs.io/) to accomplish this. It allows you to mock `http`, `WebSocket` and `GraphQL` network requests, and is framework agnostic.

Mock Service Worker (MSW) works by intercepting the requests your tests make, allowing you to use it without changing any of your application code. In-browser, this uses the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). In Node.js, and for Vitest, it uses the [`@mswjs/interceptors`](https://github.com/mswjs/interceptors) library. To learn more about MSW, read their [introduction](https://mswjs.io/docs/)

### Configuration

You can use it like below in your [setup file](/config/#setupfiles)
```js

::: code-group

```js [HTTP Setup]
import { afterAll, afterEach, beforeAll } from 'vitest'
import { setupServer } from 'msw/node'
import { graphql, http, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

const posts = [
{
Expand All @@ -458,28 +461,83 @@ export const restHandlers = [
}),
]

const server = setupServer(...restHandlers)

// Start server before all tests
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

// Close server after all tests
afterAll(() => server.close())

// Reset handlers after each test for test isolation
afterEach(() => server.resetHandlers())
```

```js [GrapQL Setup]
import { afterAll, afterEach, beforeAll } from 'vitest'
import { setupServer } from 'msw/node'
import { graphql, HttpResponse } from 'msw'

const posts = [
{
userId: 1,
id: 1,
title: 'first post title',
body: 'first post body',
},
// ...
]

const graphqlHandlers = [
graphql.query('ListPosts', () => {
return HttpResponse.json(
{
data: { posts },
},
)
return HttpResponse.json({
data: { posts },
})
}),
]

const server = setupServer(...restHandlers, ...graphqlHandlers)
const server = setupServer(...graphqlHandlers)

// Start server before all tests
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

// Close server after all tests
// Close server after all tests
afterAll(() => server.close())

// Reset handlers after each test `important for test isolation`
// Reset handlers after each test for test isolation
afterEach(() => server.resetHandlers())
```

```js [WebSocket Setup]
import { afterAll, afterEach, beforeAll } from 'vitest'
import { setupServer } from 'msw/node'
import { ws } from 'msw'

const chat = ws.link('wss://chat.example.com')

const wsHandlers = [
chat.addEventListener('connection', ({ client }) => {
client.addEventListener('message', (event) => {
console.log('Received message from client:', event.data)
// Echo the received message back to the client
client.send(`Server received: ${event.data}`)
})
}),
]

const server = setupServer(...wsHandlers)

// Start server before all tests
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

// Close server after all tests
afterAll(() => server.close())

// Reset handlers after each test for test isolation
afterEach(() => server.resetHandlers())
```
:::

> Configuring the server with `onUnhandledRequest: 'error'` ensures that an error is thrown whenever there is a request that does not have a corresponding request handler.
### More
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"test:browser:playwright": "pnpm -C test/browser run test:playwright"
},
"devDependencies": {
"@antfu/eslint-config": "^3.11.2",
"@antfu/eslint-config": "^3.16.0",
"@antfu/ni": "^23.2.0",
"@playwright/test": "^1.49.1",
"@rollup/plugin-commonjs": "^28.0.2",
Expand All @@ -51,7 +51,7 @@
"bumpp": "^9.10.1",
"changelogithub": "^0.13.11",
"esbuild": "^0.24.2",
"eslint": "^9.16.0",
"eslint": "^9.18.0",
"magic-string": "^0.30.17",
"pathe": "^2.0.1",
"rimraf": "^6.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/jest-dom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ declare namespace matchers {
* @see
* [testing-library/jest-dom#tohaveclass](https://github.com/testing-library/jest-dom#tohaveclass)
*/
toHaveClass(...classNames: Array<string | RegExp>): R
toHaveClass(classNames: string, options?: {exact: boolean}): R
toHaveClass(...classNames: Array<string | RegExp>): R
/**
* @description
* This allows you to check whether the given form element has the specified displayed value (the one the
Expand Down
8 changes: 4 additions & 4 deletions packages/browser/src/node/commands/screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export const screenshot: BrowserCommand<[string, ScreenshotOptions]> = async (
const path = options.path
? resolve(dirname(context.testPath), options.path)
: resolveScreenshotPath(
context.testPath,
name,
context.project.config,
)
context.testPath,
name,
context.project.config,
)
const savePath = normalize(path)
await mkdir(dirname(path), { recursive: true })

Expand Down
14 changes: 7 additions & 7 deletions packages/browser/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,12 +579,12 @@ function resolveCoverageFolder(vitest: Vitest) {
const options = vitest.config
const htmlReporter = options.coverage?.enabled
? toArray(options.coverage.reporter).find((reporter) => {
if (typeof reporter === 'string') {
return reporter === 'html'
}
if (typeof reporter === 'string') {
return reporter === 'html'
}

return reporter[0] === 'html'
})
return reporter[0] === 'html'
})
: undefined

if (!htmlReporter) {
Expand All @@ -599,8 +599,8 @@ function resolveCoverageFolder(vitest: Vitest) {

const subdir
= Array.isArray(htmlReporter)
&& htmlReporter.length > 1
&& 'subdir' in htmlReporter[1]
&& htmlReporter.length > 1
&& 'subdir' in htmlReporter[1]
? htmlReporter[1].subdir
: undefined

Expand Down
2 changes: 1 addition & 1 deletion packages/browser/src/node/serverTester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export async function resolveTester(
// if decoded test file is "__vitest_all__" or not in the list of known files, run all tests
const tests
= testFile === '__vitest_all__'
|| !testFiles.includes(testFile)
|| !testFiles.includes(testFile)
? '__vitest_browser_runner__.files'
: JSON.stringify([testFile])
const iframeId = JSON.stringify(testFile)
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// we cannot bundle it because vitest depend on the @vitest/browser and vise versa
// fortunately, the file is quite small

import { LocatorSelectors } from '@vitest/browser/context'
import { LocatorSelectors, Locator } from '@vitest/browser/context'
import { StringifyOptions } from 'vitest/utils'

export type PrettyDOMOptions = Omit<StringifyOptions, 'maxLength'>
Expand Down
12 changes: 6 additions & 6 deletions packages/expect/src/jest-asymmetric-matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,12 @@ export class ArrayContaining<T = unknown> extends AsymmetricMatcher<Array<T>> {
const matcherContext = this.getMatcherContext()
const result
= this.sample.length === 0
|| (Array.isArray(other)
&& this.sample.every(item =>
other.some(another =>
equals(item, another, matcherContext.customTesters),
),
))
|| (Array.isArray(other)
&& this.sample.every(item =>
other.some(another =>
equals(item, another, matcherContext.customTesters),
),
))

return this.inverse ? !result : result
}
Expand Down
8 changes: 4 additions & 4 deletions packages/expect/src/jest-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
if (!isNot) {
const message
= utils.flag(this, 'message')
|| 'expected promise to throw an error, but it didn\'t'
|| 'expected promise to throw an error, but it didn\'t'
const error = {
showDiff: false,
}
Expand Down Expand Up @@ -469,7 +469,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
const { value, exists } = getValue()
const pass
= exists
&& (args.length === 1 || jestEquals(expected, value, customTesters))
&& (args.length === 1 || jestEquals(expected, value, customTesters))

const valueString
= args.length === 1 ? '' : ` with value ${utils.objDisplay(expected)}`
Expand Down Expand Up @@ -751,7 +751,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
if (!isNot) {
const message
= utils.flag(this, 'message')
|| 'expected promise to throw an error, but it didn\'t'
|| 'expected promise to throw an error, but it didn\'t'
const error = {
showDiff: false,
}
Expand All @@ -774,7 +774,7 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
if (!isThrow && !isNot) {
const message
= utils.flag(this, 'message')
|| 'expected function to throw an error, but it didn\'t'
|| 'expected function to throw an error, but it didn\'t'
const error = {
showDiff: false,
}
Expand Down
18 changes: 9 additions & 9 deletions packages/expect/src/jest-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ function eq(
// Deep compare each member
result
= hasKey(b, key)
&& eq(a[key], b[key], aStack, bStack, customTesters, hasKey)
&& eq(a[key], b[key], aStack, bStack, customTesters, hasKey)

if (!result) {
return false
Expand Down Expand Up @@ -603,11 +603,11 @@ export function subsetEquality(
}
const result
= object != null
&& hasPropertyInObject(object, key)
&& equals(object[key], subset[key], [
...filteredCustomTesters,
subsetEqualityWithContext(seenReferences),
])
&& hasPropertyInObject(object, key)
&& equals(object[key], subset[key], [
...filteredCustomTesters,
subsetEqualityWithContext(seenReferences),
])
// The main goal of using seenReference is to avoid circular node on tree.
// It will only happen within a parent and its child, not a node and nodes next to it (same level)
// We should keep the reference for a parent and its child only
Expand Down Expand Up @@ -759,9 +759,9 @@ export function getObjectSubset(
trimmed[key] = seenReferences.has(object[key])
? seenReferences.get(object[key])
: getObjectSubsetWithContext(seenReferences)(
object[key],
subset[key],
)
object[key],
subset[key],
)
}
else {
if (!seenReferences.has(object[key])) {
Expand Down
6 changes: 3 additions & 3 deletions packages/mocker/src/node/esmWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ export function esmWalker(
const grandparent = stack[1]
const hasBindingShortcut
= isStaticProperty(parent)
&& parent.shorthand
&& (!isNodeInPattern(parent)
|| isInDestructuringAssignment(parent, parentStack))
&& parent.shorthand
&& (!isNodeInPattern(parent)
|| isInDestructuringAssignment(parent, parentStack))

const classDeclaration
= (parent.type === 'PropertyDefinition'
Expand Down
32 changes: 16 additions & 16 deletions packages/pretty-format/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,22 +343,22 @@ function printPlugin(
printed = isNewPlugin(plugin)
? plugin.serialize(val, config, indentation, depth, refs, printer)
: plugin.print(
val,
valChild => printer(valChild, config, indentation, depth, refs),
(str) => {
const indentationNext = indentation + config.indent
return (
indentationNext
+ str.replaceAll(NEWLINE_REGEXP, `\n${indentationNext}`)
)
},
{
edgeSpacing: config.spacingOuter,
min: config.min,
spacing: config.spacingInner,
},
config.colors,
)
val,
valChild => printer(valChild, config, indentation, depth, refs),
(str) => {
const indentationNext = indentation + config.indent
return (
indentationNext
+ str.replaceAll(NEWLINE_REGEXP, `\n${indentationNext}`)
)
},
{
edgeSpacing: config.spacingOuter,
min: config.min,
spacing: config.spacingInner,
},
config.colors,
)
}
catch (error: any) {
throw new PrettyFormatPluginError(error.message, error.stack)
Expand Down
2 changes: 1 addition & 1 deletion packages/pretty-format/src/plugins/DOMElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function testNode(val: any) {
const { nodeType, tagName } = val
const isCustomElement
= (typeof tagName === 'string' && tagName.includes('-'))
|| testHasAttribute(val)
|| testHasAttribute(val)

return (
(nodeType === ELEMENT_NODE
Expand Down
Loading

0 comments on commit 85e0df7

Please sign in to comment.