Index: test/browser/snippets.js |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/test/browser/snippets.js |
@@ -0,0 +1,128 @@ |
+/* |
+ * This file is part of Adblock Plus <https://adblockplus.org/>, |
+ * Copyright (C) 2006-present eyeo GmbH |
+ * |
+ * Adblock Plus is free software: you can redistribute it and/or modify |
+ * it under the terms of the GNU General Public License version 3 as |
+ * published by the Free Software Foundation. |
+ * |
+ * Adblock Plus is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
+ */ |
+ |
+"use strict"; |
+ |
+const library = require("../../lib/content/snippets.js"); |
+ |
+// We need this stub for the injector. |
+window.browser = |
Manish Jethani
2019/03/12 07:00:09
Nit: The normal style for object literals we use i
hub
2019/03/12 14:29:17
Done.
Manish Jethani
2019/03/12 14:48:49
The same would apply to the nested `runtime` prope
hub
2019/03/12 15:15:11
I wonder why the linter is silent.
Done
|
+{ |
+ runtime: |
+ { |
+ getURL: () => "" |
+ } |
+}; |
+ |
+let testDocument = null; |
+ |
+exports.setUp = function(callback) |
+{ |
+ let iframe = document.createElement("iframe"); |
+ document.body.appendChild(iframe); |
+ testDocument = iframe.contentDocument; |
Manish Jethani
2019/03/12 07:00:09
Where is `testDocument` being used in this file?
hub
2019/03/12 14:29:18
Used Line 44. Declared line 31.
This is the exact
Manish Jethani
2019/03/12 14:48:49
Yes, but over there we have this line:
elemHi
hub
2019/03/12 15:15:11
On second thought, we don't need this iframe eithe
|
+ |
+ callback(); |
+}; |
+ |
+exports.tearDown = function(callback) |
+{ |
+ let iframe = testDocument.defaultView.frameElement; |
+ iframe.parentNode.removeChild(iframe); |
+ testDocument = null; |
+ |
+ callback(); |
+}; |
+ |
+function timeout(delay) |
+{ |
+ return new Promise((resolve, reject) => |
Manish Jethani
2019/03/12 07:00:09
We don't need `reject` here, and we could also los
hub
2019/03/12 14:29:17
tbh this is a cut&paste from `test/browser/element
Manish Jethani
2019/03/12 14:48:49
Acknowledged.
|
+ { |
+ window.setTimeout(resolve, delay); |
Manish Jethani
2019/03/12 07:00:09
`setTimeout()` is a global function also available
hub
2019/03/12 14:29:17
This is always run in the browser context. But see
Manish Jethani
2019/03/12 14:48:49
Acknowledged.
|
+ }); |
+} |
+ |
+async function runSnippet(test, snippetName, ...args) |
Manish Jethani
2019/03/12 07:00:09
We could rename this to `runScript(test, script)`
hub
2019/03/12 14:29:18
The goal was to individually test the snippet, sim
|
+{ |
+ let snippet = library[snippetName]; |
+ |
+ test.ok(snippet); |
+ |
+ snippet(...args); |
+ await timeout(100); |
+} |
+ |
+exports.testAbortPropertyReadSnippet = async function(test) |
+{ |
+ window.abpTest = "foo"; |
+ |
+ async function testProperty(property, result = true) |
+ { |
+ let properties = property.split("."); |
+ test.ok(properties.length >= 1); |
+ |
+ let exceptionCaught = false; |
+ let value = 1; |
+ try |
+ { |
+ let obj = window; |
+ while (properties.length > 1) |
+ obj = obj[properties.shift()]; |
+ value = obj[properties.shift()]; |
+ } |
+ catch (e) |
+ { |
+ if (properties.length == 0) |
+ exceptionCaught = true; |
+ } |
+ test.equal(exceptionCaught, result, `The property "${property}" didn't trigger and exception.`); |
+ test.equal(value, result ? 1 : undefined, `The value for "${property}" shouldn't have been read.`); |
+ } |
+ |
+ await runSnippet(test, "abort-on-property-read", "abpTest"); |
+ await testProperty("abpTest"); |
+ |
+ window.abpTest2 = {prop1: "foo"}; |
+ |
+ await runSnippet(test, "abort-on-property-read", "abpTest2.prop1"); |
+ await testProperty("abpTest2.prop1"); |
+ |
+ // Test that we try to catch a property that don't exist yet. |
+ await runSnippet(test, "abort-on-property-read", "abpTest3.prop1"); |
+ window.abpTest3 = {prop1: "foo"}; |
+ await testProperty("abpTest3.prop1"); |
+ |
+ // Test that other properties don't trigger. |
+ await testProperty("abpTest3.prop2", false); |
+ |
+ // Test overwriting the object with another object |
+ window.foo = {bar: {}}; |
+ await runSnippet(test, "abort-on-property-read", "foo.bar.lambda"); |
+ await testProperty("foo.bar.lambda"); |
+ window.foo.bar = {}; |
+ await testProperty("foo.bar.lambda"); |
+ |
+ // Test if we start with a non-object |
+ window.foo2 = 5; |
+ await runSnippet(test, "abort-on-property-read", "foo2.bar2.lambda"); |
+ await testProperty("foo2.bar2.lambda"); |
+ window.foo2 = {}; |
+ await testProperty("foo2.bar2.lambda"); |
+ |
+ test.done(); |
+}; |
+ |