diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d2b716..4476053b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- Incrementally render the HTML report. ([#120](https://github.com/cucumber/html-formatter/issues/120), [#121](https://github.com/cucumber/html-formatter/pull/121)) + ## [19.2.0] - 2022-05-27 ### Changed - Upgrade to `@cucumber/react-components` `^20.1.0` diff --git a/javascript/.gitignore b/javascript/.gitignore index 571a56f3..122125c4 100644 --- a/javascript/.gitignore +++ b/javascript/.gitignore @@ -1,17 +1,5 @@ dist/ .idea/ -.nyc_output/ -coverage/ node_modules/ -*.log -.deps -.tested* -.linted -.built* -.compared -.codegen -acceptance/ -storybook-static -*-go *.iml -.vscode-test +html/ diff --git a/javascript/README.md b/javascript/README.md index ee0d7737..725c97e3 100644 --- a/javascript/README.md +++ b/javascript/README.md @@ -3,3 +3,24 @@ # html-formatter > Takes a stream of Cucumber messages and outputs a standalone HTML report using Cucumber's React components + +## Manually testing incremental output + +The generated HTML report can be viewed before the entire report has been generated. This can be tested manually. + + npm install + npm run build + npm run validate + +You should now have some HTML reports under `html/*.html`. Let's render this incrementally: + + rm -f incremental.html + touch incremental.html + + # open the empty file in a browser + open incremental.html + + # incrementally write some contents into that file, simulating cucumber writing the file slowly + cat html/examples-tables.feature.html | ./scripts/slowcat > incremental.html + +Return to the browser. Keep refresh it. You should see that the report contents changes. diff --git a/javascript/html/.gitkeep b/javascript/html/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/javascript/package.json b/javascript/package.json index 9234a4c5..1ca3c32c 100644 --- a/javascript/package.json +++ b/javascript/package.json @@ -6,7 +6,7 @@ "types": "dist/src/CucumberHtmlStream.d.ts", "repository": { "type": "git", - "url": "git+https://github.com/cucumber/cucumber.git" + "url": "git+https://github.com/cucumber/cucumber-html.git" }, "author": "Aslak Hellesøy", "license": "MIT", diff --git a/javascript/scripts/slowcat b/javascript/scripts/slowcat new file mode 100755 index 00000000..b26efc7d --- /dev/null +++ b/javascript/scripts/slowcat @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# +# Works like cat, but slows down printing after seeing the first tag. +# By default, the delay in slow mode is 1 second. This can be overridden by passing an argument +# + +pause=${1:-1} +slow=false +while IFS='$\n' read -r line; do + if [[ "$slow" = true ]]; then sleep $pause; fi + echo "$line" + if [[ "$line" = "" ]] && [[ "$slow" = false ]]; then + slow=true; + fi +done diff --git a/javascript/src/CucumberHtmlStream.ts b/javascript/src/CucumberHtmlStream.ts index f349a575..115e246a 100644 --- a/javascript/src/CucumberHtmlStream.ts +++ b/javascript/src/CucumberHtmlStream.ts @@ -47,9 +47,12 @@ export default class CucumberHtmlStream extends Transform { if (err) return callback(err) this.writeFile(this.cssPath, (err) => { if (err) return callback(err) - this.writeTemplateBetween('{{css}}', '{{messages}}', (err) => { + this.writeTemplateBetween('{{css}}', '{{script}}', (err) => { if (err) return callback(err) - callback() + this.writeFile(this.jsPath, (err) => { + if (err) return callback(err) + this.writeTemplateBetween('{{script}}', '{{messages}}', callback) + }) }) }) }) @@ -58,13 +61,7 @@ export default class CucumberHtmlStream extends Transform { private writePostMessage(callback: TransformCallback) { this.writePreMessageUnlessAlreadyWritten((err) => { if (err) return callback(err) - this.writeTemplateBetween('{{messages}}', '{{script}}', (err) => { - if (err) return callback(err) - this.writeFile(this.jsPath, (err) => { - if (err) return callback(err) - this.writeTemplateBetween('{{script}}', null, callback) - }) - }) + this.writeTemplateBetween('{{messages}}', null, callback) }) } @@ -110,11 +107,6 @@ export default class CucumberHtmlStream extends Transform { } private writeMessage(envelope: messages.Envelope) { - if (!this.firstMessageWritten) { - this.firstMessageWritten = true - } else { - this.push(',') - } - this.push(JSON.stringify(envelope)) + this.push(`\n`) } } diff --git a/javascript/src/index.mustache.html b/javascript/src/index.mustache.html index e607a4b2..a3fddb06 100644 --- a/javascript/src/index.mustache.html +++ b/javascript/src/index.mustache.html @@ -9,13 +9,10 @@ -
-
- +
+{{messages}} diff --git a/javascript/src/main.tsx b/javascript/src/main.tsx index 6db90170..e00af856 100644 --- a/javascript/src/main.tsx +++ b/javascript/src/main.tsx @@ -1,8 +1,8 @@ import './styles.scss' -import * as messages from '@cucumber/messages' +import { Envelope } from '@cucumber/messages' import { components, searchFromURLParams } from '@cucumber/react-components' -import React from 'react' +import React, { useState } from 'react' import ReactDOM from 'react-dom' const { CucumberReact } = components @@ -10,18 +10,23 @@ const { FilteredResults, EnvelopesWrapper, SearchWrapper } = components.app declare global { interface Window { - CUCUMBER_MESSAGES: messages.Envelope[] + p(envelope: Envelope): void } } -const app = ( - - - - - - - -) +const App: React.FunctionComponent = () => { + const [envelopes, setEnvelopes] = useState([]) + window.p = (envelope) => setEnvelopes(envelopes.concat(envelope)) -ReactDOM.render(app, document.getElementById('content')) + return ( + + + + + + + + ) +} + +ReactDOM.render(, document.getElementById('content')) diff --git a/javascript/test/CucumberHtmlStreamTest.ts b/javascript/test/CucumberHtmlStreamTest.ts index 7eaed864..30a92998 100644 --- a/javascript/test/CucumberHtmlStreamTest.ts +++ b/javascript/test/CucumberHtmlStreamTest.ts @@ -35,11 +35,6 @@ async function renderAsHtml( } describe('CucumberHtmlStream', () => { - it('writes zero messages to html', async () => { - const html = await renderAsHtml() - assert(html.indexOf('window.CUCUMBER_MESSAGES = []') >= 0) - }) - it('writes one message to html', async () => { const e1: messages.Envelope = { testRunStarted: { @@ -47,9 +42,7 @@ describe('CucumberHtmlStream', () => { }, } const html = await renderAsHtml(e1) - assert( - html.indexOf(`window.CUCUMBER_MESSAGES = [${JSON.stringify(e1)}]`) >= 0 - ) + assert(html.indexOf(`p(${JSON.stringify(e1)})`) >= 0) }) it('writes two messages to html', async () => { @@ -65,12 +58,8 @@ describe('CucumberHtmlStream', () => { }, } const html = await renderAsHtml(e1, e2) - assert( - html.indexOf( - `window.CUCUMBER_MESSAGES = [${JSON.stringify(e1)},${JSON.stringify( - e2 - )}]` - ) >= 0 - ) + console.log(html) + assert(html.indexOf(``) >= 0) + assert(html.indexOf(``) >= 0) }) }) diff --git a/javascript/test/acceptance.ts b/javascript/test/acceptance.ts index 568519b0..60a8d64f 100644 --- a/javascript/test/acceptance.ts +++ b/javascript/test/acceptance.ts @@ -1,6 +1,7 @@ import { NdjsonToMessageStream } from '@cucumber/message-streams' import assert from 'assert' import fs from 'fs' +import { writeFile } from 'fs/promises' import glob from 'glob' import path from 'path' import puppeteer from 'puppeteer' @@ -33,10 +34,11 @@ describe('html-formatter', () => { `./node_modules/@cucumber/compatibility-kit/features/**/*.ndjson` ) for (const ndjson of files) { - it(`can render ${path.basename(ndjson, '.ndjson')}`, async () => { + const basename = path.basename(ndjson, '.ndjson') + it(`can render ${basename}`, async () => { const ndjsonData = fs.createReadStream(ndjson, { encoding: 'utf-8' }) const toMessageStream = new NdjsonToMessageStream() - const htmlData = await new Promise((resolve, reject) => { + const html = await new Promise((resolve, reject) => { const chunks: Buffer[] = [] const out = new PassThrough() .on('data', (chunk) => chunks.push(Buffer.from(chunk))) @@ -56,7 +58,8 @@ describe('html-formatter', () => { } ) }) - assert.ok(await canRenderHtml(htmlData.toString())) + await writeFile(`html/${basename}.html`, html, 'utf-8') + assert.ok(await canRenderHtml(html)) }) } }) diff --git a/javascript/test/dummy.css b/javascript/test/dummy.css index e69de29b..30ff5636 100644 --- a/javascript/test/dummy.css +++ b/javascript/test/dummy.css @@ -0,0 +1 @@ +/* dummy css */ diff --git a/javascript/test/dummy.js b/javascript/test/dummy.js index e69de29b..ae9b3356 100644 --- a/javascript/test/dummy.js +++ b/javascript/test/dummy.js @@ -0,0 +1 @@ +// dummy js