Skip to content

Testing your editor

prosekit/core/test provides a small layer for unit-testing extensions and editors without spinning up a browser.

createTestEditor(options) is a drop-in alternative to createEditor that returns a TestEditor. It exposes the same API as Editor, plus helpers for setting the document and selection from a builder syntax.

import { unionfunction union<const E extends readonly Extension[]>(...exts: E): Union<E> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
} from 'prosekit/core'
import { createTestEditorfunction createTestEditor<E extends Extension>(options: EditorOptions<E>): TestEditor<E> } from 'prosekit/core/test' import { defineDocfunction defineDoc(): DocExtension } from 'prosekit/extensions/doc' import { defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
} from 'prosekit/extensions/paragraph'
import { defineTextfunction defineText(): TextExtension } from 'prosekit/extensions/text' const editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>> = createTestEditorcreateTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>(options: EditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>): TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>({ extensionEditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension]>
The extension to use when creating the editor.
: unionunion<readonly [DocExtension, TextExtension, ParagraphExtension]>(exts_0: DocExtension, exts_1: TextExtension, exts_2: ParagraphExtension): Union<readonly [DocExtension, TextExtension, ParagraphExtension]> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
(defineDocfunction defineDoc(): DocExtension(), defineTextfunction defineText(): TextExtension(), defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
()),
})

You don't call editor.mount(...). The test editor manages a detached view internally.

editor.nodes.<name>(...) and editor.marks.<name>(...) are typed factories generated from your schema. Use them to build a document and hand it to editor.set(...).

import { unionfunction union<const E extends readonly Extension[]>(...exts: E): Union<E> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
} from 'prosekit/core'
import { createTestEditorfunction createTestEditor<E extends Extension>(options: EditorOptions<E>): TestEditor<E> } from 'prosekit/core/test' import { defineBoldfunction defineBold(): BoldExtension } from 'prosekit/extensions/bold' import { defineDocfunction defineDoc(): DocExtension } from 'prosekit/extensions/doc' import { defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
} from 'prosekit/extensions/paragraph'
import { defineTextfunction defineText(): TextExtension } from 'prosekit/extensions/text' const editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>> = createTestEditorcreateTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>(options: EditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>): TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>({ extensionEditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>
The extension to use when creating the editor.
: unionunion<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>(exts_0: DocExtension, exts_1: TextExtension, exts_2: ParagraphExtension, exts_3: BoldExtension): Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
(
defineDocfunction defineDoc(): DocExtension(), defineTextfunction defineText(): TextExtension(), defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
(),
defineBoldfunction defineBold(): BoldExtension(), ), }) const n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
= editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.nodes
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.nodes: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
All {@link NodeAction } s defined by the editor.
const m
const m: ToMarkAction<SimplifyDeeper<{
    bold: {
        readonly [x: string]: any;
    };
}>>
= editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.marks
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.marks: ToMarkAction<SimplifyDeeper<{
    bold: {
        readonly [x: string]: any;
    };
}>>
All {@link MarkAction } s defined by the editor.
const docconst doc: Node = n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.doc
doc: NodeAction
(attrs: {
    readonly [x: string]: any;
} | null, ...children: NodeChild[]) => Node (+1 overload)
Creates a node with attributes and any number of children.
(
n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.paragraph
paragraph: NodeAction
(...children: NodeChild[]) => Node (+1 overload)
Creates a node with any number of children.
('Hello, ', m
const m: ToMarkAction<SimplifyDeeper<{
    bold: {
        readonly [x: string]: any;
    };
}>>
.bold
bold: MarkAction
(...children: NodeChild[]) => Node[] (+1 overload)
Applies a mark with any number of children.
('world'), '!'),
) editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.setTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.set(doc: Node): void
Set the editor state to the given document. You can use special tokens `<a>` and `<b>` to set the anchor and head positions of the selection.
@example```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('<a>Hello<b> world!')) editor.set(doc) // "Hello" is selected. ```
(docconst doc: Node)

The set helper recognizes two special tokens in text content:

  • <a> marks the start of the selection.
  • <b> marks the end of the selection.
