Bug 968923 - part 5c - add tests for use counters; r=bz
authorNathan Froyd <froydnj@mozilla.com>
Fri, 13 Mar 2015 15:36:55 -0400
changeset 258249 f62479c673154fb4d45a502b6611477cb42e18ed
parent 258248 8161b137af4a0146418fa216082abc8c67d5ee24
child 258250 5e045c356a613426c246c9f46ce15383e14178f1
push id29249
push userryanvm@gmail.com
push dateWed, 19 Aug 2015 11:17:27 +0000
treeherdermozilla-central@706b23a03d1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs968923
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 968923 - part 5c - add tests for use counters; r=bz
dom/base/test/browser.ini
dom/base/test/browser_use_counters.js
dom/base/test/file_use_counter_outer.html
dom/base/test/file_use_counter_svg_background.html
dom/base/test/file_use_counter_svg_currentScale.svg
dom/base/test/file_use_counter_svg_fill_pattern.svg
dom/base/test/file_use_counter_svg_fill_pattern_data.svg
dom/base/test/file_use_counter_svg_fill_pattern_definition.svg
dom/base/test/file_use_counter_svg_fill_pattern_internal.svg
dom/base/test/file_use_counter_svg_getElementById.svg
dom/base/test/file_use_counter_svg_list_style_image.html
--- a/dom/base/test/browser.ini
+++ b/dom/base/test/browser.ini
@@ -1,19 +1,29 @@
 [DEFAULT]
 support-files =
   file_messagemanager_unload.html
+  file_use_counter_outer.html
+  file_use_counter_svg_getElementById.svg
+  file_use_counter_svg_currentScale.svg
+  file_use_counter_svg_background.html
+  file_use_counter_svg_list_style_image.html
+  file_use_counter_svg_fill_pattern_definition.svg
+  file_use_counter_svg_fill_pattern.svg
+  file_use_counter_svg_fill_pattern_internal.svg
+  file_use_counter_svg_fill_pattern_data.svg
 
 [browser_bug593387.js]
 skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.iframe.addEventListener)
 [browser_bug902350.js]
 tags = mcb
 skip-if = e10s # Bug ?????? - test e10s utils don't support load events from iframe etc, which this test relies on.
 [browser_messagemanager_loadprocessscript.js]
 [browser_messagemanager_targetframeloader.js]
 [browser_pagehide_on_tab_close.js]
 skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s.
 [browser_messagemanager_unload.js]
 [browser_state_notifications.js]
 # skip-if = e10s # Bug ?????? - content-document-* notifications come while document's URI is still about:blank, but test expects real URL.
 skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
 [browser_bug1058164.js]
 skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
