<!DOCTYPE html>
<!--
  Copyright 2023 The Cobalt Authors. All Rights Reserved.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<html>
<head>
  <title>Cobalt Service Worker Add to Cache Test</title>
  <script src='black_box_js_test_utils.js'></script>
</head>
<body>
  <script>
    h5vcc.storage.clearServiceWorkerCache();

    const unregisterAll = () => navigator.serviceWorker.getRegistrations().then(registrations =>
        Promise.all(registrations.map(r => r.unregister())));
    const fail = msg => {
      if (msg) {
        console.error(msg);
      }
      unregisterAll().then(notReached);
    };
    const timeoutId = window.setTimeout(fail, 10000);
    const success = () => unregisterAll().then(() => {
      clearTimeout(timeoutId);
      onEndTest();
    });
    navigator.serviceWorker.onmessage = event => {
      if (event.data === 'SUCCESS') {
        success();
        return;
      }
      fail(event.data);
    };

    navigator.serviceWorker.ready.then(registration => {
      registration.active.postMessage('start-test');
    });

    unregisterAll().then(() => {
      navigator.serviceWorker.register('service_worker_add_to_cache_test.js').catch(fail);
    });

    setupFinished();
  </script>
</body>
</html>
