test_web-reference.js (8047B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const { ShadowRoot, WebElement, WebFrame, WebReference, WebWindow } = 6 ChromeUtils.importESModule( 7 "chrome://remote/content/marionette/web-reference.sys.mjs" 8 ); 9 const { NodeCache } = ChromeUtils.importESModule( 10 "chrome://remote/content/shared/webdriver/NodeCache.sys.mjs" 11 ); 12 13 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; 14 15 class MockElement { 16 constructor(tagName, attrs = {}) { 17 this.tagName = tagName; 18 this.localName = tagName; 19 20 this.isConnected = false; 21 this.ownerGlobal = { 22 document: { 23 isActive() { 24 return true; 25 }, 26 }, 27 }; 28 29 for (let attr in attrs) { 30 this[attr] = attrs[attr]; 31 } 32 } 33 34 get nodeType() { 35 return 1; 36 } 37 38 get ELEMENT_NODE() { 39 return 1; 40 } 41 42 // this is a severely limited CSS selector 43 // that only supports lists of tag names 44 matches(selector) { 45 let tags = selector.split(","); 46 return tags.includes(this.localName); 47 } 48 } 49 50 class MockXULElement extends MockElement { 51 constructor(tagName, attrs = {}) { 52 super(tagName, attrs); 53 this.namespaceURI = XUL_NS; 54 55 if (typeof this.ownerDocument == "undefined") { 56 this.ownerDocument = {}; 57 } 58 if (typeof this.ownerDocument.documentElement == "undefined") { 59 this.ownerDocument.documentElement = { namespaceURI: XUL_NS }; 60 } 61 } 62 } 63 64 const xulEl = new MockXULElement("text"); 65 66 const domElInPrivilegedDocument = new MockElement("input", { 67 nodePrincipal: { isSystemPrincipal: true }, 68 }); 69 const xulElInPrivilegedDocument = new MockXULElement("text", { 70 nodePrincipal: { isSystemPrincipal: true }, 71 }); 72 73 function setupTest() { 74 const browser = Services.appShell.createWindowlessBrowser(false); 75 76 browser.document.body.innerHTML = ` 77 <div id="foo" style="margin: 50px"> 78 <iframe></iframe> 79 <video></video> 80 <svg xmlns="http://www.w3.org/2000/svg"></svg> 81 <textarea></textarea> 82 </div> 83 `; 84 85 const divEl = browser.document.querySelector("div"); 86 const svgEl = browser.document.querySelector("svg"); 87 const textareaEl = browser.document.querySelector("textarea"); 88 const videoEl = browser.document.querySelector("video"); 89 90 const iframeEl = browser.document.querySelector("iframe"); 91 const childEl = iframeEl.contentDocument.createElement("div"); 92 iframeEl.contentDocument.body.appendChild(childEl); 93 94 const shadowRoot = videoEl.openOrClosedShadowRoot; 95 96 return { 97 browser, 98 childEl, 99 divEl, 100 iframeEl, 101 nodeCache: new NodeCache(), 102 shadowRoot, 103 svgEl, 104 textareaEl, 105 videoEl, 106 }; 107 } 108 109 add_task(function test_WebReference_ctor() { 110 const el = new WebReference("foo"); 111 equal(el.uuid, "foo"); 112 113 for (let t of [42, true, [], {}, null, undefined]) { 114 Assert.throws(() => new WebReference(t), /to be a string/); 115 } 116 }); 117 118 add_task(function test_WebReference_from() { 119 const { divEl, iframeEl } = setupTest(); 120 121 ok(WebReference.from(divEl) instanceof WebElement); 122 ok(WebReference.from(xulEl) instanceof WebElement); 123 ok(WebReference.from(divEl.ownerGlobal) instanceof WebWindow); 124 ok(WebReference.from(iframeEl.contentWindow) instanceof WebFrame); 125 ok(WebReference.from(domElInPrivilegedDocument) instanceof WebElement); 126 ok(WebReference.from(xulElInPrivilegedDocument) instanceof WebElement); 127 128 Assert.throws(() => WebReference.from({}), /InvalidArgumentError/); 129 }); 130 131 add_task(function test_WebReference_fromJSON_malformed() { 132 Assert.throws(() => WebReference.fromJSON({}), /InvalidArgumentError/); 133 Assert.throws(() => WebReference.fromJSON(null), /InvalidArgumentError/); 134 }); 135 136 add_task(function test_WebReference_fromJSON_ShadowRoot() { 137 const { Identifier } = ShadowRoot; 138 139 const ref = { [Identifier]: "foo" }; 140 const shadowRootEl = WebReference.fromJSON(ref); 141 ok(shadowRootEl instanceof ShadowRoot); 142 equal(shadowRootEl.uuid, "foo"); 143 144 let identifierPrecedence = { 145 [Identifier]: "identifier-uuid", 146 }; 147 const precedenceShadowRoot = WebReference.fromJSON(identifierPrecedence); 148 ok(precedenceShadowRoot instanceof ShadowRoot); 149 equal(precedenceShadowRoot.uuid, "identifier-uuid"); 150 }); 151 152 add_task(function test_WebReference_fromJSON_WebElement() { 153 const { Identifier } = WebElement; 154 155 const ref = { [Identifier]: "foo" }; 156 const webEl = WebReference.fromJSON(ref); 157 ok(webEl instanceof WebElement); 158 equal(webEl.uuid, "foo"); 159 160 let identifierPrecedence = { 161 [Identifier]: "identifier-uuid", 162 }; 163 const precedenceEl = WebReference.fromJSON(identifierPrecedence); 164 ok(precedenceEl instanceof WebElement); 165 equal(precedenceEl.uuid, "identifier-uuid"); 166 }); 167 168 add_task(function test_WebReference_fromJSON_WebFrame() { 169 const ref = { [WebFrame.Identifier]: "foo" }; 170 const frame = WebReference.fromJSON(ref); 171 ok(frame instanceof WebFrame); 172 equal(frame.uuid, "foo"); 173 }); 174 175 add_task(function test_WebReference_fromJSON_WebWindow() { 176 const ref = { [WebWindow.Identifier]: "foo" }; 177 const win = WebReference.fromJSON(ref); 178 179 ok(win instanceof WebWindow); 180 equal(win.uuid, "foo"); 181 }); 182 183 add_task(function test_WebReference_is() { 184 const a = new WebReference("a"); 185 const b = new WebReference("b"); 186 187 ok(a.is(a)); 188 ok(b.is(b)); 189 ok(!a.is(b)); 190 ok(!b.is(a)); 191 192 ok(!a.is({})); 193 }); 194 195 add_task(function test_WebReference_isReference() { 196 for (let t of [42, true, "foo", [], {}]) { 197 ok(!WebReference.isReference(t)); 198 } 199 200 ok(WebReference.isReference({ [WebElement.Identifier]: "foo" })); 201 ok(WebReference.isReference({ [WebWindow.Identifier]: "foo" })); 202 ok(WebReference.isReference({ [WebFrame.Identifier]: "foo" })); 203 }); 204 205 add_task(function test_ShadowRoot_fromJSON() { 206 const { Identifier } = ShadowRoot; 207 208 const shadowRoot = ShadowRoot.fromJSON({ [Identifier]: "foo" }); 209 ok(shadowRoot instanceof ShadowRoot); 210 equal(shadowRoot.uuid, "foo"); 211 212 Assert.throws(() => ShadowRoot.fromJSON({}), /InvalidArgumentError/); 213 }); 214 215 add_task(function test_ShadowRoot_fromUUID() { 216 const shadowRoot = ShadowRoot.fromUUID("baz"); 217 218 ok(shadowRoot instanceof ShadowRoot); 219 equal(shadowRoot.uuid, "baz"); 220 221 Assert.throws(() => ShadowRoot.fromUUID(), /InvalidArgumentError/); 222 }); 223 224 add_task(function test_ShadowRoot_toJSON() { 225 const { Identifier } = ShadowRoot; 226 227 const shadowRoot = new ShadowRoot("foo"); 228 const json = shadowRoot.toJSON(); 229 230 ok(Identifier in json); 231 equal(json[Identifier], "foo"); 232 }); 233 234 add_task(function test_WebElement_fromJSON() { 235 const { Identifier } = WebElement; 236 237 const el = WebElement.fromJSON({ [Identifier]: "foo" }); 238 ok(el instanceof WebElement); 239 equal(el.uuid, "foo"); 240 241 Assert.throws(() => WebElement.fromJSON({}), /InvalidArgumentError/); 242 }); 243 244 add_task(function test_WebElement_fromUUID() { 245 const domWebEl = WebElement.fromUUID("bar"); 246 247 ok(domWebEl instanceof WebElement); 248 equal(domWebEl.uuid, "bar"); 249 250 Assert.throws(() => WebElement.fromUUID(), /InvalidArgumentError/); 251 }); 252 253 add_task(function test_WebElement_toJSON() { 254 const { Identifier } = WebElement; 255 256 const el = new WebElement("foo"); 257 const json = el.toJSON(); 258 259 ok(Identifier in json); 260 equal(json[Identifier], "foo"); 261 }); 262 263 add_task(function test_WebFrame_fromJSON() { 264 const ref = { [WebFrame.Identifier]: "foo" }; 265 const win = WebFrame.fromJSON(ref); 266 267 ok(win instanceof WebFrame); 268 equal(win.uuid, "foo"); 269 }); 270 271 add_task(function test_WebFrame_toJSON() { 272 const frame = new WebFrame("foo"); 273 const json = frame.toJSON(); 274 275 ok(WebFrame.Identifier in json); 276 equal(json[WebFrame.Identifier], "foo"); 277 }); 278 279 add_task(function test_WebWindow_fromJSON() { 280 const ref = { [WebWindow.Identifier]: "foo" }; 281 const win = WebWindow.fromJSON(ref); 282 283 ok(win instanceof WebWindow); 284 equal(win.uuid, "foo"); 285 }); 286 287 add_task(function test_WebWindow_toJSON() { 288 const win = new WebWindow("foo"); 289 const json = win.toJSON(); 290 291 ok(WebWindow.Identifier in json); 292 equal(json[WebWindow.Identifier], "foo"); 293 });