Getting TransformError: Invalid content for node list_item in Jest Tests

Hello there,

I’ve written some code for a button, that changes casing. I’m testing the button’s ability to modify bullet points e.g. from lowercase to uppercase. My Jest tests however fail and complain about a ‘TransformError: Invalid content for node list_item’. This only happens in the case of bullet points. The tests pass in the case of individual words and sentences. Does anyone know why this may occur?

Here is my code (heavily borrowed):

export function caseCommand(): ProsemirrorCommand {
    return (state, dispatch) => {
        let tr =;
        const { from, to } = tr.selection;
        let shouldUpdate = false;
        const text = state.doc.textBetween(from, to);
        if (text.length === 0) {return false;} 
        const isTextAllLowercase = text === text.toLowerCase();
        state.doc.nodesBetween(from, to, (node, position) => {
            if (!node.isTextblock || from === to) return;
            const startPosition = Math.max(position + 1, from);
            const endPosition = Math.min(position + node.nodeSize, to);
            const substringFrom = Math.max(0, from - position - 1);
            const substringTo = Math.max(0, to - position - 1);
            const nodeText = node.textContent.substring(substringFrom, substringTo);
            const textNode = isTextAllLowercase? nodeText.toUpperCase() : nodeText.toLowerCase();
            tr = tr.replaceWith(startPosition, endPosition, state.schema.text(textNode));
            shouldUpdate = true;
    if (dispatch && shouldUpdate) {
        return true;
    return false;

And here is my test code:

                ["hi", "hi", "hi", "HI", "HI", "HI"],
                ["HI", "HI", "HI","hi", "hi", "hi"],
                ["Hi", "HI", "hi", "hi", "hi", "hi"]]
            )(`it should not concentenate a bulleted list and successfully turn '%s, %s, %s' into '%s, %s, %s'`, (input1, input2, input3, output1, output2, output3) => {
                const state = createStateWithSelection(doc(ul(li(p(input1)), li(p(input2), li(p(input3))))) , 1, 20);
                const view = new EditorView(null, { state: state.state });
                const expectedDoc = doc(ul(li(p(output1)), li(p(output2)), li(p(output3))));
                const command = caseCommand();
                const result = command(state.state, view.dispatch);

If your textblock nodes contain any non-text inline nodes, this will mess up. It seems a better idea would be to create a replacement for each text node. That way you can also preserve marks.

It looks like too few/too many closing brackets, when creating the state and expectedDoc, was the culprit :sweat_smile: Thank you so much for your help, @marijn!