Skip to content

Commit

Permalink
Upstream service worker navigation tests to WPT
Browse files Browse the repository at this point in the history
**navigation-redirect**

Update existing assertions to adhere to the latest version of the Fetch
specification. The relevant change from that document [1] is explained
as follows:

> [...]
> * Only when redirects are automatically followed should we set the
> skip-service-worker flag, otherwise we negatively affect navigations.
> [...]

(Note that the Request's "skip-service-worker flag" was subsequently
re-implemented as "service-workers mode" in [2].)

Insert two additional tests introduced by Chromium project commit
cb6838f5badc8c2df03f387f4aa726629214179a, whose message reads:

> Make no-location redirect response to be "opaque redirect" when
> redirect mode is manual.
>
> According to the spec, even if location header is not set, we should
> treat the redirect response as "opaqueredirect" if the redirect mode
> of the fetch request is "manual".
>
> This behavior was changed by this commit on the spec.
> whatwg/fetch@3e501f2

Remove the "-expectations.txt" file for this test since Chromium passes
the corrected version. Remove the Chromium-specific version of the test.

**navigation-redirect-body**

Re-locate test file to Web Platform Test directory for eventual
automated upstreaming. Simplify test body by constructing necessary DOM
declaratively with HTML. Schedule frame removal to occur following test
completion.

**navigation-redirect-to-http**

Re-locate test file to Web Platform Test directory for eventual
automated upstreaming. Prefer the generalized `redirect.py` script over
a test-specific script defining equivalent functionality. Correct typo
in test title.

[1] whatwg/fetch@ec6f5ef
[2] whatwg/fetch@d41c238

BUG=688116
[email protected]

Review-Url: https://codereview.chromium.org/2872363002
Cr-Commit-Position: refs/heads/master@{#472332}
  • Loading branch information
jugglinmike authored and chromium-wpt-export-bot committed May 17, 2017
1 parent 891e76d commit d9e8cd5
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 6 deletions.
53 changes: 53 additions & 0 deletions service-workers/service-worker/navigation-redirect-body.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<title>Service Worker: Navigation redirection must clear body</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<meta charset="utf-8">
<body>
<form id="test-form" method="POST" style="display: none;">
<input type="submit" id="submit-button" />
</form>
<script>
promise_test(function(t) {
var scope = 'resources/navigation-redirect-body.py';
var script = 'resources/navigation-redirect-body-worker.js';
var registration;
var frame = document.createElement('frame');
var form = document.getElementById('test-form');
var submit_button = document.getElementById('submit-button');

frame.src = 'about:blank';
frame.name = 'target_frame';
frame.id = 'frame';
document.body.appendChild(frame);
t.add_cleanup(function() { document.body.removeChild(frame); });

form.action = scope;
form.target = 'target_frame';

return service_worker_unregister_and_register(t, script, scope)
.then(function(r) {
registration = r;
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
var frame_load_promise = new Promise(function(resolve) {
frame.addEventListener('load', function() {
resolve(frame.contentWindow.document.body.innerText);
}, false);
});
submit_button.click();
return frame_load_promise;
})
.then(function(text) {
var request_uri = decodeURIComponent(text);
assert_equals(
request_uri,
'/service-workers/service-worker/resources/navigation-redirect-body.py?redirect');
return registration.unregister();
});
}, 'Navigation redirection must clear body');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<title>Service Worker: Service Worker can receive HTTP opaqueredirect response.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<meta charset="utf-8">
<body></body>
<script>
async_test(function(t) {
var frame_src = get_host_info()['HTTPS_ORIGIN'] + base_path() +
'resources/navigation-redirect-to-http-iframe.html';
function on_message(e) {
assert_equals(e.data.results, 'OK');
t.done();
}

window.addEventListener('message', t.step_func(on_message), false);

with_iframe(frame_src)
.then(function(frame) {
t.add_cleanup(function() { frame.remove(); });
});
}, 'Verify Service Worker can receive HTTP opaqueredirect response.');
</script>
26 changes: 23 additions & 3 deletions service-workers/service-worker/navigation-redirect.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,15 @@
return test_redirect(
SCOPE1 + 'url=' + encodeURIComponent(SCOPE1),
SCOPE1,
[[SCOPE1 + 'url=' + encodeURIComponent(SCOPE1)], [], []]);
[[SCOPE1 + 'url=' + encodeURIComponent(SCOPE1), SCOPE1], [], []]);
});
}, 'SW-fallbacked redirect to same-origin same-scope.');
promise_test(function(t) {
return setup_environment(t).then(function() {
return test_redirect(
SCOPE1 + 'url=' + encodeURIComponent(SCOPE2),
SCOPE2,
[[SCOPE1 + 'url=' + encodeURIComponent(SCOPE2)], [], []]);
[[SCOPE1 + 'url=' + encodeURIComponent(SCOPE2)], [SCOPE2], []]);
});
}, 'SW-fallbacked redirect to same-origin other-scope.');
promise_test(function(t) {
Expand All @@ -204,7 +204,7 @@
OTHER_ORIGIN_SCOPE,
[[SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE)],
[],
[]]);
[OTHER_ORIGIN_SCOPE]]);
});
}, 'SW-fallbacked redirect to other-origin in-scope.');

