| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>window-onerror</title> |
| <style> |
| #result { |
| width: 100px; |
| height:100px; |
| background-color:#0047AB; |
| } |
| </style> |
| </head> |
| <body> |
| |
| <div id="result"></div> |
| |
| <script> |
| |
| function expect(condition, message) { |
| if (!condition) { |
| document.querySelector('#result').style.display = 'none'; |
| const fullMessage = `failed expectation at: |
| ${new Error().stack} |
| ${typeof message === 'undefined' ? '' : 'with message: ' + message}`; |
| console.error(fullMessage); |
| } |
| } |
| |
| let windowOnErrorWasCalled = false; |
| |
| // No need to set this to null, but there was a regression at one point where |
| // doing so would result in an erroneous JS error, so add this line in to get |
| // some extra test coverage. |
| window.onerror = null; |
| |
| window.onerror = (message, filename, lineno, colno, error) => { |
| // We allow anything that ends with "myCoolMessage" to pass, Chrome/Firefox behavior differs here |
| // (Chrome: "Uncaught Error: myCoolMessage", Firefox: "Error: myCoolMessage"). |
| expect(/.*myCoolMessage/.test(message), message); |
| // Allow any filename that ends with "window-onerror.html", in order to not couple too heavily to |
| // the implementation of layout_tests. |
| expect(/.*window-onerror.html/.test(filename), filename); |
| expect(lineno === 89, lineno); |
| // The value of the column number is not standard across major browsers. |
| // Chrome: 1 without devtools open, 7 with devtools open. |
| // Edge: Always 1. |
| // Firefox: Always 7. |
| // Safari: 18. |
| expect(colno === 1 || colno === 7 || colno === 18, colno); |
| expect(typeof error === 'object', typeof error); |
| expect(String(error) === 'Error: myCoolMessage', String(error)); |
| |
| windowOnErrorWasCalled = true; |
| }; |
| |
| // Make sure that when an event handler is added for the 'error' event via |
| // addEventListener, it assumes the usual function signature of just the event |
| // object. |
| let windowErrorEventHandlerCalled = false; |
| window.addEventListener('error', (errorEvent) => { |
| expect(errorEvent.type == 'error', errorEvent.type); |
| |
| // Check the same parameters as above in the onerror attribute event handler, |
| // just make sure they are passed through as an event object instead of |
| // expanded. |
| expect(/.*myCoolMessage/.test(errorEvent.message), errorEvent.message); |
| expect(/.*window-onerror.html/.test(errorEvent.filename), |
| errorEvent.filename); |
| expect(errorEvent.lineno === 89, errorEvent.lineno); |
| expect(errorEvent.colno === 1 || errorEvent.colno === 7 || |
| errorEvent.colno === 18, errorEvent.colno); |
| expect(typeof errorEvent.error === 'object', typeof errorEvent.error); |
| expect(String(errorEvent.error) === 'Error: myCoolMessage', |
| String(errorEvent.error)); |
| |
| windowErrorEventHandlerCalled = true; |
| }); |
| |
| if (window.testRunner) { |
| window.testRunner.waitUntilDone(); |
| } |
| setTimeout(() => { |
| expect(windowOnErrorWasCalled); |
| expect(windowErrorEventHandlerCalled); |
| if (window.testRunner) { |
| window.testRunner.notifyDone(); |
| } |
| }, 1); |
| throw new Error('myCoolMessage'); |
| |
| </script> |
| |
| </body> |
| </html> |