intern icon indicating copy to clipboard operation
intern copied to clipboard

Supporting coverage from a Web Worker

Open kitsonk opened this issue 8 years ago • 1 comments

I ran across an issue where running code within a web worker is not providing coverage information for the report. I would assume it would be similar for service workers as well. I can tell by my functional test, which is passing, that the code is working as expected, though I can't determine my coverage though.

I am not entirely sure what it would entail, but I suspect we would have to implement a "runner" within the web worker which would collect the instrumented coverage, post that back to the web side runner, which in turn would post it back to the server for aggregation.

Here is an example of how my functional test currently looks like:

webworkerAMD.ts:

import * as assert from 'intern/chai!assert';
import * as registerSuite from 'intern!object';
import executeTest from './executeTest';

const AMD_APP_MESSAGE = 'Message from AMD app.';

registerSuite({
	name: 'AMD loading in web worker',

	'basic loading'(this: any) {
		return executeTest(this, './webworkerBasic.html', function (results: any) {
			assert.strictEqual(results.message, AMD_APP_MESSAGE);
		});
	}
});

executeTest.ts:

import * as Suite from 'intern/lib/Suite';
import * as Command from 'leadfoot/Command';
import pollUntil = require('intern/dojo/node!leadfoot/helpers/pollUntil');

export default function (suite: Suite, htmlTestPath: string, testFunction: (result: any) => void,
						timeout = 10000): Command<any> {
	return suite.remote
		.get((<any> require).toUrl(htmlTestPath))
		.then(pollUntil<any>(function () {
			return (<any> window).loaderTestResults;
		}, undefined, timeout), undefined)
		.then(testFunction, function () {
			throw new Error('loaderTestResult was not set.');
		});
}

webworkerBasic.html:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
	<script>
		if (window.Worker) {
			const worker = new Worker('worker.js');

			worker.onmessage = function (e) {
				window.loaderTestResults = e.data;
			}

			worker.postMessage('start');
		}
		else {
			console.error('does not support web workers');
		}
	</script>
</body>
</html>

worker.ts:

onmessage = function (e) {
	try {
		/* load the loader */
		importScripts('../../src/loader.js');

		require.config({
			packages: [
				{ name: 'amdApp', location: './amdApp' }
			]
		});

		require([
			'amdApp/app'
		], function (app) {
			/* post message back with the results */
			(<any> postMessage)({
				message: app.getMessage()
			});
		});
	}
	catch (e) {
		(<any> postMessage)({
			message: e.message,
			status: 'fail'
		});
		throw e;
	}
};

kitsonk avatar Mar 09 '17 14:03 kitsonk

The worker code will already be instrumented if it's loaded via the intern proxy. The trick will be to get the coverage data out of the worker without requiring the user to make it explicitly aware of code coverage.

jason0x43 avatar Mar 09 '17 14:03 jason0x43