import { unionfunction union<const E extends readonly Extension[]>(...exts: E): Union<E> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
} from 'prosekit/core'
import { createTestEditorfunction createTestEditor<E extends Extension>(options: EditorOptions<E>): TestEditor<E> } from 'prosekit/core/test' import { defineDocfunction defineDoc(): DocExtension } from 'prosekit/extensions/doc' import { defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
} from 'prosekit/extensions/paragraph'
import { defineTextfunction defineText(): TextExtension } from 'prosekit/extensions/text' const editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>> = createTestEditorcreateTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>(options: EditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>): TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>({ extensionEditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension]>
The extension to use when creating the editor.
: unionunion<readonly [DocExtension, TextExtension, ParagraphExtension]>(exts_0: DocExtension, exts_1: TextExtension, exts_2: ParagraphExtension): Union<readonly [DocExtension, TextExtension, ParagraphExtension]> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
(defineDocfunction defineDoc(): DocExtension(), defineTextfunction defineText(): TextExtension(), defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
()),
}) const n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
= editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.nodes
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.nodes: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
All {@link NodeAction } s defined by the editor.
const docconst doc: Node = n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.doc
doc: NodeAction
(attrs: {
    readonly [x: string]: any;
} | null, ...children: NodeChild[]) => Node (+1 overload)
Creates a node with attributes and any number of children.
(n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.paragraph
paragraph: NodeAction
(...children: NodeChild[]) => Node (+1 overload)
Creates a node with any number of children.
('<a>Hello<b> world!'))
editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.setTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.set(doc: Node): void
Set the editor state to the given document. You can use special tokens `<a>` and `<b>` to set the anchor and head positions of the selection.
@example```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('<a>Hello<b> world!')) editor.set(doc) // "Hello" is selected. ```
(docconst doc: Node)
// "Hello" is now selected.

Reading a selection back with extractSelection

Section titled “Reading a selection back with extractSelection”

extractSelection(doc) reads the <a>/<b> tokens out of a tagged document and returns the matching Selection. Use it in tests to assert against an expected tagged document instead of hand-counting positions.

