<html>
<head>
<title>Hash Change with an Open XHR should not stop database transactions</title>
<script type="text/javascript">
var DB_UPDATE_INTERVAL = 100;
var SEND_XHR_INTERVAL = 100;
var BACK_INTERVAL = 100;
var CREATE_HEALTH_TABLE = 'CREATE TABLE IF NOT EXISTS health (key VARCHAR(16) PRIMARY KEY);';
var UPDATE_DATA = 'REPLACE INTO health VALUES("health-check-key");';
var db = window.openDatabase('bug25710', '1.0', 'LayoutTest for bug 25710', 102400);
var backIterations;
var msgDiv;
var xhrFctIntervalId;
var backFctIntervalId;
var successCheckIntervalId;
var dbFctIntervalId;
var successes;
var databaseUpdates;
var stoppedIntervals;
function log(msg)
{
var newMsg = document.createElement('div');
newMsg.innerText = msg;
msgDiv.appendChild(newMsg);
}
function stopIntervals()
{
stoppedIntervals = true;
window.clearInterval(dbFctIntervalId);
window.clearInterval(xhrFctIntervalId);
window.clearInterval(backFctIntervalId);
}
function stopTest(message)
{
if (!stoppedIntervals)
stopIntervals();
log(message);
if (window.layoutTestController)
layoutTestController.notifyDone();
}
function updateDatabase()
{
databaseUpdates++;
db.transaction(function(transaction) {
transaction.executeSql(UPDATE_DATA, [], function() {}, errorHandler);
}, errorHandler, function() {
successes++;
});
}
function checkForSuccess()
{
if (successes == databaseUpdates) {
stopTest('Test Complete, SUCCESS');
window.clearInterval(successCheckIntervalId);
}
}
function errorHandler(tx, error)
{
log('DB error, code: ' + error.code + ', msg: ' + error.message);
stopTest('Test Complete, FAILED');
}
function sendXhr()
{
xhr = new XMLHttpRequest();
xhr.open('GET', location.href, true);
xhr.send('');
}
function invokeBack()
{
backIterations--;
if (backIterations) {
history.back();
} else {
stopIntervals();
// Allow a little time for all the database transactions to complete now we've stopped making them.
successCheckIntervalId = window.setInterval(checkForSuccess, 250);
// If we don't finish before this time, then we consider the test failed.
window.setTimeout(function() { stopTest('Timed out waiting for transactions to complete. FAILED'); }, 20000);
}
}
function runTest()
{
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
msgDiv = document.getElementById('msgs');
msgDiv.innerHTML = '';
backIterations = 10;
consecutiveFailures = 0;
successes = 0;
databaseUpdates = 0;
stoppedIntervals = false;
// Create some hashes so we can call history.back().
log('Changing the hash to create history entries.');
for (var i = 0; i < backIterations; i++) {
location.hash = i;
}
// Init the database.
db.transaction(function(transaction) {
transaction.executeSql(CREATE_HEALTH_TABLE, [], function() {}, errorHandler);
}, errorHandler, function() {
// Give a little for the database to 'warm up' before making xhr requests
// and calling history.back().
window.setTimeout(function() {
log('Db is warmed up');
// NOTE: If we don't make any xhr requests, then the test
// successfully passes (comment this line out).
xhrFctIntervalId = window.setInterval(sendXhr, SEND_XHR_INTERVAL);
backFctIntervalId = window.setInterval(invokeBack, BACK_INTERVAL);
dbFctIntervalId = window.setInterval(updateDatabase, DB_UPDATE_INTERVAL);
}, 500);
});
}
</script>
</head>
<body onload="runTest()">
<div id="msgs"></div>
</body>
</html>