···59596060::: warning
6161CDP session works only with `playwright` provider and only when using `chromium` browser. You can read more about it in playwright's [`CDPSession`](https://playwright.dev/docs/api/class-cdpsession) documentation.
6262+6363+CDP is a privileged debugging API. It is available only when browser API write and exec operations are enabled through [`browser.api.allowWrite`](/guide/browser/config#browser-api-allowwrite), [`browser.api.allowExec`](/guide/browser/config#browser-api-allowexec), [`api.allowWrite`](/config/#api-allowwrite), and [`api.allowExec`](/config/#api-allowexec).
6264:::
63656466## Custom Commands
+2-2
docs/guide/browser/config.md
···155155- **Type:** `boolean`
156156- **Default:** inherited from [`api.allowWrite`](/config/#api-allowwrite)
157157158158-Allows browser API clients to write files, including snapshots and browser command writes. If `browser.api.host` is set to anything other than `localhost` or `127.0.0.1`, Vitest disables write operations by default unless this option or [`api.allowWrite`](/config/#api-allowwrite) is explicitly enabled.
158158+Allows browser API clients to write files, including snapshots and browser command writes. If `browser.api.host` is set to anything other than `localhost` or `127.0.0.1`, Vitest disables write operations by default unless this option or [`api.allowWrite`](/config/#api-allowwrite) is explicitly enabled. This option also gates privileged browser APIs that can write files indirectly, such as raw Chrome DevTools Protocol access through [`cdp()`](/guide/browser/context#cdp).
159159160160### browser.api.allowExec {#browser-api-allowexec}
161161162162- **Type:** `boolean`
163163- **Default:** inherited from [`api.allowExec`](/config/#api-allowexec)
164164165165-Allows browser API clients to run tests from the UI. If `browser.api.host` is exposed to the network and write/exec operations are enabled, anyone who can reach the browser API server can run arbitrary code on your machine.
165165+Allows browser API clients to run tests from the UI. If `browser.api.host` is exposed to the network and write/exec operations are enabled, anyone who can reach the browser API server can run arbitrary code on your machine. This option also gates privileged browser APIs that can execute code indirectly, such as raw Chrome DevTools Protocol access through [`cdp()`](/guide/browser/context#cdp).
166166167167## browser.provider {#browser-provider}
168168
+2
docs/guide/browser/context.md
···116116117117::: warning
118118CDP session works only with `playwright` provider and only when using `chromium` browser. You can read more about it in playwright's [`CDPSession`](https://playwright.dev/docs/api/class-cdpsession) documentation.
119119+120120+CDP is a privileged debugging API. It is available only when browser API write and exec operations are enabled through [`browser.api.allowWrite`](/guide/browser/config#browser-api-allowwrite), [`browser.api.allowExec`](/guide/browser/config#browser-api-allowexec), [`api.allowWrite`](/config/#api-allowwrite), and [`api.allowExec`](/config/#api-allowexec).
119121:::
120122121123```ts
+8-9
packages/coverage-v8/src/browser.ts
···11+import type { Profiler } from 'node:inspector'
12import type { CoverageProviderModule } from 'vitest/node'
23import type { V8CoverageProvider } from './provider'
33-import { cdp } from '@vitest/browser/context'
44import { loadProvider } from './load-provider'
5566-const session = cdp()
76let enabled = false
8799-type ScriptCoverage = Awaited<ReturnType<typeof session.send<'Profiler.takePreciseCoverage'>>>
88+type ScriptCoverage = Profiler.TakePreciseCoverageReturnType
99+1010+function triggerCommand(command: string, args: any[] = []): Promise<any> {
1111+ return (globalThis as any).__vitest_browser_runner__.commands.triggerCommand(command, args)
1212+}
10131114const mod: CoverageProviderModule = {
1215 async startCoverage() {
···16191720 enabled = true
18211919- await session.send('Profiler.enable')
2020- await session.send('Profiler.startPreciseCoverage', {
2121- callCount: true,
2222- detailed: true,
2323- })
2222+ await triggerCommand('__vitest_startV8Coverage')
2423 },
25242625 async takeCoverage(): Promise<{ result: any[] }> {
2727- const coverage = await session.send('Profiler.takePreciseCoverage')
2626+ const coverage: ScriptCoverage = await triggerCommand('__vitest_takeV8Coverage')
2827 const result: typeof coverage.result = []
29283029 // Reduce amount of data sent over rpc by doing some early result filtering
+14
test/browser/specs/errors-cdp.test.ts
···11+import { expect, test } from 'vitest'
22+import { provider, runBrowserTests } from './utils'
33+44+// v3 backport of
55+// https://github.com/vitest-dev/vitest/blob/a88ab04c710d7703b3d48c74bec4cd6382077acc/test/browser/specs/errors.test.ts#L222
66+test.runIf(provider === 'playwright')('cannot use cdp if write or exec is disabled', async () => {
77+ const { stderr } = await runBrowserTests({
88+ root: './fixtures/errors-cdp',
99+ })
1010+1111+ expect(stderr).toContain(
1212+ 'Cannot use CDP because browser API write or exec operations are disabled. See https://vitest.dev/config/browser/api.',
1313+ )
1414+})