1 <html> 2 <head> 3 <title>Hash Change with an Open XHR should not stop database transactions</title> 4 5 <script type="text/javascript"> 6 7 var DB_UPDATE_INTERVAL = 100; 8 var SEND_XHR_INTERVAL = 100; 9 var BACK_INTERVAL = 100; 10 var CREATE_HEALTH_TABLE = 'CREATE TABLE IF NOT EXISTS health (key VARCHAR(16) PRIMARY KEY);'; 11 var UPDATE_DATA = 'REPLACE INTO health VALUES("health-check-key");'; 12 13 var db = window.openDatabase('bug25710', '1.0', 'LayoutTest for bug 25710', 102400); 14 var backIterations; 15 var msgDiv; 16 var xhrFctIntervalId; 17 var backFctIntervalId; 18 var successCheckIntervalId; 19 var dbFctIntervalId; 20 var successes; 21 var databaseUpdates; 22 var stoppedIntervals; 23 24 function log(msg) 25 { 26 var newMsg = document.createElement('div'); 27 newMsg.innerText = msg; 28 msgDiv.appendChild(newMsg); 29 } 30 31 function stopIntervals() 32 { 33 stoppedIntervals = true; 34 window.clearInterval(dbFctIntervalId); 35 window.clearInterval(xhrFctIntervalId); 36 window.clearInterval(backFctIntervalId); 37 } 38 39 function stopTest(message) 40 { 41 if (!stoppedIntervals) 42 stopIntervals(); 43 44 log(message); 45 46 if (window.layoutTestController) 47 layoutTestController.notifyDone(); 48 } 49 50 function updateDatabase() 51 { 52 databaseUpdates++; 53 db.transaction(function(transaction) { 54 transaction.executeSql(UPDATE_DATA, [], function() {}, errorHandler); 55 }, errorHandler, function() { 56 successes++; 57 }); 58 } 59 60 function checkForSuccess() 61 { 62 if (successes == databaseUpdates) { 63 stopTest('Test Complete, SUCCESS'); 64 window.clearInterval(successCheckIntervalId); 65 } 66 } 67 68 function errorHandler(tx, error) 69 { 70 log('DB error, code: ' + error.code + ', msg: ' + error.message); 71 stopTest('Test Complete, FAILED'); 72 } 73 74 function sendXhr() 75 { 76 xhr = new XMLHttpRequest(); 77 xhr.open('GET', location.href, true); 78 xhr.send(''); 79 } 80 81 function invokeBack() 82 { 83 backIterations--; 84 if (backIterations) { 85 history.back(); 86 } else { 87 stopIntervals(); 88 // Allow a little time for all the database transactions to complete now we've stopped making them. 89 successCheckIntervalId = window.setInterval(checkForSuccess, 250); 90 // If we don't finish before this time, then we consider the test failed. 91 window.setTimeout(function() { stopTest('Timed out waiting for transactions to complete. FAILED'); }, 20000); 92 93 } 94 } 95 96 function runTest() 97 { 98 if (window.layoutTestController) { 99 layoutTestController.dumpAsText(); 100 layoutTestController.waitUntilDone(); 101 } 102 103 msgDiv = document.getElementById('msgs'); 104 105 msgDiv.innerHTML = ''; 106 backIterations = 10; 107 consecutiveFailures = 0; 108 successes = 0; 109 databaseUpdates = 0; 110 stoppedIntervals = false; 111 112 // Create some hashes so we can call history.back(). 113 log('Changing the hash to create history entries.'); 114 for (var i = 0; i < backIterations; i++) { 115 location.hash = i; 116 } 117 118 // Init the database. 119 db.transaction(function(transaction) { 120 transaction.executeSql(CREATE_HEALTH_TABLE, [], function() {}, errorHandler); 121 }, errorHandler, function() { 122 // Give a little for the database to 'warm up' before making xhr requests 123 // and calling history.back(). 124 window.setTimeout(function() { 125 log('Db is warmed up'); 126 127 // NOTE: If we don't make any xhr requests, then the test 128 // successfully passes (comment this line out). 129 xhrFctIntervalId = window.setInterval(sendXhr, SEND_XHR_INTERVAL); 130 backFctIntervalId = window.setInterval(invokeBack, BACK_INTERVAL); 131 dbFctIntervalId = window.setInterval(updateDatabase, DB_UPDATE_INTERVAL); 132 }, 500); 133 }); 134 } 135 136 137 138 139 140