EditorView assumes the existance of global "document"

I tried to write a test like that in mocha:

import {EditorView} from "@codemirror/view";
import {test} from "mocha";
import {JSDOM} from "jsdom";

test('empty 2', function () {
  const environment = new JSDOM("<html></html>");
  const view = new EditorView({
    root: environment.window.document,
    parent: environment.window.document.createElement("div")

And I see error:

ReferenceError: document is not defined
    at new EditorView (file:///home/daniel/WebstormProjects/4play.v2/node_modules/@codemirror/view/dist/index.js:6888:27)
    at Context.<anonymous> (file:///home/daniel/WebstormProjects/4play.v2/test/unit/view/test.js:7:16)
    at processImmediate (node:internal/timers:471:21)

Since I believe EditorView in constructor implicitly reads document from global context:

    constructor(config = {}) {
        this.plugins = [];
        // [...]
        this.contentDOM = document.createElement("div");
        this.scrollDOM = document.createElement("div");
        this.scrollDOM.tabIndex = -1;
        this.scrollDOM.className = "cm-scroller";

O tried to write tests in JSDOM, I I tried passing the root or document attributes, but it doesn’t help, since the view still tries to use the implicit document from global.

Is there a way to parametrize it?

This is not going to change. There’s so many things that go through document in the browser—passing it around everywhere would be a pain. It is unlikely that an editor view created with JSDom would get very far anyway (since that doesn’t implement the whole browser interface). Run your tests in a headless browser.

I have a suite of 1000 tests that run in JSDOM and they test parsing, view, styles, highlights, decorates and autocomplete, so this is very much possible. I just had to override window, document, MutationObserver and requestAnimationFrame from JSDOM, and now it works. It is true that JSOM lacks a lot, but I managed to get satisfying results. For example after your last update, my tests started to fail because some padding styles changed from 4px to 6px, or other way around. I was so proud of them, that they managed to pick that up. I probably didn’t handle every possible case, but I’ve been using code mirror for i think two years now, and tests with JSDOM satisfy my needs very well. 1000 tests execute in around 8-10 seconds, which is great.

And also, since 2020 PR in JSOM, there’s a flag called {pretendToBeVisual:true}, and it polyfills a lot of stuff.

I can grant you read access to my private repo so you can try it yourself.

I don’t need access to your repo—I believe you. But given how easy headless browsers are to work with nowadays, I don’t consider this a case worth supporting in the library. Just keep filling in the globals you need for your tests to run.

1 Like

I would very much like to try running tests in a headless browser.

But I’m wondering, is it possible to achieve this kinds of execution times?


Do you use headless browser for code mirror? What kind of execution times do you get for all suite?