1 38 package com.gargoylesoftware.htmlunit.javascript; 39 40 import java.io.FileNotFoundException; 41 import java.io.IOException; 42 import java.net.URL; 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.Collections; 46 import java.util.HashMap; 47 import java.util.List; 48 import java.util.Map; 49 50 import org.xml.sax.EntityResolver; 51 import org.xml.sax.ErrorHandler; 52 import org.xml.sax.InputSource; 53 import org.xml.sax.SAXException; 54 import org.xml.sax.SAXParseException; 55 import org.xml.sax.XMLReader; 56 import org.xml.sax.helpers.XMLReaderFactory; 57 58 import com.gargoylesoftware.htmlunit.CollectingAlertHandler; 59 import com.gargoylesoftware.htmlunit.MockWebConnection; 60 import com.gargoylesoftware.htmlunit.ScriptEngine; 61 import com.gargoylesoftware.htmlunit.ScriptException; 62 import com.gargoylesoftware.htmlunit.WebClient; 63 import com.gargoylesoftware.htmlunit.WebTestCase; 64 import com.gargoylesoftware.htmlunit.html.HtmlAnchor; 65 import com.gargoylesoftware.htmlunit.html.HtmlButtonInput; 66 import com.gargoylesoftware.htmlunit.html.HtmlElement; 67 import com.gargoylesoftware.htmlunit.html.HtmlForm; 68 import com.gargoylesoftware.htmlunit.html.HtmlFrame; 69 import com.gargoylesoftware.htmlunit.html.HtmlPage; 70 import com.gargoylesoftware.htmlunit.html.HtmlScript; 71 import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput; 72 import com.gargoylesoftware.htmlunit.html.HtmlTextInput; 73 74 75 85 public class JavaScriptEngineTest extends WebTestCase { 86 90 public JavaScriptEngineTest( final String name ) { 91 super(name); 92 } 93 94 95 98 public void testSetJavascriptEnabled_false() throws Exception { 99 final WebClient client = new WebClient(); 100 client.setJavaScriptEnabled(false); 101 final MockWebConnection webConnection = new MockWebConnection( client ); 102 103 final String content 104 = "<html><head><title>foo</title><script>" 105 + "document.form1.textfield1='blue'" 106 + "</script></head><body>" 107 + "<p>hello world</p>" 108 + "<form name='form1'>" 109 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 110 + " <input type='text' name='textfield2' id='textfield2'/>" 111 + "</form>" 112 + "</body></html>"; 113 114 webConnection.setDefaultResponse( content ); 115 client.setWebConnection( webConnection ); 116 117 final HtmlPage page = (HtmlPage) client.getPage(URL_GARGOYLE); 118 119 final HtmlTextInput textInput = (HtmlTextInput)page.getHtmlElementById("textfield1"); 120 assertEquals("foo", textInput.getValueAttribute()); 121 } 122 123 127 public void testSetInputValue() throws Exception { 128 final String content 129 = "<html><head><title>foo</title><script>" 130 + "function doTest(){\n" 131 + " document.form1.textfield1.value='blue'" 132 + "}\n" 133 + "</script></head><body onload='doTest()'>" 134 + "<p>hello world</p>" 135 + "<form name='form1'>" 136 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 137 + " <input type='text' name='textfield2' id='textfield2'/>" 138 + "</form>" 139 + "</body></html>"; 140 final List collectedAlerts = null; 141 final HtmlPage page = loadPage(content, collectedAlerts); 142 143 final HtmlTextInput textInput = (HtmlTextInput)page.getHtmlElementById("textfield1"); 144 assertEquals("blue", textInput.getValueAttribute()); 145 } 146 147 148 151 public void testAlert() throws Exception { 152 final String content 153 = "<html><head><title>foo</title><script>" 154 + "alert('foo')" 155 + "</script></head><body>" 156 + "<p>hello world</p>" 157 + "<form name='form1'>" 158 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 159 + " <input type='text' name='textfield2' id='textfield2'/>" 160 + "</form>" 161 + "</body></html>"; 162 final List collectedAlerts = new ArrayList(); 163 final HtmlPage page = loadPage(content, collectedAlerts); 164 assertEquals("foo", page.getTitleText()); 165 166 final List expectedAlerts = Arrays.asList( new String[]{ 167 "foo" 168 }); 169 assertEquals( expectedAlerts, collectedAlerts ); 170 } 171 172 173 177 public void testScopeOfNewFunction() throws Exception { 178 final String content 179 = "<html><head><script>" 180 + "var f = new Function('alert(\"foo\")');" 181 + "f();" 182 + "</script></head><body>" 183 + "</body></html>"; 184 final List expectedAlerts = Arrays.asList( new String[]{"foo"}); 185 createTestPageForRealBrowserIfNeeded(content, expectedAlerts); 186 187 final List collectedAlerts = new ArrayList(); 188 loadPage(content, collectedAlerts); 189 190 assertEquals( expectedAlerts, collectedAlerts ); 191 } 192 193 196 public void testScopeOfNestedNewFunction() throws Exception { 197 final List expectedAlerts = Collections.singletonList("foo"); 198 final String content 199 = "<html><head>" 200 + "<script>\n" 201 + "var foo = 'foo';\n" 202 + "var f1 = new Function('f = new Function(\"alert(foo)\"); f()');\n" 203 + "f1();\n" 204 + "</script>" 205 + "</head>" 206 + "<body>\n" 207 + "</body></html>\n"; 208 createTestPageForRealBrowserIfNeeded(content, expectedAlerts); 209 final List collectedAlerts = new ArrayList(); 210 loadPage(content, collectedAlerts); 211 212 assertEquals(expectedAlerts, collectedAlerts); 213 } 214 215 220 public void testScopeOfNewFunctionCalledFormOtherWindow() throws Exception { 221 final String firstContent 222 = "<html><head>" 223 + "<script>" 224 + "var foo = 'foo';" 225 + "var test = new Function('alert(foo);');" 226 + "</script>" 227 + "</head>" 228 + "<body onload='test()'>" 229 + " <iframe SRC='page2.html'/>" 230 + "</body>" 231 + "</html>"; 232 233 final String secondContent = "<html><head><script>" 234 + "var foo = 'foo2';" 235 + "parent.test();" 236 + "var f = parent.test;" 237 + "f();" 238 + "</script></head></html>"; 239 240 241 final WebClient client = new WebClient(); 242 final MockWebConnection webConnection = new MockWebConnection( client ); 243 webConnection.setDefaultResponse( secondContent ); 244 webConnection.setResponse(URL_FIRST, firstContent); 245 client.setWebConnection( webConnection ); 246 247 final List expectedAlerts = Arrays.asList( new String[]{"foo", "foo", "foo"}); 248 249 final List collectedAlerts = new ArrayList(); 250 client.setAlertHandler( new CollectingAlertHandler(collectedAlerts) ); 251 client.getPage(URL_FIRST); 252 253 assertEquals( expectedAlerts, collectedAlerts ); 254 } 255 256 259 public void testExternalScript() throws Exception { 260 261 final WebClient client = new WebClient(); 262 final MockWebConnection webConnection = new MockWebConnection( client ); 263 264 final String htmlContent 265 = "<html><head><title>foo</title><script SRC='/foo.js' id='script1'/>" 266 + "</head><body>" 267 + "<p>hello world</p>" 268 + "<form name='form1'>" 269 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 270 + " <input type='text' name='textfield2' id='textfield2'/>" 271 + "</form>" 272 + "</body></html>"; 273 274 final String jsContent = "alert('got here');"; 275 276 webConnection.setResponse(URL_GARGOYLE, htmlContent); 277 webConnection.setResponse(new URL("http://www.gargoylesoftware.com/foo.js"), jsContent, 278 "text/javascript"); 279 client.setWebConnection( webConnection ); 280 281 final List expectedAlerts = Collections.singletonList("got here"); 282 final List collectedAlerts = new ArrayList(); 283 client.setAlertHandler( new CollectingAlertHandler(collectedAlerts) ); 284 285 final HtmlPage page = (HtmlPage) client.getPage(URL_GARGOYLE); 286 final HtmlScript htmlScript = (HtmlScript)page.getHtmlElementById("script1"); 287 assertNotNull(htmlScript); 288 assertEquals( expectedAlerts, collectedAlerts ); 289 } 290 291 292 295 public void testExternalScriptEncoding() throws Exception { 296 final WebClient client = new WebClient(); 297 final MockWebConnection webConnection = new MockWebConnection( client ); 298 301 final String htmlContent 302 = "<html><head>" 303 + "<meta http-equiv='content-type' content='text/html; charset=Shift_JIS'>" 304 + "<title>foo</title>" 305 + "<script SRC='/foo.js' id='script1'/>" 306 + "</head><body>" 307 + "<p>hello world</p>" 308 + "<form name='form1'>" 309 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 310 + " <input type='text' name='textfield2' id='textfield2'/>" 311 + "</form>" 312 + "</body></html>"; 313 314 317 final String htmlContent2 318 = "<html><head>" 319 + "<title>foo</title>" 320 + "<script SRC='/foo2.js' charset='Shift_JIS' id='script2'/>" 321 + "</head><body>" 322 + "<p>hello world</p>" 323 + "<form name='form1'>" 324 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 325 + " <input type='text' name='textfield2' id='textfield2'/>" 326 + "</form>" 327 + "</body></html>"; 328 329 334 final String jsContent = "alert('\u8868');"; 335 336 webConnection.setResponse(URL_GARGOYLE, htmlContent); 337 338 webConnection.setResponse( 339 new URL("http://www.gargoylesoftware.com/hidden"), 340 htmlContent2); 341 342 webConnection.setResponse( 343 new URL("http://www.gargoylesoftware.com/foo.js"), 344 new String(jsContent.getBytes("SJIS"),"8859_1"), "text/javascript"); 346 347 350 webConnection.setResponse( 351 new URL("http://www.gargoylesoftware.com/foo2.js"), 352 new String(jsContent.getBytes("SJIS"),"8859_1"), 354 "text/javascript"); 355 356 client.setWebConnection( webConnection ); 357 358 final List expectedAlerts = Collections.singletonList("\u8868"); 359 final List collectedAlerts = new ArrayList(); 360 client.setAlertHandler( new CollectingAlertHandler(collectedAlerts) ); 361 362 365 final HtmlPage page = (HtmlPage) client.getPage(URL_GARGOYLE); 366 final HtmlScript htmlScript = 367 (HtmlScript)page.getHtmlElementById("script1"); 368 369 assertNotNull(htmlScript); 370 assertEquals( expectedAlerts, collectedAlerts ); 371 372 375 collectedAlerts.clear(); 376 final HtmlPage page2 = ( HtmlPage )client.getPage( 377 new URL( "http://www.gargoylesoftware.com/hidden")); 378 final HtmlScript htmlScript2 = 379 (HtmlScript)page2.getHtmlElementById("script2"); 380 381 assertNotNull(htmlScript2); 382 assertEquals( expectedAlerts, collectedAlerts ); 383 } 384 385 390 public void testSetValuesThatAreNotStrings() throws Exception { 391 final String content 392 = "<html><head><title>foo</title><script>" 393 + "function doTest() {\n" 394 + " document.form1.textfield1.value=1;" 395 + " alert(document.form1.textfield1.value)" 396 + "}\n" 397 + "</script></head><body onload='doTest()'>" 398 + "<p>hello world</p>" 399 + "<form name='form1'>" 400 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 401 + " <input type='text' name='textfield2' id='textfield2'/>" 402 + "</form>" 403 + "</body></html>"; 404 final List collectedAlerts = new ArrayList(); 405 final HtmlPage page = loadPage(content, collectedAlerts); 406 assertEquals("foo", page.getTitleText()); 407 408 final List expectedAlerts = Arrays.asList( new String[]{ 409 "1" 410 }); 411 assertEquals( expectedAlerts, collectedAlerts ); 412 } 413 414 415 418 public void testReferencingVariablesFromOneScriptToAnother_Regression() throws Exception { 419 420 final WebClient client = new WebClient(); 421 final MockWebConnection webConnection = new MockWebConnection( client ); 422 423 final String htmlContent 424 = "<html><head><title>foo</title><script SRC='./test.js'></script>" 425 + "<script>var testLocalVariable = new Array();</script>" 426 + "</head><body onload='testNestedMethod();' >" 427 + "<form name='form1' method='POST' action='../foo' >" 428 + " <input type='submit' value='Login' name='loginButton'>" 429 + "</form></body></html>"; 430 431 final String jsContent 432 = "function testNestedMethod() {\n" 433 + " if (testLocalVariable == null)\n" 434 + " testLocalVariable = 'foo';\n" 435 + "} "; 436 437 webConnection.setResponse(URL_FIRST, htmlContent); 438 webConnection.setResponse(new URL("http://first/test.js"), jsContent, "text/javascript"); 439 client.setWebConnection( webConnection ); 440 441 final HtmlPage page = (HtmlPage) client.getPage(URL_FIRST); 442 assertEquals("foo", page.getTitleText()); 443 444 } 445 446 447 450 public void testJavaScriptUrl() throws Exception { 451 452 final String htmlContent 453 = "<html><head><script language='javascript'>" 454 + "var f1 = '<html><head><title>frame1</title></head><body><h1>frame1</h1></body></html>';\n" 455 + "var f2 = '<html><head><title>frame2</title></head><body><h1>frame2</h1></body></html>';\n" 456 + "</script></head>\n" 457 + "<frameset border='0' frameborder='0' framespacing='0' rows='100,*'>" 458 + " <frame id='frame1' SRC='javascript:parent.f1'/>" 459 + " <frame id='frame2' SRC='javascript:parent.f2'/>" 460 + "</frameset></html>"; 461 462 createTestPageForRealBrowserIfNeeded(htmlContent, Collections.EMPTY_LIST); 463 final HtmlPage page = loadPage(htmlContent); 464 465 final HtmlPage page1 = (HtmlPage)((HtmlFrame)page.getHtmlElementById("frame1")).getEnclosedPage(); 466 final HtmlPage page2 = (HtmlPage)((HtmlFrame)page.getHtmlElementById("frame2")).getEnclosedPage(); 467 468 assertNotNull("page1", page1); 469 assertNotNull("page2", page2); 470 471 assertEquals( "frame1", page1.getTitleText() ); 472 assertEquals( "frame2", page2.getTitleText() ); 473 } 474 475 476 479 public void testJavaScriptWrappedInHtmlComments() throws Exception { 480 final String htmlContent 481 = "<html><head><title>foo</title><script language='javascript'><!--\n" 482 + "function doTest() {\n" 483 + "}\n" 484 + "-->\n</script></head>\n" 485 + "<body onload='doTest()'></body></html>"; 486 final HtmlPage page = loadPage(htmlContent); 487 assertEquals("foo", page.getTitleText()); 488 } 489 490 491 494 public void testJavaScriptWrappedInHtmlComments_commentOnOpeningLine() throws Exception { 495 final String htmlContent 496 = "<html><head><title>foo</title><script language='javascript'><!-- Some comment here\n" 497 + "function doTest() {\n" 498 + "}\n" 499 + "-->\n</script></head>\n" 500 + "<body onload='doTest()'></body></html>"; 501 502 final HtmlPage page = loadPage(htmlContent); 503 assertEquals("foo", page.getTitleText()); 504 } 505 506 507 510 public void testJavaScriptWrappedInHtmlComments_allOnOneLine() throws Exception { 511 final String content 512 = "<html>\n" 513 + " <head>\n" 514 + " <title>test</title>\n" 515 + " <script>var test;</script>\n" 516 + " <!-- var test should be undefined since it's on first line -->\n" 517 + " <!-- but there should be no index out of bounds exception -->\n" 518 + " <script> <!-- test = 'abc'; // --> </script>\n" 519 + " </head>\n" 520 + " <body onload='alert(test)'>\n" 521 + " </body>\n" 522 + "</html>\n"; 523 final List collectedAlerts = new ArrayList(); 524 loadPage(content, collectedAlerts); 525 final List expectedAlerts = Arrays.asList( new String[]{"undefined"} ); 526 assertEquals(expectedAlerts, collectedAlerts); 527 } 528 529 530 535 public void testThisDotInOnClick() throws Exception { 536 537 final String htmlContent 538 = "<html><head><title>First</title><script>function foo(message){alert(message);}</script><body>" 539 + "<form name='form1'><input type='submit' name='button1' onClick='foo(this.name)'></form>" 540 + "</body></html>"; 541 542 final List collectedAlerts = new ArrayList(); 543 final HtmlPage page = loadPage(htmlContent, collectedAlerts); 544 assertEquals("First", page.getTitleText()); 545 546 ((HtmlSubmitInput)page.getFormByName("form1").getInputByName("button1")).click(); 547 548 final List expectedAlerts = Collections.singletonList("button1"); 549 assertEquals( expectedAlerts, collectedAlerts ); 550 } 551 552 553 556 public void testFunctionDefinedInExternalFile_CalledFromInlineScript() throws Exception { 557 558 final WebClient client = new WebClient(); 559 final MockWebConnection webConnection = new MockWebConnection( client ); 560 561 final String htmlContent 562 = "<html><head><title>foo</title><script SRC='./test.js'></script>" 563 + "</head><body>" 564 + " <script>externalMethod()</script>" 565 + "</body></html>"; 566 567 final String jsContent 568 = "function externalMethod() {\n" 569 + " alert('Got to external method');\n" 570 + "} "; 571 572 webConnection.setResponse( 573 new URL("http://first/index.html"), 574 htmlContent); 575 webConnection.setResponse( 576 new URL("http://first/test.js"), 577 jsContent, "text/javascript"); 578 client.setWebConnection( webConnection ); 579 580 final List collectedAlerts = new ArrayList(); 581 client.setAlertHandler( new CollectingAlertHandler(collectedAlerts) ); 582 583 final HtmlPage page = (HtmlPage) client.getPage(new URL("http://first/index.html")); 584 assertEquals("foo", page.getTitleText()); 585 assertEquals( Collections.singletonList("Got to external method"), collectedAlerts ); 586 } 587 588 589 593 public void testFunctionDefinedInSameFile() throws Exception { 594 final String htmlContent 595 = "<html><head><title>First</title><script>" 596 + "function showFoo( foo ) {\n" 597 + " alert( 'Foo is: |' + foo + '|' );\n" 598 + "}\n" 599 + "</script>" 600 + "</head><body><form name='form1'>" 601 + "<input name='text1' type='text'>\n" 602 + "<input name='button1' type='button' onclick='showFoo( document.form1.text1.value);'>\n" 603 + "</form></body></html>"; 604 605 final List collectedAlerts = new ArrayList(); 606 607 final HtmlPage page = loadPage(htmlContent, collectedAlerts); 608 assertEquals("First", page.getTitleText()); 609 610 final HtmlForm form = page.getFormByName("form1"); 611 final HtmlTextInput textInput = (HtmlTextInput)form.getInputByName("text1"); 612 textInput.setValueAttribute("flintstone"); 613 614 final HtmlButtonInput button = (HtmlButtonInput)form.getInputByName("button1"); 615 assertEquals( Collections.EMPTY_LIST, collectedAlerts ); 616 617 button.click(); 618 619 assertEquals( Collections.singletonList("Foo is: |flintstone|"), collectedAlerts ); 620 } 621 622 626 public void testConfigurationFileAgainstSchema() throws Exception { 627 final XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); 628 final String directory = "src/java/com/gargoylesoftware/htmlunit/javascript/"; 629 parser.setFeature("http://xml.org/sax/features/validation", true); 630 parser.setFeature("http://apache.org/xml/features/validation/schema", true); 631 parser.setEntityResolver( new EntityResolver() { 632 public InputSource resolveEntity (final String publicId, final String systemId) throws IOException { 633 return createInputSourceForFile(directory+"JavaScriptConfiguration.xsd"); 634 } 635 }); 636 parser.setErrorHandler( new ErrorHandler() { 637 public void warning(final SAXParseException exception) throws SAXException { 638 throw exception; 639 } 640 public void error(final SAXParseException exception) throws SAXException { 641 throw exception; 642 } 643 public void fatalError(final SAXParseException exception) throws SAXException { 644 throw exception; 645 } 646 }); 647 648 parser.parse( createInputSourceForFile(directory+"JavaScriptConfiguration.xml") ); 649 650 } 651 652 656 public void testJavaScriptEngineCallsForVariableAccess() throws Exception { 657 final WebClient client = new WebClient(); 658 final MockWebConnection webConnection = new MockWebConnection( client ); 659 660 final List collectedAlerts = new ArrayList(); 661 client.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); 662 663 final String content 664 = "<html><head><title>foo</title><script>" 665 + "myDate = 'foo';" 666 + "function doUnqualifiedVariableAccess() {\n" 667 + " alert('unqualified: ' + myDate);\n" 668 + "}\n" 669 + "function doQualifiedVariableAccess() {\n" 670 + " alert('qualified: ' + window.myDate);\n" 671 + "}\n" 672 + "</script></head><body>" 673 + "<p>hello world</p>" 674 + "<a id='unqualified' onclick='doUnqualifiedVariableAccess();'>unqualified</a>" 675 + "<a id='qualified' onclick='doQualifiedVariableAccess();'>qualified</a>" 676 + "</body></html>"; 677 678 webConnection.setDefaultResponse( content ); 679 client.setWebConnection( webConnection ); 680 final CountingJavaScriptEngine countingJavaScriptEngine = new CountingJavaScriptEngine( 681 client.getScriptEngine()); 682 client.setScriptEngine(countingJavaScriptEngine); 683 684 final HtmlPage page = (HtmlPage) client.getPage(URL_GARGOYLE); 685 686 assertEquals(1, countingJavaScriptEngine.getExecutionCount()); 687 assertEquals(0, countingJavaScriptEngine.getCallCount()); 688 689 ((HtmlAnchor) page.getHtmlElementById("unqualified")).click(); 690 assertEquals(1, countingJavaScriptEngine.getExecutionCount()); 691 assertEquals(1, countingJavaScriptEngine.getCallCount()); 692 693 ((HtmlAnchor) page.getHtmlElementById("qualified")).click(); 694 assertEquals(1, countingJavaScriptEngine.getExecutionCount()); 695 assertEquals(2, countingJavaScriptEngine.getCallCount()); 696 697 final List expectedAlerts = Arrays.asList(new String[]{"unqualified: foo", "qualified: foo"}); 698 assertEquals(expectedAlerts, collectedAlerts); 699 } 700 701 705 public void testActiveXObjectNoMap() throws Exception { 706 707 try { 708 loadPage(getJavaScriptContent( "new ActiveXObject()" )); 709 fail( "An exception should be thrown for zero argument constructor." ); 710 } 711 catch( final ScriptException e ) { 712 } 714 715 try { 716 loadPage(getJavaScriptContent( "new ActiveXObject(1, '2', '3')" )); 717 fail( "An exception should be thrown for a three argument constructor." ); 718 } 719 catch( final ScriptException e ) { 720 } 722 723 try { 724 loadPage(getJavaScriptContent( "new ActiveXObject(a)" )); 725 fail( "An exception should be thrown for an undefined parameter in the constructor." ); 726 } 727 catch( final ScriptException e ) { 728 } 730 731 try { 732 loadPage(getJavaScriptContent( "new ActiveXObject(10)" )); 733 fail( "An exception should be thrown for an integer parameter in the constructor." ); 734 } 735 catch( final ScriptException e ) { 736 } 738 739 try { 740 loadPage(getJavaScriptContent( "new ActiveXObject('UnknownObject')" )); 741 fail( "An exception should be thrown for a null map." ); 742 } 743 catch( final ScriptException e ) { 744 } 746 } 747 748 753 public void testActiveXObjectWithMap() throws Exception { 754 final Map activexToJavaMapping = new HashMap(); 755 activexToJavaMapping.put( 756 "MockActiveXObject", 757 "com.gargoylesoftware.htmlunit.javascript.MockActiveXObject"); 758 activexToJavaMapping.put( 759 "FakeObject", 760 "com.gargoylesoftware.htmlunit.javascript.NoSuchObject"); 761 activexToJavaMapping.put("BadObject", new Object()); 762 763 final WebClient client = new WebClient(); 764 final MockWebConnection webConnection = new MockWebConnection(client); 765 client.setWebConnection(webConnection); 766 client.setActiveXObjectMap(activexToJavaMapping); 767 final List collectedAlerts = new ArrayList(); 768 client.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); 769 770 webConnection.setDefaultResponse( getJavaScriptContent( "new ActiveXObject('UnknownObject')" ) ); 771 try { 772 client.getPage( new URL( "http://www.yahoo.com" ) ); 773 fail( "An exception should be thrown for non existent object in the map." ); 774 } 775 catch( final ScriptException e ) { 776 } 778 779 webConnection.setDefaultResponse( getJavaScriptContent( "new ActiveXObject('BadObject', 'server')" ) ); 780 try { 781 client.getPage( new URL( "http://www.yahoo.com" ) ); 782 fail( "An exception should be thrown for an invalid object in the map." ); 783 } 784 catch( final ScriptException e ) { 785 } 787 788 webConnection.setDefaultResponse( getJavaScriptContent( "new ActiveXObject('FakeObject')" ) ); 790 try { 791 client.getPage( new URL( "http://www.yahoo.com" ) ); 792 fail( "An exception should be thrown for a non existent object in the map." ); 793 } 794 catch( final ScriptException e ) { 795 } 797 798 assertEquals("should no alerts yet", Collections.EMPTY_LIST, collectedAlerts); 799 800 webConnection.setDefaultResponse( getJavaScriptContent( 802 "var t = new ActiveXObject('MockActiveXObject'); alert(t.MESSAGE);" ) ); 803 client.getPage( new URL( "http://www.yahoo.com" ) ); 804 assertEquals( 805 "The active x object did not bind to the object.", 806 Collections.singletonList(MockActiveXObject.MESSAGE), 807 collectedAlerts); 808 809 collectedAlerts.clear(); 810 811 webConnection.setDefaultResponse( getJavaScriptContent( 812 "var t = new ActiveXObject('MockActiveXObject', 'server'); alert(t.GetMessage());" ) ); 813 client.getPage( new URL( "http://www.yahoo.com" ) ); 814 assertEquals( 815 "The active x object did not bind to the object.", 816 Collections.singletonList(new MockActiveXObject().GetMessage()), 817 collectedAlerts); 818 819 } 820 821 private String getJavaScriptContent( final String javascript ) { 822 return "<html><head><title>foo</title><script>" 823 + javascript 824 + "</script></head><body>" 825 + "<p>hello world</p>" 826 + "<form name='form1'>" 827 + " <input type='text' name='textfield1' id='textfield1' value='foo' />" 828 + " <input type='text' name='textfield2' id='textfield2'/>" 829 + "</form>" 830 + "</body></html>"; 831 } 832 833 834 838 public void testScriptErrorIsolated() throws Exception { 839 840 final String content 841 = "<html>" 842 + "<head>" 843 + "<script>alert(1);</script>" 844 + "<script>alert(2</script>" 845 + "<script>alert(3);</script>" 846 + "</head>" 847 + "<body onload='alert(4);notExisting()'>" 848 + "<button onclick='alert(5)'>click me</button>" 849 + "</body>" 850 + "</html>"; 851 852 final List expectedAlerts = Arrays.asList( new String[]{ "1", "3", "4" } ); 853 createTestPageForRealBrowserIfNeeded(content, expectedAlerts); 854 855 final WebClient client = new WebClient(); 856 final MockWebConnection webConnection = new MockWebConnection(client); 857 webConnection.setDefaultResponse(content); 858 client.setWebConnection(webConnection); 859 final List collectedAlerts = new ArrayList(); 860 client.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); 861 862 try { 864 client.getPage(URL_FIRST); 865 fail("Should have thrown a script error"); 866 } 867 catch (final Exception e) { 868 } 870 assertEquals(Collections.singletonList("1"), collectedAlerts); 871 collectedAlerts.clear(); 872 873 client.setThrowExceptionOnScriptError(false); 875 client.getPage(URL_FIRST); 876 877 assertEquals(expectedAlerts, collectedAlerts); 878 } 879 880 881 private InputSource createInputSourceForFile( final String fileName ) throws FileNotFoundException { 882 return new InputSource( getFileAsStream(fileName) ); 883 } 884 885 private static final class CountingJavaScriptEngine extends ScriptEngine { 886 private ScriptEngine delegate_; 887 private int scriptExecutionCount_ = 0; 888 private int scriptCallCount_ = 0; 889 890 894 protected CountingJavaScriptEngine(ScriptEngine delegate) { 895 super(delegate.getWebClient()); 896 delegate_ = delegate; 897 } 898 899 903 public void initialize(final HtmlPage page) { 904 delegate_.initialize(page); 905 } 906 907 908 public Object execute( 909 final HtmlPage htmlPage, final String sourceCode, 910 final String sourceName, final HtmlElement htmlElement) { 911 scriptExecutionCount_++; 912 return delegate_.execute(htmlPage, sourceCode, sourceName, htmlElement); 913 } 914 915 916 public Object callFunction( 917 final HtmlPage htmlPage, final Object javaScriptFunction, 918 final Object thisObject, final Object[] args, 919 final HtmlElement htmlElementScope) { 920 scriptCallCount_++; 921 return delegate_.callFunction(htmlPage, javaScriptFunction, thisObject, args, htmlElementScope); 922 } 923 924 925 public String toString(final HtmlPage htmlPage, final Object javaScriptObject) { 926 return delegate_.toString(htmlPage, javaScriptObject); 927 } 928 929 930 public int getCallCount() { 931 return scriptCallCount_; 932 } 933 934 public int getExecutionCount() { 935 return scriptExecutionCount_; 936 } 937 938 public boolean isScriptRunning() { 939 return false; 940 } 941 } 942 } 943 944 | Popular Tags |