<!DOCTYPE html>
<title>Service Worker: Clients.matchAll</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
var scope = 'resources/blank.html?clients-matchAll';
var t = async_test('Test Clients.matchAll()');
var frames = [];
t.step(function() {
    service_worker_unregister_and_register(
        t, 'resources/clients-matchall-worker.js', scope)
      .then(function(registration) {
          return wait_for_state(t, registration.installing, 'activated');
        })
      .then(function() { return with_iframe(scope + '#1'); })
      .then(function(frame1) {
          frames.push(frame1);
          frame1.focus();
          return with_iframe(scope + '#2');
        })
      .then(function(frame2) {
          frames.push(frame2);
          var channel = new MessageChannel();
          channel.port1.onmessage = t.step_func(onMessage);
          frame2.contentWindow.navigator.serviceWorker.controller.postMessage(
              {port:channel.port2}, [channel.port2]);
        })
      .catch(unreached_rejection(t));
  });

var expected = [
    // visibilityState, focused, url, type, frameType
    ['visible', true, new URL(scope + '#1', location).toString(), 'window', 'nested'],
    ['visible', false, new URL(scope + '#2', location).toString(), 'window', 'nested']
];

function onMessage(e) {
  assert_equals(e.data.length, 2);
  assert_array_equals(e.data[0], expected[0]);
  assert_array_equals(e.data[1], expected[1]);
  frames.forEach(function(f) { f.remove(); });
  service_worker_unregister_and_done(t, scope);
}
</script>
