KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > gargoylesoftware > htmlunit > WebClientTest


1 /*
2  * Copyright (c) 2002, 2005 Gargoyle Software Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  * 3. The end-user documentation included with the redistribution, if any, must
13  * include the following acknowledgment:
14  *
15  * "This product includes software developed by Gargoyle Software Inc.
16  * (http://www.GargoyleSoftware.com/)."
17  *
18  * Alternately, this acknowledgment may appear in the software itself, if
19  * and wherever such third-party acknowledgments normally appear.
20  * 4. The name "Gargoyle Software" must not be used to endorse or promote
21  * products derived from this software without prior written permission.
22  * For written permission, please contact info@GargoyleSoftware.com.
23  * 5. Products derived from this software may not be called "HtmlUnit", nor may
24  * "HtmlUnit" appear in their name, without prior written permission of
25  * Gargoyle Software Inc.
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30  * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */

38 package com.gargoylesoftware.htmlunit;
39
40 import java.io.ByteArrayOutputStream;
41 import java.io.File;
42 import java.io.FileNotFoundException;
43 import java.io.IOException;
44 import java.io.OutputStreamWriter;
45 import java.net.URI;
46 import java.net.URL;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collections;
50 import java.util.List;
51
52 import org.apache.commons.io.FileUtils;
53 import org.apache.commons.lang.StringUtils;
54
55 import com.gargoylesoftware.base.testing.EventCatcher;
56 import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
57 import com.gargoylesoftware.htmlunit.html.HtmlElement;
58 import com.gargoylesoftware.htmlunit.html.HtmlInlineFrame;
59 import com.gargoylesoftware.htmlunit.html.HtmlPage;
60 import com.gargoylesoftware.htmlunit.xml.XmlPage;
61
62 /**
63  * Tests for WebClient
64  *
65  * @version $Revision: 1.51 $
66  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
67  * @author <a HREF="mailto:cse@dynabean.de">Christian Sell</a>
68  * @author <a HREF="mailto:bcurren@esomnie.com">Ben Curren</a>
69  * @author Marc Guillemot
70  * @author David D. Kilzer
71  * @author Chris Erskine
72  * @author Hans Donner
73  */

