diff --git a/e2e/__tests__/__snapshots__/coverageHandlebars.test.ts.snap b/e2e/__tests__/__snapshots__/coverageHandlebars.test.ts.snap
new file mode 100644
index 000000000000..3510fb666914
--- /dev/null
+++ b/e2e/__tests__/__snapshots__/coverageHandlebars.test.ts.snap
@@ -0,0 +1,10 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`code coverage for Handlebars 1`] = `
+"-----------|---------|----------|---------|---------|-------------------
+File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
+-----------|---------|----------|---------|---------|-------------------
+All files | 75 | 66.67 | 66.67 | 66.67 |
+ greet.hbs | 75 | 66.67 | 66.67 | 66.67 | 10
+-----------|---------|----------|---------|---------|-------------------"
+`;
diff --git a/e2e/__tests__/coverageHandlebars.test.ts b/e2e/__tests__/coverageHandlebars.test.ts
new file mode 100644
index 000000000000..eaaeb205abd4
--- /dev/null
+++ b/e2e/__tests__/coverageHandlebars.test.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import * as path from 'path';
+import {cleanup, run} from '../Utils';
+import runJest from '../runJest';
+
+const dir = path.resolve(__dirname, '../coverage-handlebars');
+const coverageDir = path.join(dir, 'coverage');
+
+beforeAll(() => {
+ cleanup(coverageDir);
+});
+
+it('code coverage for Handlebars', () => {
+ run('yarn', dir);
+ const result = runJest(dir, ['--coverage', '--no-cache']);
+ expect(result.exitCode).toBe(0);
+ expect(result.stdout).toMatchSnapshot();
+});
diff --git a/e2e/coverage-handlebars/__tests__/greet.js b/e2e/coverage-handlebars/__tests__/greet.js
new file mode 100644
index 000000000000..f5775645112e
--- /dev/null
+++ b/e2e/coverage-handlebars/__tests__/greet.js
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+const greet = require('../greet.hbs');
+
+test('am', () => {
+ expect(greet({am: true, name: 'Joe'})).toEqual(
+ '
Good\n morning\nJoe!
\n'
+ );
+});
diff --git a/e2e/coverage-handlebars/greet.hbs b/e2e/coverage-handlebars/greet.hbs
new file mode 100644
index 000000000000..9dd3847305ae
--- /dev/null
+++ b/e2e/coverage-handlebars/greet.hbs
@@ -0,0 +1,13 @@
+{{!
+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+}}
+Good
+{{#if am}}
+ morning
+{{else}}
+ evening
+{{/if}}
+{{name}}!
diff --git a/e2e/coverage-handlebars/package.json b/e2e/coverage-handlebars/package.json
new file mode 100644
index 000000000000..3eb23f01b754
--- /dev/null
+++ b/e2e/coverage-handlebars/package.json
@@ -0,0 +1,12 @@
+{
+ "jest": {
+ "transform": {
+ "\\.hbs$": "/transform-handlebars.js"
+ },
+ "testEnvironment": "node"
+ },
+ "dependencies": {
+ "handlebars": "^4.7.3",
+ "source-map": "^0.6.1"
+ }
+}
diff --git a/e2e/coverage-handlebars/transform-handlebars.js b/e2e/coverage-handlebars/transform-handlebars.js
new file mode 100644
index 000000000000..a20adf41393d
--- /dev/null
+++ b/e2e/coverage-handlebars/transform-handlebars.js
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const Handlebars = require('handlebars/dist/cjs/handlebars.js');
+const {SourceMapConsumer, SourceNode} = require('source-map');
+
+exports.process = (code, filename) => {
+ const pc = Handlebars.precompile(code, {srcName: filename});
+ const out = new SourceNode(null, null, null, [
+ 'const Handlebars = require("handlebars/dist/cjs/handlebars.runtime.js");\n',
+ 'module.exports = Handlebars.template(',
+ SourceNode.fromStringWithSourceMap(pc.code, new SourceMapConsumer(pc.map)),
+ ');\n',
+ ]).toStringWithSourceMap();
+ return {code: out.code, map: out.map.toString()};
+};
diff --git a/e2e/coverage-handlebars/yarn.lock b/e2e/coverage-handlebars/yarn.lock
new file mode 100644
index 000000000000..71a0f6e78e8b
--- /dev/null
+++ b/e2e/coverage-handlebars/yarn.lock
@@ -0,0 +1,55 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+commander@~2.20.3:
+ version "2.20.3"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
+ integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+
+handlebars@^4.7.3:
+ version "4.7.3"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.3.tgz#8ece2797826886cf8082d1726ff21d2a022550ee"
+ integrity sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg==
+ dependencies:
+ neo-async "^2.6.0"
+ optimist "^0.6.1"
+ source-map "^0.6.1"
+ optionalDependencies:
+ uglify-js "^3.1.4"
+
+minimist@~0.0.1:
+ version "0.0.10"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
+ integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
+
+neo-async@^2.6.0:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
+ integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
+
+optimist@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
+ integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
+ dependencies:
+ minimist "~0.0.1"
+ wordwrap "~0.0.2"
+
+source-map@^0.6.1, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+uglify-js@^3.1.4:
+ version "3.8.0"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.8.0.tgz#f3541ae97b2f048d7e7e3aa4f39fd8a1f5d7a805"
+ integrity sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ==
+ dependencies:
+ commander "~2.20.3"
+ source-map "~0.6.1"
+
+wordwrap@~0.0.2:
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
+ integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=