Skip to content

Commit

Permalink
Remove support for running jsdom in a browser
Browse files Browse the repository at this point in the history
This is not worth maintaining at this point:

* Maintainer bandwidth is at a historical low.

* Very few people use Browserify these days (as opposed to Webpack or ESBuild).

* Karma is deprecated, so our testing solution is going to be hard to maintain.

* Web platform tests have never run in the browser so much of our coverage is missing.

* Having a more complex testing solution makes improvements to testing harder.

Closes #2892.
  • Loading branch information
domenic committed May 1, 2023
1 parent 97122b4 commit 148368e
Show file tree
Hide file tree
Showing 41 changed files with 62 additions and 2,535 deletions.
18 changes: 0 additions & 18 deletions .github/workflows/jsdom-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,6 @@ jobs:
run: yarn --frozen-lockfile
- name: Run tests
run: yarn add canvas && yarn test --retries 1
build-with-browser:
env:
TEST_SUITE: 'browser'
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Run web browser tests
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Setup HOSTS file for Web Platform Test server
run: ./test/web-platform-tests/tests/wpt make-hosts-file | sudo tee -a /etc/hosts
- name: Install dependencies
run: yarn --frozen-lockfile
- name: Run tests
run: yarn test-browser
build:
runs-on: ubuntu-latest
strategy:
Expand Down
18 changes: 1 addition & 17 deletions Contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,27 +78,11 @@ To write such a test that, simply add a file in `test/api/`, following the surro

Although ideally you should not need to worry about this, there are some tests that are for legacy reasons not in the right format; they use Mocha, but really should be web platform tests. We're keeping them around for coverage until we can convert them. If you run `yarn test`, you will get the full test suite, including such old tests.

### Testing against the browser

jsdom has experimental support to run in directly in a browser, in both the main document and in a web worker! So we try run as many tests as possible in browsers too. Currently we only test in Chrome, since it has the same JavaScript features as the Node.js environment we usually develop in. So you'll need Chrome installed on your machine.