74 public class WebClientTest extends WebTestCase {
75
76     /**
77      * Create an instance
78      *
79      * @param name The name of the test
80      */

81     public WebClientTest( final String name ) {
82         super( name );
83     }
84
85
86     /**
87      * Test the situation where credentials are required but they haven't been specified.
88      *
89      * @throws Exception If something goes wrong.
90      */

91     public void testCredentialProvider_NoCredentials() throws Exception {
92
93         final String htmlContent
94             = "<html><head><title>foo</title></head><body>"
95             + "No access</body></html>";
96         final WebClient client = new WebClient();
97         client.setPrintContentOnFailingStatusCode( false );
98
99         final MockWebConnection webConnection = new MockWebConnection( client );
100         webConnection.setDefaultResponse(
101             htmlContent, 401, "Credentials missing or just plain wrong", "text/plain" );
102         client.setWebConnection( webConnection );
103
104         try {
105             client.getPage(new WebRequestSettings(URL_GARGOYLE, SubmitMethod.POST));
106             fail( "Expected FailingHttpStatusCodeException" );
107         }
108         catch( final FailingHttpStatusCodeException e ) {
109             assertEquals( 401, e.getStatusCode() );
110         }
111     }
112
113
114     /**
115      * Test that {@link WebClient#assertionFailed(String)} actually throws an exception.
116      */

117     public void testAssertionFailed() {
118         final WebClient client = new WebClient();
119
120         try {
121             client.assertionFailed( "foobar" );
122             fail( "Expected AssertionFailedError" );
123         }
124         catch( final junit.framework.AssertionFailedError e ) {
125             assertEquals( "foobar", e.getMessage() );
126         }
127     }
128
129
130     /**
131      * Test that the {@link WebWindowEvent#CHANGE} window event gets fired at the
132      * appropriate time.
133      * @throws Exception If something goes wrong.
134      */

135     public void testHtmlWindowEvents_changed() throws Exception {
136         final String htmlContent
137             = "<html><head><title>foo</title></head><body>"
138             + "<a HREF='http://www.foo2.com' id='a2'>link to foo2</a>"
139             + "</body></html>";
140         final WebClient client = new WebClient();
141         final EventCatcher eventCatcher = new EventCatcher();
142         eventCatcher.listenTo(client);
143
144         final MockWebConnection webConnection = new MockWebConnection( client );
145         webConnection.setDefaultResponse( htmlContent );
146         client.setWebConnection( webConnection );
147
148         final HtmlPage firstPage = ( HtmlPage )client.getPage(URL_GARGOYLE);
149         final HtmlAnchor anchor = ( HtmlAnchor )firstPage.getHtmlElementById( "a2" );
150
151         final List firstExpectedEvents = Arrays.asList( new Object[] {
152             new WebWindowEvent(
153                 client.getCurrentWindow(), WebWindowEvent.CHANGE, null, firstPage),
154         } );
155         assertEquals( firstExpectedEvents, eventCatcher.getEvents() );
156
157         eventCatcher.clear();
158         final HtmlPage secondPage = ( HtmlPage )anchor.click();
159
160         final List secondExpectedEvents = Arrays.asList( new Object[] {
161             new WebWindowEvent(
162                 client.getCurrentWindow(), WebWindowEvent.CHANGE, firstPage, secondPage),
163         } );
164         assertEquals( secondExpectedEvents, eventCatcher.getEvents() );
165     }
166
167
168     /**
169      * Test that the {@link WebWindowEvent#OPEN} window event gets fired at
170      * the appropriate time.
171      * @throws Exception If something goes wrong.
172      */

173     public void testHtmlWindowEvents_opened() throws Exception {
174         final String page1Content
175             = "<html><head><title>foo</title>"
176             + "<script>window.open('" + URL_SECOND.toExternalForm() + "', 'myNewWindow')</script>"
177             + "</head><body>"
178             + "<a HREF='http://www.foo2.com' id='a2'>link to foo2</a>"
179             + "</body></html>";
180         final String page2Content
181             = "<html><head><title>foo</title></head><body></body></html>";
182         final WebClient client = new WebClient();
183         final EventCatcher eventCatcher = new EventCatcher();
184         eventCatcher.listenTo(client);
185
186         final MockWebConnection webConnection = new MockWebConnection( client );
187         webConnection.setResponse(URL_FIRST, page1Content);
188         webConnection.setResponse(URL_SECOND, page2Content);
189
190         client.setWebConnection( webConnection );
191
192         final HtmlPage firstPage = ( HtmlPage )client.getPage(URL_FIRST);
193         assertEquals("foo", firstPage.getTitleText());
194
195         final WebWindow firstWindow = client.getCurrentWindow();
196         final WebWindow secondWindow = client.getWebWindowByName("myNewWindow");
197         final List expectedEvents = Arrays.asList( new Object[] {
198             new WebWindowEvent(
199                 secondWindow, WebWindowEvent.OPEN, null, null),
200             new WebWindowEvent(
201                 secondWindow, WebWindowEvent.CHANGE, null, secondWindow.getEnclosedPage()),
202             new WebWindowEvent(
203                 firstWindow, WebWindowEvent.CHANGE, null, firstPage),
204         } );
205         assertEquals( expectedEvents, eventCatcher.getEvents() );
206     }
207
208
209     /**
210      * Test that the {@link WebWindowEvent#CLOSE} window event gets fired at
211      * the appropriate time.
212      * @throws Exception If something goes wrong.
213      */

214     public void testHtmlWindowEvents_closedFromFrame() throws Exception {
215         final String firstContent
216             = "<html><head><title>first</title></head><body>"
217             + "<iframe SRC='http://third' id='frame1'>"
218             + "<a HREF='http://second' id='a2'>link to foo2</a>"
219             + "</body></html>";
220         final String secondContent
221             = "<html><head><title>second</title></head><body></body></html>";
222         final String thirdContent
223             = "<html><head><title>third</title></head><body></body></html>";
224         final WebClient client = new WebClient();
225
226         final MockWebConnection webConnection = new MockWebConnection( client );
227         webConnection.setResponse(URL_FIRST, firstContent);
228         webConnection.setResponse(URL_SECOND, secondContent);
229         webConnection.setResponse(URL_THIRD, thirdContent);
230
231         client.setWebConnection( webConnection );
232
233         final HtmlPage firstPage = ( HtmlPage )client.getPage(URL_FIRST);
234         assertEquals("first", firstPage.getTitleText());
235
236         final EventCatcher eventCatcher = new EventCatcher();
237         eventCatcher.listenTo(client);
238
239         final HtmlInlineFrame frame = (HtmlInlineFrame)firstPage.getHtmlElementById("frame1");
240         final HtmlPage thirdPage = (HtmlPage)frame.getEnclosedPage();
241
242         // Load the second page
243
final HtmlAnchor anchor = (HtmlAnchor)firstPage.getHtmlElementById( "a2" );
244         final HtmlPage secondPage = (HtmlPage)anchor.click();
245         assertEquals("second", secondPage.getTitleText());
246
247         final WebWindow firstWindow = client.getCurrentWindow();
248         final List expectedEvents = Arrays.asList( new Object[] {
249             new WebWindowEvent(
250                 frame.getEnclosedWindow(), WebWindowEvent.CLOSE, thirdPage, null),
251             new WebWindowEvent(
252                 firstWindow, WebWindowEvent.CHANGE, firstPage, secondPage),
253         } );
254         assertEquals( expectedEvents.get(0), eventCatcher.getEvents().get(0) );
255         assertEquals( expectedEvents, eventCatcher.getEvents() );
256     }
257
258
259     /**
260      * Test a 301 redirection code where the original request was a GET.
261      * @throws Exception If something goes wrong.
262      */

263     public void testRedirection301_MovedPermanently_GetMethod() throws Exception {
264         final int statusCode = 301;
265         final SubmitMethod initialRequestMethod = SubmitMethod.GET;
266         final SubmitMethod expectedRedirectedRequestMethod = SubmitMethod.GET;
267
268         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
269     }
270
271
272     /**
273      * From the http spec: If the 301 status code is received in response
274      * to a request other than GET or HEAD, the user agent MUST NOT automatically
275      * redirect the request unless it can be confirmed by the user, since this
276      * might change the conditions under which the request was issued.
277      * @throws Exception If something goes wrong.
278      */

279     public void testRedirection301_MovedPermanently_PostMethod() throws Exception {
280         final int statusCode = 301;
281         final SubmitMethod initialRequestMethod = SubmitMethod.POST;
282         final SubmitMethod expectedRedirectedRequestMethod = null;
283
284         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
285     }
286
287
288     /**
289      * From the http spec: Note: RFC 1945 and RFC 2068 specify that the client
290      * is not allowed to change the method on the redirected request. However,
291      * most existing user agent implementations treat 302 as if it were a 303
292      * response, performing a GET on the Location field-value regardless
293      * of the original request method. The status codes 303 and 307 have
294      * been added for servers that wish to make unambiguously clear which
295      * kind of reaction is expected of the client.
296      * @throws Exception If something goes wrong.
297      */

298     public void testRedirection302_MovedTemporarily_PostMethod() throws Exception {
299         final int statusCode = 302;
300         final SubmitMethod initialRequestMethod = SubmitMethod.POST;
301         final SubmitMethod expectedRedirectedRequestMethod = SubmitMethod.GET;
302
303         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
304     }
305
306
307     /**
308      * Test a 302 redirection code.
309      * @throws Exception If something goes wrong.
310      */

311     public void testRedirection302_MovedTemporarily_GetMethod() throws Exception {
312         final int statusCode = 302;
313         final SubmitMethod initialRequestMethod = SubmitMethod.GET;
314         final SubmitMethod expectedRedirectedRequestMethod = SubmitMethod.GET;
315
316         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
317     }
318
319
320     /**
321      * Tests a 303 redirection code. This should be the same as a 302.
322      * @throws Exception If something goes wrong.
323      */

324     public void testRedirection303_SeeOther_GetMethod() throws Exception {
325         final int statusCode = 303;
326         final SubmitMethod initialRequestMethod = SubmitMethod.GET;
327         final SubmitMethod expectedRedirectedRequestMethod = SubmitMethod.GET;
328
329         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
330     }
331
332
333     /**
334      * Tests a 303 redirection code - this should be the same as a 302.
335      * @throws Exception If something goes wrong.
336      */

337     public void testRedirection303_SeeOther_PostMethod() throws Exception {
338         final int statusCode = 303;
339         final SubmitMethod initialRequestMethod = SubmitMethod.POST;
340         final SubmitMethod expectedRedirectedRequestMethod = SubmitMethod.GET;
341
342         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
343     }
344
345
346     /**
347      * Tests a 307 redirection code.
348      * @throws Exception If something goes wrong.
349      */

350     public void testRedirection307_TemporaryRedirect_GetMethod() throws Exception {
351         final int statusCode = 307;
352         final SubmitMethod initialRequestMethod = SubmitMethod.GET;
353         final SubmitMethod expectedRedirectedRequestMethod = SubmitMethod.GET;
354
355         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
356     }
357
358
359     /**
360      * Tests a 307 redirection code.
361      * @throws Exception If something goes wrong.
362      */

363     public void testRedirection307_TemporaryRedirect_PostMethod() throws Exception {
364         final int statusCode = 307;
365         final SubmitMethod initialRequestMethod = SubmitMethod.POST;
366         final SubmitMethod expectedRedirectedRequestMethod = null;
367
368         doTestRedirection( statusCode, initialRequestMethod, expectedRedirectedRequestMethod );
369     }
370
371
372     /**
373      * Basic logic for all the redirection tests.
374      *
375      * @param statusCode The code to return from the initial request
376      * @param initialRequestMethod The initial request.
377      * @param expectedRedirectedRequestMethod The submit method of the second (redirected) request.
378      * If a redirect is not expected to happen then this must be null
379      * @throws Exception if the test fails.
380      */

381     private void doTestRedirection(
382             final int statusCode,
383             final SubmitMethod initialRequestMethod,
384             final SubmitMethod expectedRedirectedRequestMethod )
385         throws
386              Exception {
387
388         final String firstContent = "<html><head><title>First</title></head><body></body></html>";
389         final String secondContent = "<html><head><title>Second</title></head><body></body></html>";
390
391         final WebClient webClient = new WebClient();
392         webClient.setThrowExceptionOnFailingStatusCode(false);
393         webClient.setPrintContentOnFailingStatusCode(false);
394
395         final List headers = Collections.singletonList(
396             new KeyValuePair("Location", "http://second") );
397         final MockWebConnection webConnection = new MockWebConnection( webClient );
398         webConnection.setResponse(
399             URL_FIRST, firstContent, statusCode,
400             "Some error", "text/html", headers );
401         webConnection.setResponse(URL_SECOND, secondContent);
402
403         webClient.setWebConnection( webConnection );
404
405         final URL url = URL_FIRST;
406
407         HtmlPage page;
408         WebResponse webResponse;
409
410         //
411
// Second time redirection is turned on (default setting)
412
//
413
page = (HtmlPage) webClient.getPage(new WebRequestSettings(url, initialRequestMethod));
414         webResponse = page.getWebResponse();
415         if( expectedRedirectedRequestMethod == null ) {
416             // No redirect should have happened
417
assertEquals( statusCode, webResponse.getStatusCode() );
418             assertEquals( initialRequestMethod, webConnection.getLastMethod() );
419         }
420         else {
421             // A redirect should have happened
422
assertEquals( 200, webResponse.getStatusCode() );
423             assertEquals( "Second", page.getTitleText() );
424             assertEquals( expectedRedirectedRequestMethod, webConnection.getLastMethod() );
425         }
426
427         //
428
// Second time redirection is turned off
429
//
430
webClient.setRedirectEnabled(false);
431         page = (HtmlPage) webClient.getPage(new WebRequestSettings(url, initialRequestMethod));
432         webResponse = page.getWebResponse();
433         assertEquals( statusCode, webResponse.getStatusCode() );
434         assertEquals( initialRequestMethod, webConnection.getLastMethod() );
435
436     }
437
438
439     /**
440      * Test passing in a null page creator.
441      */

442     public void testSetPageCreator_null() {
443         final WebClient webClient = new WebClient();
444         try {
445             webClient.setPageCreator(null);
446             fail("Expected NullPointerException");
447         }
448         catch( final NullPointerException e ) {
449             // expected path
450
}
451     }
452
453
454     /**
455      * Test {@link WebClient#setPageCreator(PageCreator)}.
456      * @throws Exception If something goes wrong.
457      */

458     public void testSetPageCreator() throws Exception {
459         final String page1Content
460             = "<html><head><title>foo</title>"
461             + "</head><body>"
462             + "<a HREF='http://www.foo2.com' id='a2'>link to foo2</a>"
463             + "</body></html>";
464         final WebClient client = new WebClient();
465
466         final MockWebConnection webConnection = new MockWebConnection( client );
467         webConnection.setResponse(
468             URL_FIRST, page1Content, 200, "OK", "text/html", Collections.EMPTY_LIST );
469
470         client.setWebConnection( webConnection );
471         final List collectedPageCreationItems = new ArrayList();
472         client.setPageCreator( new CollectingPageCreator(collectedPageCreationItems) );
473
474         final Page page = client.getPage(URL_FIRST);
475         assertTrue( "instanceof TextPage", page instanceof TextPage );
476
477         final List expectedPageCreationItems = Arrays.asList( new Object[] {
478             page
479         } );
480
481         assertEquals( expectedPageCreationItems, collectedPageCreationItems );
482     }
483
484
485     /** A PageCreator that collects data */
486     private class CollectingPageCreator implements PageCreator {
487         private final List collectedPages_;
488         /**
489          * Create an instance
490          * @param list The list that will contain the data
491          */

492         public CollectingPageCreator( final List list ) {
493             this.collectedPages_ = list;
494         }
495         /**
496          * Create a page
497          * @param webResponse The web response
498          * @param webWindow The web window
499          * @return The new page
500          * @throws IOException If an IO problem occurs
501          */

502         public Page createPage( final WebResponse webResponse, final WebWindow webWindow )
503             throws IOException {
504             final Page page = new TextPage(webResponse, webWindow);
505             webWindow.setEnclosedPage(page);
506             collectedPages_.add(page);
507             return page;
508         }
509     }
510
511     /**
512      * Test loading a page with POST parameters.
513      * @throws Exception If something goes wrong.
514      */

515     public void testLoadPage_PostWithParameters() throws Exception {
516
517         final String htmlContent
518             = "<html><head><title>foo</title></head><body>"
519             + "</body></html>";
520         final WebClient client = new WebClient();
521
522         final MockWebConnection webConnection = new MockWebConnection( client );
523         webConnection.setDefaultResponse( htmlContent );
524         client.setWebConnection( webConnection );
525
526         final String urlString = "http://first?a=b";
527         final URL url = new URL(urlString);
528         final HtmlPage page = (HtmlPage) client.getPage(new WebRequestSettings(url, SubmitMethod.POST));
529
530         assertEquals(urlString, page.getWebResponse().getUrl().toExternalForm());
531     }
532
533     /**
534      * Test that double / in query string are not changed.
535      * @throws Exception If something goes wrong.
536      */

537     public void testLoadPage_SlashesInQueryString() throws Exception {
538         final String htmlContent
539             = "<html><head><title>foo</title></head>"
540             + "<body><a HREF='foo.html?id=UYIUYTY//YTYUY..F'>to page 2</a>"
541             + "</body></html>";
542
543         final WebClient client = new WebClient();
544
545         final MockWebConnection webConnection = new MockWebConnection(client);
546         webConnection.setDefaultResponse(htmlContent);
547         client.setWebConnection(webConnection);
548         
549         final HtmlPage page = (HtmlPage) client.getPage(URL_FIRST);
550         final HtmlAnchor link = (HtmlAnchor) page.getAnchors().get(0);
551         final Page page2 = link.click();
552         assertEquals("http://first/foo.html?id=UYIUYTY//YTYUY..F", page2.getWebResponse().getUrl().toExternalForm());
553     }
554
555     /**
556      * Test that the query string is encoded to be valid.
557      * @throws Exception If something goes wrong.
558      */

559     public void testLoadPage_EncodeQueryString() throws Exception {
560         final String htmlContent
561             = "<html><head><title>foo</title></head><body>"
562             + "</body></html>";
563         
564         final WebClient client = new WebClient();
565
566         final MockWebConnection webConnection = new MockWebConnection(client);
567         webConnection.setDefaultResponse(htmlContent);
568         client.setWebConnection(webConnection);
569
570         // with query string not encoded
571
HtmlPage page = (HtmlPage) client.getPage(new URL("http://first?a=b c&d=" + ((char) 0xE9) + ((char) 0xE8)));
572         assertEquals(
573             "http://first?a=b%20c&d=%C3%A9%C3%A8",
574             page.getWebResponse().getUrl().toExternalForm());
575
576
577         // with query string already encoded
578
page = (HtmlPage) client.getPage(new URL("http://first?a=b%20c&d=%C3%A9%C3%A8"));
579         assertEquals(
580             "http://first?a=b%20c&d=%C3%A9%C3%A8",
581             page.getWebResponse().getUrl().toExternalForm());
582         
583         // with query string partially encoded
584
page = (HtmlPage) client.getPage(new URL("http://first?a=b%20c&d=e f"));
585         assertEquals(
586             "http://first?a=b%20c&d=e%20f",
587             page.getWebResponse().getUrl().toExternalForm());
588         
589         // with anchor
590
page = (HtmlPage) client.getPage(new URL("http://first?a=b c#myAnchor"));
591         assertEquals(
592             "http://first?a=b%20c#myAnchor",
593             page.getWebResponse().getUrl().toExternalForm());
594         
595         // with query string containing encoded "&", "=", "+", ",", and "$"
596
page = (HtmlPage) client.getPage(new URL("http://first?a=%26%3D%20%2C%24"));
597         assertEquals(
598             "http://first?a=%26%3D%20%2C%24",
599             page.getWebResponse().getUrl().toExternalForm());
600     }
601
602     /**
603      * Test loading a file page
604      * @throws Exception If something goes wrong.
605      */

606     public void testLoadFilePage() throws Exception {
607
608         // create a real file to read
609
// it could be usefull to have existing files to test in a special location in filesystem.
610
// It will be really needed when we have to test binary files using the file protocol.
611
final String htmlContent = "<html><head><title>foo</title></head><body></body></html>";
612         final File currentDirectory = new File((new File("")).getAbsolutePath());
613         final File tmpFile = File.createTempFile("test", ".html", currentDirectory);
614         tmpFile.deleteOnExit();
615         final String encoding = (new OutputStreamWriter(new ByteArrayOutputStream())).getEncoding();
616         FileUtils.writeStringToFile(tmpFile, htmlContent, encoding);
617
618         final URL fileURL = new URL("file://" + tmpFile.getCanonicalPath());
619         
620         final WebClient client = new WebClient();
621         final HtmlPage page = (HtmlPage) client.getPage(fileURL);
622
623         assertEquals(htmlContent, page.getWebResponse().getContentAsString());
624         assertEquals("text/html", page.getWebResponse().getContentType());
625         assertEquals(200, page.getWebResponse().getStatusCode());
626         assertEquals("foo", page.getTitleText());
627     }
628
629     /**
630      * Test loading a file page with xml content.
631      * Regression test for bug 1113487.
632      * @throws Exception If something goes wrong.
633      */

634     public void testLoadFilePageXml() throws Exception {
635         final String xmlContent = "<?xml version='1.0' encoding='UTF-8'?>\n"
636             + "<dataset>\n"
637             + "<table name=\"USER\">\n"
638             + "<column>ID</column>\n"
639             + "<row>\n"
640             + "<value>116517</value>\n"
641             + "</row>\n"
642             + "</table>\n"
643             + "</dataset>";
644         final File currentDirectory = new File((new File("")).getAbsolutePath());
645         final File tmpFile = File.createTempFile("test", ".xml", currentDirectory);
646         tmpFile.deleteOnExit();
647         final String encoding = (new OutputStreamWriter(new ByteArrayOutputStream())).getEncoding();
648         FileUtils.writeStringToFile(tmpFile, xmlContent, encoding);
649
650         URL fileURL = new URL("file://" + tmpFile.getCanonicalPath());
651         
652         final WebClient client = new WebClient();
653         final XmlPage page = (XmlPage) client.getPage(fileURL);
654
655         assertEquals(xmlContent, page.getWebResponse().getContentAsString());
656         // "text/xml" or "application/xml", it doesn't matter
657
assertEquals("/xml", StringUtils.substring(page.getWebResponse().getContentType(), -4));
658         assertEquals(200, page.getWebResponse().getStatusCode());
659     }
660
661     /**
662      * Test redirecting with javascript during page load.
663      * @throws Exception If something goes wrong.
664      */

665     public void testRedirectViaJavaScriptDuringInitialPageLoad() throws Exception {
666         final String firstContent = "<html><head><title>First</title><script>"
667             + "location.href='http://second'"
668             + "</script></head><body></body></html>";
669         final String secondContent = "<html><head><title>Second</title></head><body></body></html>";
670
671         final WebClient webClient = new WebClient();
672
673         final MockWebConnection webConnection = new MockWebConnection( webClient );
674         webConnection.setResponse(
675             URL_FIRST, firstContent, 200, "OK", "text/html", Collections.EMPTY_LIST );
676         webConnection.setResponse(
677             URL_SECOND, secondContent, 200, "OK", "text/html", Collections.EMPTY_LIST );
678
679         webClient.setWebConnection( webConnection );
680
681         final URL url = URL_FIRST;
682
683         final HtmlPage page = (HtmlPage)webClient.getPage(url);
684         assertEquals("Second", page.getTitleText());
685     }
686
687
688     /**
689      * Test tabbing where there are no tabbable elements.
690      * @throws Exception If something goes wrong.
691      */

692     public void testKeyboard_NoTabbableElements() throws Exception {
693         final WebClient webClient = new WebClient();
694         final HtmlPage page = getPageForKeyboardTest(webClient, new String[0]);
695         final List collectedAlerts = new ArrayList();
696         webClient.setAlertHandler( new CollectingAlertHandler(collectedAlerts) );
697
698         assertNull( "original", webClient.getElementWithFocus() );
699         assertNull( "next", page.tabToNextElement() );
700         assertNull( "previous", page.tabToPreviousElement() );
701         assertNull( "accesskey", page.pressAccessKey('a') );
702
703         final List expectedAlerts = Collections.EMPTY_LIST;
704         assertEquals(expectedAlerts, collectedAlerts);
705     }
706
707
708     /**
709      * Test tabbing where there is only one tabbable element.
710      * @throws Exception If something goes wrong.
711      */

712     public void testKeyboard_OneTabbableElement() throws Exception {
713         final WebClient webClient = new WebClient();
714         final List collectedAlerts = new ArrayList();
715         webClient.setAlertHandler( new CollectingAlertHandler(collectedAlerts) );
716
717         final HtmlPage page = getPageForKeyboardTest(webClient, new String[]{ null });
718         final HtmlElement element = page.getHtmlElementById("submit0");
719
720         assertNull( "original", webClient.getElementWithFocus() );
721         assertNull( "accesskey", page.pressAccessKey('x') );
722
723         assertEquals( "next", element, page.tabToNextElement() );
724         assertEquals( "nextAgain", element, page.tabToNextElement() );
725
726         webClient.getElementWithFocus().blur();
727         assertNull( "original", webClient.getElementWithFocus() );
728
729         assertEquals( "previous", element, page.tabToPreviousElement() );
730         assertEquals( "previousAgain", element, page.tabToPreviousElement() );
731
732         assertEquals( "accesskey", element, page.pressAccessKey('z') );
733
734         final List expectedAlerts = Arrays.asList( new String[]{"focus-0", "blur-0", "focus-0"} );
735         assertEquals(expectedAlerts, collectedAlerts);
736     }
737
738
739     /**
740      * Test pressing an accesskey.
741      * @throws Exception If something goes wrong.
742      */

743     public void testAccessKeys() throws Exception {
744         final WebClient webClient = new WebClient();
745         final List collectedAlerts = new ArrayList();
746         webClient.setAlertHandler( new CollectingAlertHandler(collectedAlerts) );
747
748         final HtmlPage page = getPageForKeyboardTest(webClient, new String[]{ "1", "2", "3" });
749
750         assertEquals( "submit0", page.pressAccessKey('a').getAttributeValue("name") );
751         assertEquals( "submit2", page.pressAccessKey('c').getAttributeValue("name") );
752         assertEquals( "submit1", page.pressAccessKey('b').getAttributeValue("name") );
753
754         final List expectedAlerts = Arrays.asList( new String[]{
755             "focus-0", "blur-0", "focus-2", "blur-2", "focus-1"
756         } );
757         assertEquals( expectedAlerts, collectedAlerts );
758     }
759
760
761     /**
762      * Test tabbing to the next element.
763      * @throws Exception If something goes wrong.
764      */

765     public void testTabNext() throws Exception {
766         final WebClient webClient = new WebClient();
767         final List collectedAlerts = new ArrayList();
768         webClient.setAlertHandler( new CollectingAlertHandler(collectedAlerts) );
769
770         final HtmlPage page = getPageForKeyboardTest(webClient, new String[]{ "1", "2", "3" });
771
772         assertEquals( "submit0", page.tabToNextElement().getAttributeValue("name") );
773         assertEquals( "submit1", page.tabToNextElement().getAttributeValue("name") );
774         assertEquals( "submit2", page.tabToNextElement().getAttributeValue("name") );
775
776         final List expectedAlerts = Arrays.asList( new String[]{
777             "focus-0", "blur-0", "focus-1", "blur-1", "focus-2"
778         } );
779         assertEquals( expectedAlerts, collectedAlerts );
780     }
781
782
783     /**
784      * Test tabbing to the previous element.
785      * @throws Exception If something goes wrong.
786      */

787     public void testTabPrevious() throws Exception {
788         final WebClient webClient = new WebClient();
789         final List collectedAlerts = new ArrayList();
790         webClient.setAlertHandler( new CollectingAlertHandler(collectedAlerts) );
791
792         final HtmlPage page = getPageForKeyboardTest(webClient, new String[]{ "1", "2", "3" });
793
794         assertEquals( "submit2", page.tabToPreviousElement().getAttributeValue("name") );
795         assertEquals( "submit1", page.tabToPreviousElement().getAttributeValue("name") );
796         assertEquals( "submit0", page.tabToPreviousElement().getAttributeValue("name") );
797
798         final List expectedAlerts = Arrays.asList( new String[]{
799             "focus-2", "blur-2", "focus-1", "blur-1", "focus-0"
800         } );
801         assertEquals( expectedAlerts, collectedAlerts );
802     }
803
804
805     /**
806      * Test that a button can be selected via accesskey.
807      * @throws Exception If something goes wrong.
808      */

809