1 <!DOCTYPE HTML> 2 <html> 3 <script src='test.js'></script> 4 <script src='call_function.js'></script> 5 <script> 6 7 function clearCache() { 8 getPageCache().cache_ = {}; 9 } 10 11 function testCallFunctionNoArgs() { 12 clearCache(); 13 14 var result = callFunction(null, function() { return 1; }, []); 15 assertEquals(0, result.status); 16 assertEquals(1, result.value); 17 } 18 19 function testCallFunctionThrows() { 20 clearCache(); 21 22 var result = callFunction(null, function() { throw new Error('fake error'); }, 23 []); 24 assertEquals(StatusCode.UNKNOWN_ERROR, result.status); 25 assertEquals('fake error', result.value); 26 27 result = callFunction(null, function() { 28 var e = new Error('fake error'); 29 e.code = 77; 30 e.message = 'CUSTOM'; 31 throw e; 32 }, []); 33 assertEquals(77, result.status); 34 assertEquals('CUSTOM', result.value); 35 } 36 37 function testCallFunctionArgs() { 38 clearCache(); 39 40 function func(primitive, elem) { 41 return [primitive, elem.querySelector('div')]; 42 } 43 var result = callFunction(null, func, [1, wrap(document)]); 44 assertEquals(0, result.status); 45 assertEquals(1, result.value[0]); 46 var cache = getPageCache(); 47 assertEquals(document.querySelector('div'), unwrap(result.value[1], cache)); 48 } 49 50 function testCallFunctionArgsUnwrappedReturn() { 51 clearCache(); 52 53 function func(elem) { 54 return elem.querySelector('div'); 55 } 56 var result = callFunction(null, func, [wrap(document)], true); 57 assertEquals(document.querySelector('div'), result); 58 } 59 60 function testCacheWrap() { 61 clearCache(); 62 63 assertEquals(1, wrap(1)); 64 assertEquals(1, unwrap(1)); 65 assertEquals("1", wrap("1")); 66 assertEquals("1", unwrap("1")); 67 assertEquals(false, wrap(false)); 68 assertEquals(false, unwrap(false)); 69 assertEquals(null, wrap(null)); 70 assertEquals(null, unwrap(null)); 71 assertEquals(undefined, wrap(undefined)); 72 assertEquals(undefined, unwrap(undefined)); 73 function func() {} 74 assertEquals(func, wrap(func)); 75 assertEquals(func, unwrap(func)); 76 77 var cache = getPageCache(); 78 var arr = [1, new Array(1, new Object({a: 1, b: {a: 1, b: {}, c: 3}}), 3)]; 79 var originalJson = JSON.stringify(arr); 80 arr[1][1].b.b[ELEMENT_KEY] = cache.idPrefix_ + '-' + cache.nextId_; 81 var wrappedJson = JSON.stringify(arr); 82 arr[1][1].b.b = document; 83 assertEquals(wrappedJson, JSON.stringify(wrap(arr))); 84 var unwrapped = unwrap(JSON.parse(wrappedJson), cache); 85 assertEquals(document, unwrapped[1][1].b.b); 86 unwrapped[1][1].b.b = {}; 87 assertEquals(originalJson, JSON.stringify(unwrapped)); 88 } 89 90 function testCacheDoubleWrap() { 91 clearCache(); 92 93 assertEquals(wrap(document)[ELEMENT_KEY], wrap(document)[ELEMENT_KEY]); 94 } 95 96 function testCacheUnwrapThrows() { 97 clearCache(); 98 99 try { 100 var wrapped = {}; 101 wrapped[ELEMENT_KEY] = '1'; 102 unwrap(wrapped, getPageCache()); 103 assert(false); 104 } catch (e) { 105 } 106 } 107 108 function testClearStale() { 109 clearCache(); 110 111 var doc = document; 112 var div = doc.querySelector('div'); 113 var span = doc.querySelector('span'); 114 115 var wrappedDoc = wrap(doc); 116 var wrappedDiv = wrap(div); 117 var wrappedSpan = wrap(span); 118 119 var cache = getPageCache(); 120 cache.clearStale(); 121 assertEquals(doc, unwrap(wrappedDoc, cache)); 122 assertEquals(div, unwrap(wrappedDiv, cache)); 123 assertEquals(span, unwrap(wrappedSpan, cache)); 124 125 div.removeChild(span); 126 cache.clearStale(); 127 assertEquals(doc, unwrap(wrappedDoc, cache)); 128 assertEquals(div, unwrap(wrappedDiv, cache)); 129 try { 130 unwrap(wrappedSpan, cache); 131 assert(false); 132 } catch (e) { 133 } 134 } 135 136 function testCacheQuerySelector() { 137 clearCache(); 138 139 var cache = getPageCache(); 140 assertEquals(document.querySelector('div'), 141 unwrap(wrap(document.querySelector('div')), cache)); 142 assertEquals(document.querySelectorAll('div')[0], 143 unwrap(wrap(document.querySelectorAll('div')), cache)[0]); 144 } 145 146 function testCacheStaleRef() { 147 clearCache(); 148 149 var cache = getPageCache(); 150 var img = document.createElement('img'); 151 document.body.appendChild(img); 152 var wrappedImg = wrap(img); 153 document.body.removeChild(img); 154 cache.clearStale(); 155 try { 156 unwrap(wrappedImg, cache); 157 assert(false); 158 } catch (e) { 159 assertEquals(StatusCode.STALE_ELEMENT_REFERENCE, e.code); 160 } 161 } 162 163 function testCallFunctionWithShadowHost() { 164 clearCache(); 165 166 // Set up something in the shadow DOM. 167 var host = document.body.appendChild(document.createElement('div')); 168 var root = host.webkitCreateShadowRoot(); 169 var shadowDiv = root.appendChild(document.createElement('div')); 170 171 function func(element) { 172 return element; 173 } 174 var wrappedHost = wrap(host); 175 176 var result = callFunction(null, func, [wrappedHost]); 177 assertEquals(0, result.status); 178 assertEquals(wrappedHost['ELEMENT'], result.value['ELEMENT']); 179 var cache = getPageCache(); 180 assertEquals(host, unwrap(result.value, cache)); 181 182 document.body.removeChild(host); 183 } 184 185 function testCallFunctionWithShadowRoot() { 186 clearCache(); 187 188 // Set up something in the shadow DOM. 189 var host = document.body.appendChild(document.createElement('div')); 190 var root = host.webkitCreateShadowRoot(); 191 var shadowDiv = root.appendChild(document.createElement('div')); 192 193 function func(element) { 194 return element; 195 } 196 var wrappedHost = wrap(host); 197 var wrappedRoot = wrap(root); 198 199 // Trying without setting the shadow_path should fail. 200 var result = callFunction(null, func, [wrappedRoot]); 201 assertEquals(StatusCode.STALE_ELEMENT_REFERENCE, result.status); 202 // Should succeed with the shadow_path. 203 result = callFunction([wrappedHost['ELEMENT']], func, [wrappedRoot]); 204 assertEquals(0, result.status); 205 assertEquals(wrappedRoot['ELEMENT'], result.value['ELEMENT']); 206 var cache = getPageCache(root); 207 assertEquals(root, unwrap(result.value, cache)); 208 209 document.body.removeChild(host); 210 } 211 212 function testCacheWithShadowDomAttached() { 213 clearCache(); 214 var pageCache = getPageCache(); 215 216 // Set up something in the shadow DOM. 217 var host = document.body.appendChild(document.createElement('div')); 218 var root = host.webkitCreateShadowRoot(); 219 var shadowDiv = root.appendChild(document.createElement('div')); 220 221 // Test with attached element in shadow DOM. 222 var wrappedDiv = wrap(shadowDiv); 223 // It should NOT be in the page cache. 224 try { 225 unwrap(wrappedDiv, pageCache); 226 assert(false); 227 } catch (e) { 228 assertEquals(StatusCode.STALE_ELEMENT_REFERENCE, e.code); 229 } 230 // It should be in the shadow root cache. 231 var rootCache = getPageCache(root); 232 rootCache.clearStale(); 233 var unwrappedDiv = unwrap(wrappedDiv, rootCache); 234 assertEquals(shadowDiv, unwrappedDiv); 235 236 document.body.removeChild(host); 237 } 238 239 function testCacheWithShadowDomDetachedChild() { 240 clearCache(); 241 242 // Set up something in the shadow DOM. 243 var host = document.body.appendChild(document.createElement('div')); 244 var root = host.webkitCreateShadowRoot(); 245 var shadowDiv = root.appendChild(document.createElement('div')); 246 247 // Test with detached element in shadow DOM. 248 var wrappedDiv = wrap(shadowDiv); 249 root.removeChild(shadowDiv); 250 var rootCache = getPageCache(root); 251 rootCache.clearStale(); 252 try { 253 unwrap(wrappedDiv, rootCache); 254 assert(false); 255 } catch (e) { 256 assertEquals(StatusCode.STALE_ELEMENT_REFERENCE, e.code); 257 } 258 259 document.body.removeChild(host); 260 } 261 262 </script> 263 <body> 264 <div><span></span></div> 265 </body> 266 </html> 267