120 lines
3.3 KiB
HTML
120 lines
3.3 KiB
HTML
<html>
|
|
<head>
|
|
<title>Render Process Hang Test</title>
|
|
<style>
|
|
#loading {
|
|
display: inline-block;
|
|
width: 10px;
|
|
height: 10px;
|
|
border: 3px solid rgba(0,0,0,.3);
|
|
border-radius: 50%;
|
|
border-top-color: #000;
|
|
animation: spin 1s ease-in-out infinite;
|
|
-webkit-animation: spin 1s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes spin {
|
|
to { -webkit-transform: rotate(360deg); }
|
|
}
|
|
@-webkit-keyframes spin {
|
|
to { -webkit-transform: rotate(360deg); }
|
|
}
|
|
|
|
#hangtime {
|
|
width: 40px;
|
|
}
|
|
</style>
|
|
<script language="JavaScript">
|
|
|
|
function setFormEnabled(enabled) {
|
|
var elements = document.getElementById("form").elements;
|
|
for (var i = 0, element; element = elements[i++]; ) {
|
|
element.disabled = !enabled;
|
|
}
|
|
}
|
|
|
|
function updateTime() {
|
|
document.getElementById('time').innerText = new Date().toLocaleString();
|
|
}
|
|
|
|
function setupTest() {
|
|
// Retrieve the currently configured command.
|
|
// Results in a call to the OnQuery method in hang_test.cc
|
|
window.cefQuery({
|
|
request: 'HangTest:getcommand',
|
|
onSuccess: function(response) {
|
|
document.getElementById(response).checked = true;
|
|
setFormEnabled(true);
|
|
},
|
|
});
|
|
}
|
|
|
|
function setup() {
|
|
// Disable all elements.
|
|
setFormEnabled(false);
|
|
|
|
updateTime();
|
|
setInterval(updateTime, 1000);
|
|
|
|
if (location.hostname == 'tests' || location.hostname == 'localhost') {
|
|
setupTest();
|
|
return;
|
|
}
|
|
|
|
alert('This page can only be run from tests or localhost.');
|
|
}
|
|
|
|
// Send a query to the browser process.
|
|
function sendCommand(command) {
|
|
// Set the configured command.
|
|
// Results in a call to the OnQuery method in hang_test.cc
|
|
window.cefQuery({
|
|
request: 'HangTest:' + command
|
|
});
|
|
}
|
|
|
|
// Hang the render process for the specified number of seconds.
|
|
function triggerHang() {
|
|
const delayMs = parseInt(document.getElementById('hangtime').value) * 1000;
|
|
const startTime = performance.now();
|
|
while(performance.now() - startTime < delayMs) {}
|
|
}
|
|
|
|
</script>
|
|
|
|
</head>
|
|
<form id="form">
|
|
<body bgcolor="white" onload="setup()">
|
|
<div>Use the below controls to trigger a render process hang.</div>
|
|
<br/>
|
|
<div>Hang for <input type="number" id="hangtime" min="1" max="99" step="1" value="20"/> seconds.</div>
|
|
<br/>
|
|
<div>Action after hanging for at least 15 seconds:</div>
|
|
<br/>
|
|
<div><input type="radio" name="command" id="default" value="default" onclick="sendCommand('setdefault')"/>
|
|
<label for="default">Default behavior (Alloy style: Wait; Chrome style: show "Page unresponsive" dialog [1])</label></div>
|
|
<div><input type="radio" name="command" id="wait" value="wait" onclick="sendCommand('setwait')"/>
|
|
<label for="wait">Wait</label></div>
|
|
<div><input type="radio" name="command" id="terminate" value="terminate" onclick="sendCommand('setterminate')"/>
|
|
<label for="terminate">Terminate the render process [2]</label></div>
|
|
<br/>
|
|
<div>[1] The "Page unresponsive" dialog will be auto-dismissed when the hang ends.</div>
|
|
<div>[2] After termination the browser navigates to the startup URL or shows an error page.</div>
|
|
<br/>
|
|
<div><input type="button" value="Trigger Hang" onclick="triggerHang()"/></div>
|
|
</form>
|
|
Observe page responsiveness:
|
|
<br/><br/>
|
|
<table><tr>
|
|
<td valign="top">
|
|
CSS:<br/><div id="loading"></div>
|
|
</td>
|
|
<td> </td>
|
|
<td valign="top">
|
|
JavaScript:<br/><div id="time"></div>
|
|
</td>
|
|
</tr></table>
|
|
(JavaScript will stop updating during the hang)
|
|
</body>
|
|
</html>
|