| <body> |
| <script> |
| |
| window.testStatus = ''; |
| var objects = ['runtime', 'require', 'test', 'binding']; |
| var leaked = []; |
| |
| function intercept(objectKey) { |
| Object.defineProperty(Object.prototype, objectKey, { |
| get: function () { |
| leaked.push({name: objectKey, obj: this}); |
| }, |
| set: function (v) { |
| Object.defineProperty(this, objectKey, { |
| value: v, |
| configurable: true, |
| enumerable: true, |
| writable: true |
| }); |
| }, |
| configurable: true, |
| }); |
| } |
| |
| // Set up interceptors. |
| for (let objectKey of objects) |
| intercept(objectKey); |
| |
| // Poke chrome.runtime and chrome.app. |
| try { |
| chrome.runtime; |
| } catch (e) {} |
| try { |
| chrome.app; |
| } catch (e) {} |
| |
| // Cleanup - we don't want to be triggering our own interceptors. |
| for (let objKey of objects) |
| delete Object.prototype[objKey]; |
| |
| // Check what we intercepted. |
| var keysToCheck = ['utils', 'binding']; |
| for (let nameAndObj of leaked) { |
| for (let key of keysToCheck) { |
| if (!!nameAndObj.obj[key]) { |
| window.testStatus += |
| 'Failed: Found ' + key + ' on ' + nameAndObj.name + '\n'; |
| } |
| } |
| } |
| |
| if (window.testStatus === '') |
| window.testStatus = 'success'; |
| |
| </script> |
| </body> |