summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/presentation-api/receiving-ua/support/PresentationReceiver_create_receiving-ua_child.html
blob: 2f67f7fac02f967eeff1ff3e6170cb487d656ccf (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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>

<meta charset="utf-8">
<title>Creating a receiving browsing context</title>
<link rel="author" title="Tomoyuki Shimizu" href="https://github.com/tomoyukilabs/">
<link rel="help" href="https://w3c.github.io/presentation-api/#creating-a-receiving-browsing-context">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<p id="notice">Checking <code id="modal"></code>: if you see this message, please wait for test to time out.</p>

<script>
add_completion_callback((tests, status) => {
    // remove unserializable attributes, then send the result to the parent window
    // note: a single test result is supposed to appear here.
    window.parent.postMessage(JSON.parse(JSON.stringify({
        type: 'presentation-api', test: tests[0], status: status
    })), location.origin);
});

window.addEventListener('message', event => {
    if(event.data !== 'start')
        return;

    promise_test(t => {
        const notice = document.getElementById('notice');
        const modal = document.getElementById('modal');

        // Presentation and PresentationReceiver
        assert_true(navigator.presentation instanceof Presentation, 'navigator.presentation in a nested browsing context is an instanceof Presentation.');
        assert_equals(navigator.presentation.receiver, null, 'navigator.presentation.receiver in a nested browsing context is set to null.');

        // Session history
        assert_equals(window.history.length, 1, 'Session history consists of the current page only.');

        // The Sandboxed auxiliary navigation browsing context flag (codes below are expected to be ignored)
        assert_equals(window.open('./idlharness_receiving-ua.html'), null, 'Sandboxed auxiliary navigation browsing context flag is set.');

        // The sandboxed modals flag (codes below are expected to be ignored):
        // If user agent prompts user, a timeout will occur and the test will eventually fail
        let message = 'If you see this prompt, do not dismiss it and wait for test to time out.';
        notice.style.display = 'block';
        modal.textContent = 'alert()';
        alert(message);
        modal.textContent = 'confirm()';
        confirm(message);
        modal.textContent = 'print()';
        print();
        modal.textContent = 'prompt()';
        prompt(message);
        notice.style.display = 'none';

        // Permissions
        const checkPermission = query => {
            return navigator.permissions ? navigator.permissions.query(query).then(status => {
                assert_equals(status.state, 'denied', 'The state of the "' + query.name + '" permission in a nested browsing context is set to "denied".');
            }, () => { /* skip this assertion if the specified permission is not implemented */ }) : Promise.resolve();
        };

        // Cookie
        assert_equals(document.cookie, 'PresentationApiTest=Receiving-UA', 'A cookie store is shared by top-level and nested browsing contexts.');

        // Indexed Database
        const dbName = 'db-presentation-api-receiving-ua';
        const checkIndexedDB = () => {
            if ('indexedDB' in window) {
                message = 'Indexed Database is shared by top-level and nested browsing contexts.';

                const req = indexedDB.open(dbName);
                const upgradeneededWatcher = new EventWatcher(t, req, 'upgradeneeded');
                const successWatcher = new EventWatcher(t, req, 'success');
                return Promise.race([
                    upgradeneededWatcher.wait_for('upgradeneeded').then(evt => {
                        evt.target.result.close();
                        // This would fail if the database is not created by the top-level browsing context
                        assert_unreached(message);
                    }),
                    successWatcher.wait_for('success').then(evt => {
                        evt.target.result.close();
                        const db = evt.target.result;
                        const version = db.version;
                        db.close();
                        // Check if the version of the database is 2 as specified by the top-level browsing context
                        assert_equals(version, 2, message);

                        // Upgrade the version
                        const req = indexedDB.open(dbName, 3);
                        const eventWatcher = new EventWatcher(t, req, 'upgradeneeded');
                        return eventWatcher.wait_for('upgradeneeded');
                    }).then(evt => {
                        evt.target.result.close();
                    })
                ]);
            }
            else
                return Promise.resolve();
        };

        // Web Storage
        assert_equals(sessionStorage.length, 1, 'Session storage is shared by top-level and nested browsing contexts.');
        assert_equals(sessionStorage.getItem('presentation_api_test'), 'receiving-ua', 'Session storage is shared by top-level and nested browsing contexts.');
        assert_equals(localStorage.length, 1, 'Local storage is shared by top-level and nested browsing contexts.');
        assert_equals(localStorage.getItem('presentation_api_test'), 'receiving-ua', 'Local storage is shared by top-level and nested browsing contexts.');

        // Service Workers
        const checkServiceWorkers = () => {
            return 'serviceWorker' in navigator ? navigator.serviceWorker.getRegistrations().then(registrations => {
                message = 'List of registered service worker registrations is shared by top-level and nested browsing contexts.';
                assert_equals(registrations.length, 1, message);
                assert_equals(registrations[0].active.scriptURL, new Request('../serviceworker.js').url, message);
            }) : Promise.resolve();
        };
        const checkCaches = () => {
            message = 'Cache storage is shared by top-level and nested browsing contexts.';
            return 'caches' in window ? caches.keys().then(keys => {
                assert_equals(keys.length, 1, message);
                assert_equals(keys[0], 'receiving-ua', message);
                return caches.open(keys[0]);
            }).then(cache => cache.matchAll())
            .then(responses => {
                assert_equals(responses.length, 1, message);
                assert_equals(responses[0].url, new Request('../cache.txt').url, message);
            }) : Promise.resolve();
        };

        // Update storages and service workers shared with the top-level brosing context
        document.cookie = 'NestedBrowsingContext=True';
        sessionStorage.setItem('nested_browsing_context', 'yes');
        localStorage.setItem('nested_browsing_context', 'yes');

        // register a service worker with different scope from that of the top-level browsing context
        const registerServiceWorker = () => {
            return 'serviceWorker' in navigator ?
                navigator.serviceWorker.register('serviceworker.js').then(registration => {
                    return new Promise((resolve, reject) => {
                        if (registration.installing) {
                            registration.installing.addEventListener('statechange', event => {
                                if(event.target.state === 'installed')
                                    resolve();
                            });
                        }
                        else
                            resolve();
                    });
                }) : Promise.resolve();
        };

        const openCaches = () => {
            return 'caches' in window
                ? caches.open('nested-browsing-context').then(cache => cache.add('../cache.txt')) : Promise.resolve();
        };

        // Asynchronous tests
        const permissionList = [
            { name: 'geolocation' },
            { name: 'notifications' },
            { name: 'push', userVisibleOnly: true },
            { name: 'midi' },
            { name: 'camera' },
            { name: 'microphone' },
            { name: 'speaker' },
            { name: 'background-sync' }
        ];
        return Promise.all(permissionList.map(perm => { return checkPermission(perm); }))
            .then(checkIndexedDB)
            .then(checkServiceWorkers)
            .then(checkCaches)
            .then(registerServiceWorker)
            .then(openCaches);
    });
});
</script>