+[browser_use_counters.js]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/browser_use_counters.js
@@ -0,0 +1,276 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
+
+let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
+
+const gHttpTestRoot = "http://example.com/browser/dom/base/test/";
+
+/**
+ * Enable local telemetry recording for the duration of the tests.
+ */
+let gOldContentCanRecord = false;
+add_task(function* test_initialize() {
+   gOldContentCanRecord = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
+    let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+    let old = telemetry.canRecordExtended;
+    telemetry.canRecordExtended = true;
+    return old;
+  });
+  info("canRecord for content: " + gOldContentCanRecord);
+});
+
+add_task(function* () {
+  // Check that use counters are incremented by SVGs loaded directly in iframes.
+  yield check_use_counter_iframe("file_use_counter_svg_getElementById.svg",
+                                 "SVGSVGELEMENT_GETELEMENTBYID");
+  yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
+                                 "SVGSVGELEMENT_CURRENTSCALE_getter");
+  yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
+                                 "SVGSVGELEMENT_CURRENTSCALE_setter");
+
+  // Check that use counters are incremented by SVGs loaded as images.
+  // Note that SVG images are not permitted to execute script, so we can only
+  // check for properties here.
+  yield check_use_counter_img("file_use_counter_svg_getElementById.svg",
+                              "PROPERTY_FILL");
+  yield check_use_counter_img("file_use_counter_svg_currentScale.svg",
+                              "PROPERTY_FILL");
+
+  // Check that use counters are incremented by directly loading SVGs
+  // that reference patterns defined in another SVG file.
+  yield check_use_counter_direct("file_use_counter_svg_fill_pattern.svg",
+                                 "PROPERTY_FILLOPACITY", /*xfail=*/true);
+
+  // Check that use counters are incremented by directly loading SVGs
+  // that reference patterns defined in the same file or in data: URLs.
+  yield check_use_counter_direct("file_use_counter_svg_fill_pattern_internal.svg",
+                                 "PROPERTY_FILLOPACITY");
+  // data: URLs don't correctly propagate to their referring document yet.
+  //yield check_use_counter_direct("file_use_counter_svg_fill_pattern_data.svg",
+  //                               "PROPERTY_FILL_OPACITY");
+
+  // Check that use counters are incremented by SVGs loaded as CSS images in
+  // pages loaded in iframes.  Again, SVG images in CSS aren't permitted to
+  // execute script, so we need to use properties here.
+  yield check_use_counter_iframe("file_use_counter_svg_background.html",
+                                 "PROPERTY_FILL");
+  yield check_use_counter_iframe("file_use_counter_svg_list_style_image.html",
+                                 "PROPERTY_FILL");
+
+  // Check that even loads from the imglib cache update use counters.  The
+  // background images should still be there, because we just loaded them
+  // in the last set of tests.  But we won't get updated counts for the
+  // document counters, because we won't be re-parsing the SVG documents.
+  yield check_use_counter_iframe("file_use_counter_svg_background.html",
+                                 "PROPERTY_FILL", false);
+  yield check_use_counter_iframe("file_use_counter_svg_list_style_image.html",
+                                 "PROPERTY_FILL", false);
+});
+
+add_task(function* () {
+  yield ContentTask.spawn(gBrowser.selectedBrowser, { oldCanRecord: gOldContentCanRecord }, function (arg) {
+    Cu.import("resource://gre/modules/PromiseUtils.jsm");
+    yield new Promise(resolve => {
+      let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+      telemetry.canRecordExtended = arg.oldCanRecord;
+      resolve();
+    });
+  });
+});
+
+
+function waitForDestroyedDocuments() {
+  let deferred = promise.defer();
+  SpecialPowers.exactGC(window, deferred.resolve);
+  return deferred.promise;
+}
+
+function waitForPageLoad(browser) {
+  return ContentTask.spawn(browser, null, function*() {
+    Cu.import("resource://gre/modules/PromiseUtils.jsm");
+    yield new Promise(resolve => {
+      let listener = () => {
+        removeEventListener("load", listener, true);
+        resolve();
+      }
+      addEventListener("load", listener, true);
+    });
+  });
+}
+
+function grabHistogramsFromContent(browser, use_counter_middlefix) {
+  return ContentTask.spawn(browser, { middlefix: use_counter_middlefix }, function* (arg) {
+    let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+    function snapshot_histogram(name) {
+      return telemetry.getHistogramById(name).snapshot();
+    }
+
+    let histogram_page_name = "USE_COUNTER_" + arg.middlefix + "_PAGE";
+    let histogram_document_name = "USE_COUNTER_" + arg.middlefix + "_DOCUMENT";
+    let histogram_page = snapshot_histogram(histogram_page_name);
+    let histogram_document = snapshot_histogram(histogram_document_name);
+    return [histogram_page.sum, histogram_document.sum];
+  });
+}
+
+let check_use_counter_iframe = Task.async(function* (file, use_counter_middlefix, check_documents=true) {
+  info("checking " + file + " with histogram " + use_counter_middlefix);
+
+  let newTab = gBrowser.addTab( "about:blank");
+  gBrowser.selectedTab = newTab;
+  newTab.linkedBrowser.stop();
+
+  // Hold on to the current values of the telemetry histograms we're
+  // interested in.
+  let [histogram_page_before, histogram_document_before] =
+      yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
+
+  gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html");
+  yield waitForPageLoad(gBrowser.selectedBrowser);
+
+  // Inject our desired file into the iframe of the newly-loaded page.
+  yield ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) {
+    Cu.import("resource://gre/modules/PromiseUtils.jsm");
+    let deferred = PromiseUtils.defer();
+
+    let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+
+    let iframe = content.document.getElementById('content');
+    iframe.src = opts.file;
+    let listener = (event) => {
+      event.target.removeEventListener("load", listener, true);
+
+      // We flush the main document first, then the iframe's document to
+      // ensure any propagation that might happen from child->parent should
+      // have already happened when counters are reported to telemetry.
+      wu.forceUseCounterFlush(content.document);
+      wu.forceUseCounterFlush(iframe.contentDocument);
+
+      deferred.resolve();
+    };
+    iframe.addEventListener("load", listener, true);
+
+    return deferred.promise;
+  });
+  
+  // Tear down the page.
+  gBrowser.removeTab(newTab);
+
+  // The histograms only get recorded when the document actually gets
+  // destroyed, which might not have happened yet due to GC/CC effects, etc.
+  // Try to force document destruction.
+  yield waitForDestroyedDocuments();
+
+  // Grab histograms again and compare.
+  let [histogram_page_after, histogram_document_after] =
+      yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
+
+  is(histogram_page_after, histogram_page_before + 1,
+     "page counts for " + use_counter_middlefix + " after are correct");
+  if (check_documents) {
+    is(histogram_document_after, histogram_document_before + 1,
+       "document counts " + use_counter_middlefix + " after are correct");
+  }
+});
+
+let check_use_counter_img = Task.async(function* (file, use_counter_middlefix) {
+  info("checking " + file + " as image with histogram " + use_counter_middlefix);
+
+  let newTab = gBrowser.addTab("about:blank");
+  gBrowser.selectedTab = newTab;
+  newTab.linkedBrowser.stop();
+
+  // Hold on to the current values of the telemetry histograms we're
+  // interested in.
+  let [histogram_page_before, histogram_document_before] =
+      yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
+
+  gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html");
+  yield waitForPageLoad(gBrowser.selectedBrowser);
+
+  // Inject our desired file into the img of the newly-loaded page.
+  yield ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) {
+    Cu.import("resource://gre/modules/PromiseUtils.jsm");
+    let deferred = PromiseUtils.defer();
+
+    let img = content.document.getElementById('display');
+    img.src = opts.file;
+    let listener = (event) => {
+      img.removeEventListener("load", listener, true);
+
+      // Flush for the image.  It matters what order we do these in, so that
+      // the image can propagate its use counters to the document prior to the
+      // document reporting its use counters.
+      let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+      wu.forceUseCounterFlush(img);
+
+      // Flush for the main window.
+      wu.forceUseCounterFlush(content.document);
+
+      deferred.resolve();
+    };
+    img.addEventListener("load", listener, true);
+
+    return deferred.promise;
+  });
+  
+  // Tear down the page.
+  gBrowser.removeTab(newTab);
+
+  // The histograms only get recorded when the document actually gets
+  // destroyed, which might not have happened yet due to GC/CC effects, etc.
+  // Try to force document destruction.
+  yield waitForDestroyedDocuments();
+
+  // Grab histograms again and compare.
+  let [histogram_page_after, histogram_document_after] =
+      yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
+  is(histogram_page_after, histogram_page_before + 1,
+     "page counts for " + use_counter_middlefix + " after are correct");
+  is(histogram_document_after, histogram_document_before + 1,
+     "document counts " + use_counter_middlefix + " after are correct");
+});
+
+let check_use_counter_direct = Task.async(function* (file, use_counter_middlefix, xfail=false) {
+  info("checking " + file + " with histogram " + use_counter_middlefix);
+
+  let newTab = gBrowser.addTab( "about:blank");
+  gBrowser.selectedTab = newTab;
+  newTab.linkedBrowser.stop();
+
+  // Hold on to the current values of the telemetry histograms we're
+  // interested in.
+  let [histogram_page_before, histogram_document_before] =
+      yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
+
+  gBrowser.selectedBrowser.loadURI(gHttpTestRoot + file);
+  yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
+    Cu.import("resource://gre/modules/PromiseUtils.jsm");
+    yield new Promise(resolve => {
+      let listener = () => {
+        removeEventListener("load", listener, true);
+
+        let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+        wu.forceUseCounterFlush(content.document);
+
+        setTimeout(resolve, 0);
+      }
+      addEventListener("load", listener, true);
+    });
+  });
+  
+  // Tear down the page.
+  gBrowser.removeTab(newTab);
+
+  // The histograms only get recorded when the document actually gets
+  // destroyed, which might not have happened yet due to GC/CC effects, etc.
+  // Try to force document destruction.
+  yield waitForDestroyedDocuments();
+
+  // Grab histograms again and compare.
+  let [histogram_page_after, histogram_document_after] =
+      yield grabHistogramsFromContent(gBrowser.selectedBrowser, use_counter_middlefix);
+  (xfail ? todo_is : is)(histogram_page_after, histogram_page_before + 1,
+                         "page counts for " + use_counter_middlefix + " after are correct");
+  (xfail ? todo_is : is)(histogram_document_after, histogram_document_before + 1,
+                         "document counts " + use_counter_middlefix + " after are correct");
+});
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_outer.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=968923
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 968923</title>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a>
+<img id="display" />
+<iframe id="content">
+
+</iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_background.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=968923
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 968923</title>
+  <style>
+/* Use a query string to work around imagelib caching.
+   Otherwise, we won't get use counters for this file.  */
+body { background-image: url('file_use_counter_svg_getElementById.svg?asbackground=1') }
+  </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a>
+<img id="display" />
+<iframe id="content" src="about:blank">
+
+</iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_currentScale.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="4in" height="3in" version="1.1"
+     xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+  <desc>Test graphic for hitting currentScale
+  </desc>
+  <script type="text/javascript"> <![CDATA[
+    document.documentElement.currentScale = document.documentElement.currentScale;
+    ]]>
+  </script>
+  <image id="i1" x="200" y="200" width="100px" height="80px"
+         xlink:href="no-such-scheme:nothing">
+  </image>
+  <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_fill_pattern.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
+     xmlns="http://www.w3.org/2000/svg">
+  <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
+  <!-- Outline the drawing area in blue -->
+  <rect fill="none" stroke="blue" 
+        x="1" y="1" width="798" height="398"/>
+
+  <!-- The ellipse is filled using a triangle pattern paint server
+       and stroked with black -->
+  <ellipse fill="url(http://example.com/browser/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg#TrianglePattern)" stroke="black" stroke-width="5"  
+           cx="400" cy="200" rx="350" ry="150" />
+</svg>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_fill_pattern_data.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
+     xmlns="http://www.w3.org/2000/svg">
+  <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
+  <!-- Outline the drawing area in blue -->
+  <rect fill="none" stroke="blue" 
+        x="1" y="1" width="798" height="398"/>
+
+  <!-- The ellipse is filled using a triangle pattern paint server
+       and stroked with black -->
+  <ellipse fill="url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iIAogICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI4Y20iIGhlaWdodD0iNGNtIiB2aWV3Qm94PSIwIDAgODAwIDQwMCIgdmVyc2lvbj0iMS4xIgogICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlc2M+Qm9ycm93ZWQgZnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcvcHNlcnZlcnMuaHRtbDwvZGVzYz4KICA8ZGVmcz4KICAgIDxwYXR0ZXJuIGlkPSJUcmlhbmdsZVBhdHRlcm4iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgICAgICAgICB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIKICAgICAgICAgICAgIHZpZXdCb3g9IjAgMCAxMCAxMCIgPgogICAgICA8cGF0aCBkPSJNIDAgMCBMIDcgMCBMIDMuNSA3IHoiIGZpbGw9InJlZCIgZmlsbC1vcGFjaXR5PSIwLjciIHN0cm9rZT0iYmx1ZSIgLz4KICAgIDwvcGF0dGVybj4gCiAgPC9kZWZzPgo8L3N2Zz4K#TrianglePattern)" stroke="black" stroke-width="5"  
+           cx="400" cy="200" rx="350" ry="150" />
+</svg>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
+     xmlns="http://www.w3.org/2000/svg">
+  <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
+  <defs>
+    <pattern id="TrianglePattern" patternUnits="userSpaceOnUse"
+             x="0" y="0" width="100" height="100"
+             viewBox="0 0 10 10" >
+      <path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" fill-opacity="0.7" stroke="blue" />
+    </pattern> 
+  </defs>
+</svg>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_fill_pattern_internal.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1"
+     xmlns="http://www.w3.org/2000/svg">
+  <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc>
+  <!-- Outline the drawing area in blue -->
+  <rect fill="none" stroke="blue" 
+        x="1" y="1" width="798" height="398"/>
+
+  <defs>
+    <pattern id="TrianglePattern" patternUnits="userSpaceOnUse"
+             x="0" y="0" width="100" height="100"
+             viewBox="0 0 10 10" >
+      <path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" fill-opacity="0.7" stroke="blue" />
+    </pattern> 
+  </defs>
+
+  <!-- The ellipse is filled using a triangle pattern paint server
+       and stroked with black -->
+  <ellipse fill="url(#TrianglePattern)" stroke="black" stroke-width="5"  
+           cx="400" cy="200" rx="350" ry="150" />
+</svg>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_getElementById.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="4in" height="3in" version="1.1"
+     xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+  <desc>Test graphic for hitting getElementById
+  </desc>
+  <image id="i1" x="200" y="200" width="100px" height="80px"
+         xlink:href="no-such-scheme:nothing">
+  </image>
+  <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
+  <script type="text/javascript"> <![CDATA[
+    var image = document.documentElement.getElementById("i1");
+    image.addEventListener("load",
+                           function() {
+                            document.documentElement.removeAttribute("class");
+                           },
+                           false);
+    ]]>
+  </script>
+</svg>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_use_counter_svg_list_style_image.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=968923
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 968923</title>
+  <style>
+/* Use a query string to work around imagelib caching.
+   Otherwise, we won't get use counters for this file.  */
+ul { list-style-image: url('file_use_counter_svg_currentScale.svg?asliststyleimage=1') }
+  </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a>
+<ul>
+  <li>Some text</li>
+  <li>Some other text</li>
+</ul>
+</body>
+</html>