Skip to content

Commit

Permalink
WPT: service worker: fix test for CSS base URL.
Browse files Browse the repository at this point in the history
The existing test was asserting the opposite of the standard,
which is to use the response URL. See
whatwg/fetch#146.

This CL does the following:
- Tests that a CSS stylesheet fetched via respondWith(fetch(responseUrl)
  uses responseUrl as its base URL.
- Tests that a CSS stylesheet fetched via respondWith(new Response())
  uses the response URL (which is the request URL) as its base URL.
- Changes the test to not test cross-origin stylesheets. That is more
  complex than needed for this test, and there is talk of making
  subresource requests from opaque stylesheets skip the service worker,
  which would render the test ineffective for testing base URL.
- Changes the test to use waitUntil() in the message event to try
  to ensure the service worker stays alive between the message and
  fetch events.

Bug: 911974
Change-Id: I167dfe86986ec718a50d512f862f1eb49889608b
  • Loading branch information
mfalken authored and chromium-wpt-export-bot committed Dec 5, 2018
1 parent 30b3f1d commit 389103e
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 76 deletions.
131 changes: 79 additions & 52 deletions service-workers/service-worker/fetch-request-css-base-url.https.html
Original file line number Diff line number Diff line change
@@ -1,58 +1,85 @@
<!DOCTYPE html>
<title>Service Worker: CSS's base URL must be the request URL even when fetched from other URL</title>
<title>Service Worker: CSS's base URL must be the response URL</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?pipe=sub"></script>
<script>
promise_test(function(t) {
var SCOPE = 'resources/fetch-request-css-base-url-iframe.html';
var SCRIPT = 'resources/fetch-request-css-base-url-worker.js';
var worker;
var testDonePromise;

return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
.then(function(registration) {
t.add_cleanup(function() {
return service_worker_unregister(t, SCOPE);
});

worker = registration.installing;
return wait_for_state(t, worker, 'activated');
})
.then(function() {
return new Promise(function(resolve) {
var channel = new MessageChannel();
testDonePromise = new Promise(function(resolveTestDone) {
channel.port1.onmessage = t.step_func(function(msg) {
if (msg.data.ready) {
resolve();
return;
}
var result = msg.data;
var base = get_host_info()['HTTPS_ORIGIN'] + base_path();
assert_equals(
result.url,
base + 'resources/dummy.png',
'The base URL while loading the images referred from CSS ' +
'must be the request URL of CSS.');
assert_equals(
result.referrer,
base + 'resources/fetch-request-css-base-url-style.css',
'While loading the image defined in CSS the referrer must ' +
'be the request URL of CSS.');
resolveTestDone();
});
});
worker.postMessage(
{port: channel.port2}, [channel.port2]);
});
})
.then(function() { return with_iframe(SCOPE); })
.then(function(f) {
return testDonePromise.then(function() {
f.remove();
});
});
}, 'CSS\'s base URL must be the request URL even when fetched from other URL.');
const SCOPE = 'resources/fetch-request-css-base-url-iframe.html';
const SCRIPT = 'resources/fetch-request-css-base-url-worker.js';
let worker;

var signalMessage;
function getNextMessage() {
return new Promise(resolve => { signalMessage = resolve; });
}

promise_test(async (t) => {
const registration = await service_worker_unregister_and_register(
t, SCRIPT, SCOPE);
worker = registration.installing;
await wait_for_state(t, worker, 'activated');
}, 'global setup');

// Creates a test concerning the base URL of a stylesheet. It loads a
// stylesheet from a controlled page. The stylesheet makes a subresource
// request for an image. The service worker messages back the details of the
// image request in order to test the base URL.
//
// The request URL for the stylesheet is under "resources/request-url-path/".
// The service worker may respond in a way such that the response URL is
// different to the request URL.
function base_url_test(params) {
promise_test(async (t) => {
let frame;
t.add_cleanup(() => {
if (frame)
frame.remove();
});

// Ask the service worker to message this page once it gets the request
// for the image.
var channel = new MessageChannel();
channel.port1.onmessage = (event) => {
signalMessage(event.data);
};
worker.postMessage({port:channel.port2},[channel.port2]);

// It sends a pong back immediately. This ping/pong protocol helps deflake
// the test for browsers where message/fetch ordering isn't guaranteed.
assert_equals('pong', await getNextMessage());

// Load the frame which will load the stylesheet that makes the image
// request.
frame = await with_iframe(params.framePath);
const result = await getNextMessage();

// Test the image request.
const base = new URL('.', document.location).href;
assert_equals(result.url,
base + params.expectImageRequestPath,
'request');
assert_equals(result.referrer,
base + params.expectImageRequestReferrer,
'referrer');
}, params.description);
}

const cssFile = 'fetch-request-css-base-url-style.css';

base_url_test({
framePath: SCOPE + '?fetch',
expectImageRequestPath: 'resources/dummy.png',
expectImageRequestReferrer: `resources/${cssFile}?fetch`,
description: 'base URL when service worker does respondWith(fetch(responseUrl)).'});

base_url_test({
framePath: SCOPE + '?newResponse',
expectImageRequestPath: 'resources/request-url-path/dummy.png',
expectImageRequestReferrer: `resources/request-url-path/${cssFile}?newResponse`,
description: 'base URL when service worker does respondWith(new Response()).'});

// Cleanup step: this must be the last promise_test.
promise_test(async (t) => {
return service_worker_unregister(t, SCOPE);
}, 'cleanup global state');
</script>
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
<link href="./fetch-request-css-base-url-style.css" rel="stylesheet" type="text/css">
<html>
<head>
<title>iframe for css base url test</title>
</head>
<body>
<script>
// Load a stylesheet.
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
// Add request-url-path to the path to help distinguish the request URL from
// the response URL.
link.href = 'request-url-path/fetch-request-css-base-url-style.css' +
document.location.search;
document.head.appendChild(link);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
importScripts('/common/get-host-info.sub.js');
importScripts('test-helpers.sub.js');
let source;
let resolveDone;
let done = new Promise(resolve => resolveDone = resolve);

var port = undefined;
self.addEventListener('message', event => {
source = event.data.port;
source.postMessage('pong');
event.waitUntil(done);
});

self.onmessage = function(e) {
var message = e.data;
if ('port' in message) {
port = message.port;
port.postMessage({ready: true});
}
};
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);

self.addEventListener('fetch', function(event) {
var url = event.request.url;
if (url.indexOf('fetch-request-css-base-url-style.css') != -1) {
event.respondWith(fetch(
get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() +
'fetch-request-css-base-url-style.css',
{mode: 'no-cors'}));
} else if (url.indexOf('dummy.png') != -1) {
port.postMessage({
url: event.request.url,
referrer: event.request.referrer
});
// For the CSS file, respond in a way that may change the response URL,
// depending on |url.search|.
const cssPath = 'request-url-path/fetch-request-css-base-url-style.css';
if (url.pathname.indexOf(cssPath) != -1) {
// Respond with a different URL, deleting "request-url-path/".
if (url.search == '?fetch') {
event.respondWith(fetch('fetch-request-css-base-url-style.css'));
}
// Respond with new Response().
else if (url.search == '?newResponse') {
const styleString = 'body { background-image: url("./dummy.png");}';
const headers = {'content-type': 'text/css'};
event.respondWith(new Response(styleString, headers));
}
});
}

// The image request indicates what the base URL of the CSS was. Message the
// result back to the test page.
else if (url.pathname.indexOf('dummy.png') != -1) {
source.postMessage({
url: event.request.url,
referrer: event.request.referrer
});
resolveDone();
}
});

0 comments on commit 389103e

Please sign in to comment.