chromium/third_party/blink/web_tests/http/tests/subresource_filter/image-allow-disallow-transitions.html

<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<body>
<script type="text/javascript">
// Verify that when the 'src' attribute for an <img> element is changed, the
// element transitions properly between states where primary content is shown,
// fallback content is shown, and when the element is collapsed.
//
// This test is carried out using a matrix of <img> elements. Initially, all
// images in the first row are set to show primary content, all images in the
// second row are set to show fallback content, etc. Once everything is loaded,
// the 'src' URLs are changed so that all images in the first column should show
// primary content, in the second column fallback content, etc.

var INITIAL_URLS = {
  "primary": "resources/alpha.png",
  "fallback": "resources/non-existent-1.png",
  "collapsed": "resources/gamma.png"
};

var FINAL_URLS = {
  "primary": "resources/beta.png",
  "fallback": "resources/non-existent-2.png",
  "collapsed": "resources/delta.png"
};

var EXPECTED_LOADEND_EVENT = {
  "primary": "load",
  "fallback": "error",
  "collapsed": "error"
};

var EXPECTED_WIDTH = {
  "primary": 100,
  "fallback": 0,
  "collapsed": 0
};

var EXPECTED_DISPLAY = {
  "primary": "inline",
  "fallback": "inline",
  "collapsed": "none",
};

var numPendingImages =
    Object.keys(INITIAL_URLS).length * Object.keys(FINAL_URLS).length;

if (window.testRunner)
  testRunner.setDisallowedSubresourcePathSuffixes(["gamma.png", "delta.png"], true /* block_subresources */);

let table = document.createElement("table");
let headerRow = table.insertRow();

headerRow.insertCell().innerHTML = "- - - - \\ Final<br>Initial \\";
for (let finalState of Object.keys(FINAL_URLS)) {
  headerRow.insertCell().textContent = finalState;
}

for (let [initialState, initialUrl] of Object.entries(INITIAL_URLS)) {
  let row = table.insertRow();
  row.insertCell().textContent = initialState;
  for (let [finalState, finalUrl] of Object.entries(FINAL_URLS)) {
    let cell = row.insertCell();
    let img = document.createElement("img");
    img.src = initialUrl;
    async_test(t => {
      let eventWatcher = new EventWatcher(t, img, ["load", "error"]);
      eventWatcher.wait_for(EXPECTED_LOADEND_EVENT[initialState])
        .then(_ => {
          window.setTimeout(_ => img.src = finalUrl);
          return eventWatcher.wait_for(EXPECTED_LOADEND_EVENT[finalState]);
        })
        .then(t.step_func_done(_ => {
          assert_equals(img.clientWidth, EXPECTED_WIDTH[finalState],
              "Image has incorrect width for the expected final state.");
          let style = window.getComputedStyle(img);
          assert_equals(style.display, EXPECTED_DISPLAY[finalState],
              "Images has incorrect computed style for the final state.");
        }));
    }, "State transition " + initialState + " to " + finalState + ". ");
    cell.append(img);
  }
}
document.body.append(table);
</script>