<!DOCTYPE html>
<title>Access to the Push API is deferred</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/common/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.js"></script>

<body>
<script>
setup(() => assertSpeculationRulesIsSupported());

promise_test(async t => {
  const uid = token();
  const bc = new PrerenderChannel('test-channel', uid);
  t.add_cleanup(_ => bc.close());

  const gotMessage = new Promise(resolve => {
    bc.addEventListener('message', e => {
      resolve(e.data);
    }, {
      once: true
    });
  });

  // We grant the permission here to make a more discerning test because
  // pushManager.subscribe() waits until the permission is granted, which
  // is deferred during prerendering so the test would trivially pass without
  // the permission.
  await test_driver.set_permission({ name: 'push', userVisibleOnly: true },
                                   'granted');

  // Install the service worker first to test pushManager.subscribe in the
  // prerendering page.
  const scope = `resources/`;
  const script = `resources/do-nothing-worker.js`;
  const registration =
      await service_worker_unregister_and_register(t, script, scope);
  t.add_cleanup(() => registration.unregister());
  await wait_for_state(t, registration.installing, 'activated');

  const url = `resources/push.https.html?uid=${uid}`;
  window.open(url, '_blank', 'noopener');

  const result = await gotMessage;
  const expected = [
    {event: 'started waiting pushManager.subscribe',    prerendering: true},
    {event: 'prerendering change',                      prerendering: false},
    {event: 'finished waiting pushManager.subscribe',   prerendering: false},
  ];
  assert_equals(result.length, expected.length);
  for (let i = 0; i < result.length; i++) {
    assert_equals(result[i].event, expected[i].event, `event[${i}]`);
    assert_equals(result[i].prerendering, expected[i].prerendering,
      `prerendering[${i}]`);
  }

  // Send a close signal to PrerenderEventCollector on the prerendered page.
  new PrerenderChannel('close', uid).postMessage('');
}, `The access to the Push API should be deferred until the prerendered page is
    activated`);
</script>
