diff --git a/.eslintignore b/.eslintignore
index a345e7e4..5821b50a 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,3 +1,4 @@
 dist/*
 node_modules/*
 playground/*
+tap-snapshots/*
diff --git a/src/util/svg-text-bubble.js b/src/util/svg-text-bubble.js
index 328c3a2e..a7bcab55 100644
--- a/src/util/svg-text-bubble.js
+++ b/src/util/svg-text-bubble.js
@@ -169,12 +169,16 @@ class SVGTextBubble {
         return svgString;
     }
 
+    _buildTextFragment (text) {
+        const textNode = this.svgTextWrapper.wrapText(MAX_LINE_LENGTH, text);
+        const serializer = new XMLSerializer();
+        return serializer.serializeToString(textNode);
+    }
+
     buildString (type, text, pointsLeft) {
         this.type = type;
         this.pointsLeft = pointsLeft;
-        const textNode = this.svgTextWrapper.wrapText(MAX_LINE_LENGTH, text);
-        const serializer = new XMLSerializer();
-        this._textFragment = serializer.serializeToString(textNode);
+        this._textFragment = this._buildTextFragment(text);
 
         let fragment = '';
 
diff --git a/tap-snapshots/test-integration-scratch-tests.js-TAP.test.js b/tap-snapshots/test-integration-scratch-tests.js-TAP.test.js
new file mode 100644
index 00000000..4cd97cf6
--- /dev/null
+++ b/tap-snapshots/test-integration-scratch-tests.js-TAP.test.js
@@ -0,0 +1,10 @@
+/* IMPORTANT
+ * This snapshot file is auto-generated, but designed for humans.
+ * It should be checked into source control and tracked carefully.
+ * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
+ * Make sure to inspect the output below.  Do not ignore changes!
+ */
+'use strict'
+exports[`test/integration/scratch-tests.js TAP bubble snapshot > bubble-text-snapshot 1`] = `
+<text xmlns="http://www.w3.org/2000/svg" alignment-baseline="text-before-edge" font-size="14" fill="#575E75" font-family="Helvetica"><tspan x="0" dy="1.2em">&lt;e*&amp;%$&amp;^$&gt;&lt;/!abc'&gt;</tspan></text>
+`
diff --git a/test/integration/scratch-tests.js b/test/integration/scratch-tests.js
index 668d72e8..c09f1de7 100644
--- a/test/integration/scratch-tests.js
+++ b/test/integration/scratch-tests.js
@@ -1,4 +1,4 @@
-/* global vm, Promise */
+/* global vm, render, Promise */
 const {Chromeless} = require('chromeless');
 const test = require('tap').test;
 const path = require('path');
@@ -101,6 +101,16 @@ const testFile = file => test(file, async t => {
     }
 });
 
+const testBubbles = () => test('bubble snapshot', async t => {
+    const bubbleSvg = await chromeless.goto(`file://${indexHTML}`)
+        .evaluate(() => {
+            const testString = '<e*&%$&^$></!abc\'>';
+            return render._svgTextBubble._buildTextFragment(testString);
+        });
+    t.matchSnapshot(bubbleSvg, 'bubble-text-snapshot');
+    t.end();
+});
+
 // immediately invoked async function to let us wait for each test to finish before starting the next.
 (async () => {
     const files = fs.readdirSync(testDir())
@@ -110,6 +120,8 @@ const testFile = file => test(file, async t => {
         await testFile(file);
     }
 
+    await testBubbles();
+
     // close the browser window we used
     await chromeless.end();
 })();