Commit 944e94a7 authored by Nicolás Peña Moreno's avatar Nicolás Peña Moreno Committed by Commit Bot

ElementTiming and LargestContentfulPaint: add more redirect tests

This CL adds more tests for Timing-Allow-Origin checks in ElementTiming
and LargestContentfulPaint with multiple redirects. Before, we had tests
for:
* Single cross-origin response with a TAO header (image-TAO.sub.html).
* Multiple redirects, with '*' TAO header (multi-redirect-image.html).

This CL renames the latter to be more descriptive and adds:
* Same-origin redirect tests (should pass without TAO headers).
* Multi-cross-origin redirect tests with various TAO header values.

Bug: 1003943
Change-Id: Id44f0f18f143c8ca4ee3ca40c2383fa2ae22590c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2001070
Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
Reviewed-by: default avatarYoav Weiss <yoavweiss@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732589}
parent 0b76c5a0
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>This test validates some Timing-Allow-Origin header usage in multiple redirects.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/element-timing-helpers.js"></script>
<script src="/common/get-host-info.sub.js"></script>
</head>
<body>
<script>
async_test(t => {
assert_precondition(window.PerformanceElementTiming, "PerformanceElementTiming is not implemented");
let destUrl = get_host_info().HTTP_REMOTE_ORIGIN
+ '/element-timing/resources/multiple-redirects.py?';
destUrl += 'redirect_count=2';
// The final resource has '*' in TAO header, so will not affect the result.
destUrl += '&final_resource=/element-timing/resources/circle-tao.svg';
destUrl += '&origin1=' + get_host_info().UNAUTHENTICATED_ORIGIN;
destUrl += '&origin2=' + get_host_info().HTTP_REMOTE_ORIGIN;
const taoCombinations = [
{tao1: location.origin, tao2: location.origin, passes: false},
{tao1: location.origin, tao2: get_host_info().HTTP_REMOTE_ORIGIN, passes: false},
{tao1: location.origin, tao2: 'null', passes: true},
{tao1: location.origin, tao2: '*', passes: true},
{tao1: location.origin, tao2: location.origin, passes: false},
{tao1: 'null', tao2: '*', passes: false},
{tao1: '*', tao2: 'null', passes: true},
];
function getURL(item) {
return destUrl + '&tao1=' + item.tao1 + '&tao2=' + item.tao2;
}
taoCombinations.forEach((item, index) => {
const image = document.createElement('img');
image.src = getURL(item);
image.setAttribute('elementtiming', item.passes.toString());
image.setAttribute('id', index);
document.body.appendChild(image);
});
let observed = new Array(taoCombinations.length).fill(false);
let observedCount = 0;
const beforeRender = performance.now();
new PerformanceObserver(t.step_func(entries => {
entries.getEntries().forEach(e => {
const index = parseInt(e.id);
assert_false(observed[index]);
const item = taoCombinations[index];
const url = getURL(item);
checkElement(e, url, item.passes.toString(), e.id, item.passes ? beforeRender : 0,
document.getElementById(e.id));
observed[index] = true;
observedCount++;
if (observedCount === taoCombinations.length)
t.done();
});
})).observe({entryTypes: ['element']});
}, 'Cross-origin images with passing/failing TAO should/shouldn\'t have its renderTime set.');
</script>
</body>
</html>
......@@ -18,7 +18,7 @@ async_test(t => {
+ '/resource-timing/resources/multi_redirect.py?';
destUrl += 'page_origin=' + get_host_info().HTTP_ORIGIN;
destUrl += '&cross_origin=' + get_host_info().HTTP_REMOTE_ORIGIN;
destUrl += '&final_resource=' + '/element-timing/resources/circle.svg';
destUrl += '&final_resource=' + '/element-timing/resources/circle-tao.svg';
destUrl += '&timing_allow=1';
destUrl += '&tao_steps=';
for (let taoSteps=0; taoSteps < 4; taoSteps++) {
......
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<circle cx="50%" cy="50%" r="80" style="fill:blue;" />
</svg>
......@@ -6,9 +6,11 @@ function checkElementInternal(entry, expectedUrl, expectedIdentifier, expectedID
assert_equals(entry.identifier, expectedIdentifier, 'identifier does not match');
if (beforeRender != 0) {
// In this case, renderTime is not 0.
assert_greater_than(entry.renderTime, 0, 'renderTime should be nonzero');
assert_equals(entry.startTime, entry.renderTime, 'startTime should equal renderTime');
} else {
// In this case, renderTime is 0, so compare to loadTime.
assert_equals(entry.renderTime, 0, 'renderTime should be zero');
assert_equals(entry.startTime, entry.loadTime, 'startTime should equal loadTime');
}
assert_equals(entry.duration, 0, 'duration should be 0');
......
def main(request, response):
"""Handler that causes multiple redirections.
Mandatory parameters:
redirect_count - A number which is at least 1 (number of redirects).
final_resource - The location of the last redirect.
For each number i between 1 and |redirect_count| we have the following optional parameters:
tao{{i}} - The Timing-Allow-Origin header of the ith response. Default is no header.
origin{{i}} - The origin of the ith redirect (i+1 response). Default is location.origin.
Note that the origin of the initial request cannot be controlled here
and the Timing-Allow-Origin header of the final response cannot be controlled here.
Example: redirect_count=2&final_resource=miau.png&tao1=*
Note: |step| is used internally to track the current redirect number.
"""
step = 1
if "step" in request.GET:
try:
step = int(request.GET.first("step"))
except ValueError:
pass
redirect_count = int(request.GET.first("redirect_count"))
final_resource = request.GET.first("final_resource")
tao_value = None
tao = "tao" + str(step)
if tao in request.GET:
tao_value = request.GET.first(tao)
redirect_url = ""
origin = "origin" + str(step)
if origin in request.GET:
redirect_url = request.GET.first(origin)
if step == redirect_count:
redirect_url += final_resource
else:
redirect_url += "/element-timing/resources/multiple-redirects.py?"
redirect_url += "redirect_count=" + str(redirect_count)
redirect_url += "&final_resource=" + final_resource
for i in range(1, redirect_count + 1):
tao = "tao" + str(i)
if tao in request.GET:
redirect_url += "&" + tao + "=" + request.GET.first(tao)
origin = "origin" + str(i)
if origin in request.GET:
redirect_url += "&" + origin + "=" + request.GET.first(origin)
redirect_url += "&step=" + str(step + 1)
if tao_value:
response.headers.set("timing-allow-origin", tao_value)
response.status = 302
response.headers.set("Location", redirect_url)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>This test validates element timing information for same-origin redirect chain.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/element-timing-helpers.js"></script>
</head>
<body>
<script>
async_test(t => {
assert_precondition(window.PerformanceElementTiming, "PerformanceElementTiming is not implemented");
// First redirect
let destUrl = '/common/redirect.py?location='
// Second redirect
destUrl += '/common/redirect.py?location='
// Image without TAO headers.
destUrl += '/element-timing/resources/square20.png';
let beforeRender;
new PerformanceObserver(t.step_func_done(entries => {
assert_equals(entries.getEntries().length, 1, 'There should be one entry');
const entry = entries.getEntries()[0];
checkElement(entry, location.origin + destUrl, 'et', 'id', beforeRender,
document.getElementById('id'));
})).observe({entryTypes: ['element']});
const image = document.createElement('img');
image.src = destUrl;
image.setAttribute('elementtiming', 'et');
image.setAttribute('id', 'id')
document.body.appendChild(image);
beforeRender = performance.now();
}, 'Same-origin image redirect without TAO should have its renderTime set.');
</script>
</body>
</html>
......@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8" />
<title>This test validates LargestContenfulPaint information for cross-origin redirect chain images.</title>
<title>This test validates LargestContentfulPaint information for cross-origin redirect chain images.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/largest-contentful-paint-helpers.js"></script>
......@@ -11,14 +11,12 @@
<body>
<script>
async_test(t => {
if (!window.LargestContentfulPaint) {
assert_unreached("LargestContentfulPaint is not implemented");
}
assert_precondition(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented");
let destUrl = get_host_info().HTTP_REMOTE_ORIGIN
+ '/resource-timing/resources/multi_redirect.py?';
destUrl += 'page_origin=' + get_host_info().HTTP_ORIGIN;
destUrl += '&cross_origin=' + get_host_info().HTTP_REMOTE_ORIGIN;
destUrl += '&final_resource=' + '/element-timing/resources/circle.svg';
destUrl += '&final_resource=' + '/element-timing/resources/circle-tao.svg';
destUrl += '&timing_allow=1';
destUrl += '&tao_steps=';
......
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>This test validates LargestContentfulPaint for same-origin redirect chain.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/largest-contentful-paint-helpers.js"></script>
</head>
<body>
<script>
async_test(t => {
assert_precondition(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented");
// First redirect
let destUrl = '/common/redirect.py?location='
// Second redirect
destUrl += '/common/redirect.py?location='
// Image without TAO headers.
destUrl += '/element-timing/resources/square20.png';
let beforeLoad;
new PerformanceObserver(t.step_func_done(entries => {
assert_equals(entries.getEntries().length, 1, 'There should be one entry');
const entry = entries.getEntries()[0];
checkImage(entry, location.origin + destUrl, 'id', 20*20, beforeLoad);
})).observe({entryTypes: ['largest-contentful-paint']});
const image = document.createElement('img');
image.src = destUrl;
image.setAttribute('id', 'id')
document.body.appendChild(image);
beforeLoad = performance.now();
}, 'Same-origin image redirect without TAO should have its renderTime set.');
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment