001: /*
002: * Copyright (c) 2002-2008 Gargoyle Software Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: * 2. Redistributions in binary form must reproduce the above copyright notice,
010: * this list of conditions and the following disclaimer in the documentation
011: * and/or other materials provided with the distribution.
012: * 3. The end-user documentation included with the redistribution, if any, must
013: * include the following acknowledgment:
014: *
015: * "This product includes software developed by Gargoyle Software Inc.
016: * (http://www.GargoyleSoftware.com/)."
017: *
018: * Alternately, this acknowledgment may appear in the software itself, if
019: * and wherever such third-party acknowledgments normally appear.
020: * 4. The name "Gargoyle Software" must not be used to endorse or promote
021: * products derived from this software without prior written permission.
022: * For written permission, please contact info@GargoyleSoftware.com.
023: * 5. Products derived from this software may not be called "HtmlUnit", nor may
024: * "HtmlUnit" appear in their name, without prior written permission of
025: * Gargoyle Software Inc.
026: *
027: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
028: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
029: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
030: * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
031: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
032: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
033: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
036: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: */
038: package com.gargoylesoftware.htmlunit;
039:
040: import java.util.ArrayList;
041: import java.util.Collections;
042: import java.util.List;
043:
044: import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
045: import com.gargoylesoftware.htmlunit.html.HtmlInlineFrame;
046: import com.gargoylesoftware.htmlunit.html.HtmlPage;
047:
048: /**
049: * Tests for {@link ThreadManager}.
050: *
051: * @version $Revision: 2132 $
052: * @author Brad Clarke
053: *
054: */
055: public class ThreadManagerTest extends WebTestCase {
056: /**
057: * Make a test
058: * @param name test name
059: */
060: public ThreadManagerTest(final String name) {
061: super (name);
062: }
063:
064: private long startTime_;
065:
066: private void startTimedTest() {
067: startTime_ = System.currentTimeMillis();
068: }
069:
070: private void assertMaxTestRunTime(final long maxRunTimeMilliseconds) {
071: final long endTime = System.currentTimeMillis();
072: final long runTime = endTime - startTime_;
073: assertTrue(
074: "\nTest took too long to run and results may not be accurate. Please try again. "
075: + "\n Actual Run Time: "
076: + runTime
077: + "\n Max Run Time: " + maxRunTimeMilliseconds,
078: runTime < maxRunTimeMilliseconds);
079: }
080:
081: /**
082: * @throws Exception If the test fails
083: */
084: public void testSetClearTimeoutUsesManager() throws Exception {
085: final String content = "<html>\n"
086: + "<head>\n"
087: + " <title>test</title>\n"
088: + " <script>\n"
089: + " var threadID;\n"
090: + " function test() {\n"
091: + " threadID = setTimeout('doAlert()', 10000);\n"
092: + " }\n"
093: + " function doAlert() {\n"
094: + " alert('blah');\n"
095: + " }\n"
096: + " </script>\n"
097: + "</head>\n"
098: + "<body onload='test()'>\n"
099: + "<a onclick='clearTimeout(threadID);' id='clickme'/>\n"
100: + "</body>\n" + "</html>";
101:
102: final List collectedAlerts = Collections
103: .synchronizedList(new ArrayList());
104: startTimedTest();
105: final HtmlPage page = loadPage(content, collectedAlerts);
106: final ThreadManager threadManager = page.getEnclosingWindow()
107: .getThreadManager();
108: assertNotNull(threadManager);
109: assertEquals(1, threadManager.activeCount());
110: final HtmlAnchor a = (HtmlAnchor) page
111: .getHtmlElementById("clickme");
112: a.click();
113: threadManager.joinAll(10000);
114: assertEquals(0, threadManager.activeCount());
115: assertEquals(Collections.EMPTY_LIST, collectedAlerts);
116: assertMaxTestRunTime(10000);
117: }
118:
119: /**
120: * @throws Exception If the test fails
121: */
122: public void testSetClearIntervalUsesManager() throws Exception {
123: final String content = "<html>\n" + "<head>\n"
124: + " <title>test</title>\n" + " <script>\n"
125: + " var threadID;\n" + " function test() {\n"
126: + " threadID = setInterval('doAlert()', 100);\n"
127: + " }\n" + " var iterationNumber=0;\n"
128: + " function doAlert() {\n"
129: + " alert('blah');\n"
130: + " if (++iterationNumber >= 3) {"
131: + " clearInterval(threadID);\n" + " }"
132: + " }\n" + " </script>\n" + "</head>\n"
133: + "<body onload='test()'>\n" + "</body>\n" + "</html>";
134:
135: final List collectedAlerts = Collections
136: .synchronizedList(new ArrayList());
137: startTimedTest();
138: final HtmlPage page = loadPage(content, collectedAlerts);
139: final ThreadManager threadManager = page.getEnclosingWindow()
140: .getThreadManager();
141: assertNotNull(threadManager);
142: assertEquals(1, threadManager.activeCount());
143: threadManager.joinAll(1000);
144: assertEquals(0, threadManager.activeCount());
145: assertEquals(Collections.nCopies(3, "blah"), collectedAlerts);
146: assertMaxTestRunTime(1000);
147: }
148:
149: /**
150: * @throws Exception If the test fails
151: */
152: public void testNavigationStopThreadsInChildWindows()
153: throws Exception {
154: final String firstContent = "<html><head><title>First</title></head><body>\n"
155: + "<iframe id='iframe1' src='"
156: + URL_SECOND
157: + "'>\n"
158: + "<a href='"
159: + URL_THIRD.toExternalForm()
160: + "' id='clickme'>click me</a>\n" + "</body></html>";
161: final String secondContent = "<html><head><title>Second</title></head><body>\n"
162: + "<script>\n"
163: + "setInterval('', 10000);\n"
164: + "</script>\n" + "</body></html>";
165: final String thirdContent = "<html><head><title>Third</title></head><body></body></html>";
166: final WebClient client = new WebClient();
167:
168: final MockWebConnection webConnection = new MockWebConnection(
169: client);
170: webConnection.setResponse(URL_FIRST, firstContent);
171: webConnection.setResponse(URL_SECOND, secondContent);
172: webConnection.setResponse(URL_THIRD, thirdContent);
173:
174: client.setWebConnection(webConnection);
175:
176: final HtmlPage page = (HtmlPage) client.getPage(URL_FIRST);
177: final HtmlInlineFrame iframe = (HtmlInlineFrame) page
178: .getHtmlElementById("iframe1");
179: final ThreadManager innerThreadManager = iframe
180: .getEnclosedWindow().getThreadManager();
181: assertEquals("inner frame should show child thread", 1,
182: innerThreadManager.activeCount());
183:
184: final HtmlAnchor anchor = (HtmlAnchor) page
185: .getHtmlElementById("clickme");
186: final HtmlPage newPage = (HtmlPage) anchor.click();
187:
188: assertEquals("new page should load", "Third", newPage
189: .getTitleText());
190: assertEquals("frame should be gone", 0, newPage.getFrames()
191: .size());
192: // this thread manager really is not accessible anymore, but this is a unit test
193: innerThreadManager.joinAll(1000);
194: assertEquals("thread should stop", 0, innerThreadManager
195: .activeCount());
196: }
197: }
|