mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 13:09:21 +01:00
test: update performance-timeline
wpt
PR-URL: https://github.com/nodejs/node/pull/55197 Reviewed-By: Filip Skokan <panva.ip@gmail.com>
This commit is contained in:
parent
c185e11623
commit
1aa71351fa
2
test/fixtures/wpt/README.md
vendored
2
test/fixtures/wpt/README.md
vendored
@ -24,7 +24,7 @@ Last update:
|
||||
- html/webappapis/structured-clone: https://github.com/web-platform-tests/wpt/tree/47d3fb280c/html/webappapis/structured-clone
|
||||
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/5873f2d8f1/html/webappapis/timers
|
||||
- interfaces: https://github.com/web-platform-tests/wpt/tree/e90ece61d6/interfaces
|
||||
- performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline
|
||||
- performance-timeline: https://github.com/web-platform-tests/wpt/tree/94caab7038/performance-timeline
|
||||
- resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing
|
||||
- resources: https://github.com/web-platform-tests/wpt/tree/1e140d63ec/resources
|
||||
- streams: https://github.com/web-platform-tests/wpt/tree/2bd26e124c/streams
|
||||
|
95
test/fixtures/wpt/performance-timeline/back-forward-cache-restoration.tentative.html
vendored
Normal file
95
test/fixtures/wpt/performance-timeline/back-forward-cache-restoration.tentative.html
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="/common/dispatcher/dispatcher.js"></script>
|
||||
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const BackForwardCacheRestorationName = '';
|
||||
const BackForwardCacheRestorationType = 'back-forward-cache-restoration';
|
||||
|
||||
let getNavigationId = (i) => {
|
||||
let identifier = 'mark' + i;
|
||||
performance.mark(identifier);
|
||||
return window.performance.getEntriesByName(identifier)[0].navigationId;
|
||||
}
|
||||
|
||||
let getNumberofBackForwardCacheRestorationEntries = (BackForwardCacheRestorationType) => {
|
||||
return window.performance.getEntriesByType(BackForwardCacheRestorationType).length;
|
||||
}
|
||||
|
||||
let getBackForwardCacheRestorationByType = (BackForwardCacheRestorationType) => {
|
||||
let entries = window.performance.getEntriesByType(BackForwardCacheRestorationType);
|
||||
return entries[entries.length - 1];
|
||||
}
|
||||
|
||||
let getBackForwardCacheRestorationByGetAllAndFilter = (BackForwardCacheRestorationType) => {
|
||||
let entries = window.performance.getEntries().filter(e => e.entryType == BackForwardCacheRestorationType);
|
||||
return entries[entries.length - 1];
|
||||
}
|
||||
|
||||
let getBackForwardCacheRestorationByPerformanceObserverBuffered = async (BackForwardCacheRestorationType) => {
|
||||
let p = new Promise(resolve => {
|
||||
new PerformanceObserver((list) => {
|
||||
const entries = list.getEntries().filter(e => e.entryType == BackForwardCacheRestorationType);
|
||||
if (entries.length > 0) {
|
||||
resolve(entries[entries.length - 1]);
|
||||
}
|
||||
}).observe({ type: BackForwardCacheRestorationType, buffered: true });
|
||||
});
|
||||
return await p;
|
||||
}
|
||||
|
||||
let checkEntry = (entry, previousNavigationId) => {
|
||||
assert_equals(entry.name, BackForwardCacheRestorationName);
|
||||
assert_equals(entry.entryType, BackForwardCacheRestorationType);
|
||||
assert_not_equals(entry.navigationId, previousNavigationId);
|
||||
assert_true(entry.pageshowEventStart > entry.startTime);
|
||||
assert_true(entry.pageshowEventEnd >= entry.pageshowEventStart);
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const pageA = new RemoteContext(token());
|
||||
const pageB = new RemoteContext(token());
|
||||
|
||||
const urlA = executorPath + pageA.context_id;
|
||||
const urlB = originCrossSite + executorPath + pageB.context_id;
|
||||
// Open url A.
|
||||
window.open(urlA, '_blank', 'noopener');
|
||||
await pageA.execute_script(waitForPageShow);
|
||||
|
||||
// Assert no instance of BackForwardCacheRestoration exists without back forward cache navigatoin.
|
||||
let size = await pageA.execute_script(getNumberofBackForwardCacheRestorationEntries);
|
||||
assert_equals(0, size);
|
||||
|
||||
let entry;
|
||||
for (i = 0; i < 2; i++) {
|
||||
let curr_nav_id = await pageA.execute_script(getNavigationId, [i]);
|
||||
|
||||
// Navigate away to url B and back.
|
||||
await navigateAndThenBack(pageA, pageB, urlB);
|
||||
|
||||
// Assert Performance Observer API supports BackForwardCacheRestoration.
|
||||
entry = await pageA.execute_script(getBackForwardCacheRestorationByPerformanceObserverBuffered, [BackForwardCacheRestorationType]);
|
||||
// The navigation id after a bfcache restoration should be different
|
||||
// from that before.
|
||||
checkEntry(entry, curr_nav_id);
|
||||
|
||||
// Assert Performance Timeline API supports BackForwardCacheRestoration.
|
||||
entry = await pageA.execute_script(getBackForwardCacheRestorationByType, [BackForwardCacheRestorationType]);
|
||||
checkEntry(entry, curr_nav_id);
|
||||
|
||||
entry = await pageA.execute_script(getBackForwardCacheRestorationByGetAllAndFilter, [BackForwardCacheRestorationType]);
|
||||
checkEntry(entry, curr_nav_id);
|
||||
}
|
||||
}, 'Performance API for the back forward cache restoration entry.');
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
81
test/fixtures/wpt/performance-timeline/droppedentriescount.any.js
vendored
Normal file
81
test/fixtures/wpt/performance-timeline/droppedentriescount.any.js
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
promise_test(t => {
|
||||
// This setup is required for later tests as well.
|
||||
// Await for a dropped entry.
|
||||
return new Promise(res => {
|
||||
// Set a buffer size of 0 so that new resource entries count as dropped.
|
||||
performance.setResourceTimingBufferSize(0);
|
||||
// Use an observer to make sure the promise is resolved only when the
|
||||
// new entry has been created.
|
||||
new PerformanceObserver(res).observe({type: 'resource'});
|
||||
fetch('resources/square.png?id=1');
|
||||
}).then(() => {
|
||||
return new Promise(resolve => {
|
||||
new PerformanceObserver(t.step_func((entries, obs, options) => {
|
||||
assert_equals(options['droppedEntriesCount'], 0);
|
||||
resolve();
|
||||
})).observe({type: 'mark'});
|
||||
performance.mark('test');
|
||||
})});
|
||||
}, 'Dropped entries count is 0 when there are no dropped entries of relevant type.');
|
||||
|
||||
promise_test(async t => {
|
||||
return new Promise(resolve => {
|
||||
new PerformanceObserver(t.step_func((entries, obs, options) => {
|
||||
assert_equals(options['droppedEntriesCount'], 1);
|
||||
resolve();
|
||||
})).observe({entryTypes: ['mark', 'resource']});
|
||||
performance.mark('meow');
|
||||
});
|
||||
}, 'Dropped entries correctly counted with multiple types.');
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
new PerformanceObserver(t.step_func((entries, obs, options) => {
|
||||
assert_equals(options['droppedEntriesCount'], 1,
|
||||
'There should have been some dropped resource timing entries at this point');
|
||||
resolve();
|
||||
})).observe({type: 'resource', buffered: true});
|
||||
});
|
||||
}, 'Dropped entries counted even if observer was not registered at the time.');
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
let callback_ran = false;
|
||||
new PerformanceObserver(t.step_func((entries, obs, options) => {
|
||||
if (!callback_ran) {
|
||||
assert_equals(options['droppedEntriesCount'], 2,
|
||||
'There should be two dropped entries right now.');
|
||||
fetch('resources/square.png?id=3');
|
||||
callback_ran = true;
|
||||
} else {
|
||||
assert_equals(options['droppedEntriesCount'], undefined,
|
||||
'droppedEntriesCount should be unset after the first callback!');
|
||||
resolve();
|
||||
}
|
||||
})).observe({type: 'resource'});
|
||||
fetch('resources/square.png?id=2');
|
||||
});
|
||||
}, 'Dropped entries only surfaced on the first callback.');
|
||||
|
||||
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
let callback_ran = false;
|
||||
let droppedEntriesCount = -1;
|
||||
new PerformanceObserver(t.step_func((entries, obs, options) => {
|
||||
if (!callback_ran) {
|
||||
assert_greater_than(options['droppedEntriesCount'], 0,
|
||||
'There should be several dropped entries right now.');
|
||||
droppedEntriesCount = options['droppedEntriesCount'];
|
||||
callback_ran = true;
|
||||
obs.observe({type: 'mark'});
|
||||
performance.mark('woof');
|
||||
} else {
|
||||
assert_equals(options['droppedEntriesCount'], droppedEntriesCount,
|
||||
'There should be droppedEntriesCount due to the new observe().');
|
||||
resolve();
|
||||
}
|
||||
})).observe({type: 'resource'});
|
||||
fetch('resources/square.png?id=4');
|
||||
});
|
||||
}, 'Dropped entries surfaced after an observe() call!');
|
2
test/fixtures/wpt/performance-timeline/idlharness-shadowrealm.window.js
vendored
Normal file
2
test/fixtures/wpt/performance-timeline/idlharness-shadowrealm.window.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// META: script=/resources/idlharness-shadowrealm.js
|
||||
idl_test_shadowrealm(["performance-timeline"], ["hr-time", "dom"]);
|
30
test/fixtures/wpt/performance-timeline/navigation-id-detached-frame.tentative.html
vendored
Normal file
30
test/fixtures/wpt/performance-timeline/navigation-id-detached-frame.tentative.html
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>The navigation_id Detached iframe Parent Page.</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
promise_test(t => {
|
||||
return new Promise(resolve => {
|
||||
const frame = document.createElement("iframe");
|
||||
frame.addEventListener("load", async () => {
|
||||
// Wait for iframe to be detached.
|
||||
while (frame.contentWindow) {
|
||||
await new Promise(r => t.step_timeout(r, 10));
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
frame.src = "resources/navigation-id-detached-frame-page.html";
|
||||
document.body.appendChild(frame);
|
||||
});
|
||||
}, "The navigation_id getter does not crash a window of detached frame");
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
14
test/fixtures/wpt/performance-timeline/navigation-id-element-timing.tentative.html
vendored
Normal file
14
test/fixtures/wpt/performance-timeline/navigation-id-element-timing.tentative.html
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="/common/dispatcher/dispatcher.js"></script>
|
||||
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
|
||||
<script src="navigation-id.helper.js"></script>
|
||||
<script>
|
||||
runNavigationIdTest({
|
||||
navigationTimes: 3,
|
||||
testName: 'element_timing',
|
||||
}, "Element Timing navigation id test");
|
||||
</script>
|
49
test/fixtures/wpt/performance-timeline/navigation-id-initial-load.tentative.html
vendored
Normal file
49
test/fixtures/wpt/performance-timeline/navigation-id-initial-load.tentative.html
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
Navigation timing, LCP and paint timing entries are only emitted during initial
|
||||
load, not after a bfcache navigation. Therefore we only verify the existence of
|
||||
navigation id, not the increment.
|
||||
-->
|
||||
|
||||
<body>
|
||||
<p>This text is to trigger a LCP entry emission.</p>
|
||||
<script>
|
||||
async function NavigationIdsFromLCP() {
|
||||
return new Promise(resolve => {
|
||||
new PerformanceObserver((entryList) => {
|
||||
resolve(entryList.getEntries());
|
||||
}).observe({ type: 'largest-contentful-paint', buffered: true });
|
||||
})
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
// Assert navigation id exists in LCP entries and and are all the same.
|
||||
const navigationIdsOfLCP = (await NavigationIdsFromLCP()).map(e => e.navigationId);
|
||||
assert_true(navigationIdsOfLCP.every(e => e == navigationIdsOfLCP[0]),
|
||||
'Navigation Ids of LCP entries should be the same at initial navigation');
|
||||
|
||||
// Assert navigation id exists in a NavigationTiming entry.
|
||||
const navigationIdOfNavigationTiming =
|
||||
performance.getEntriesByType('navigation')[0].navigationId;
|
||||
assert_true(!!navigationIdOfNavigationTiming,
|
||||
'Navigation Id of a navigation timing entry should exist at initial navigation');
|
||||
|
||||
// Assert navigation id exists in PaintTiming entries and are all the same.
|
||||
const navigationIdsOfPaintTiming =
|
||||
performance.getEntriesByType('paint').map(e => e.navigationId);
|
||||
assert_true(navigationIdsOfPaintTiming.every(e =>
|
||||
e == navigationIdsOfPaintTiming[0]),
|
||||
'Navigation Id of PaintTiming entries should be the same as the initial navigation.');
|
||||
|
||||
// Assert navigation ids are all the same.
|
||||
const navigationIdsOfAll =
|
||||
navigationIdsOfLCP.concat(navigationIdsOfPaintTiming, navigationIdOfNavigationTiming);
|
||||
assert_true(navigationIdsOfAll.every(e => e == navigationIdsOfAll[0]),
|
||||
'Navigation Id of all entries should be the same as the initial navigation.');
|
||||
|
||||
}, 'Navigation Ids should exist and are all the same as the initial navigation.');
|
||||
</script>
|
||||
</body>
|
14
test/fixtures/wpt/performance-timeline/navigation-id-long-task-task-attribution.tentative.html
vendored
Normal file
14
test/fixtures/wpt/performance-timeline/navigation-id-long-task-task-attribution.tentative.html
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="/common/dispatcher/dispatcher.js"></script>
|
||||
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
|
||||
<script src="navigation-id.helper.js"></script>
|
||||
<script>
|
||||
runNavigationIdTest({
|
||||
navigationTimes: 3,
|
||||
testName: 'long_task_task_attribution',
|
||||
}, "Long Task/Task Attribution navigation id test");
|
||||
</script>
|
14
test/fixtures/wpt/performance-timeline/navigation-id-mark-measure.tentative.html
vendored
Normal file
14
test/fixtures/wpt/performance-timeline/navigation-id-mark-measure.tentative.html
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="/common/dispatcher/dispatcher.js"></script>
|
||||
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
|
||||
<script src="navigation-id.helper.js"></script>
|
||||
<script>
|
||||
runNavigationIdTest({
|
||||
navigationTimes: 3,
|
||||
testName: 'mark_measure',
|
||||
}, "Mark/Measure navigation id test");
|
||||
</script>
|
53
test/fixtures/wpt/performance-timeline/navigation-id-reset.tentative.html
vendored
Normal file
53
test/fixtures/wpt/performance-timeline/navigation-id-reset.tentative.html
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="/common/dispatcher/dispatcher.js"></script>
|
||||
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
|
||||
<script>
|
||||
const reload = () => {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
const getNavigationId = () => {
|
||||
window.performance.mark('initial_load');
|
||||
let entries = window.performance.getEntriesByType('mark');
|
||||
return entries[entries.length - 1].navigationId;
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const pageA = new RemoteContext(token());
|
||||
const pageB = new RemoteContext(token());
|
||||
|
||||
const urlA = executorPath + pageA.context_id;
|
||||
const urlB = originCrossSite + executorPath + pageB.context_id;
|
||||
// Open url A.
|
||||
window.open(urlA, '_blank', 'noopener')
|
||||
await pageA.execute_script(waitForPageShow);
|
||||
|
||||
let navigationIdInitial = await pageA.execute_script(getNavigationId);
|
||||
|
||||
// Navigate away to url B and back.
|
||||
await navigateAndThenBack(pageA, pageB, urlB);
|
||||
|
||||
// Assert navigation id is re-generated and thus different when the
|
||||
// document is load from bfcache.
|
||||
navigationIdAfterBFCacheNav = await pageA.execute_script(getNavigationId);
|
||||
assert_not_equals(navigationIdInitial, navigationIdAfterBFCacheNav, 'Navigation Id should be \
|
||||
re-generated and different from the previous one after back-forward-cache navigation.');
|
||||
|
||||
// Reload page.
|
||||
await pageA.execute_script(reload);
|
||||
await pageA.execute_script(waitForPageShow);
|
||||
|
||||
navigationIdAfterReset = await pageA.execute_script(getNavigationId);
|
||||
|
||||
assert_not_equals(navigationIdAfterReset, navigationIdAfterBFCacheNav, 'Navigation Id should\
|
||||
be re-generated after reload which is different from the previous one.');
|
||||
|
||||
assert_not_equals(navigationIdAfterReset, navigationIdInitial, 'Navigation Id should\
|
||||
be re-generated after reload which is different from the one of the initial load.');
|
||||
|
||||
}, 'Navigation Id should be re-generated after reload.');
|
||||
</script>
|
14
test/fixtures/wpt/performance-timeline/navigation-id-resource-timing.tentative.html
vendored
Normal file
14
test/fixtures/wpt/performance-timeline/navigation-id-resource-timing.tentative.html
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
<script src="/common/dispatcher/dispatcher.js"></script>
|
||||
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
|
||||
<script src="navigation-id.helper.js"></script>
|
||||
<script>
|
||||
runNavigationIdTest({
|
||||
navigationTimes: 3,
|
||||
testName: 'resource_timing',
|
||||
}, "Resource Timing navigation id test");
|
||||
</script>
|
27
test/fixtures/wpt/performance-timeline/navigation-id-worker-created-entries.html
vendored
Normal file
27
test/fixtures/wpt/performance-timeline/navigation-id-worker-created-entries.html
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
promise_test(async () => {
|
||||
const worker = new Worker("resources/worker-navigation-id.js");
|
||||
|
||||
const navigationId = await new Promise(resolve => {
|
||||
worker.onmessage = (e) => {
|
||||
resolve(e.data);
|
||||
};
|
||||
worker.postMessage('');
|
||||
});
|
||||
|
||||
assert_equals(navigationId.length, 0,
|
||||
'Navigation id of performance entries created by a worker should be empty.');
|
||||
}, 'Navigation id of performance entries created by workers should be empty');
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
144
test/fixtures/wpt/performance-timeline/navigation-id.helper.js
vendored
Normal file
144
test/fixtures/wpt/performance-timeline/navigation-id.helper.js
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
// The test functions called in the navigation-counter test. They rely on
|
||||
// artifacts defined in
|
||||
// '/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js'
|
||||
// which should be included before this file to use these functions.
|
||||
|
||||
// This function is to obtain navigation ids of all performance entries to
|
||||
// verify.
|
||||
let testInitial = () => {
|
||||
return window.performance.getEntries().map(e => e.navigationId);
|
||||
}
|
||||
|
||||
let testMarkMeasure = (markId, markName, MeasureName) => {
|
||||
const markName1 = 'test-mark';
|
||||
const markName2 = 'test-mark' + markId;
|
||||
const measureName = 'test-measure' + markId;
|
||||
|
||||
window.performance.mark(markName1);
|
||||
window.performance.mark(markName2);
|
||||
window.performance.measure(measureName, markName1, markName2);
|
||||
return window.performance.getEntriesByName(markName2).concat(
|
||||
window.performance.getEntriesByName(measureName)).map(e => e.navigationId);
|
||||
}
|
||||
|
||||
let testResourceTiming = async (resourceTimingEntryId) => {
|
||||
let navigationId;
|
||||
|
||||
let p = new Promise(resolve => {
|
||||
new PerformanceObserver((list) => {
|
||||
const entry = list.getEntries().find(
|
||||
e => e.name.includes('json_resource' + resourceTimingEntryId));
|
||||
if (entry) {
|
||||
navigationId = entry.navigationId;
|
||||
resolve();
|
||||
}
|
||||
}).observe({ type: 'resource' });
|
||||
});
|
||||
|
||||
const resp = await fetch(
|
||||
'/performance-timeline/resources/json_resource' + resourceTimingEntryId + '.json');
|
||||
await p;
|
||||
return [navigationId];
|
||||
}
|
||||
|
||||
let testElementTiming = async (elementTimingEntryId) => {
|
||||
let navigationId;
|
||||
let p = new Promise(resolve => {
|
||||
new PerformanceObserver((list) => {
|
||||
const entry = list.getEntries().find(
|
||||
e => e.entryType === 'element' && e.identifier === 'test-element-timing' + elementTimingEntryId);
|
||||
if (entry) {
|
||||
navigationId = entry.navigationId;
|
||||
resolve();
|
||||
}
|
||||
}).observe({ type: 'element' });
|
||||
});
|
||||
|
||||
let el = document.createElement('p');
|
||||
el.setAttribute('elementtiming', 'test-element-timing' + elementTimingEntryId);
|
||||
el.textContent = 'test element timing text';
|
||||
document.body.appendChild(el);
|
||||
await p;
|
||||
return [navigationId];
|
||||
}
|
||||
|
||||
let testLongTask = async () => {
|
||||
let navigationIds = [];
|
||||
|
||||
let p = new Promise(resolve => {
|
||||
new PerformanceObserver((list) => {
|
||||
const entry = list.getEntries().find(e => e.entryType === 'longtask')
|
||||
if (entry) {
|
||||
navigationIds.push(entry.navigationId);
|
||||
navigationIds = navigationIds.concat(
|
||||
entry.attribution.map(a => a.navigationId));
|
||||
resolve();
|
||||
}
|
||||
}).observe({ type: 'longtask' });
|
||||
});
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = '/performance-timeline/resources/make_long_task.js';
|
||||
document.body.appendChild(script);
|
||||
await p;
|
||||
document.body.removeChild(script);
|
||||
return navigationIds;
|
||||
}
|
||||
|
||||
const testFunctionMap = {
|
||||
'mark_measure': testMarkMeasure,
|
||||
'resource_timing': testResourceTiming,
|
||||
'element_timing': testElementTiming,
|
||||
'long_task_task_attribution': testLongTask,
|
||||
};
|
||||
|
||||
function runNavigationIdTest(params, description) {
|
||||
const defaultParams = {
|
||||
openFunc: url => window.open(url, '_blank', 'noopener'),
|
||||
scripts: [],
|
||||
funcBeforeNavigation: () => { },
|
||||
targetOrigin: originCrossSite,
|
||||
navigationTimes: 4,
|
||||
funcAfterAssertion: () => { },
|
||||
} // Apply defaults.
|
||||
params = { ...defaultParams, ...params };
|
||||
|
||||
promise_test(async t => {
|
||||
const pageA = new RemoteContext(token());
|
||||
const pageB = new RemoteContext(token());
|
||||
|
||||
const urlA = executorPath + pageA.context_id;
|
||||
const urlB = params.targetOrigin + executorPath + pageB.context_id;
|
||||
// Open url A.
|
||||
params.openFunc(urlA);
|
||||
await pageA.execute_script(waitForPageShow);
|
||||
|
||||
// Assert navigation ids of all performance entries are the same.
|
||||
let navigationIds = await pageA.execute_script(testInitial);
|
||||
assert_true(
|
||||
navigationIds.every(t => t === navigationIds[0]),
|
||||
'Navigation Ids should be the same as the initial load.');
|
||||
|
||||
for (i = 1; i <= params.navigationTimes; i++) {
|
||||
// Navigate away to url B and back.
|
||||
await navigateAndThenBack(pageA, pageB, urlB);
|
||||
|
||||
// Assert new navigation ids are generated when the document is load from bfcache.
|
||||
let nextNavigationIds = await pageA.execute_script(
|
||||
testFunctionMap[params.testName], [i + 1]);
|
||||
|
||||
// Assert navigation ids of all performance entries are the same.
|
||||
assert_true(
|
||||
nextNavigationIds.every(t => t === nextNavigationIds[0]),
|
||||
'All Navigation Ids should be same after bfcache navigation.');
|
||||
|
||||
// Assert navigation ids after bfcache navigation are different from those before.
|
||||
assert_true(
|
||||
navigationIds[0] !== nextNavigationIds[0],
|
||||
params.testName +
|
||||
' Navigation Ids should be re-generated and different from the previous ones.');
|
||||
|
||||
navigationIds = nextNavigationIds;
|
||||
}
|
||||
}, description);
|
||||
}
|
21
test/fixtures/wpt/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js
vendored
Normal file
21
test/fixtures/wpt/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// META: title=Aborting a parser should block bfcache
|
||||
// META: script=./test-helper.js
|
||||
// META: timeout=long
|
||||
|
||||
|
||||
async_test(t => {
|
||||
if (!sessionStorage.getItem("pageVisited")) {
|
||||
// This is the first time loading the page.
|
||||
sessionStorage.setItem("pageVisited", 1);
|
||||
t.step_timeout(() => {
|
||||
// Go to another page and instantly come back to this page.
|
||||
location.href = new URL("../resources/going-back.html", window.location);
|
||||
}, 0);
|
||||
// Abort parsing in the middle of loading the page.
|
||||
window.stop();
|
||||
} else {
|
||||
const nrr = performance.getEntriesByType('navigation')[0].notRestoredReasons;
|
||||
assert_true(ReasonsInclude(nrr.reasons, "parser-aborted"));
|
||||
t.done();
|
||||
}
|
||||
}, "aborting a parser should block bfcache.");
|
@ -0,0 +1,55 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that empty attributes are reported as empty strings and missing
|
||||
// attributes are reported as null.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Add a cross-origin iframe.
|
||||
const rc1_child = await rc1.addIframe(
|
||||
/*extraConfig=*/ {
|
||||
origin: 'HTTP_REMOTE_ORIGIN',
|
||||
scripts: [],
|
||||
headers: [],
|
||||
},
|
||||
/*attributes=*/ {id: '', name: ''},
|
||||
);
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
const rc1_child_url = await rc1_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/[{
|
||||
'url': null,
|
||||
'src': rc1_child_url,
|
||||
// Id and name should be empty.
|
||||
'id': '',
|
||||
'name': '',
|
||||
'reasons': null,
|
||||
'children': null
|
||||
}]);
|
||||
});
|
@ -0,0 +1,47 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that notRestoredReasons are only updated after non BFCache navigation.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/ []);
|
||||
|
||||
// This time no blocking feature is used, so the page is restored
|
||||
// from BFCache. Ensure that the previous reasons stay there.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/ []);
|
||||
});
|
@ -0,0 +1,28 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that notRestoredReasons is empty for successful BFCache restore.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
|
||||
// Check the BFCache result and verify that no reasons are recorded
|
||||
// for successful restore.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true);
|
||||
assert_true(await rc1.executeScript(() => {
|
||||
let reasons =
|
||||
performance.getEntriesByType('navigation')[0].notRestoredReasons;
|
||||
return reasons === null;
|
||||
}));
|
||||
});
|
@ -0,0 +1,60 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that cross-origin subtree's reasons are not exposed to
|
||||
// notRestoredReasons.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Add a cross-origin iframe.
|
||||
const rc1_child = await rc1.addIframe(
|
||||
/*extraConfig=*/ {
|
||||
origin: 'HTTP_REMOTE_ORIGIN',
|
||||
scripts: [],
|
||||
headers: [],
|
||||
},
|
||||
/*attributes=*/ {id: 'test-id'},
|
||||
);
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1_child);
|
||||
const rc1_child_url = await rc1_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Add a child to the iframe.
|
||||
const rc1_grand_child = await rc1_child.addIframe();
|
||||
const rc1_grand_child_url = await rc1_grand_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': "masked"}],
|
||||
/*children=*/[{
|
||||
'url': null,
|
||||
'src': rc1_child_url,
|
||||
'id': 'test-id',
|
||||
'name': null,
|
||||
'reasons': null,
|
||||
'children': null
|
||||
}]);
|
||||
});
|
@ -0,0 +1,40 @@
|
||||
// META: title=Ensure that ongoing fetch upon entering bfcache blocks bfcache and recorded.
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
const wavURL = new URL(get_host_info().HTTP_REMOTE_ORIGIN + '/fetch/range/resources/long-wav.py');
|
||||
await rc1.executeScript((wavURL) => {
|
||||
// Register pagehide handler to create a fetch request.
|
||||
addEventListener('pagehide', (wavURL) => {
|
||||
fetch(wavURL, {
|
||||
keepalive: true
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'fetch'}],
|
||||
/*children=*/[]);
|
||||
});
|
@ -0,0 +1,103 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that empty attributes are reported as empty strings and missing
|
||||
// attributes are reported as null.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Add a cross-origin iframe.
|
||||
const rc1_child = await rc1.addIframe(
|
||||
/*extraConfig=*/ {
|
||||
origin: 'HTTP_REMOTE_ORIGIN',
|
||||
scripts: [],
|
||||
headers: [],
|
||||
},
|
||||
/*attributes=*/ {id: '', name: ''},
|
||||
);
|
||||
const rc2_child = await rc1.addIframe(
|
||||
/*extraConfig=*/ {
|
||||
origin: 'HTTP_REMOTE_ORIGIN',
|
||||
scripts: [],
|
||||
headers: [],
|
||||
},
|
||||
/*attributes=*/ {},
|
||||
);
|
||||
const rc3_child = await rc1.addIframe(
|
||||
/*extraConfig=*/ {},
|
||||
/*attributes=*/ {},
|
||||
);
|
||||
const rc4_child = await rc1.addIframe(
|
||||
/*extraConfig=*/ {},
|
||||
/*attributes=*/ {id: '', name: ''},
|
||||
);
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
const rc1_child_url = await rc1_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
const rc2_child_url = await rc2_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
const rc3_child_url = await rc3_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
const rc4_child_url = await rc4_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/[{
|
||||
'url': null,
|
||||
'src': rc1_child_url,
|
||||
// Id and name should be empty.
|
||||
'id': '',
|
||||
'name': '',
|
||||
'reasons': null,
|
||||
'children': null
|
||||
}, {
|
||||
'url': null,
|
||||
'src': rc2_child_url,
|
||||
// Id and name should be null.
|
||||
'id': null,
|
||||
'name': null,
|
||||
'reasons': null,
|
||||
'children': null
|
||||
},{
|
||||
'url': rc3_child_url,
|
||||
'src': rc3_child_url,
|
||||
// Id and name should be null.
|
||||
'id': null,
|
||||
'name': null,
|
||||
'reasons': [],
|
||||
'children': []
|
||||
}, {
|
||||
'url': rc4_child_url,
|
||||
'src': rc4_child_url,
|
||||
'id': '',
|
||||
'name': '',
|
||||
'reasons': [],
|
||||
'children': []
|
||||
}]);
|
||||
});
|
@ -0,0 +1,32 @@
|
||||
// META: title=Ensure that if WebLock is held upon entering bfcache, it cannot enter bfcache and gets reported.
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: timeout=long
|
||||
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Request a WebLock.
|
||||
let return_value = await rc1.executeScript(() => {
|
||||
return new Promise((resolve) => {
|
||||
navigator.locks.request('resource', () => {
|
||||
resolve(42);
|
||||
});
|
||||
})
|
||||
});
|
||||
assert_equals(return_value, 42);
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredFromBFCache(rc1, ['lock']);
|
||||
});
|
@ -0,0 +1,26 @@
|
||||
// META: title=Ensure that navigation failure blocks bfcache and gets recorded.
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/404.py
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
const {ORIGIN} = get_host_info();
|
||||
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ {status: 404}, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredFromBFCache(rc1, ['response-status-not-ok']);
|
||||
});
|
@ -0,0 +1,36 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that notRestoredReasons is populated when not restored.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/ []);
|
||||
});
|
@ -0,0 +1,53 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
|
||||
|
||||
// Ensure that notRestoredReasons reset after the server redirect.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
|
||||
// Create a remote context with the redirected URL.
|
||||
let rc1_redirected =
|
||||
await rcHelper.createContext(/*extraConfig=*/ {
|
||||
origin: 'HTTP_ORIGIN',
|
||||
scripts: [],
|
||||
headers: [],
|
||||
});
|
||||
|
||||
const redirectUrl =
|
||||
`${ORIGIN}/common/redirect.py?location=${encodeURIComponent(rc1_redirected.url)}`;
|
||||
// Replace the history state.
|
||||
await rc1.executeScript((url) => {
|
||||
window.history.replaceState(null, '', url);
|
||||
}, [redirectUrl]);
|
||||
|
||||
// Navigate away.
|
||||
const newRemoteContextHelper = await rc1.navigateToNew();
|
||||
|
||||
// Go back.
|
||||
await newRemoteContextHelper.historyBack();
|
||||
|
||||
const navigation_entry = await rc1_redirected.executeScript(() => {
|
||||
return performance.getEntriesByType('navigation')[0];
|
||||
});
|
||||
assert_equals(
|
||||
navigation_entry.redirectCount, 1, 'Expected redirectCount is 1.');
|
||||
// Becauase of the redirect, notRestoredReasons is reset.
|
||||
assert_equals(
|
||||
navigation_entry.notRestoredReasons, null,
|
||||
'Expected notRestoredReasons is null.');
|
||||
});
|
@ -0,0 +1,50 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
|
||||
|
||||
// Ensure that notRestoredReasons reset after the server redirect.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/ []);
|
||||
|
||||
// Reload.
|
||||
await rc1.navigate(() => {
|
||||
location.reload();
|
||||
}, []);
|
||||
|
||||
// Becauase of the reload, notRestoredReasons is reset.
|
||||
const navigation_entry = await rc1.executeScript(() => {
|
||||
return performance.getEntriesByType('navigation')[0];
|
||||
});
|
||||
|
||||
assert_equals(
|
||||
navigation_entry.notRestoredReasons, null,
|
||||
'Expected notRestoredReasons is null.');
|
||||
});
|
@ -0,0 +1,61 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that same-origin subtree's reasons are exposed to notRestoredReasons.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Add a same-origin iframe and use WebSocket.
|
||||
const rc1_child = await rc1.addIframe(
|
||||
/*extra_config=*/ {}, /*attributes=*/ {id: 'test-id'});
|
||||
await useWebSocket(rc1_child);
|
||||
|
||||
const rc1_child_url = await rc1_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
// Add a child to the iframe.
|
||||
const rc1_grand_child = await rc1_child.addIframe();
|
||||
const rc1_grand_child_url = await rc1_grand_child.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Check the BFCache result and the reported reasons.
|
||||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[],
|
||||
/*children=*/[{
|
||||
'url': rc1_child_url,
|
||||
'src': rc1_child_url,
|
||||
'id': 'test-id',
|
||||
'name': '',
|
||||
'reasons': [{'reason': 'websocket'}],
|
||||
'children': [{
|
||||
'url': rc1_grand_child_url,
|
||||
'src': rc1_grand_child_url,
|
||||
'id': '',
|
||||
'name': '',
|
||||
'reasons': [],
|
||||
'children': []
|
||||
}]
|
||||
}]);
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
// META: title=RemoteContextHelper navigation using BFCache
|
||||
// META: script=./test-helper.js
|
||||
// META: script=/common/dispatcher/dispatcher.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
|
||||
// META: script=/websockets/constants.sub.js
|
||||
// META: timeout=long
|
||||
|
||||
'use strict';
|
||||
|
||||
// Ensure that notRestoredReasons are accessible after history replace.
|
||||
promise_test(async t => {
|
||||
const rcHelper = new RemoteContextHelper();
|
||||
// Open a window with noopener so that BFCache will work.
|
||||
const rc1 = await rcHelper.addWindow(
|
||||
/*config=*/ null, /*options=*/ {features: 'noopener'});
|
||||
const rc1_url = await rc1.executeScript(() => {
|
||||
return location.href;
|
||||
});
|
||||
|
||||
// Use WebSocket to block BFCache.
|
||||
await useWebSocket(rc1);
|
||||
// Navigate away.
|
||||
const newRemoteContextHelper = await rc1.navigateToNew();
|
||||
// Replace the history state to a same-origin site.
|
||||
await newRemoteContextHelper.executeScript((destUrl) => {
|
||||
window.history.replaceState(null, '', '#');
|
||||
});
|
||||
// Go back.
|
||||
await newRemoteContextHelper.historyBack();
|
||||
|
||||
// Reasons are not reset for same-origin replace.
|
||||
await assertNotRestoredReasonsEquals(
|
||||
rc1,
|
||||
/*url=*/ rc1_url,
|
||||
/*src=*/ null,
|
||||
/*id=*/ null,
|
||||
/*name=*/ null,
|
||||
/*reasons=*/[{'reason': 'websocket'}],
|
||||
/*children=*/ []);
|
||||
});
|
57
test/fixtures/wpt/performance-timeline/not-restored-reasons/test-helper.js
vendored
Normal file
57
test/fixtures/wpt/performance-timeline/not-restored-reasons/test-helper.js
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
// META: script=../../html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js
|
||||
|
||||
async function assertNotRestoredReasonsEquals(
|
||||
remoteContextHelper, url, src, id, name, reasons, children) {
|
||||
let result = await remoteContextHelper.executeScript(() => {
|
||||
return performance.getEntriesByType('navigation')[0].notRestoredReasons;
|
||||
});
|
||||
assertReasonsStructEquals(
|
||||
result, url, src, id, name, reasons, children);
|
||||
}
|
||||
|
||||
function assertReasonsStructEquals(
|
||||
result, url, src, id, name, reasons, children) {
|
||||
assert_equals(result.url, url);
|
||||
assert_equals(result.src, src);
|
||||
assert_equals(result.id, id);
|
||||
assert_equals(result.name, name);
|
||||
|
||||
// Reasons should match.
|
||||
let expected = new Set(reasons);
|
||||
let actual = new Set(result.reasons);
|
||||
matchReasons(extractReason(expected), extractReason(actual));
|
||||
|
||||
// Children should match.
|
||||
if (children == null) {
|
||||
assert_equals(result.children, children);
|
||||
} else {
|
||||
for (let j = 0; j < children.length; j++) {
|
||||
assertReasonsStructEquals(
|
||||
result.children[j], children[j].url,
|
||||
children[j].src, children[j].id, children[j].name, children[j].reasons,
|
||||
children[j].children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ReasonsInclude(reasons, targetReason) {
|
||||
for (const reason of reasons) {
|
||||
if (reason.reason == targetReason) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Requires:
|
||||
// - /websockets/constants.sub.js in the test file and pass the domainPort
|
||||
// constant here.
|
||||
async function useWebSocket(remoteContextHelper) {
|
||||
let return_value = await remoteContextHelper.executeScript((domain) => {
|
||||
return new Promise((resolve) => {
|
||||
var webSocketInNotRestoredReasonsTests = new WebSocket(domain + '/echo');
|
||||
webSocketInNotRestoredReasonsTests.onopen = () => { resolve(42); };
|
||||
});
|
||||
}, [SCHEME_DOMAIN_PORT]);
|
||||
assert_equals(return_value, 42);
|
||||
}
|
7
test/fixtures/wpt/performance-timeline/resources/child-frame.html
vendored
Normal file
7
test/fixtures/wpt/performance-timeline/resources/child-frame.html
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head></head>
|
||||
<body></body>
|
||||
<script>
|
||||
performance.mark('mark_child_frame');
|
||||
</script>
|
0
test/fixtures/wpt/performance-timeline/resources/empty.html
vendored
Normal file
0
test/fixtures/wpt/performance-timeline/resources/empty.html
vendored
Normal file
9
test/fixtures/wpt/performance-timeline/resources/going-back.html
vendored
Normal file
9
test/fixtures/wpt/performance-timeline/resources/going-back.html
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<!doctype html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
onload = (event) => {
|
||||
history.back();
|
||||
};
|
||||
</script>
|
60
test/fixtures/wpt/performance-timeline/resources/include-frames-helper.js
vendored
Normal file
60
test/fixtures/wpt/performance-timeline/resources/include-frames-helper.js
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
const verifyEntries = (entries, filterOptions) => {
|
||||
for (const filterOption of filterOptions) {
|
||||
let countBeforeFiltering = entries.length;
|
||||
|
||||
// Using negate of the condition so that the next filtering is applied on less entries.
|
||||
entries = entries.filter(
|
||||
e => !(e.entryType == filterOption['entryType'] && e.name.includes(filterOption['name'])));
|
||||
|
||||
assert_equals(
|
||||
countBeforeFiltering - entries.length, filterOption['expectedCount'], filterOption['failureMsg']);
|
||||
}
|
||||
}
|
||||
|
||||
const createFilterOption = (name, entryType, expectedCount, msgPrefix, description = '') => {
|
||||
if (description) {
|
||||
description = ' ' + description;
|
||||
}
|
||||
|
||||
let failureMsg =
|
||||
`${msgPrefix} should have ${expectedCount} ${entryType} entries for name ${name}` + description;
|
||||
|
||||
return {
|
||||
name: name,
|
||||
entryType: entryType,
|
||||
expectedCount: expectedCount,
|
||||
failureMsg: failureMsg
|
||||
};
|
||||
}
|
||||
|
||||
const loadChildFrame = (src) => {
|
||||
return new Promise(resolve => {
|
||||
|
||||
const childFrame = document.createElement('iframe');
|
||||
|
||||
childFrame.addEventListener("load", resolve);
|
||||
|
||||
childFrame.src = src;
|
||||
|
||||
document.body.appendChild(childFrame);
|
||||
});
|
||||
}
|
||||
|
||||
const loadChildFrameAndGrandchildFrame = (src) => {
|
||||
return new Promise(resolve => {
|
||||
|
||||
const crossOriginChildFrame = document.createElement('iframe');
|
||||
|
||||
// Wait for the child frame to send a message. The child frame would send a message
|
||||
// when it loads its child frame.
|
||||
window.addEventListener('message', e => {
|
||||
if (e.data == 'Load completed') {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
crossOriginChildFrame.src = src;
|
||||
|
||||
document.body.appendChild(crossOriginChildFrame)
|
||||
});
|
||||
}
|
43
test/fixtures/wpt/performance-timeline/resources/include-frames-subframe.html
vendored
Normal file
43
test/fixtures/wpt/performance-timeline/resources/include-frames-subframe.html
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
</head>
|
||||
<!--
|
||||
This html is embedded as a sub-frame in include-frames-originA-B-A.html,
|
||||
include-frames-originA-B-B.html and include-frames-originA-A-A.html. Once embedded,
|
||||
this would take a url parameter named origin which is the origin of the child frame
|
||||
this html is to load in step 3 listed below.
|
||||
It does,
|
||||
1, waits for load.
|
||||
2, creates a single mark performance entry.
|
||||
3, creates and loads a child frame, and waits for it to load.
|
||||
4. verify entries obtained from this frame.
|
||||
-->
|
||||
|
||||
<body>
|
||||
<script>
|
||||
(async () => {
|
||||
// Wait for load.
|
||||
await new Promise(resolve => window.addEventListener("load", resolve));
|
||||
|
||||
// Mark.
|
||||
performance.mark("mark_subframe");
|
||||
|
||||
// Create and load an iframe and wait for load.
|
||||
await new Promise(resolve => {
|
||||
const childFrame = document.createElement('iframe');
|
||||
|
||||
childFrame.addEventListener('load', async () => {
|
||||
window.parent.postMessage('Load completed', "*");
|
||||
resolve();
|
||||
});
|
||||
|
||||
childFrame.src = (new URL(document.location)).searchParams.get('origin')
|
||||
+ '/performance-timeline/resources/child-frame.html';
|
||||
|
||||
document.body.appendChild(childFrame);
|
||||
}
|
||||
);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
4
test/fixtures/wpt/performance-timeline/resources/json_resource.json
vendored
Normal file
4
test/fixtures/wpt/performance-timeline/resources/json_resource.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "nav_id_test",
|
||||
"target": "resource_timing"
|
||||
}
|
4
test/fixtures/wpt/performance-timeline/resources/make_long_task.js
vendored
Normal file
4
test/fixtures/wpt/performance-timeline/resources/make_long_task.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
(function () {
|
||||
let now = window.performance.now();
|
||||
while (window.performance.now() < now + 60);
|
||||
}());
|
21
test/fixtures/wpt/performance-timeline/resources/navigation-id-detached-frame-page.html
vendored
Normal file
21
test/fixtures/wpt/performance-timeline/resources/navigation-id-detached-frame-page.html
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>The navigation_id Detached iframe Page.</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener("load", () => {
|
||||
setTimeout(() => {
|
||||
const container = window.frameElement;
|
||||
container.remove();
|
||||
}, 10);
|
||||
performance.mark('mark-window-detached-frame');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
6
test/fixtures/wpt/performance-timeline/resources/worker-navigation-id.js
vendored
Normal file
6
test/fixtures/wpt/performance-timeline/resources/worker-navigation-id.js
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
self.onmessage = () => {
|
||||
const mark_name = 'user_timig_mark';
|
||||
performance.mark(mark_name);
|
||||
postMessage(performance.getEntriesByName(mark_name)[0].navigationId);
|
||||
self.close();
|
||||
}
|
18
test/fixtures/wpt/performance-timeline/supportedEntryTypes-cross-realm-access.html
vendored
Normal file
18
test/fixtures/wpt/performance-timeline/supportedEntryTypes-cross-realm-access.html
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Cross-realm access of supportedEntryTypes returns Array of another realm</title>
|
||||
<link rel="help" href="https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
test(t => {
|
||||
const iframe = document.createElement("iframe");
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
iframe.onload = t.step_func_done(() => {
|
||||
const otherWindow = iframe.contentWindow;
|
||||
assert_true(otherWindow.PerformanceObserver.supportedEntryTypes instanceof otherWindow.Array);
|
||||
});
|
||||
document.body.append(iframe);
|
||||
});
|
||||
</script>
|
27
test/fixtures/wpt/performance-timeline/tentative/detached-frame.html
vendored
Normal file
27
test/fixtures/wpt/performance-timeline/tentative/detached-frame.html
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings()
|
||||
|
||||
// Create child iframe.
|
||||
const childFrame = document.createElement('iframe')
|
||||
childFrame.src = "../resources/child-frame.html"
|
||||
document.body.appendChild(childFrame)
|
||||
|
||||
// wait until the child frame's onload event fired
|
||||
await new Promise(r => childFrame.addEventListener("load", r));
|
||||
|
||||
const childWindow = childFrame.contentWindow;
|
||||
// Detach the child frame
|
||||
document.body.removeChild(childFrame);
|
||||
|
||||
const entries = childWindow.performance.getEntries({ includeChildFrames: true });
|
||||
const parent_entries = performance.getEntries({ includeChildFrames: true });
|
||||
}, "GetEntries of a detached parent frame does not crash");
|
||||
</script>
|
93
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A-A.html
vendored
Normal file
93
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A-A.html
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=/common/get-host-info.sub.js></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries, description = '') => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-A-A', 'navigation', 1, 'Main Frame', description),
|
||||
createFilterOption('include-frames-subframe', 'resource', 1, 'Main Frame', description),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyChildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-subframe', 'navigation', 1, 'Child Frame'),
|
||||
createFilterOption('child-frame.html', 'resource', 1, 'Child Frame'),
|
||||
createFilterOption('mark_subframe', 'mark', 1, 'Child frame')
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyGrandchildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('child-frame.html', 'navigation', 1, 'Grandchild Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 1, 'Grandchild frame')
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
// Load a child frame. The child frame upon loading would load a child frame of its own.
|
||||
await loadChildFrameAndGrandchildFrame(
|
||||
'../resources/include-frames-subframe.html?origin=' + get_host_info().ORIGIN);
|
||||
|
||||
// Verify entries retrieved from main frame.
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
verifyMainFrameEntries(entries);
|
||||
|
||||
verifyChildFrameEntries(entries);
|
||||
|
||||
verifyGrandchildFrameEntries(entries);
|
||||
|
||||
// 1 entry for parent, 1 for child, 1 for grandchild.
|
||||
const navigationEntries = performance.getEntries({ entryType: "navigation", includeChildFrames: true });
|
||||
assert_equals(navigationEntries.length, 3, 'Navigation entries should be 3.');
|
||||
|
||||
const markedChildFrameEntries = performance.getEntries(
|
||||
{ name: 'mark_subframe', includeChildFrames: true });
|
||||
assert_equals(markedChildFrameEntries.length, 1, 'Child frame mark entries should be 1.');
|
||||
|
||||
const markedGrandchildFrameEntries = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: true });
|
||||
assert_equals(markedGrandchildFrameEntries.length, 1, 'Grand child frame mark entries should be 1.');
|
||||
|
||||
// Test cases where includeChildFrames is false.
|
||||
const entriesWithNoFitlerOptions = performance.getEntries();
|
||||
|
||||
const entriesWithoutIncludingChildFrames = performance.getEntries({ includeChildFrames: false });
|
||||
|
||||
const navigationEntriesWithoutIncludingChildFrames = performance.getEntries({ entryType: "navigation", includeChildFrames: false });
|
||||
|
||||
const markedEntriesWithoutIncludingChildFrames = performance.getEntries(
|
||||
{ name: 'entry-name', includeChildFrames: false });
|
||||
|
||||
verifyMainFrameEntries(entriesWithNoFitlerOptions, 'with no filter options.');
|
||||
|
||||
verifyMainFrameEntries(entriesWithoutIncludingChildFrames, 'with includingChildFrames being false.')
|
||||
|
||||
// 1 entry for main frame.
|
||||
assert_equals(navigationEntriesWithoutIncludingChildFrames.length, 1,
|
||||
'Navigation entries with includeChildFrame being false should be 1.');
|
||||
|
||||
// 0 entry since grandchild frame is not included.
|
||||
assert_equals(markedEntriesWithoutIncludingChildFrames.length, 0,
|
||||
'Mark entries with includeChildFrame being false should be 0.');
|
||||
|
||||
}, 'GetEntries of a document of origin A, its child frame of origin B and \
|
||||
its grandchild frame of origin A.');
|
||||
</script>
|
||||
</body>
|
76
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A.html
vendored
Normal file
76
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A.html
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries, description = '') => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-A', 'navigation', 1, 'Main Frame', description),
|
||||
createFilterOption('child-frame.html', 'resource', 1, 'Main Frame', description),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyChildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('child-frame.html', 'navigation', 1, 'Child Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 1, 'Child Frame'),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
// Load a child frame.
|
||||
await loadChildFrame('../resources/child-frame.html');
|
||||
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
const navigationEntries = performance.getEntries({ entryType: "navigation", includeChildFrames: true });
|
||||
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: true });
|
||||
|
||||
verifyMainFrameEntries(entries);
|
||||
|
||||
verifyChildFrameEntries(entries);
|
||||
|
||||
// 1 entry for main frame, 1 for child frame.
|
||||
assert_equals(navigationEntries.length, 2, 'Navigation entries should be 2.');
|
||||
|
||||
// 1 entry for child frame.
|
||||
assert_equals(markedEntries.length, 1, 'Mark entries should be 1.');
|
||||
|
||||
// Test cases where includeChildFrames is false.
|
||||
const entriesWithNoFitlerOptions = performance.getEntries();
|
||||
|
||||
const entriesWithoutIncludingChildFrames = performance.getEntries({ includeChildFrames: false });
|
||||
|
||||
const navigationEntriesWithoutIncludingChildFrames = performance.getEntries({ entryType: "navigation", includeChildFrames: false });
|
||||
|
||||
const markedEntriesWithoutIncludingChildFrames = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: false });
|
||||
|
||||
verifyMainFrameEntries(entriesWithNoFitlerOptions, 'with no filter options.');
|
||||
|
||||
verifyMainFrameEntries(entriesWithoutIncludingChildFrames, 'with includeChildFrame being false.');
|
||||
|
||||
// 1 entry for main frame.
|
||||
assert_equals(navigationEntriesWithoutIncludingChildFrames.length, 1,
|
||||
'Navigation entries with includeChildFrame being false should be 1.');
|
||||
|
||||
// 0 entry for child frame.
|
||||
assert_equals(markedEntriesWithoutIncludingChildFrames.length, 0,
|
||||
'Mark entries with includeChildFrame being false should be 0.');
|
||||
|
||||
}, 'GetEntries of a document of origin A and its child frame of origin A.');
|
||||
</script>
|
||||
</body>
|
51
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AA.html
vendored
Normal file
51
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AA.html
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-AA', 'navigation', 1, 'Main Frame'),
|
||||
createFilterOption('child-frame.html', 'navigation', 2, 'Child Frames'),
|
||||
createFilterOption('child-frame.html', 'resource', 2, 'Main Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 2, 'Child frames')
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyPerformanceEntries = () => {
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
const navigationEntries = performance.getEntries({ entryType: "navigation", includeChildFrames: true });
|
||||
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: true });
|
||||
|
||||
verifyMainFrameEntries(entries);
|
||||
|
||||
// 1 entry for main frame, 1 for each child frame.
|
||||
assert_equals(navigationEntries.length, 3, 'Navigation entries should be 3.');
|
||||
|
||||
// 1 entry for each child frame.
|
||||
assert_equals(markedEntries.length, 2, 'Mark entries should be 2.');
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
// Load first child iframe.
|
||||
const promise1 = loadChildFrame('../resources/child-frame.html');
|
||||
|
||||
// Load second child iframe.
|
||||
const promise2 = loadChildFrame('../resources/child-frame.html');
|
||||
|
||||
return Promise.all([promise1, promise2]).then(verifyPerformanceEntries);
|
||||
}, 'GetEntries of a document of origin A and its two child frames both of origin A.');
|
||||
</script>
|
||||
</body>
|
53
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AB.html
vendored
Normal file
53
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AB.html
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=/common/get-host-info.sub.js></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-AB', 'navigation', 1, 'Main Frame'),
|
||||
createFilterOption('child-frame.html', 'navigation', 1, 'Child Frames'),
|
||||
createFilterOption('child-frame.html', 'resource', 2, 'Main Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 1, 'Child frames')
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyPerformanceEntries = () => {
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
const navigationEntries = performance.getEntries({ entryType: "navigation", includeChildFrames: true });
|
||||
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: true });
|
||||
|
||||
verifyMainFrameEntries(entries);
|
||||
|
||||
// 1 entry for main frame, 1 for local child frame.
|
||||
assert_equals(navigationEntries.length, 2, 'Navigation entries should be 2.');
|
||||
|
||||
// 1 entry for local child frame.
|
||||
assert_equals(markedEntries.length, 1, 'Mark entries should be 1.');
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
// Load first child iframe.
|
||||
sameOriginPromise = loadChildFrame('../resources/child-frame.html');
|
||||
|
||||
// Create second child iframe.
|
||||
crossOriginPromise = loadChildFrame(
|
||||
get_host_info().HTTP_REMOTE_ORIGIN + '/resources/child-frame.html');
|
||||
|
||||
return Promise.all([sameOriginPromise, crossOriginPromise]).then(verifyPerformanceEntries);
|
||||
}, 'GetEntries of a document of origin A and its two child frames of origin A and B respectively.');
|
||||
</script>
|
||||
</body>
|
91
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-A.html
vendored
Normal file
91
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-A.html
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=/common/get-host-info.sub.js></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries, description = '') => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-B-A', 'navigation', 1, 'Main Frame', description),
|
||||
createFilterOption('include-frames-subframe', 'resource', 1, 'Main Frame', description),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyChildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-subframe', 'navigation', 0, 'Child Frame'),
|
||||
createFilterOption('child-frame.html', 'resource', 0, 'Child Frame'),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyGrandchildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('child-frame.html', 'navigation', 1, 'Grandchild Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 1, 'Grandchild frame')
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
|
||||
performance.clearResourceTimings();
|
||||
|
||||
// Load a child frame. The child frame upon loading would load a child frame of its own.
|
||||
await loadChildFrameAndGrandchildFrame(get_host_info().REMOTE_ORIGIN +
|
||||
'/performance-timeline/resources/include-frames-subframe.html?origin=' + get_host_info().ORIGIN);
|
||||
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
const navigationEntries = performance.getEntries({ entryType: "navigation", includeChildFrames: true });
|
||||
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: true });
|
||||
|
||||
verifyMainFrameEntries(entries);
|
||||
|
||||
verifyChildFrameEntries(entries);
|
||||
|
||||
verifyGrandchildFrameEntries(entries);
|
||||
|
||||
// 1 entry for main frame, 1 for grandchild frame.
|
||||
assert_equals(navigationEntries.length, 2, 'Navigation entries should be 2.');
|
||||
|
||||
// 1 entry for grandchild frame.
|
||||
assert_equals(markedEntries.length, 1, 'Mark entries should be 1.');
|
||||
|
||||
// Test cases where includeChildFrames is false.
|
||||
const entriesWithNoFitlerOptions = performance.getEntries();
|
||||
|
||||
const entriesWithoutIncludingChildFrames = performance.getEntries({ includeChildFrames: false });
|
||||
|
||||
const navigationEntriesWithoutIncludingChildFrames = performance.getEntries({ entryType: "navigation", includeChildFrames: false });
|
||||
|
||||
const markedEntriesWithoutIncludingChildFrames = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: false });
|
||||
|
||||
verifyMainFrameEntries(entriesWithNoFitlerOptions, 'with no filter options.');
|
||||
|
||||
verifyMainFrameEntries(entriesWithoutIncludingChildFrames, 'with includeChildFrame being false.');
|
||||
|
||||
// 1 entry for main frame.
|
||||
assert_equals(navigationEntriesWithoutIncludingChildFrames.length, 1,
|
||||
'Navigation entries with includeChildFrame being false should be 1.');
|
||||
|
||||
// 0 entry since grandchild frame is not included.
|
||||
assert_equals(markedEntriesWithoutIncludingChildFrames.length, 0,
|
||||
'Mark entries with includeChildFrame being false should be 0.');
|
||||
|
||||
}, 'GetEntries of a document of origin A, its child frame of origin B and \
|
||||
its grandchild frame of origin A.');
|
||||
</script>
|
||||
</body>
|
57
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-B.html
vendored
Normal file
57
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-B.html
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=/common/get-host-info.sub.js></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-B-B', 'navigation', 1, 'Main Frame'),
|
||||
createFilterOption('include-frames-subframe', 'resource', 1, 'Main Frame'),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyChildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-subframe', 'navigation', 0, 'Child Frame'),
|
||||
createFilterOption('child-frame.html', 'resource', 0, 'Child Frame'),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyGrandchildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('child-frame.html', 'navigation', 0, 'Grandchild Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 0, 'Grandchild frame')
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
// Load a origin child frame. The child frame upon loading would load a child frame of its own.
|
||||
await loadChildFrameAndGrandchildFrame(get_host_info().REMOTE_ORIGIN
|
||||
+ '/performance-timeline/resources/include-frames-subframe.html?origin='
|
||||
+ get_host_info().REMOTE_ORIGIN);
|
||||
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
verifyMainFrameEntries(entries);
|
||||
|
||||
verifyChildFrameEntries(entries);
|
||||
|
||||
verifyGrandchildFrameEntries(entries);
|
||||
}, 'GetEntries of a document of origin A, its child frame of origin B and \
|
||||
its grandchild frame of origin B.');
|
||||
</script>
|
||||
</body>
|
50
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B.html
vendored
Normal file
50
test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B.html
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=/common/get-host-info.sub.js></script>
|
||||
<script src="../resources/include-frames-helper.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
const verifyMainFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('include-frames-originA-B', 'navigation', 1, 'Main Frame'),
|
||||
createFilterOption('child-frame.html', 'resource', 1, 'Main Frame'),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
const verifyChildFrameEntries = (entries) => {
|
||||
let filterOptions = [
|
||||
createFilterOption('child-frame.html', 'navigation', 0, 'Child Frame'),
|
||||
createFilterOption('mark_child_frame', 'mark', 0, 'Child Frame'),
|
||||
];
|
||||
|
||||
verifyEntries(entries, filterOptions);
|
||||
}
|
||||
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
await loadChildFrame(
|
||||
get_host_info().HTTP_REMOTE_ORIGIN + '/performance_timeline/resources/child-frame.html');
|
||||
|
||||
const entries = performance.getEntries({ includeChildFrames: true });
|
||||
|
||||
const navigationEntries = performance.getEntries({ entryType: "navigation", includeChildFrames: true });
|
||||
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'mark_subframe', includeChildFrames: true });
|
||||
|
||||
// 1 entry for main frame.
|
||||
assert_equals(navigationEntries.length, 1, 'Navigation entries should 1.');
|
||||
|
||||
// 0 entry since child frame is cross origin.
|
||||
assert_equals(markedEntries.length, 0, 'Mark entries should 0.');
|
||||
}, 'GetEntries of a parent Frame of origin A and its child frame of origin B');
|
||||
</script>
|
||||
</body>
|
37
test/fixtures/wpt/performance-timeline/tentative/performance-entry-source.html
vendored
Normal file
37
test/fixtures/wpt/performance-timeline/tentative/performance-entry-source.html
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
promise_test(() => {
|
||||
return new Promise(resolve => {
|
||||
const navigationEntries = performance.getEntries({ type: 'navigation' })
|
||||
const parentEntry = navigationEntries[0]
|
||||
|
||||
// Parent NavigationTiming source is current window.
|
||||
assert_equals(parentEntry.source, window)
|
||||
|
||||
// Create child iframe.
|
||||
const childFrame = document.createElement('iframe')
|
||||
childFrame.src = "../resources/child-frame.html"
|
||||
document.body.appendChild(childFrame)
|
||||
|
||||
childFrame.addEventListener('load', () => {
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'mark_child_frame', includeChildFrames: true });
|
||||
|
||||
const childEntry = markedEntries[0]
|
||||
|
||||
// Child PerformanceMark source is the child's Window.
|
||||
assert_equals(childEntry.source, childFrame.contentWindow)
|
||||
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}, "PerformanceEntry source is equal to its respective Window")
|
||||
</script>
|
26
test/fixtures/wpt/performance-timeline/tentative/with-filter-options-originA.html
vendored
Normal file
26
test/fixtures/wpt/performance-timeline/tentative/with-filter-options-originA.html
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
promise_test(async () => {
|
||||
performance.clearResourceTimings();
|
||||
|
||||
performance.mark('entry-name');
|
||||
|
||||
const navigationEntries = performance.getEntries({ entryType: 'navigation' });
|
||||
|
||||
const markedEntries = performance.getEntries(
|
||||
{ name: 'entry-name', entryType: 'mark' });
|
||||
|
||||
assert_equals(navigationEntries.length, 1, 'navigationEntries should be 1.');
|
||||
|
||||
assert_equals(markedEntries.length, 1, 'markedEntries should be 1.');
|
||||
|
||||
}, 'GetEntries with filter options.');
|
||||
</script>
|
||||
</body>
|
16
test/fixtures/wpt/performance-timeline/timing-removed-iframe.html
vendored
Normal file
16
test/fixtures/wpt/performance-timeline/timing-removed-iframe.html
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test(() => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = "resources/empty.html"
|
||||
document.body.appendChild(iframe);
|
||||
const iframePerformance = iframe.contentWindow.performance;
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
const timing = iframePerformance.timing;
|
||||
}, "Test that a removed iframe which timing is accessed does not crash the renderer.");
|
||||
</script>
|
2
test/fixtures/wpt/versions.json
vendored
2
test/fixtures/wpt/versions.json
vendored
@ -56,7 +56,7 @@
|
||||
"path": "interfaces"
|
||||
},
|
||||
"performance-timeline": {
|
||||
"commit": "17ebc3aea0d6321e69554067c39ab5855e6fb67e",
|
||||
"commit": "94caab7038b27c16d605fa3547dacbee3a2fde4e",
|
||||
"path": "performance-timeline"
|
||||
},
|
||||
"resource-timing": {
|
||||
|
@ -21,5 +21,58 @@
|
||||
},
|
||||
"webtiming-resolution.any.js": {
|
||||
"skip": "flaky"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-reload.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js": {
|
||||
"skip": "Depends on HTML WPT"
|
||||
},
|
||||
"not-restored-reasons/abort-block-bfcache.window.js": {
|
||||
"fail": {
|
||||
"note": "Requires window.stop()",
|
||||
"expected": [
|
||||
"aborting a parser should block bfcache."
|
||||
]
|
||||
}
|
||||
},
|
||||
"idlharness-shadowrealm.window.js": {
|
||||
"skip": "ShadowRealm support is not enabled"
|
||||
},
|
||||
"droppedentriescount.any.js": {
|
||||
"skip": "WPTRunner does not support fetch()"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user