summaryrefslogtreecommitdiffstats
path: root/dom/serviceworkers/test/test_onmessageerror.html
blob: 425b890951003ea110640ac40d3b329f57495699 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<!DOCTYPE html>
<html>
  <head>
    <title>Test onmessageerror event handlers</title>
  </head>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="utils.js"></script>
  <script>
    /**
     * Test that ServiceWorkerGlobalScope and ServiceWorkerContainer handle
     * `messageerror` events, using a test helper class `StructuredCloneTester`.
     * Intances of this class can be configured to fail to serialize or
     * deserialize, as it's difficult to artificially create the case where an
     * object successfully serializes but fails to deserialize (which can be
     * caused by out-of-memory failures or the target global not supporting a
     * serialized interface).
     */

    let registration = null;
    let serviceWorker = null;
    let serviceWorkerContainer = null;
    const swScript = 'onmessageerror_worker.js';

    add_task(async () => {
      await SpecialPowers.pushPrefEnv({
        set: [
          ['dom.serviceWorkers.enabled', true],
          ['dom.serviceWorkers.testing.enabled', true],
          ['dom.testing.structuredclonetester.enabled', true],
        ],
      });

      swContainer = navigator.serviceWorker;

      registration = await swContainer.register(swScript);
      ok(registration, 'Service Worker regsisters');

      serviceWorker = registration.installing;
      await waitForState(serviceWorker, 'activated');
    }); // setup

    add_task(async () => {
      const serializable = true;
      const deserializable = true;
      let sct = new StructuredCloneTester(serializable, deserializable);

      const p = new Promise((resolve, reject) => {
        function onMessage(e) {
          const expectedBehavior = 'Serializable and deserializable ' +
            'StructuredCloneTester serializes and deserializes';

          is(e.data.received, 'message', expectedBehavior);
          swContainer.removeEventListener('message', onMessage);
          resolve();
        }

        swContainer.addEventListener('message', onMessage);
      });

      serviceWorker.postMessage({ serializable, deserializable, sct });

      await p;
    });

    add_task(async () => {
      const serializable = false;
      // if it's not serializable, being deserializable or not doesn't matter
      const deserializable = false;
      let sct = new StructuredCloneTester(serializable, deserializable);

      try {
        serviceWorker.postMessage({ serializable, deserializable, sct });
        ok(false, 'StructuredCloneTester serialization should have thrown -- ' +
          'this line should not have been reached.');
      } catch (e) {
        const expectedBehavior = 'Unserializable StructuredCloneTester fails ' +
          `to send, with exception name: ${e.name}`;
        is(e.name, 'DataCloneError', expectedBehavior);
      }
    });

    add_task(async () => {
      const serializable = true;
      const deserializable = false;
      let sct = new StructuredCloneTester(serializable, deserializable);

      const p = new Promise((resolve, reject) => {
        function onMessage(e) {
          const expectedBehavior = 'ServiceWorkerGlobalScope handles ' +
            'messageerror events';

          is(e.data.received, 'messageerror', expectedBehavior);
          swContainer.removeEventListener('message', onMessage);
          resolve();
        }

        swContainer.addEventListener('message', onMessage);
      });

      serviceWorker.postMessage({ serializable, deserializable, sct });

      await p;
    }); // test ServiceWorkerGlobalScope onmessageerror

    add_task(async () => {
      const p = new Promise((resolve, reject) => {
        function onMessageError(e) {
          ok(true, 'ServiceWorkerContainer handles messageerror events');
          swContainer.removeEventListener('messageerror', onMessageError);
          resolve();
        }

        swContainer.addEventListener('messageerror', onMessageError);
      });

      serviceWorker.postMessage('send-bad-message');

      await p;
    }); // test ServiceWorkerContainer onmessageerror

    add_task(async () => {
      await SpecialPowers.popPrefEnv();
      ok(await registration.unregister(), 'Service Worker unregisters');
    }); // teardown
  </script>
  <body>
  </body>
</html>