mirror of
https://github.com/servo/servo
synced 2026-05-09 08:32:31 +02:00
538 lines
23 KiB
HTML
538 lines
23 KiB
HTML
<!DOCTYPE html>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="resources/get-host-info.sub.js"></script>
|
|
<script src="resources/test-helpers.sub.js"></script>
|
|
<body>
|
|
<script>
|
|
var worker = 'resources/fetch-event-test-worker.js';
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?string';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'Test string',
|
|
'Service Worker should respond to fetch with a test string');
|
|
assert_equals(
|
|
frame.contentDocument.contentType,
|
|
'text/plain',
|
|
'The content type of the response created with a string should be text/plain');
|
|
assert_equals(
|
|
frame.contentDocument.characterSet,
|
|
'UTF-8',
|
|
'The character set of the response created with a string should be UTF-8');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with string');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?blob';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'Test blob',
|
|
'Service Worker should respond to fetch with a test string');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with blob body');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?referrer';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'Referrer: ' + document.location.href,
|
|
'Service Worker should respond to fetch with the referrer URL');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with the referrer URL');
|
|
|
|
function run_referrer_policy_tests(frame, referrer, href, origin) {
|
|
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
|
{method: "GET", referrer: referrer})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + href + '\n' +
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present');
|
|
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
|
'/resources/simple.html?referrerFull';
|
|
return frame.contentWindow.fetch(http_url,
|
|
{method: "GET", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: about:client\n' +
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with no referrer when a member of RequestInit is present with an HTTP request');
|
|
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
|
{referrerPolicy: "", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + href + '\n' +
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with the referrer with ""');
|
|
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
|
'/resources/simple.html?referrerFull';
|
|
return frame.contentWindow.fetch(http_url,
|
|
{referrerPolicy: "", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: about:client\n' +
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with no referrer with ""');
|
|
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
|
{referrerPolicy: "origin", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + origin + '/' + '\n' +
|
|
'ReferrerPolicy: origin',
|
|
'Service Worker should respond to fetch with the referrer origin with "origin" and a same origin request');
|
|
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
|
'/resources/simple.html?referrerFull';
|
|
return frame.contentWindow.fetch(http_url,
|
|
{referrerPolicy: "origin", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + origin + '/' + '\n' +
|
|
'ReferrerPolicy: origin',
|
|
'Service Worker should respond to fetch with the referrer origin with "origin" and a cross origin request');
|
|
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
|
{referrerPolicy: "origin-when-cross-origin", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + href + '\n' +
|
|
'ReferrerPolicy: origin-when-cross-origin',
|
|
'Service Worker should respond to fetch with the referrer URL with "origin-when-cross-origin" and a same origin request');
|
|
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
|
'/resources/simple.html?referrerFull';
|
|
return frame.contentWindow.fetch(http_url,
|
|
{referrerPolicy: "origin-when-cross-origin", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + origin + '/' + '\n' +
|
|
'ReferrerPolicy: origin-when-cross-origin',
|
|
'Service Worker should respond to fetch with the referrer origin with "origin-when-cross-origin" and a cross origin request');
|
|
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
|
{referrerPolicy: "no-referrer-when-downgrade", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + href + '\n' +
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and a same origin request');
|
|
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
|
'/resources/simple.html?referrerFull';
|
|
return frame.contentWindow.fetch(http_url,
|
|
{referrerPolicy: "no-referrer-when-downgrade", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: about:client\n' +
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and an HTTP request');
|
|
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
|
'/resources/simple.html?referrerFull';
|
|
return frame.contentWindow.fetch(http_url, {referrerPolicy: "unsafe-url", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: ' + href + '\n' +
|
|
'ReferrerPolicy: unsafe-url',
|
|
'Service Worker should respond to fetch with no referrer with "unsafe-url"');
|
|
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
|
{referrerPolicy: "no-referrer", referrer: referrer});
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
assert_equals(
|
|
response_text,
|
|
'Referrer: about:client\n' +
|
|
'ReferrerPolicy: no-referrer',
|
|
'Service Worker should respond to fetch with no referrer URL with "no-referrer"');
|
|
});
|
|
}
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?referrerPolicy';
|
|
var frame;
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(f) {
|
|
frame = f;
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'ReferrerPolicy: no-referrer-when-downgrade',
|
|
'Service Worker should respond to fetch with the default referrer policy');
|
|
// First, run the referrer policy tests without passing a referrer in RequestInit.
|
|
return run_referrer_policy_tests(frame, undefined, frame.contentDocument.location.href,
|
|
frame.contentDocument.location.origin);
|
|
})
|
|
.then(function() {
|
|
// Now, run the referrer policy tests while passing a referrer in RequestInit.
|
|
var referrer = get_host_info()['HTTPS_ORIGIN'] + base_path() + 'fake-referrer';
|
|
return run_referrer_policy_tests(frame, 'fake-referrer', referrer,
|
|
frame.contentDocument.location.origin);
|
|
})
|
|
.then(function() {
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with the referrer URL');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?clientId';
|
|
var frame;
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(f) {
|
|
frame = f;
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'Client ID Not Found',
|
|
'Service Worker should respond to fetch with a client id');
|
|
return frame.contentWindow.fetch('resources/other.html?clientId');
|
|
})
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
var new_client_id = response_text.substr(17);
|
|
assert_equals(
|
|
response_text.substr(0, 15),
|
|
'Client ID Found',
|
|
'Service Worker should respond to fetch with an existing client id');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with an existing client id');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?ignore';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(frame.contentDocument.body.textContent,
|
|
'Here\'s a simple html file.\n',
|
|
'Response should come from fallback to native fetch');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker does not respond to fetch event');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?null';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(frame.contentDocument.body.textContent,
|
|
'',
|
|
'Response should be the empty string');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with null response body');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?fetch';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(frame.contentDocument.body.textContent,
|
|
'Here\'s an other html file.\n',
|
|
'Response should come from fetched other file');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker fetches other file in fetch event');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?form-post';
|
|
var frame_name = 'xhr-post-frame';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function(sw) {
|
|
return new Promise(function(resolve) {
|
|
var frame = document.createElement('iframe');
|
|
frame.name = frame_name;
|
|
document.body.appendChild(frame);
|
|
var form = document.createElement('form');
|
|
form.target = frame_name;
|
|
form.action = scope;
|
|
form.method = 'post';
|
|
var input1 = document.createElement('input');
|
|
input1.type = 'text';
|
|
input1.value = 'testValue1';
|
|
input1.name = 'testName1'
|
|
form.appendChild(input1);
|
|
var input2 = document.createElement('input');
|
|
input2.type = 'text';
|
|
input2.value = 'testValue2';
|
|
input2.name = 'testName2'
|
|
form.appendChild(input2);
|
|
document.body.appendChild(form);
|
|
frame.onload = function() {
|
|
document.body.removeChild(form);
|
|
resolve(frame);
|
|
};
|
|
form.submit();
|
|
});
|
|
})
|
|
.then(function(frame) {
|
|
assert_equals(frame.contentDocument.body.textContent,
|
|
'POST:application/x-www-form-urlencoded:' +
|
|
'testName1=testValue1&testName2=testValue2');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with POST form');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?multiple-respond-with';
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'(0)(1)[InvalidStateError](2)[InvalidStateError]',
|
|
'Multiple calls of respondWith must throw InvalidStateErrors.');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Multiple calls of respondWith must throw InvalidStateErrors');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?used-check';
|
|
var first_frame;
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(frame) {
|
|
assert_equals(frame.contentDocument.body.textContent,
|
|
'Here\'s an other html file.\n',
|
|
'Response should come from fetched other file');
|
|
first_frame = frame;
|
|
return with_iframe(scope);
|
|
})
|
|
.then(function(frame) {
|
|
// When we access to the scope in the second time, the content of the
|
|
// response is generated inside the ServiceWorker. The body contains
|
|
// the value of bodyUsed of the first response which is already
|
|
// consumed by FetchEvent.respondWith method.
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'bodyUsed: true',
|
|
'event.respondWith must set the used flag.');
|
|
first_frame.remove();
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker event.respondWith must set the used flag');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?fragment-check';
|
|
var fragment = '#/some/fragment';
|
|
var first_frame;
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope + fragment); })
|
|
.then(function(frame) {
|
|
assert_equals(
|
|
frame.contentDocument.body.textContent,
|
|
'Fragment Not Found',
|
|
'Service worker should not expose URL fragments.');
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker must not expose FetchEvent URL fragments.');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?cache';
|
|
var frame;
|
|
var cacheTypes = [
|
|
undefined, 'default', 'no-store', 'reload', 'no-cache', 'force-cache', 'only-if-cached'
|
|
];
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(f) {
|
|
frame = f;
|
|
assert_equals(frame.contentWindow.document.body.textContent, 'default');
|
|
var tests = cacheTypes.map(function(type) {
|
|
return new Promise(function(resolve, reject) {
|
|
var init = {cache: type};
|
|
if (type === 'only-if-cached') {
|
|
// For privacy reasons, for the time being, only-if-cached
|
|
// requires the mode to be same-origin.
|
|
init.mode = 'same-origin';
|
|
}
|
|
return frame.contentWindow.fetch(scope + '=' + type, init)
|
|
.then(function(response) { return response.text(); })
|
|
.then(function(response_text) {
|
|
var expected = (type === undefined) ? 'default' : type;
|
|
assert_equals(response_text, expected,
|
|
'Service Worker should respond to fetch with the correct type');
|
|
})
|
|
.then(resolve)
|
|
.catch(reject);
|
|
});
|
|
});
|
|
})
|
|
.then(function() {
|
|
return new Promise(function(resolve, reject) {
|
|
frame.addEventListener('load', function onLoad() {
|
|
frame.removeEventListener('load', onLoad);
|
|
try {
|
|
assert_equals(frame.contentWindow.document.body.textContent,
|
|
'no-cache');
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
frame.contentWindow.location.reload();
|
|
});
|
|
})
|
|
.then(function() {
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker responds to fetch event with the correct cache types');
|
|
|
|
async_test(function(t) {
|
|
var scope = 'resources/simple.html?eventsource';
|
|
var frame;
|
|
|
|
function test_eventsource(opts) {
|
|
return new Promise(function(resolve, reject) {
|
|
var eventSource = new frame.contentWindow.EventSource(scope, opts);
|
|
eventSource.addEventListener('message', function(msg) {
|
|
eventSource.close();
|
|
try {
|
|
var data = JSON.parse(msg.data);
|
|
assert_equals(data.mode, 'cors',
|
|
'EventSource should make CORS requests.');
|
|
assert_equals(data.cache, 'no-store',
|
|
'EventSource should bypass the http cache.');
|
|
var expectedCredentials = opts.withCredentials ? 'include'
|
|
: 'same-origin';
|
|
assert_equals(data.credentials, expectedCredentials,
|
|
'EventSource should pass correct credentials mode.');
|
|
resolve();
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
});
|
|
eventSource.addEventListener('error', function(e) {
|
|
eventSource.close();
|
|
reject('The EventSource fired an error event.');
|
|
});
|
|
});
|
|
}
|
|
|
|
service_worker_unregister_and_register(t, worker, scope)
|
|
.then(function(reg) {
|
|
return wait_for_state(t, reg.installing, 'activated');
|
|
})
|
|
.then(function() { return with_iframe(scope); })
|
|
.then(function(f) {
|
|
frame = f;
|
|
return test_eventsource({ withCredentials: false });
|
|
})
|
|
.then(function() {
|
|
return test_eventsource({ withCredentials: true });
|
|
})
|
|
.then(function() {
|
|
frame.remove();
|
|
return service_worker_unregister_and_done(t, scope);
|
|
})
|
|
.catch(unreached_rejection(t));
|
|
}, 'Service Worker should intercept EventSource');
|
|
|
|
</script>
|
|
</body>
|