Skip to content

Commit

Permalink
[WIP] Core: Support HTML/TAP preconfig via QUnit.config.reporters
Browse files Browse the repository at this point in the history
Allow disabling of HTML Reporter even if `<div id="qunit">` exists.

Ref qunitjs#1711.
  • Loading branch information
Krinkle committed Jul 22, 2024
1 parent c73e8e5 commit 8870890
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ module.exports = function (grunt) {
all: {
options: {
timeout: 30000,
console: false,
puppeteer: {
args: isCI

Expand Down Expand Up @@ -106,6 +107,7 @@ module.exports = function (grunt) {
'test/browser-runner/autostart.html',
'test/browser-runner/config-fixture-null.html',
'test/browser-runner/config-fixture-string.html',
'test/browser-runner/config-reporters-html.html',
'test/browser-runner/headless.html',
'test/browser-runner/window-onerror-preexisting-handler.html',
'test/browser-runner/window-onerror.html'
Expand Down
68 changes: 68 additions & 0 deletions docs/api/config/reporters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
layout: page-api
title: QUnit.config.reporters
excerpt: Control which reporters to enable or disable.
groups:
- config
redirect_from:
- "/config/reporters/"
version_added: "unreleased"
---

Control which reporters to enable or disable.

<table>
<tr>
<th>type</th>
<td markdown="span">`object`</td>
</tr>
<tr>
<th>default</th>
<td markdown="span">`{}`</td>
</tr>
</table>

## See also

* [Preconfig](./index.md#preconfiguration)
* [QUnit Reporter API](../callbacks/QUnit.on.md#reporter-api)

## Built-in reporters

### console

The **console** reporter, logs a JSON object for each reporter event from [`QUnit.on`](./api/callbacks/QUnit.on.md). Use this to explore or debug the Reporter API.

```
runStart {…}
testStart {…}
testEnd {…}
testStart {…}
testEnd {…}
runEnd {…}
```

### perf

The **perf** reporter.

### tap

The **tap** reporter.

### html

The **html** reporter.

## Examples

By default, the HTML Reporter is enabled in browser environments if a `<div id="qunit">` element exists. You can [disable the HTML Reporter](../../browser.md).

```js
//
QUnit.config.reporters.html = false;
```

```js
QUnit.config.reporters.html = true;
```
2 changes: 2 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ Built-in reporters:
* `tap`: [TAP compliant](https://testanything.org/) reporter.
* `console`: Log the JSON object for each reporter event from [`QUnit.on`](./api/callbacks/QUnit.on.md). Use this to explore or debug the Reporter API.

Check [`QUnit.config.reporters`](./api/config/reporters.md) for more information.

### `--require`

These modules or scripts will be required before any tests begin running.
Expand Down
14 changes: 11 additions & 3 deletions src/core/browser/browser-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,25 @@ export function initBrowser (QUnit, window, document) {

initFixture(QUnit, document);
initUrlConfig(QUnit);
QUnit.reporters.perf.init(QUnit);
QUnit.reporters.html.init(QUnit);

function autostart () {
// Check as late as possible because if projecst set autostart=false,
// Check as late as possible because if projects set autostart=false,
// they generally do so in their own scripts, after qunit.js.
if (QUnit.config.autostart) {
QUnit.start();
}
}
if (document.readyState === 'complete') {
// NOTE: This branch calls autostart() before reporters have been set up.
// qunit.js sets up reporters right after calling initBrowser(). That would
// cause the "begin" event and first sync test results to be missed, except
// that doBegin() always defers itself by one setTimeout tick, so it's fine.
// The alternative is to set up reporters before initBrowser() installs error
// handlers (which reduces telemetry) and before fixture+urlconfig init
// (which breaks the dependency expectation there). The compromise is to
// depend here on the fact that QUnit.start() defers via setTimeout, which
// is largely there for this very reason, to give reporters a tick for
// discovery and set up.
autostart();
} else {
window.addEventListener('load', autostart, false);
Expand Down
2 changes: 1 addition & 1 deletion src/core/browser/urlparams.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function initUrlConfig (QUnit) {
// already set. This prevents internal TypeError from bad urls where keys
// could otherwise unexpectedly be set to type string or array.
//
// Given that HTML Reporter renders checkboxes based on QUnit.config
// Given that HTML Reporter sets checkbox state based on QUnit.config,
// instead of QUnit.urlParams, this also helps make sure that checkboxes
// for built-in keys are correctly shown as off if a urlParams value exists
// but was invalid and discarded by config.js.
Expand Down
17 changes: 17 additions & 0 deletions src/core/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const config = {
// very useful in combination with "Hide passed tests" checked
reorder: true,

reporters: {},

// When enabled, all tests must call expect()
requireExpects: false,

Expand Down Expand Up @@ -216,6 +218,21 @@ function readFlatPreconfig (obj) {
readFlatPreconfigString(obj.qunit_config_seed, 'seed');
readFlatPreconfigStringArray(obj.qunit_config_testid, 'testId');
readFlatPreconfigNumber(obj.qunit_config_testtimeout, 'testTimeout');

const reporterKeys = {
qunit_config_reporters_console: 'console',
qunit_config_reporters_perf: 'perf',
qunit_config_reporters_tap: 'tap',
qunit_config_reporters_html: 'html'
};
for (const key in reporterKeys) {
const val = obj[key];
// Based on readFlatPreconfigBoolean
if (typeof val === 'boolean' || (typeof val === 'string' && val !== '')) {
const dest = reporterKeys[key];
config.reporters[dest] = (val === true || val === 'true' || val === '1');
}
}
}

if (process && 'env' in process) {
Expand Down
26 changes: 26 additions & 0 deletions src/core/qunit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,29 @@ exportQUnit(QUnit);
if (window && document) {
initBrowser(QUnit, window, document);
}

// TODO: QUnit.config.reporters is writable and should work as expected
// if you change these between qunit.js and QUnit.start().
// Consider moving this to doBegin() instead.
//
// TODO: Address moving to doBegin() breaking plugins that use the HTML API
// of the HTML Reporter to extend the DOM, they rely on built-in reporters
// being among the first, so that their handler for the same event is after
// the built-in one.
//
// TODO: Does moving to doBegin() affect reliability of error reporting?

// Perf before others, to ensure coverage and accuracy of event spans
if (QUnit.config.reporters.perf || (QUnit.config.reporters.perf === undefined && window && document)) {
QUnit.reporters.perf.init(QUnit);
}

if (QUnit.config.reporters.console) {
QUnit.reporters.console.init(QUnit);
}
if (QUnit.config.reporters.tap) {
QUnit.reporters.tap.init(QUnit);
}
if (QUnit.config.reporters.html || (QUnit.config.reporters.html === undefined && window && document)) {
QUnit.reporters.html.init(QUnit);
}
20 changes: 20 additions & 0 deletions test/browser-runner/config-reporters-html.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>config-reporters-html</title>
<link rel="stylesheet" href="../../src/core/qunit.css">
<script>
/* eslint-disable camelcase, no-undef */
// go headless
qunit_config_reporters_html = false;
// enable TAP
qunit_config_reporters_tap = true;
</script>
<script src="../../qunit/qunit.js"></script>
<script src="config-reporters-html.js"></script>
</head>
<body>
<div id="qunit"></div>
</body>
</html>
14 changes: 14 additions & 0 deletions test/browser-runner/config-reporters-html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-env browser */
QUnit.module('QUnit.config.reporters');

QUnit.test('read config', function (assert) {
assert.deepEqual(QUnit.config.reporters, {
html: false,
tap: true
});
});

QUnit.test('HtmlReporter disabled', function (assert) {
var children = [].slice.call(document.querySelectorAll('#qunit > *'));
assert.deepEqual(children, [], '#qunit element is empty');
});

0 comments on commit 8870890

Please sign in to comment.