Is there a standalone version of EditorView's `dispatch` that works without having to construct an EditorView?

I’m writing tests for an extension I wrote, and I would like to avoid “mounting” an EditorView to a real DOM. I’m looking for a function that’ll essentially let me do something like this:

const oldState = EditorState.create({ doc: "" })
const transaction = { changes: [{ from: 0, insert: "new text" }] }
const newState = magicFunction(oldState, transaction)

Does such a magicFunction exist? Is there a better way to do this that avoids this function?

I’m not entirely sure if this testing strategy even makes sense. I’m trying to do this because writing UI/E2E tests (using Playwright, for example) seems to be really hard since I’d have to programmatically “click” on very specific coordinates in a browser window.

On a side note, it’d be great to have a few examples for testing on the documentation website! I’m also willing to help if you need it :slight_smile:

There’s no prefab function like that, but yes, you can easily do this (and a lot of the core module tests do it in order to be able to run without browser). Something like this:

function applyCommand(state, command) {
  command({state, dispatch: tr => state = tr.state})
  return state
}
1 Like

Ah understood, so you suggest I use the built-in StateCommands to do all the manipulation I want? I’ll give that a shot, thanks!

Oh, no, if you’re just looking for a way to create transactions, you want state.update.

1 Like

Oh yep that was exactly what I wanted (I was just a little confused)! Looking at your examples (and @codemirror/commands's tests), I’ve realized that a transaction is “self-contained”, as in, the new state is already calculated and stored in the tranasaction itself, and I can get it from the .state property, without having to “dispatch” anything.

So in my tests, I can do this:

let editorState = EditorState.create({ doc: "" })
editorState = editorState.update({ changes: [{ from: 0, insert: "new text" }] }).state

which is what I was looking for.

Thanks for your responses! (Let me know if I misunderstood anything :sweat_smile:)