Commands
Command is a function that invokes another function on the server and passes down the result back to the browser. Vitest exposes several built-in commands you can use in your browser tests.
Built-in Commands
Files Handling
You can use readFile, writeFile and removeFile API to handle files inside your browser tests. All paths are resolved relative to the test file even if they are called in a helper function located in another file.
By default, Vitest uses utf-8 encoding but you can override it with options.
TIP
This API follows server.fs limitations for security reasons.
import { server } from '@vitest/browser/context'
const { readFile, writeFile, removeFile } = server.commands
it('handles files', async () => {
const file = './test.txt'
await writeFile(file, 'hello world')
const content = await readFile(file)
expect(content).toBe('hello world')
await removeFile(file)
})CDP Session
Vitest exposes access to raw Chrome Devtools Protocol via the cdp method exported from @vitest/browser/context. It is mostly useful to library authors to build tools on top of it.
import { cdp } from '@vitest/browser/context'
const input = document.createElement('input')
document.body.appendChild(input)
input.focus()
await cdp().send('Input.dispatchKeyEvent', {
type: 'keyDown',
text: 'a',
})
expect(input).toHaveValue('a')WARNING
CDP session works only with playwright provider and only when using chromium browser. You can read more about it in playwright's CDPSession documentation.
Custom Commands
You can also add your own commands via browser.commands config option. If you develop a library, you can provide them via a config hook inside a plugin:
import type { Plugin } from 'vitest/config'
import type { BrowserCommand } from 'vitest/node'
const myCustomCommand: BrowserCommand<[arg1: string, arg2: string]> = ({
testPath,
provider
}, arg1, arg2) => {
if (provider.name === 'playwright') {
console.log(testPath, arg1, arg2)
return { someValue: true }
}
throw new Error(`provider ${provider.name} is not supported`)
}
export default function BrowserCommands(): Plugin {
return {
name: 'vitest:custom-commands',
config() {
return {
test: {
browser: {
commands: {
myCustomCommand,
}
}
}
}
}
}
}Then you can call it inside your test by importing it from @vitest/browser/context:
import { commands } from '@vitest/browser/context'
import { expect, test } from 'vitest'
test('custom command works correctly', async () => {
const result = await commands.myCustomCommand('test1', 'test2')
expect(result).toEqual({ someValue: true })
})
// if you are using TypeScript, you can augment the module
declare module '@vitest/browser/context' {
interface BrowserCommands {
myCustomCommand: (arg1: string, arg2: string) => Promise<{
someValue: true
}>
}
}WARNING
Custom functions will override built-in ones if they have the same name.
Custom playwright commands
Vitest exposes several playwright specific properties on the command context.
pagereferences the full page that contains the test iframe. This is the orchestrator HTML and you most likely shouldn't touch it to not break things.frameis an async method that will resolve testerFrame. It has a simillar API to thepage, but it doesn't support certain methods. If you need to query an element, you should prefer usingcontext.iframeinstead because it is more stable and faster.iframeis aFrameLocatorthat should be used to query other elements on the page.contextrefers to the unique BrowserContext.
import { BrowserCommand } from 'vitest/node'
export const myCommand: BrowserCommand<[string, number]> = async (
ctx,
arg1: string,
arg2: number
) => {
if (ctx.provider.name === 'playwright') {
const element = await ctx.iframe.findByRole('alert')
const screenshot = await element.screenshot()
// do something with the screenshot
return difference
}
}TIP
If you are using TypeScript, don't forget to add @vitest/browser/providers/playwright to your tsconfig "compilerOptions.types" field to get autocompletion in the config and on userEvent and page options:
{
"compilerOptions": {
"types": [
"@vitest/browser/providers/playwright"
]
}
}Custom webdriverio commands
Vitest exposes some webdriverio specific properties on the context object.
browseris theWebdriverIO.BrowserAPI.
Vitest automatically switches the webdriver context to the test iframe by calling browser.switchToFrame before the command is called, so $ and $$ methods refer to the elements inside the iframe, not in the orchestrator, but non-webdriver APIs will still refer to the parent frame context.
TIP
If you are using TypeScript, don't forget to add @vitest/browser/providers/webdriverio to your tsconfig "compilerOptions.types" field to get autocompletion:
{
"compilerOptions": {
"types": [
"@vitest/browser/providers/webdriverio"
]
}
}