Expand Down Expand Up @@ -372,6 +372,16 @@
[OTHER_ORIGIN_SCOPE]]);
});
}, 'Redirect to other-origin in-scope with opaque redirect response.');
promise_test(function(t) {
return setup_environment(t).then(function() {
return test_redirect(
SCOPE1 + 'sw=opaque&noLocationRedirect',
SCOPE1 + 'sw=opaque&noLocationRedirect',
[[SCOPE1 + 'sw=opaque&noLocationRedirect'],
[],
[]]);
});
}, 'No location redirect response.');

// Opaque redirect passed through Cache.
// SW responds with an opaque redirectresponse from the Cache API.
Expand Down Expand Up @@ -445,5 +455,15 @@
},
'Redirect to other-origin in-scope with opaque redirect response which ' +
'is passed through Cache.');
promise_test(function(t) {
return setup_environment(t).then(function() {
return test_redirect(
SCOPE1 + 'sw=opaqueThroughCache&noLocationRedirect',
SCOPE1 + 'sw=opaqueThroughCache&noLocationRedirect',
[[SCOPE1 + 'sw=opaqueThroughCache&noLocationRedirect'],
[],
[]]);
});
}, 'No location redirect response via Cache.');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request)
.then(
function(response) {
return response;
},
function(error) {
return new Response('Error:' + error);
}));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os

filename = os.path.basename(__file__)

def main(request, response):
if request.method == 'POST':
return 302, [('Location', './%s?redirect' % filename)], ''

return [('Content-Type', 'text/plain')], request.request_path
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ def main(request, response):
headers = [("Location", request.GET["url"])]
return 302, headers, ''

return [], '''
status = 200

if "noLocationRedirect" in request.GET:
status = 302

return status, [], '''
<!DOCTYPE html>
<script>
window.parent.postMessage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ def main(request, response):
headers = [("Location", request.GET["url"])]
return 302, headers, ''

return [], '''
status = 200

if "noLocationRedirect" in request.GET:
status = 302

return status, [], '''
<!DOCTYPE html>
<script>
window.parent.postMessage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ def main(request, response):
headers = [("Location", request.GET["url"])]
return 302, headers, ''

return [], '''
status = 200

if "noLocationRedirect" in request.GET:
status = 302

return status, [], '''
<!DOCTYPE html>
<script>
window.parent.postMessage(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<script src="/common/get-host-info.sub.js"></script>
<script src="test-helpers.sub.js"></script>
<script>
var SCOPE = './redirect.py?Redirect=' + encodeURI('http://example.com');
var SCRIPT = 'navigation-redirect-to-http-worker.js';
var host_info = get_host_info();

navigator.serviceWorker.getRegistration(SCOPE)
.then(function(registration) {
if (registration)
return registration.unregister();
})
.then(function() {
return navigator.serviceWorker.register(SCRIPT, {scope: SCOPE});
})
.then(function(registration) {
return new Promise(function(resolve) {
registration.addEventListener('updatefound', function() {
resolve(registration.installing);
});
});
})
.then(function(worker) {
worker.addEventListener('statechange', on_state_change);
})
.catch(function(reason) {
window.parent.postMessage({results: 'FAILURE: ' + reason.message},
host_info['HTTPS_ORIGIN']);
});

function on_state_change(event) {
if (event.target.state != 'activated')
return;
with_iframe(SCOPE, {auto_remove: false})
.then(function(frame) {
window.parent.postMessage(
{results: frame.contentDocument.body.textContent},
host_info['HTTPS_ORIGIN']);
});
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
importScripts('/resources/testharness.js');

self.addEventListener('fetch', function(event) {
event.respondWith(new Promise(function(resolve) {
Promise.resolve()
.then(function() {
assert_equals(
event.request.redirect, 'manual',
'The redirect mode of navigation request must be manual.');
return fetch(event.request);
})
.then(function(response) {
assert_equals(
response.type, 'opaqueredirect',
'The response type of 302 response must be opaqueredirect.');
resolve(new Response('OK'));
})
.catch(function(error) {
resolve(new Response('Failed in SW: ' + error));
});
}));
});

0 comments on commit d9e8cd5

Please sign in to comment.