The mocha test cases are executed in Chrome using [karma](https://karma-runner.github.io/). Currently, web platform tests are not executed in the browser yet.

**To run all browser tests:** `yarn test-browser`

**To run the karma tests in an iframe:** `yarn test-browser-iframe`

**To run the karma tests in a web worker:** `yarn test-browser-worker`

## Benchmarks

This project cares about performance. There are a number of benchmarks that you can run. If you suspect your contribution has an impact on the performance of existing functionality, make sure you run the benchmarks before and after your change so that you can compare.

You can also run the benchmarks using the native DOM implementation of Chrome. A comparison with jsdom will automatically be made for you. If your new feature is much slower than the alternative DOM implementation, there might be an unexpected bottleneck somewhere in your change.

**To run benchmarks in Node.js:** `yarn benchmark`

**To run benchmarks in the browser:** `yarn benchmark-browser`, then open `benchmark/browser-runner.html` in Chrome (or Chromium) and use the developer console to execute the `run()` function.
**To run benchmarks:** `yarn benchmark`

## Issues

Expand Down
10 changes: 0 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,16 +446,6 @@ Timers in the jsdom (set by `window.setTimeout()` or `window.setInterval()`) wil

If you want to be sure to shut down a jsdom window, use `window.close()`, which will terminate all running timers (and also remove any event listeners on the window and document).

### Running jsdom inside a web browser

jsdom has some support for being run inside a web browser, using [browserify](https://browserify.org/). That is, inside a web browser, you can use a browserified jsdom to create an entirely self-contained set of plain JavaScript objects which look and act much like the browser's existing DOM objects, while being entirely independent of them. "Virtual DOM", indeed!

jsdom's primary target is still Node.js, and so we use language features that are only present in recent Node.js versions. Thus, older browsers will likely not work. (Even transpilation will not help: we use `Proxy`s extensively throughout the jsdom codebase.)

Notably, jsdom works well inside a web worker. The original contributor, [@lawnsea](https://github.com/lawnsea/), who made this possible, has [published a paper](https://pdfs.semanticscholar.org/47f0/6bb6607a975500a30e9e52d7c9fbc0034e27.pdf) about his project which uses this capability.

Not everything works perfectly when running jsdom inside a web browser. Sometimes that is because of fundamental limitations (such as not having filesystem access), but sometimes it is simply because we haven't spent enough time making the appropriate small tweaks. Bug reports are certainly welcome.

### Debugging the DOM using Chrome DevTools

In Node.js you can debug programs using Chrome DevTools. See the [official documentation](https://nodejs.org/en/docs/inspector/) for how to get started.
Expand Down
18 changes: 0 additions & 18 deletions benchmark/browser-runner.html

This file was deleted.

47 changes: 0 additions & 47 deletions benchmark/browser-runner.js

This file was deleted.

25 changes: 10 additions & 15 deletions benchmark/document-suite.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
"use strict";
const Benchmark = require("benchmark");
const jsdomBenchmark = require("./jsdom-benchmark");

// jsdom might be an empty object if omitted by browserify
const jsdom = require("..");

const nativeDoc = global.document;
const jsdomDoc = jsdom.JSDOM && (new jsdom.JSDOM()).window.document;
const jsdomDoc = (new jsdom.JSDOM()).window.document;

function noop() {
// intentional no-op function
Expand Down Expand Up @@ -71,19 +69,16 @@ module.exports = function documentSuite(optionsArg) {
addBenchmark(suite, benchmark);
}

if (jsdomDoc) {
const newOptions = {

...options,
...benchmarkFunctions(jsdomDoc, options),
jsdomDocumentImplementation: "jsdom"
};
const benchmark = jsdomBenchmark(newOptions);
const newOptions = {
...options,
...benchmarkFunctions(jsdomDoc, options),
jsdomDocumentImplementation: "jsdom"
};
const benchmark = jsdomBenchmark(newOptions);

// extra space in "jsdom " so that it aligns with "native"
benchmark.name = benchmark.name ? benchmark.name + " :: jsdom " : "jsdom ";
addBenchmark(suite, benchmark);
}
// extra space in "jsdom " so that it aligns with "native"
benchmark.name = benchmark.name ? benchmark.name + " :: jsdom " : "jsdom ";
addBenchmark(suite, benchmark);

return suite;
};
23 changes: 0 additions & 23 deletions benchmark/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
const consoleReporter = require("./console-reporter");
const pathToSuites = require("./path-to-suites");
const benchmarks = require(".");
const fs = require("fs");
const path = require("path");
const { toFileUrl } = require("../lib/jsdom/utils");
const yargs = require("yargs/yargs");
const { hideBin } = require("yargs/helpers");

Expand All @@ -18,28 +15,8 @@ const { argv } = yargs(hideBin(process.argv))
alias: "s",
describe: "suites that you want to run, e.g.: dom/construction/createElement dom/foo"
})
.option("bundle", {
type: "boolean",
describe: "generate the JavaScript bundle required to run benchmarks in a browser"
})
.help();

if (argv.bundle) {
const bundle = require("browserify")({ debug: true });
bundle.require(path.resolve(__dirname, ".."), { expose: "jsdom" });
bundle.require(path.resolve(__dirname, "browser-runner.js"), { expose: "jsdom-browser-runner" });

bundle.bundle()
.pipe(fs.createWriteStream(path.resolve(__dirname, "browser-bundle.js")))
.on("finish", () => {
console.info(
"Open the following page in Chrome to begin benchmarking:",
toFileUrl(path.resolve(__dirname, "browser-runner.html"))
);
});
return;
}

let suitesToRun;
if (argv.suites) {
suitesToRun = pathToSuites(benchmarks, argv.suites);
Expand Down
175 changes: 0 additions & 175 deletions lib/jsdom/living/websockets/WebSocket-impl-browser.js

This file was deleted.

Loading

0 comments on commit 148368e

Please sign in to comment.