import { unionfunction union<const E extends readonly Extension[]>(...exts: E): Union<E> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
} from 'prosekit/core'
import { createTestEditorfunction createTestEditor<E extends Extension>(options: EditorOptions<E>): TestEditor<E>, extractSelectionfunction extractSelection(doc: Node): Selection | undefined
Extracts a {@link Selection } from a tagged ProseMirror document built with the test node builders. The position of the `<a>` token becomes the anchor, and the optional `<b>` token becomes the head. Returns a `TextSelection` when `<a>` resolves inside inline content, a `NodeSelection` when `<a>` resolves inside a block parent, or `undefined` when the document contains no tags.
@exampleExtracting a `TextSelection`: ```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('<a>Hello<b> world!')) const selection = extractSelection(doc) // TextSelection covering "Hello" ```@exampleExtracting a `NodeSelection`: ```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc('<a>', n.paragraph('foo')) const selection = extractSelection(doc) // NodeSelection on the paragraph ```@exampleA document without tags returns `undefined`: ```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('Hello world!')) const selection = extractSelection(doc) // undefined ```
} from 'prosekit/core/test'
import { defineDocfunction defineDoc(): DocExtension } from 'prosekit/extensions/doc' import { defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
} from 'prosekit/extensions/paragraph'
import { defineTextfunction defineText(): TextExtension } from 'prosekit/extensions/text' import { expectconst expect: ExpectStatic, itconst it: TestAPI
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
} from 'vitest'
const editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>> = createTestEditorcreateTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>(options: EditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>): TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>({ extensionEditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension]>
The extension to use when creating the editor.
: unionunion<readonly [DocExtension, TextExtension, ParagraphExtension]>(exts_0: DocExtension, exts_1: TextExtension, exts_2: ParagraphExtension): Union<readonly [DocExtension, TextExtension, ParagraphExtension]> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
(defineDocfunction defineDoc(): DocExtension(), defineTextfunction defineText(): TextExtension(), defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
()),
}) const n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
= editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.nodes
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.nodes: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
All {@link NodeAction } s defined by the editor.
itit<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
('preserves the selection that <a> and <b> describe', () => {
const docconst doc: Node = n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.doc
doc: NodeAction
(attrs: {
    readonly [x: string]: any;
} | null, ...children: NodeChild[]) => Node (+1 overload)
Creates a node with attributes and any number of children.
(n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.paragraph
paragraph: NodeAction
(...children: NodeChild[]) => Node (+1 overload)
Creates a node with any number of children.
('<a>Hello<b> world!'))
editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.setTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.set(doc: Node): void
Set the editor state to the given document. You can use special tokens `<a>` and `<b>` to set the anchor and head positions of the selection.
@example```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('<a>Hello<b> world!')) editor.set(doc) // "Hello" is selected. ```
(docconst doc: Node)
expectexpect<any>(actual: any, message?: string): Assertion<any> (+1 overload)(editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.stateEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.state: EditorState
The editor's current state.
.selectionEditorState.selection: Selection
The selection.
.toJSONSelection.toJSON(): any
Convert the selection to a JSON representation. When implementing this for a custom selection class, make sure to give the object a `type` property whose value matches the ID under which you [registered](https://prosemirror.net/docs/ref/#state.Selection^jsonID) your class.
()).toEqualJestAssertion<any>.toEqual: <any>(expected: any) => void
Used when you want to check that two objects have the same value. This matcher recursively checks the equality of all fields, rather than checking for object identity.
@exampleexpect(user).toEqual({ name: 'Alice', age: 30 });
(
extractSelectionfunction extractSelection(doc: Node): Selection | undefined
Extracts a {@link Selection } from a tagged ProseMirror document built with the test node builders. The position of the `<a>` token becomes the anchor, and the optional `<b>` token becomes the head. Returns a `TextSelection` when `<a>` resolves inside inline content, a `NodeSelection` when `<a>` resolves inside a block parent, or `undefined` when the document contains no tags.
@exampleExtracting a `TextSelection`: ```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('<a>Hello<b> world!')) const selection = extractSelection(doc) // TextSelection covering "Hello" ```@exampleExtracting a `NodeSelection`: ```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc('<a>', n.paragraph('foo')) const selection = extractSelection(doc) // NodeSelection on the paragraph ```@exampleA document without tags returns `undefined`: ```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('Hello world!')) const selection = extractSelection(doc) // undefined ```
(docconst doc: Node)?.toJSONSelection.toJSON(): any
Convert the selection to a JSON representation. When implementing this for a custom selection class, make sure to give the object a `type` property whose value matches the ID under which you [registered](https://prosemirror.net/docs/ref/#state.Selection^jsonID) your class.
(),
) })
import { unionfunction union<const E extends readonly Extension[]>(...exts: E): Union<E> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
} from 'prosekit/core'
import { createTestEditorfunction createTestEditor<E extends Extension>(options: EditorOptions<E>): TestEditor<E> } from 'prosekit/core/test' import { defineBoldfunction defineBold(): BoldExtension } from 'prosekit/extensions/bold' import { defineDocfunction defineDoc(): DocExtension } from 'prosekit/extensions/doc' import { defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
} from 'prosekit/extensions/paragraph'
import { defineTextfunction defineText(): TextExtension } from 'prosekit/extensions/text' import { describeconst describe: SuiteAPI
Creates a suite of tests, allowing for grouping and hierarchical organization of tests. Suites can contain both tests and other suites, enabling complex test structures.
@paramname - The name of the suite, used for identification and reporting.@paramfn - A function that defines the tests and suites within this suite.@example```ts // Define a suite with two tests describe('Math operations', () => { test('should add two numbers', () => { expect(add(1, 2)).toBe(3); }); test('should subtract two numbers', () => { expect(subtract(5, 2)).toBe(3); }); }); ```@example```ts // Define nested suites describe('String operations', () => { describe('Trimming', () => { test('should trim whitespace from start and end', () => { expect(' hello '.trim()).toBe('hello'); }); }); describe('Concatenation', () => { test('should concatenate two strings', () => { expect('hello' + ' ' + 'world').toBe('hello world'); }); }); }); ```
, expectconst expect: ExpectStatic, itconst it: TestAPI
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
} from 'vitest'
describedescribe<object>(name: string | Function, fn?: SuiteFactory<object> | undefined, options?: number): SuiteCollector<object> (+1 overload)
Creates a suite of tests, allowing for grouping and hierarchical organization of tests. Suites can contain both tests and other suites, enabling complex test structures.
@paramname - The name of the suite, used for identification and reporting.@paramfn - A function that defines the tests and suites within this suite.@example```ts // Define a suite with two tests describe('Math operations', () => { test('should add two numbers', () => { expect(add(1, 2)).toBe(3); }); test('should subtract two numbers', () => { expect(subtract(5, 2)).toBe(3); }); }); ```@example```ts // Define nested suites describe('String operations', () => { describe('Trimming', () => { test('should trim whitespace from start and end', () => { expect(' hello '.trim()).toBe('hello'); }); }); describe('Concatenation', () => { test('should concatenate two strings', () => { expect('hello' + ' ' + 'world').toBe('hello world'); }); }); }); ```
('toggleBold', () => {
itit<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
('wraps the selection in a bold mark', () => {
const editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>> = createTestEditorcreateTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>(options: EditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>): TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>({ extensionEditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>
The extension to use when creating the editor.
: unionunion<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>(exts_0: DocExtension, exts_1: TextExtension, exts_2: ParagraphExtension, exts_3: BoldExtension): Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```
(
defineDocfunction defineDoc(): DocExtension(), defineTextfunction defineText(): TextExtension(), defineParagraphfunction defineParagraph(): ParagraphExtension
Defines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
(),
defineBoldfunction defineBold(): BoldExtension(), ), }) const n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
= editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.nodes
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.nodes: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
All {@link NodeAction } s defined by the editor.
editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.setTestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.set(doc: Node): void
Set the editor state to the given document. You can use special tokens `<a>` and `<b>` to set the anchor and head positions of the selection.
@example```ts const editor = createTestEditor({ extension }) const n = editor.nodes const doc = n.doc(n.paragraph('<a>Hello<b> world!')) editor.set(doc) // "Hello" is selected. ```
(n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.doc
doc: NodeAction
(attrs: {
    readonly [x: string]: any;
} | null, ...children: NodeChild[]) => Node (+1 overload)
Creates a node with attributes and any number of children.
(n
const n: ToNodeAction<SimplifyDeeper<{
    doc: {
        readonly [x: string]: any;
    };
    paragraph: {
        readonly [x: string]: any;
    };
    text: {
        readonly [x: string]: any;
    };
}>>
.paragraph
paragraph: NodeAction
(...children: NodeChild[]) => Node (+1 overload)
Creates a node with any number of children.
('<a>hi<b>')))
expectexpect<boolean>(actual: boolean, message?: string): Assertion<boolean> (+1 overload)(editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.commands
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.commands: ToCommandAction<{
    toggleBold: [];
    setParagraph: [];
}>
All {@link CommandAction } s defined by the editor.
.toggleBoldtoggleBold: CommandAction<[]>.canExecCommandAction<[]>.canExec(): boolean
Check if the current command can be executed. Return `true` if the command can be executed, otherwise `false`.
()).toBeJestAssertion<boolean>.toBe: <boolean>(expected: boolean) => void
Checks that a value is what you expect. It calls `Object.is` to compare values. Don't use `toBe` with floating-point numbers.
@exampleexpect(result).toBe(42); expect(status).toBe(true);
(true)
editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.commands
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.commands: ToCommandAction<{
    toggleBold: [];
    setParagraph: [];
}>
All {@link CommandAction } s defined by the editor.
.toggleBold
toggleBold: CommandAction
() => boolean
Execute the current command. Return `true` if the command was successfully executed, otherwise `false`.
()
expectexpect<boolean>(actual: boolean, message?: string): Assertion<boolean> (+1 overload)(editorconst editor: TestEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.marks
Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension, BoldExtension]>>.marks: ToMarkAction<SimplifyDeeper<{
    bold: {
        readonly [x: string]: any;
    };
}>>
All {@link MarkAction } s defined by the editor.
.bold
bold: MarkAction<{
    readonly [x: string]: any;
}>
.isActive
MarkAction<{ readonly [x: string]: any; }>.isActive: (attrs?: {
    readonly [x: string]: any;
} | undefined) => boolean
Checks if the mark is active in the current editor selection. If the optional `attrs` parameter is provided, it will check if the mark is active with the given attributes.
()).toBeJestAssertion<boolean>.toBe: <boolean>(expected: boolean) => void
Checks that a value is what you expect. It calls `Object.is` to compare values. Don't use `toBe` with floating-point numbers.
@exampleexpect(result).toBe(42); expect(status).toBe(true);
(true)
}) })