httpunit-1.7+dfsg/0000755000175000017500000000000011014557542014121 5ustar twernertwernerhttpunit-1.7+dfsg/META-INF/0000755000175000017500000000000011162002061015242 5ustar twernertwernerhttpunit-1.7+dfsg/META-INF/services/0000755000175000017500000000000011014557540017102 5ustar twernertwernerhttpunit-1.7+dfsg/META-INF/services/com.sun.security.sasl.preview.SaslClientFactory0000644000175000017500000000012711014557540030266 0ustar twernertwernercom.sun.security.sasl.digest.ClientFactory com.sun.security.sasl.gsskerb.ClientFactory httpunit-1.7+dfsg/META-INF/services/java.awt.im.spi.InputMethodDescriptor0000644000175000017500000000007711014557540026240 0ustar twernertwernercom.sun.inputmethods.internal.thaiim.ThaiInputMethodDescriptor httpunit-1.7+dfsg/META-INF/APPLEPRO.DSA0000644000175000017500000000213611014557542017036 0ustar twernertwerner0Z *H K0G1 0 +0  *H D0@0A=00 *H801 0 UUS1 0 UCA10U Cupertino10U Apple Computer1#0!U Java Software Code Signing10UApple Computer0 040907142656Z 070604142656Z01 0 UUS1 0 UCA10U Cupertino10U Apple Computer1#0!U Java Software Code Signing10UApple Computer00,*H80Su)RJ.R!hblHIK^EQq f0d0 `HB0U00U#0eNNXjxZ0UeNNXjxZ0 *H8/0,*<]xA EL䴜Eui!ֳ)33I10001 0 UUS1 0 UCA10U Palo Alto10U Sun Microsystems Inc1#0!U Java Software Code Signing10UJCE Code Signing CA0 +0 *H8/0-rO/T9B/.d2$[hhttpunit-1.7+dfsg/META-INF/JCE_DSA.SF0000644000175000017500000001507011014557540016604 0ustar twernertwernerSignature-Version: 1.0 Created-By: 1.4.2_09 (Sun Microsystems Inc.) SHA1-Digest-Manifest: XPuP228LWAzgwmjU+MN39eqNUc8= Name: com/sun/crypto/provider/DESKeyGenerator.class SHA1-Digest: qweu+eD6VvB46aPEti07/avDgK4= Name: com/sun/crypto/provider/SunJCE_aa.class SHA1-Digest: JGdZEi6WKnCGavzkxRFq4Y4iOMk= Name: com/sun/crypto/provider/DHKeyAgreement.class SHA1-Digest: 5SQJCtPKgMEJYDluwub8MuLO9iM= Name: com/sun/crypto/provider/DESedeKey.class SHA1-Digest: jRP1z/1sj4YwCZ9A5fbiE6b2VWY= Name: com/sun/crypto/provider/SunJCE_q.class SHA1-Digest: qz+iNurq5KGmyULsuj4FCyRIVE8= Name: com/sun/crypto/provider/DESParameters.class SHA1-Digest: z0WrlFXo6wkeZdbcOE9PVfNjfn0= Name: com/sun/crypto/provider/BlowfishCipher.class SHA1-Digest: Me38PL7qndl+IhJqYpLzE+eaMF8= Name: com/sun/crypto/provider/SunJCE_ab.class SHA1-Digest: JZ1LHpYG8ZfWDs5PW3KJoJsdKUg= Name: com/sun/crypto/provider/PBEKey.class SHA1-Digest: CljTzfSQz8YHpVgABJyUwWli44o= Name: com/sun/crypto/provider/DESedeCipher.class SHA1-Digest: JIbP5eYLRWwtaDDTG92HuEg4Gn0= Name: com/sun/crypto/provider/HmacSHA1.class SHA1-Digest: pgXsjFzyFfKzr7fF8xVjW5wdQb4= Name: com/sun/crypto/provider/SunJCE_ah.class SHA1-Digest: la01/g6KBm01YKBPRB9BJsZErTY= Name: com/sun/crypto/provider/SunJCE_ae.class SHA1-Digest: SH6Po24bZS1gjdVm00JPCAe7Oeg= Name: com/sun/crypto/provider/DESedeParameters.class SHA1-Digest: eEwPa+lyaXr0nsdN+srp+/puYNE= Name: com/sun/crypto/provider/HmacMD5.class SHA1-Digest: ZUseQiAoywzEtHz6+10NUk1euLA= Name: com/sun/crypto/provider/SunJCE_ad.class SHA1-Digest: I0qUxQAiXazT3bi9qy25xhC6Ei4= Name: com/sun/crypto/provider/DESCipher.class SHA1-Digest: 1VAPeaFonHZipsFEGbz3bBH5mH4= Name: com/sun/crypto/provider/SunJCE_z.class SHA1-Digest: XsnCvw+aShTWb1hVOJDY+ehcnLA= Name: com/sun/crypto/provider/SunJCE_e.class SHA1-Digest: iEyL2euepOt67IPsFQyPY8NU6Eo= Name: com/sun/crypto/provider/SunJCE_u.class SHA1-Digest: vhc1KIDZ9qJU9gXI9YexV374MKA= Name: com/sun/crypto/provider/DESKeyFactory.class SHA1-Digest: uqWl6LidnOodfh2gSIG91D6xr14= Name: com/sun/crypto/provider/SunJCE_j.class SHA1-Digest: X6YMxmMgWEmh9HudNJ0/rH1CKRs= Name: com/sun/crypto/provider/SunJCE_ai.class SHA1-Digest: z70AwlEaAHOc+gzq/qbmJvmYBJo= Name: com/sun/crypto/provider/SunJCE_x.class SHA1-Digest: Gv9OXnW5W2C75UXu2JQ2euKwAsA= Name: com/sun/crypto/provider/SunJCE_p.class SHA1-Digest: CfXqnl7g+g/bhQoZ7K5Pf4jDIBU= Name: com/sun/crypto/provider/SunJCE_b.class SHA1-Digest: LgeOr9dLbLG+UZevkQx7iAtcuxY= Name: com/sun/crypto/provider/SunJCE_o.class SHA1-Digest: suuElHt5hxN3kNlc/O9jCjabqHY= Name: com/sun/crypto/provider/SunJCE_h.class SHA1-Digest: vyZ4HC5lE5TYxulpNL8M6h9+9JQ= Name: com/sun/crypto/provider/DHParameterGenerator.class SHA1-Digest: /bI1MqLzme1I4TC6WHb01mXHB+8= Name: com/sun/crypto/provider/SunJCE_f.class SHA1-Digest: kuCvl2Vdz9LgKNV2Sbq//8Nr8OE= Name: com/sun/crypto/provider/SunJCE_k.class SHA1-Digest: 93xHhCz022itWcPfK0RM5kMUVwM= Name: com/sun/crypto/provider/SunJCE_ag.class SHA1-Digest: /9XMmYuPj3XNrNI0tLqPFy1O2IQ= Name: com/sun/crypto/provider/JceKeyStore.class SHA1-Digest: kuIRv9mQ8e4bADv7DU33LfzLGOM= Name: com/sun/crypto/provider/DHParameters.class SHA1-Digest: AOxvMCMtpCYaK1PS9RD+BtCnvss= Name: com/sun/crypto/provider/ai.class SHA1-Digest: MiM+0VjiR3vE9rDOD1P/oXEXSQ4= Name: com/sun/crypto/provider/SunJCE_g.class SHA1-Digest: 4jKN5eXRwFMCsy+yhBOwZRyMcJk= Name: com/sun/crypto/provider/SunJCE_v.class SHA1-Digest: 7JHal30e0TYXIumAH+qqrlDl2Nw= Name: com/sun/crypto/provider/AESParameters.class SHA1-Digest: bERzofZeKH7zwQtNCwgYgMW9+c4= Name: com/sun/crypto/provider/HmacMD5KeyGenerator.class SHA1-Digest: t5gFcFOUJRfGzHXwsTRiVUhuQEE= Name: com/sun/crypto/provider/HmacSHA1KeyGenerator.class SHA1-Digest: QLt9cQHwlVAcKrx63dIAj1fv9eY= Name: com/sun/crypto/provider/SunJCE_c.class SHA1-Digest: S/mh39epoQ54/ZAuJRAMiudeZxU= Name: com/sun/crypto/provider/SunJCE_af.class SHA1-Digest: w6PtHSr4nVJkqABrOqD6W+TMwXQ= Name: com/sun/crypto/provider/BlowfishKeyGenerator.class SHA1-Digest: b6h/CN7UxA4YS3bNYRt/e482zZo= Name: com/sun/crypto/provider/SunJCE.class SHA1-Digest: 6hlkqFjArmmotKqUZXO/TuRwrTU= Name: com/sun/crypto/provider/DHKeyFactory.class SHA1-Digest: oIna6HI8PGwBeHIOVETA4quIbbQ= Name: com/sun/crypto/provider/SunJCE_y.class SHA1-Digest: tsfuEN68koeIRdH9OvNjh7VawRg= Name: com/sun/crypto/provider/SunJCE_ac.class SHA1-Digest: bjAUSX82G9iHRtiZXvolqdUMnbE= Name: com/sun/crypto/provider/DESedeKeyFactory.class SHA1-Digest: JJgi5SSHEukrxHdzmvQHPwvJ0Ng= Name: com/sun/crypto/provider/SunJCE_d.class SHA1-Digest: mqJe+5zcY8NKLUsH3cz1a/GAfZo= Name: com/sun/crypto/provider/SealedObjectForKeyProtector.class SHA1-Digest: Xl1PD2VNHCB2dVYJGLqSUyN6PSg= Name: com/sun/crypto/provider/DESedeKeyGenerator.class SHA1-Digest: 6oeBqmMMUTp+E2TVpc7l/uX+KBM= Name: com/sun/crypto/provider/DHPrivateKey.class SHA1-Digest: +nHvVXXjRwTTsSWwGcOcgOav/ZA= Name: com/sun/crypto/provider/SunJCE_s.class SHA1-Digest: T6xCWJZYSNym4NIe1OztydbPlVc= Name: com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.class SHA1-Digest: 6bU3BpjQLNenkTo0vl1N5yK7fow= Name: com/sun/crypto/provider/PBEKeyFactory.class SHA1-Digest: 0xWz2pGZDAkHARZgz8YcvJtHajc= Name: com/sun/crypto/provider/AESKeyGenerator.class SHA1-Digest: X1CHUQtJVEyWCB3/gZXzBbdENcE= Name: com/sun/crypto/provider/DHPublicKey.class SHA1-Digest: jZAXw3+bDtQYw1uRw8Y21GDtGWw= Name: com/sun/crypto/provider/SunJCE_r.class SHA1-Digest: vR+NYOX6Z0EeGyXl6siT9REf2IU= Name: com/sun/crypto/provider/DHKeyPairGenerator.class SHA1-Digest: zzV4MPMtervnLEn6iCWryxzesRk= Name: com/sun/crypto/provider/SunJCE_l.class SHA1-Digest: DWnRXQZrivqloMDSArDz5g1ql7M= Name: com/sun/crypto/provider/SunJCE_t.class SHA1-Digest: M/20HAVOjRKCFRP02jJv+VSgIH8= Name: com/sun/crypto/provider/SunJCE_n.class SHA1-Digest: Q4r4PDl4rKdZLcoLACrpNcWp9YQ= Name: com/sun/crypto/provider/SunJCE_i.class SHA1-Digest: 4WkAKlw2vdP66WqVesamUDsTy9s= Name: com/sun/crypto/provider/DESKey.class SHA1-Digest: T+bpi450l26Im5rspeoLxr7ppQo= Name: com/sun/crypto/provider/SunJCE_w.class SHA1-Digest: 4PF78LLvpXsXo5DhvDctWhoI60A= Name: com/sun/crypto/provider/BlowfishParameters.class SHA1-Digest: JVJAOVJiBhQ223qPszLaYjynj+M= Name: com/sun/crypto/provider/PBEWithMD5AndDESCipher.class SHA1-Digest: WIYkHIdMeo0a/wYA3Vm7LSpCSC4= Name: com/sun/crypto/provider/AESCipher.class SHA1-Digest: vH+XDA4yXtSCMTPhLXX9n5+ICVs= Name: com/sun/crypto/provider/SunJCE_m.class SHA1-Digest: q3Aor/ZjS45Msbmu8mmAnFpE6xk= Name: com/sun/crypto/provider/PBEParameters.class SHA1-Digest: 2WiQxeZUl+J1MA3zZys3ApoUioU= httpunit-1.7+dfsg/META-INF/JCE_RSA.RSA0000644000175000017500000000374611014557540016746 0ustar twernertwerner0 *H 010 *H 0  *H f00[]0 *H801 0 UUS1 0 UCA10U Palo Alto10U Sun Microsystems Inc1#0!U Java Software Code Signing10UJCE Code Signing CA0 021025190510Z 071029190510Z0c10U Sun Microsystems Inc1#0!U Java Software Code Signing10USun Microsystems Inc00  *H 0צʣB \0#-#'lo}JX 5k;ӛxQwLdhzx\FzmgȳH!q$Obj+R=:̛1Av?fdXǒìZn00 `HB0U0UH_c \5V[Wɱ͏0U#0eNNXjxZ0 U0yu-ching.peng@sun.com0 *H800-Y]_{)g7ňm䅩!hblHIK^EQq f0d0 `HB0U00U#0eNNXjxZ0UeNNXjxZ0 *H8/0,*<]xA EL䴜Eui!ֳ)33I1A0=001 0 UUS1 0 UCA10U Palo Alto10U Sun Microsystems Inc1#0!U Java Software Code Signing10UJCE Code Signing CA]0 *H 0  *H \m:<*('݆3}gOkK9sP<MP#m9 q&IÆڊpt9uGW8rͼJ'櫖zR043dEޓS)y99O^3iEhhttpunit-1.7+dfsg/META-INF/JCE_RSA.SF0000644000175000017500000000030611014557540016616 0ustar twernertwernerSignature-Version: 1.0 Created-By: 1.4.2 (Sun Microsystems Inc.) SHA1-Digest-Manifest: QP+rmQC30Eis3vVnMmYG/46u8J8= Name: default_US_export.policy SHA1-Digest: SfiCYqc6oOZcgYltmQ5iw5y5lWo= httpunit-1.7+dfsg/META-INF/MANIFEST.MF0000644000175000017500000000025511014557540016713 0ustar twernertwernerManifest-Version: 1.0 Created-By: 1.4.2 (Sun Microsystems Inc.) Crypto-Strength: unlimited Name: default_US_export.policy SHA1-Digest: cITKKaqB2E2DsMCcfrm2MykjVmk= httpunit-1.7+dfsg/doc/0000755000175000017500000000000011014557542014666 5ustar twernertwernerhttpunit-1.7+dfsg/doc/api/0000755000175000017500000000000011162002061015420 5ustar twernertwernerhttpunit-1.7+dfsg/doc/images/0000755000175000017500000000000011014557542016133 5ustar twernertwernerhttpunit-1.7+dfsg/doc/images/HttpUnit.jpg0000644000175000017500000000633611014557542020424 0ustar twernertwernerJFIFddDucky<&Adobed  Z        < 10!A2#4@`p"B$ !1AQa "2r0@qBRb#3Pcs$`p!1AQ aq0@𑡱Pp ǩ\a蕔HG)y!B2/v 1昩zD`+2nDFEŻͪi`]"TcwWŚz=hU+Z92/v.~MW/Rh6sNe>zUΥo*dZieyROc4 yUP; W(/D-VL݈)!bl}Y G@,?prNL`eBæEϨpr')r#&!Bɓ&QPCPMءѨU&qPCFe6 #'/9 Ve:mv;JTrLc#9inPUdrmy6d**U٣o۬265ZiQrQiu+:n$ȫY;)Ei&m6>8YK3Uw}]32w^RMe'IlxωGͥ? (?M??|FwC|VeiR@˥y] 9c!JgDC)Y\Lḛ-G!X}>g *.ō3`c!gyK)^$@fMWvb^Qˌ/ή2*k/HQo.8mbqnRcP/J<4$e :28LG*xF_LjwzO/ mB&G${ޮؿN_  2#_Q֧9 ֮vv[K{}1rՏUk!]/nN0`?4F,ll;#6HQ.;Bg}ϊ.bxjWۗWrTͩ#,'vu c26&sQȂǼ"e#"1*&2t a*ˌ$_`C7RUBus,)(e8ԜYeYI6ږt?`?!>dBI{pjm=+lys{@l^.<_p0\]m}#"hu&@Jʶ%=7ÁF’X>p0gxcS?F,?BU38bY`~Loݏ?hhOPE^E&5x>c Р(KQpWy2zʸC)o([<`a佺i0)b7_Ķ3އ;cc+ÛnΙ5 = 1Q]/c%1' +tofTis웆ъqe.vHop+.=Px՞0ox3 tD}ˠULg}צ05pʫ6h31kC=}"!,؅։(t)}#Њ "ֺ/kwnpC}m;-kpc48Hi g"$!:(Z~GR&A?!btڣNՁmKW1IphC^h ̡YIG6ih5 u+,n>2/\ GWDEuN*WW_~'?!? 8$+$HlDcc,Ngrvo'>Iε0|L X}ƽ+)+́?ŕjC,1D=v1ߢ3]`KGp4t']7B\g11"z0 8\sl" G>1&EXP4/$XsOR}--϶cHse#TſF7\_ /UrH".Ջ\ݐF 5d 1bpjkⅡTŴAQ k,KvCC3!\+sCPJ^JE2QfdH-( ◱ )DW䋤^Cv|t8b; HttpUnit User Manual <a href="toc.html">HttpUnit User Manual (noframes)</a> httpunit-1.7+dfsg/doc/manual/installing.html0000644000175000017500000001402711014557542021201 0ustar twernertwerner HttpUnit Manual - Installing HttpUnit

Installing HttpUnit

Getting HttpUnit

Releases

The latest release of HttpUnit is available from the HttpUnit project download page.
From time to time, pre-release versions are made available from the web site prerelease directory. Because HttpUnit is build test-first, these should usually be as stable as the releases; however, they are not tracked as closely and formally, and typically are only available for a relatively short time. Either form of distribution includes all source code and jars required to build the project.

Subversion access

If you prefer to see the very latest code, you can always obtain directly it from the Subversion/svn archive at svn co https://httpunit.svn.sourceforge.net/svnroot/httpunit httpunit. Be sure to check out the httpunit module.

You can also access the svn repository online. See Building HttpUnit for instructions on building HttpUnit from the source code.

System Requirements

HttpUnit should run on any system that supports Java JDK 1.4 or higher.

Examining the Distribution

When you unpack the HttpUnit distribution, you should find the following directory layout:

httpunit
   +--- jars // contains jars required to build, test, and run HttpUnit
   |
   +--- lib  // contains the HttpUnit jar
   |
   +--- doc  // contains documentation
   |      |
   |      +--- tutorial  // a brief tutorial in test-first development of a servlet-based web site
   |      |
   |      +--- api       // the javadoc
   |      |
   |      +--- manual    // this user manual
   |
   +--- examples // some example programs written with HttpUnit
   |
   +--- src      // the HttpUnit source code
   |
   +--- test     // unit tests for HttpUnit - a good source for more examples
Only the lib and jars directories are required to run HttpUnit. You must have at least the HttpUnit jar in your classpath. Many of the other jars are optional. See the sext section, Understanding HttpUnit's dependencies for more information.

Understanding HttpUnit's dependencies

HttpUnit supports a number of optional capabilities. If you don't need them, you don't need the corresponding libraries in your classpath. At the minimum you must have an HTML parser (both JTidy and NekoHTML are supported) and a jaxp-compliant parser (xerces 2.2 is included in the distribution).

Jar Name Needed For Documented at
nekohtml.jar HTML parsing. Very tolerant of sloppy HTML. Requires xerces-j 2.2 or higher www.apache.org/~andyc/neko/doc/html/index.html.
tidy.jar HTML parsing. Very picky. Works with any jaxp-compliant parser. lempinen.net/sami/jtidy/
xmlParserAPIs.jar the generic parser APIs supported by xerces-j xml.apache.org
xercesImpl.jar the xerces-j 2.2 implementation xml.apache.org
js.jar javascript support www.mozilla.org/rhino
servlet.jar required for ServletUnit - unit testing of servlets java.sun.com
junit.jar running the unit tests. www.junit.org
mail.jar Testing the file upload capabilities - not used to run HttpUnit itself java.sun.com/products/javamail/
activation.jar Testing the file upload capabilities - not used to run HttpUnit itself java.sun.com/products/javabeans/glasgow/jaf.html

Building HttpUnit

By far the easiest way to build HttpUnit is by using ant. If you choose to build with less than the full set of jars, some classes will not compile. The included ant script handles this automatically for you, selecting only those that are appropriate. If you have ant installed, simply go to the main httpunit installation directory and type:

ant jar
to build the httpunit jar using any classes available in the jars directory. You can then verify your installation by running one of the examples. The command
ant run-example
will compile the examples and run the simplest of them, going to the Meterware web site and following a link to the main HttpUnit site. If all is working properly, it should print out a message telling you the number of links it found there.

Copyright © 2000-2007 Russell Gold. All rights Reserved.

httpunit-1.7+dfsg/doc/manual/introduction.html0000644000175000017500000000561511014557540021557 0ustar twernertwerner HttpUnit Manual - Introduction

Introduction

Automated unit testing is a great way to ensure that code being maintained works and continues to work. The Extreme Programming (XP) methodology relies heavily on it, and practitioners have available to them a range of unit testing frameworks, which work by making direct calls to the code being tested. But what if you want to test a web application? HttpUnit is a library which makes this possible.

HttpUnit works by emulating a browser, handling frames, cookies, redirects, and so on. It lets you view pages as plain text, an XML DOM, or as an aggregation of collection of links, frames, images, and so on. It lets you select an element which should lead to a new page and follow it, so that you can easily handle a chain of web pages.

Test Design and Abstraction

Unlike most commercial tools, HttpUnit does not rely on record and playback. Its API lets you define what you want to see or change, even before the web site is built. This is essential for test-first development. Since the primary use of HttpUnit is to write functional tests, it helps you abstract those elements which are most likely to change. For example, a page might start by providing a small number of options, using a set of radio buttons:

Select the desired color: Red Green Blue

As the site evolves, the number of options might grow until the UI designer feels that a pull-down menu would be easier to use to send the same values:

Select the desired color:

Further expansion could lead to a free-form textual input:

Enter the desired color:

A tool which focuses on the type of control actually on the page would force the testers to rewrite their tests with each change, even though the functionality of the site is unchanged. HttpUnit focuses on the intent of the entry, and allows tests to be defined in terms of the values to be transmitted. It is aware of the controls being used and ensures that only values which a user could supply will be sent; however, the tester need only focus on the desired value for each test.


Copyright © 2000-2002 Russell Gold. All rights Reserved.

httpunit-1.7+dfsg/doc/manual/manual.css0000644000175000017500000000141411014557542020132 0ustar twernertwernerFORM.sample { margin-left: 2%; margin-right: 2%; padding-top: .5em; padding-bottom: .5em; padding-right: .5em; padding-left: .5em; background-color: #cccccc; border-color: #0000cc; border-width: 2; border-style: solid } H2 { padding-left: .5em; padding-top: .5em; padding-bottom: .5 em; margin-bottom: 1em; background-color: #e3e3e3; border-color: #000000; border-width: 2; border-style: solid } SPAN.code { font-family: courier, monospaced, sans-serif } PRE { font-family: "courier new", courier; font-size: 8pt; margin-left: 2%; margin-right: 2%; padding-top: .5em; padding-bottom: .5em; padding-right: .5em; padding-left: .5em; border-color: black; border-width: 2; border-style: solid } PRE.code-examples { background-color: #cccccc } httpunit-1.7+dfsg/doc/manual/notes.txt0000644000175000017500000000062211014557540020032 0ustar twernertwernerget page for URL (see text) parsing XML find links in page following links find tables in a page reading data from a table reading form data submitting a form working with text parameters working with discrete parameters verifying cookies examining headers setting headers uploading files downloading files working with framesets opening new windows handling JavaScript problems interactive JavaScript httpunit-1.7+dfsg/doc/manual/retrieving.html0000644000175000017500000000200711014557540021204 0ustar twernertwerner HttpUnit Manual - Retrieving Web Pages

Retrieving Web Pages

Explicit Specification of a Page URL

The very first step in any interaction with a web site is to obtain a start page. To do this, we create a WebConversation object to play the role of the web browser. This object will store browser state such a cookies, windows, and so on. We then ask for the page by specifying the desired URL:

WebConversation wc = new WebConversation();
WebResponse wr = wc.getResponse( "http://www.meterware.com" );
System.out.println( wr.getText() );
This example will simply print out the text of the retrieved page. Obviously, given this text, it is easy to search for particular strings on the page, if that is desired. httpunit-1.7+dfsg/doc/manual/toc.html0000644000175000017500000000154111014557540017615 0ustar twernertwerner HttpUnit User Manual

Table of Contents

1. Getting Started

Introduction
Installing HttpUnit
Retrieving Web Pages
httpunit-1.7+dfsg/doc/tutorial/0000755000175000017500000000000011162002061016512 5ustar twernertwernerhttpunit-1.7+dfsg/doc/tutorial/src/0000755000175000017500000000000011014557540017316 5ustar twernertwernerhttpunit-1.7+dfsg/doc/tutorial/src/tutorial/0000755000175000017500000000000011014557542021163 5ustar twernertwernerhttpunit-1.7+dfsg/doc/tutorial/src/tutorial/persistence/0000755000175000017500000000000011014557542023507 5ustar twernertwernerhttpunit-1.7+dfsg/doc/tutorial/src/tutorial/persistence/BettingPool.java0000644000175000017500000000226711014557540026605 0ustar twernertwernerpackage tutorial.persistence; public class BettingPool { public static void reset() { for (int i = 0; i < _games.length; i++) _games[i] = new BettingPoolGame(); _tieBreakerIndex = 0; _state = INITIAL_STATE; } public static BettingPoolGame[] getGames() { return _games; } public static int getTieBreakerIndex() { return _tieBreakerIndex; } public static void setTieBreakerIndex( int tieBreakerIndex ) { if (!isEditable()) throw new IllegalStateException( "May only modify the pool in INITIAL state" ); _tieBreakerIndex = tieBreakerIndex; } public static boolean isEditable() { return _state == INITIAL_STATE; } public static void openPool() { if (!isEditable()) throw new IllegalStateException( "May only modify the pool in INITIAL state" ); _state = POOL_OPEN; } private final static int NUM_GAMES = 10; private final static int INITIAL_STATE = 0; private final static int POOL_OPEN = 1; private static int _state; private static int _tieBreakerIndex; private static BettingPoolGame[] _games = new BettingPoolGame[ NUM_GAMES ]; } httpunit-1.7+dfsg/doc/tutorial/src/tutorial/persistence/BettingPoolGame.java0000644000175000017500000000131611014557542027373 0ustar twernertwernerpackage tutorial.persistence; public class BettingPoolGame { BettingPoolGame() { _homeTeam = _awayTeam = ""; } public String getHomeTeam() { return _homeTeam; } public void setHomeTeam( String homeTeam ) { if (!BettingPool.isEditable()) throw new IllegalStateException( "The pool is not editable" ); _homeTeam = homeTeam; } public String getAwayTeam() { return _awayTeam; } public void setAwayTeam( String awayTeam ) { if (!BettingPool.isEditable()) throw new IllegalStateException( "The pool is not editable" ); _awayTeam = awayTeam; } private String _homeTeam = ""; private String _awayTeam = ""; } httpunit-1.7+dfsg/doc/tutorial/src/tutorial/PoolEditorServlet.java0000644000175000017500000001100611014557542025451 0ustar twernertwernerpackage tutorial; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import javax.servlet.http.*; import javax.servlet.ServletException; import tutorial.persistence.BettingPool; import tutorial.persistence.BettingPoolGame; public class PoolEditorServlet extends HttpServlet { protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { updateBettingPool( request ); response.setContentType( "text/html" ); PrintWriter pw = response.getWriter(); pw.println( "" ); if (request.getParameter( "save" ).equals( "Open Pool" )) { String[] errors = getValidationErrors(); if (errors.length != 0) reportErrors( pw, errors ); else { BettingPool.openPool(); } } printBody( pw ); pw.println( "" ); } private void reportErrors( PrintWriter pw, String[] errors ) { pw.println( "" ); pw.println( "" ); for (int i=0; i < errors.length; i++) { pw.println( "" ); } pw.println( "
Cannot open pool for betting:
 " + errors[i] + "
" ); } String[] getValidationErrors() { ArrayList errorList = new ArrayList(); BettingPoolGame game = BettingPool.getGames()[ BettingPool.getTieBreakerIndex() ]; if (game.getAwayTeam().length() == 0 || game.getHomeTeam().length() == 0) { errorList.add( "Tiebreaker is not a valid game" ); } BettingPoolGame[] games = BettingPool.getGames(); for (int i = 0; i < games.length; i++) { if (games[i].getAwayTeam().length() == 0 && games[i].getHomeTeam().length() != 0) { errorList.add( "Game " + i + " has no away team" ); } else if (games[i].getAwayTeam().length() != 0 && games[i].getHomeTeam().length() == 0) { errorList.add( "Game " + i + " has no home team" ); } } String[] errors = (String[]) errorList.toArray( new String[ errorList.size() ] ); return errors; } void updateBettingPool( HttpServletRequest request ) { BettingPoolGame[] games = BettingPool.getGames(); for (int i = 0; i < games.length; i++) { games[i].setAwayTeam( request.getParameter( "away" + i ) ); games[i].setHomeTeam( request.getParameter( "home" + i ) ); } BettingPool.setTieBreakerIndex( getTieBreakerIndex( request ) ); } private int getTieBreakerIndex( HttpServletRequest request ) { try { return Integer.parseInt( request.getParameter( "tiebreaker" ) ); } catch (NumberFormatException e) { return 0; } } protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.setContentType( "text/html" ); PrintWriter pw = response.getWriter(); pw.println( "" ); printBody( pw ); pw.println( "" ); } private void printBody( PrintWriter pw ) { pw.println( "
" ); pw.println( "" ); pw.println( "" ); BettingPoolGame[] games = BettingPool.getGames(); for (int i = 0; i < games.length; i++) { pw.println( "" ); pw.println( "" ); pw.print( "" ); } pw.println( "
Home TeamAway TeamTiebreaker?
" ); if (BettingPool.isEditable()) { pw.println( "" ); pw.println( "" ); } pw.println( "
" ); } private String getReadOnlyFlag() { return BettingPool.isEditable() ? "" : " readonly"; } } httpunit-1.7+dfsg/doc/tutorial/src/tutorial/PoolEditorTest.java0000644000175000017500000002251511014557540024751 0ustar twernertwernerpackage tutorial; import com.meterware.httpunit.*; import com.meterware.servletunit.*; import java.util.Arrays; import junit.framework.*; import tutorial.persistence.BettingPool; public class PoolEditorTest extends TestCase { public static void main( String args[] ) { junit.textui.TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( PoolEditorTest.class ); } public PoolEditorTest( String s ) { super( s ); } public void setUp() throws Exception { BettingPool.reset(); } public void testGetForm() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); try { client.getResponse( "http://localhost/PoolEditor" ); fail( "PoolEditor is not protected" ); } catch (AuthorizationRequiredException e) { } client.setAuthorization( "aUser", "pool-admin" ); client.getResponse( "http://localhost/PoolEditor" ); } public void testFormAction() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); assertNotNull( "No form found with ID 'pool'", form ); assertEquals( "Form method", "POST", form.getMethod() ); assertEquals( "Form action", "", form.getAction() ); } public void testFormContents() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); assertNotNull( "No form found with ID 'pool'", form ); for (int i = 0; i < 10; i++) { assertTrue( "Missing home team " + i, form.isTextParameter( "home" + i ) ); assertTrue( "Missing away team " + i, form.isTextParameter( "away" + i ) ); } assertEquals( "Tie breaker values", Arrays.asList( new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } ), Arrays.asList( form.getOptionValues( "tiebreaker" ) ) ); } public void testSubmitButtons() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); assertNotNull( "No form found with ID 'pool'", form ); assertEquals( "Number of submit buttons", 2, form.getSubmitButtons().length ); assertNotNull( "Save button not found", form.getSubmitButton( "save", "Save" ) ); assertNotNull( "Open Pool button not found", form.getSubmitButton( "save", "Open Pool" ) ); } public void testPoolDisplay() throws Exception { BettingPool.getGames()[0].setAwayTeam( "New York Jets" ); BettingPool.getGames()[0].setHomeTeam( "Philadelphia Eagles" ); BettingPool.getGames()[2].setAwayTeam( "St. Louis Rams" ); BettingPool.getGames()[2].setHomeTeam( "Chicago Bears" ); BettingPool.setTieBreakerIndex(2); ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); assertNotNull( "No form found with ID 'pool'", form ); assertEquals( "Away team 0", "New York Jets", form.getParameterValue( "away0" ) ); assertEquals( "Home team 0", "Philadelphia Eagles", form.getParameterValue( "home0" ) ); assertEquals( "Away team 1", "", form.getParameterValue( "away1" ) ); assertEquals( "Home team 1", "", form.getParameterValue( "home1" ) ); assertEquals( "Away team 2", "St. Louis Rams", form.getParameterValue( "away2" ) ); assertEquals( "Home team 2", "Chicago Bears", form.getParameterValue( "home2" ) ); assertEquals( "Tie breaker game", "2", form.getParameterValue( "tiebreaker" ) ); } public void testPoolEntry() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); assertNotNull( "No form found with ID 'pool'", form ); WebRequest request = form.getRequest( "save", "Save" ); request.setParameter( "away1", "Detroit Lions" ); request.setParameter( "home1", "Denver Broncos" ); request.setParameter( "tiebreaker", "1" ); response = client.getResponse( request ); form = response.getFormWithID( "pool" ); assertEquals( "Away team 0", "", form.getParameterValue( "away0" ) ); assertEquals( "Home team 0", "", form.getParameterValue( "home0" ) ); assertEquals( "Away team 1", "Detroit Lions", form.getParameterValue( "away1" ) ); assertEquals( "Home team 1", "Denver Broncos", form.getParameterValue( "home1" ) ); assertEquals( "Tie breaker game", "1", form.getParameterValue( "tiebreaker" ) ); } public void testPoolValidation() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); WebRequest request = form.getRequest( "save", "Open Pool" ); request.setParameter( "away1", "Detroit Lions" ); request.setParameter( "home1", "Denver Broncos" ); request.setParameter( "home2", "Baltimore Ravens" ); request.setParameter( "tiebreaker", "3" ); InvocationContext context = client.newInvocation( request ); PoolEditorServlet servlet = (PoolEditorServlet) context.getServlet(); servlet.updateBettingPool( context.getRequest() ); String[] errors = servlet.getValidationErrors(); assertEquals( "Number of errors reported", 2, errors.length ); assertEquals( "First error", "Tiebreaker is not a valid game", errors[0] ); assertEquals( "Second error", "Game 2 has no away team", errors[1] ); } public void testPoolOpenErrorDetection() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); WebRequest request = form.getRequest( "save", "Open Pool" ); request.setParameter( "away1", "Detroit Lions" ); request.setParameter( "home1", "Denver Broncos" ); request.setParameter( "home2", "Baltimore Ravens" ); request.setParameter( "tiebreaker", "3" ); response = client.getResponse( request ); WebTable errorTable = response.getTableStartingWith( "Cannot open pool for betting:" ); assertNotNull( "No errors reported", errorTable ); String[][] cells = errorTable.asText(); assertEquals( "Number of error messages provided", 2, cells.length - 1 ); assertEquals( "Error message", "Tiebreaker is not a valid game", cells[1][0] ); assertEquals( "Error message", "Game 2 has no away team", cells[2][0] ); } public void testGoodPoolOpen() throws Exception { ServletRunner sr = new ServletRunner( "web.xml" ); ServletUnitClient client = sr.newClient(); client.setAuthorization( "aUser", "pool-admin" ); WebResponse response = client.getResponse( "http://localhost/PoolEditor" ); WebForm form = response.getFormWithID( "pool" ); WebRequest request = form.getRequest( "save", "Open Pool" ); request.setParameter( "away1", "Detroit Lions" ); request.setParameter( "home1", "Denver Broncos" ); request.setParameter( "away3", "Indianapolis Colts" ); request.setParameter( "home3", "Baltimore Ravens" ); request.setParameter( "tiebreaker", "3" ); client.getResponse( request ); // (1) ignore the response response = client.getResponse( "http://localhost/PoolEditor" ); // (2) retrieve the page separately form = response.getFormWithID( "pool" ); assertNull( "Could still update the pool", form.getSubmitButton( "save" ) ); // (3) look for the buttons try { request = form.getRequest(); request.setParameter( "home3", "Philadelphia Eagles" ); // (4) try to change an entry fail( "Could still edit the pool" ); } catch (IllegalRequestParameterException e) {} } } httpunit-1.7+dfsg/doc/tutorial/arrow_yellow.gif0000644000175000017500000000016211014557542021744 0ustar twernertwernerGIF89a fa\VQ<~~2WW#LL00!, !0) X$2- iJ(I11< httpunit-1.7+dfsg/doc/tutorial/pool_editor_static.html0000644000175000017500000000373611014557540023314 0ustar twernertwerner UniSports Betting Pool - Definition
Cannot open pool for betting:
 No tiebreaker was specified
Enter teams for up to 10 games, selecting one as a tie-breaker.
Home TeamAway TeamTiebreaker?
httpunit-1.7+dfsg/doc/tutorial/task1.html0000644000175000017500000000314311014557540020441 0ustar twernertwerner HttpUnit Tutorial - create pool editor

Tutorial ->Task 1

Creating the Pool Editor

Our initial task will be the creation of the simple pool editor, following use case 1.1. To restrict access to the administrator, we will take advantage of declarative security defined by the Servlet standard. As part of this task, we will use the Basic Authentication approach, which causes the browser to pop up a challenge dialog. The more common form-based authentication is handled the same way that all forms should be.

To begin the tutorial, create a working directory and expand this archive into it. To run the tutorial, you will need httpunit.jar, junit.jar, servlet.jar, nekohtml.jar, xercesImpl.jar, and xmlParserAPIs.jar (all included in the HttpUnit download) on your classpath. If you use ant, you can either copy them into the jars directory just created, or invoke ant with -Dclasspath="...", specifying the locations of those jars between the quotation marks. If you do not use ant, note that the main class is named tutorial.PoolEditorTest

You will write your code in the src/tutorial sub-directory.

Once you are ready, proceed to step one to begin the tutorial.

httpunit-1.7+dfsg/doc/tutorial/task1editor-entry.html0000644000175000017500000001734211014557542023017 0ustar twernertwerner HttpUnit Tutorial - create pool editor - step 3

Tutorial -> Task 1 -> Step 3: Submitting edits

Submitting a Form

In this step, you will learn how to:
• Check form default parameter values
• Create a request from a form
• Override the default parameter values in a request
• Submit a form and get a response

We now have a form which can generate POST requests to define the betting pool. Our next step will be to build the code which handles these requests. We will start by simply recording changes, and defer validation until the administrator attempts to open the pool. For our demonstration application, we will use in-memory persistence only, and will provide ourselves with a way to clear it so that each JUnit test can run independantly.

Testing pool display

The first thing we want to test and implement is the display of the current state of the pool. We will do this by setting the state directly, using the supplied entity classes and then invoke the form to display the pool. At this time, we will also add the set up code to clear the pool before each test:

public void setUp() throws Exception {
    BettingPool.reset();
}

public void testPoolDisplay() throws Exception {
    BettingPool.getGames()[0].setAwayTeam( "New York Jets" );                                // (1) set up data
    BettingPool.getGames()[0].setHomeTeam( "Philadelphia Eagles" );
    BettingPool.getGames()[2].setAwayTeam( "St. Louis Rams" );
    BettingPool.getGames()[2].setHomeTeam( "Chicago Bears" );
    BettingPool.setTieBreakerIndex(2);

    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

    WebForm form = response.getFormWithID( "pool" );
    assertNotNull( "No form found with ID 'pool'", form );

    assertEquals( "Away team 0", "New York Jets", form.getParameterValue( "away0" ) );       // (2) check team names
    assertEquals( "Home team 0", "Philadelphia Eagles", form.getParameterValue( "home0" ) );
    assertEquals( "Away team 1", "", form.getParameterValue( "away1" ) );
    assertEquals( "Home team 1", "", form.getParameterValue( "home1" ) );
    assertEquals( "Away team 2", "St. Louis Rams", form.getParameterValue( "away2" ) );
    assertEquals( "Home team 2", "Chicago Bears", form.getParameterValue( "home2" ) );

    assertEquals( "Tie breaker game", "2", form.getParameterValue( "tiebreaker" ) );         // (3) check radio button
}

Here we are:

  1. Setting up the data that the servlet which read to create the entry form. Here we are using a simple in-memory persistence strategy. If the servlet accessed the database, we would have to do JDBC calls here.
  2. Reading the names of the teams and comparing them to what we initialized. Note the test for the skipped game to verify that the defaults come through.
  3. Checking the state of the radio button. Note that we can use the same method WebForm.getParameterValue for each parameter, no matter its type.

As before, the above test should initially fail. We then make it work by changing the loop in printBody as follows:

    BettingPoolGame[] games = BettingPool.getGames();
    for (int i = 0; i < games.length; i++) {
        pw.println( "<tr><td><input name='home" + i + "' value='" + games[i].getHomeTeam() + "' ></td>" );
        pw.println( "<td><input name='away" + i + "' value='" + games[i].getAwayTeam() + "'></td>" );
        pw.print( "<td><input type='radio' name='tiebreaker' value='" + i + "'" );
        if (i == BettingPool.getTieBreakerIndex()) pw.print( " checked" );
        pw.println( " /></td></tr>" );
    }

Testing pool entry

Now that we know we can display the current state of the pool, we will verify that we can use the form to change it as well:

public void testPoolEntry() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

    WebForm form = response.getFormWithID( "pool" );
    assertNotNull( "No form found with ID 'pool'", form );

    form.setParameter( "away1", "Detroit Lions" );                           // (1) enter values into the form
    form.setParameter( "home1", "Denver Broncos" );
    form.setParameter( "tiebreaker", "1" );

    SubmitButton saveButton = form.getSubmitButton( "save", "Save" );        // (2) select the desired submit button
    response = form.submit( saveButton );                                    // (3) submit the form

    assertEquals( "Away team 0", "", form.getParameterValue( "away0" ) );    // (4) verify the response
    assertEquals( "Home team 0", "", form.getParameterValue( "home0" ) );
    assertEquals( "Away team 1", "Detroit Lions", form.getParameterValue( "away1" ) );
    assertEquals( "Home team 1", "Denver Broncos", form.getParameterValue( "home1" ) );

    assertEquals( "Tie breaker game", "1", form.getParameterValue( "tiebreaker" ) );
}

This is our first form submission. Take note:

  1. We make a call for each parameter that we want to set. Any parameters we do not set will be submitted with their default values.
  2. Since there is more than one button in the form, we ask for the one we want by name and value.
  3. We submit the form, specifying the desired button.
  4. We can use the same methods as above to check the new state of the pool. Alternately, we could have examined the BettingPool object directly.

This test will fail with a 405 response, since we have not defined a handler for the POST message. We do so now:

protected void doPost( HttpServletRequest request, HttpServletResponse response )
        throws ServletException, IOException {
    updateBettingPool( request );
    response.setContentType( "text/html" );
    PrintWriter pw = response.getWriter();

    pw.println( "<html><head></head><body>" );
    printBody( pw );
    pw.println( "</body></html>" );
}

void updateBettingPool( HttpServletRequest request ) {
    BettingPoolGame[] games = BettingPool.getGames();
    for (int i = 0; i < games.length; i++) {
        games[i].setAwayTeam( request.getParameter( "away" + i ) );
        games[i].setHomeTeam( request.getParameter( "home" + i ) );
    }
    BettingPool.setTieBreakerIndex( getTieBreakerIndex( request ) );
}

private int getTieBreakerIndex( HttpServletRequest request ) {
    try {
        return Integer.parseInt( request.getParameter( "tiebreaker" ) );
    } catch (NumberFormatException e) {
        return 0;
    }
}

Note that we are using the same printBody method as the doGet method does.

We now have the ability to edit the pool entries. Our next step is to add the validation and handle opening the pool to bettors. httpunit-1.7+dfsg/doc/tutorial/task1editor-form.html0000644000175000017500000001541711014557540022620 0ustar twernertwerner HttpUnit Tutorial - create pool editor - step 2

Tutorial -> Task 1 -> Step 2: The pool editor form

Examining a Form

In this step, you will learn how to:
• Extract a form from a web page, using its ID
• Examine form attributes
• Check text and radio button input fields
• Check form submit buttons

Now that we can invoke our servlet, the next step will be to produce the form in response to a GET command. This form will POST back to the same URL, allow for entry of 10 pairs of team names, allow for selection of a tie-breaker game, and allow the user to either save his entries or save them and open the betting pool. We can write a test for each of these required behaviors.

Testing the Form action

Let us add the following test:

public void testFormAction() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

    WebForm form = response.getFormWithID( "pool" );               // (1) obtain the desired form
    assertNotNull( "No form found with ID 'pool'", form );
    assertEquals( "Form method", "POST", form.getMethod() );       // (2) verify that the form uses POST
    assertEquals( "Form action", "", form.getAction() );           // (3) verify that the default action is used
}

The significant points in the code are:

  1. Extracting the form from the page. In this case, we use the ID (which should be unique) attribute to find the form. We could also just ask for all the forms in the page and select the first one, but this skips the need to count the number of forms in the page. If the form is not present, we will just get a null value.
  2. Checking that the form uses the POST method.
  3. Checking that the form has no action attribute specified and will therefore default to the URL from which it was retrieved - in the case, the same servlet that produced it.

Again we run the test and fix the reported errors, one by one. The printBody method will now look like this:

private void printBody( PrintWriter pw ) {
    pw.println( "<form id='pool' method='POST'>" );
    pw.println( "</form>" );
}

and we now have two working tests.

Testing the form contents

We can now test the input fields in the form:

public void testFormContents() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

    WebForm form = response.getFormWithID( "pool" );
    assertNotNull( "No form found with ID 'pool'", form );

    for (int i = 0; i < 10; i++) {
        assertTrue( "Missing home team " + i, form.isTextParameter( "home" + i ) ); // (1) text parameter
        assertTrue( "Missing away team " + i, form.isTextParameter( "away" + i ) ); // (1) text parameter
    }
    assertEquals( "Tie breaker values",
                  Arrays.asList( new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } ),
                  Arrays.asList( form.getOptionValues( "tiebreaker" ) ) );          // (2) radio button
}

The significant points in the code are:

  1. We verify that a text parameter has been defined with the desired name for each of the 20 possible team values.
  2. Here we verify that we have a set of radio buttons with a specific name and each of the desired values.

We satisfy this test by making the printBody method look like this:

private void printBody( PrintWriter pw ) {
    pw.println( "<form id='pool' method='POST'>" );
    pw.println( "<table>" );
    pw.println( "<tr><th>Home Team</th><th>Away Team</th><th>Tiebreaker?</th></tr>" );
    for (int i = 0; i < 10; i++) {
        pw.println( "<tr><td><input name='home" + i + "'></td>" );
        pw.println( "<td><input name='away" + i + "'></td>" );
        pw.println( "<td><input type='radio' name='tiebreaker' value='" + i + "'/></td></tr>" );
    }
    pw.println( "</table>" );
    pw.println( "</form>" );
}

Testing the Submit Buttons

We confirm the presence of the desired submit buttons as follows:

public void testSubmitButtons() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

    WebForm form = response.getFormWithID( "pool" );
    assertNotNull( "No form found with ID 'pool'", form );

    assertEquals( "Number of submit buttons", 2, form.getSubmitButtons().length );    // (1) count the buttons
    assertNotNull( "Save button not found", form.getSubmitButton( "save", "Save" ) ); // (2) look up by name
    assertNotNull( "Open Pool button not found", form.getSubmitButton( "save", "Open Pool" ) );
}

In this test, please note the following:

  1. We ask for all the submit buttons associated with the form and just count them. This will ensure that we don't have more than we want, either.
  2. We ask for each button that we do want by specifying its name and value - which will be used when we submit the form.

This test will pass once we modify the end of printBody, inserting lines to generate the submit buttons:

    }
    pw.println( "</table>" );
    pw.println( "<input type='submit' name='save' value='Save' />" );
    pw.println( "<input type='submit' name='save' value='Open Pool' />" );
    pw.println( "</form>" );
}
We now have our form being generated, along with tests to confirm it. In the next step, we will test and code the response to a form submission. httpunit-1.7+dfsg/doc/tutorial/task1editor-initial.html0000644000175000017500000001134511014557540023302 0ustar twernertwerner HttpUnit Tutorial - create pool editor - step 1

Tutorial -> Task 1 -> Step 1: Invoking the pool editor

Invoking the Pool Editor

In this step, you will learn how to:
• Initialize ServletUnit
• Invoke a servlet
• Specify a username and password for basic authentication

The first step will simply be to verify that we can register and access the servlet, which we will name PoolEditorServlet. A GET method to this page should return the editor form itself, while updates will be handled by a POST method to the same address. Since we are working with servlets, we can bypass the web server and use the servletunit package to run our tests.

Here is the initial test code:

package tutorial;

import com.meterware.httpunit.*;
import com.meterware.servletunit.*;
import java.util.*;
import junit.framework.*;
import tutorial.persistence.*;

public class PoolEditorTest extends TestCase {

    public static void main( String args[] ) {
        junit.textui.TestRunner.run( suite() );
    }

    public static TestSuite suite() {
        return new TestSuite( PoolEditorTest.class );
    }

    public PoolEditorTest( String s ) {
        super( s );
    }

    public void testGetForm() throws Exception {
        ServletRunner sr = new ServletRunner( "web.xml" );       // (1) use the web.xml file to define mappings
        ServletUnitClient client = sr.newClient();               // (2) create a client to invoke the application

        try {
            client.getResponse( "http://localhost/PoolEditor" ); // (3) invoke the servlet w/o authorization
            fail( "PoolEditor is not protected" );
        } catch (AuthorizationRequiredException e) {             // (4) verify that access is denied
        }

        client.setAuthorization( "aUser", "pool-admin" );        // (5) specify authorization and
        client.getResponse( "http://localhost/PoolEditor" );     //     invoke the servlet again
    }

}

This code uses JUnit and ServletUnit to verify that a servlet is present at the specified address. The significant points in the code are:

  1. Creating the ServletRunner class which represents access to a Servlet application. The application is defined by an XML file which maps URL information to servlet classes.
  2. Creating a client which can access the application and maintain state across multiple invocations.
  3. Invoking the servlet via its URL. Note that ServletUnit ignores any host and port information. All URL patterns are treated as being relative to the root ("/").
  4. Catching an exception which indicates that authentication is required.
  5. Specifying the authorization information. ServletUnit does not maintain a database of users, no any username is accepted, and the password is interpreted as a comma-separated list of role names associated with the user.

To run this code, you will also need the web.xml file in your current directory. This file maps the request URL to the Pool Editor servlet.

This code should fail with a HttpNotFoundException, because we have not yet created the servlet class. We can now proceed to do so. Here is a simple implementation:

package tutorial;

import java.io.*;
import java.util.*;

import javax.servlet.http.*;
import javax.servlet.ServletException;

import tutorial.persistence.*;

public class PoolEditorServlet extends HttpServlet {

    protected void doGet( HttpServletRequest request, HttpServletResponse response )
            throws ServletException, IOException {
        response.setContentType( "text/html" );
        PrintWriter pw = response.getWriter();

        pw.println( "<html><head></head><body>" );
        printBody( pw );
        pw.println( "</body></html>" );
    }

    private void printBody( PrintWriter pw ) {
        pw.println( "A simple page" );
    }
}

With this code in place, the first test will now pass and we can move to the next task.

httpunit-1.7+dfsg/doc/tutorial/task1editor-validation.html0000644000175000017500000003153411014557540024005 0ustar twernertwerner HttpUnit Tutorial - create pool editor - step 4

Tutorial -> Task 1 -> Step 4: Validating data entry

Testing servlet internals

In this step, you will learn how to:
• Access a servlet directly during an invocation
• Extract a table from a web response, using its contents
• Examine the contents of an HTML table
• Verify that fields are marked read-only

We are nearly done with the pool editor. We can now use it to define the contents of the pool; however, we can only permit the administrator to open the pool for betting if it is valid. We therefore have to define the validity rules. For this tutorial, the only rules that we will insist on is that all teams must have opponents, and that only a game with a pair of teams may be selected as the tie-breaker.

We must also prevent edits to the pool once it has been opened.

Testing bad inputs

Validation is often complicated, since we have to not only check the data against our validation rules, we also have to recognize the need to validate, and modify the output to show any errors. It would be nice if we could break this into pieces and build one at a time. With ServletUnit, we can:

public void testPoolValidation() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );
    WebForm form = response.getFormWithID( "pool" );

    form.setParameter( "away1", "Detroit Lions" );
    form.setParameter( "home1", "Denver Broncos" );
    form.setParameter( "home2", "Baltimore Ravens" );
    form.setParameter( "tiebreaker", "3" );
    WebRequest request = form.getRequest( "save", "Open Pool" );           // (1) select the request object directly
    InvocationContext context = client.newInvocation( request );           // (2) create an invocation context

    PoolEditorServlet servlet = (PoolEditorServlet) context.getServlet();  // (3) locate the invoked servlet
    servlet.updateBettingPool( context.getRequest() );                     // (4) ask servlet to update the data
    String[] errors = servlet.getValidationErrors();                       // (5) ask servlet to check the data
    assertEquals( "Number of errors reported", 2, errors.length );
    assertEquals( "First error", "Tiebreaker is not a valid game", errors[0] );
    assertEquals( "Second error", "Game 2 has no away team", errors[1] );
}

This test starts out like all the others, but once we have created the request, things venture into new territory:

  1. Rather than simply submitting the form, we ask for the request object used to do the submission. This was hidden from us in the last test.
  2. Given the request, we create a context in which we can step through the invocation of the servlet. This uses the same mechanisms to locate and initialize the servlet, request, and response objects, but does not actually invoke the servlet to process the request.
  3. We retrieve the initialized servlet and cast it in order to get at its intermediate methods.
  4. We call the updateBettingPool method (which we need to make package-accessible), passing the request object found in the context.
  5. We can now call a new method in the servlet which will return an array of error messages, which we can compare against our expected values for them.

This test won't even compile yet, so before proceeding, we should create the new method in the servlet without any logic:

String[] getValidationErrors() {
    return new String[0];
}

Now it compiles and fails, as expected. To make this test pass, we need to implement the new method in the servlet:

String[] getValidationErrors() {
    ArrayList errorList = new ArrayList();
    BettingPoolGame game = BettingPool.getGames()[ BettingPool.getTieBreakerIndex() ];
    if (game.getAwayTeam().length() == 0 || game.getHomeTeam().length() == 0) {
        errorList.add( "Tiebreaker is not a valid game" );
    }
    BettingPoolGame[] games = BettingPool.getGames();
    for (int i = 0; i < games.length; i++) {
        if (games[i].getAwayTeam().length() == 0 && games[i].getHomeTeam().length() != 0) {
            errorList.add( "Game " + i + " has no away team" );
        } else if (games[i].getAwayTeam().length() != 0 && games[i].getHomeTeam().length() == 0) {
            errorList.add( "Game " + i + " has no home team" );
        }
    }
    String[] errors = (String[]) errorList.toArray( new String[ errorList.size() ] );
    return errors;
}

Displaying the error messages

Once we are sure of our validation logic, we need to have the error messages displayed. We will arrange to have any error message displayed in the top of row of the table, and we will highlight any cells containing bad inputs. We therefore ask for the response from the bad open pool request:

public void testBadPoolOpen() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );
    WebForm form = response.getFormWithID( "pool" );

    form.setParameter( "away1", "Detroit Lions" );                         // (1) enter bad values into the form
    form.setParameter( "home1", "Denver Broncos" );
    form.setParameter( "home2", "Baltimore Ravens" );
    form.setParameter( "tiebreaker", "3" );

    SubmitButton openButton = form.getSubmitButton( "save", "Open Pool" ); // (2) select the desired submit button
    response = form.submit( saveButton );                                  // (3) submit the form

    WebTable errorTable = response.getTableWithID( "errors" );             // (4) Look for the error table
    assertNotNull( "No errors reported", errorTable );
    errorTable.purgeEmptyCells();                                          // (5) Remove any empty cells from the table
    String[][] cells = errorTable.asText();                                // (6) Convert non-empty cells to text
    assertEquals( "Number of error messages provided", 2, cells.length - 1 );
    assertEquals( "Error message", "Tiebreaker is not a valid game", cells[1][0] );
    assertEquals( "Error message", "Game 2 has no away team", cells[2][0] );
}

Note:

  1. We enter known bad values.
  2. We then select the "Open Pool" button to be included with the form submission.
  3. We want the response when we submit the form changes.
  4. We expect to find them in a table with "errors" as its ID.
  5. We are not interested in any empty cells used for formatting.
  6. Since we want to examine the textual content of any non-empty cells in the table, we ask that the table be converted to a two-dimensional string array. In this case, there should only be one non-blank cell in each row.

This test passes once we modify the end of the doPost method :

    pw.println( "<html><head></head><body>" );
    if (request.getParameter( "save" ).equals( "Open Pool" )) {
        String[] errors = getValidationErrors();
        if (errors.length != 0) reportErrors( pw, errors );
    }
    printBody( pw );
    pw.println( "</body></html>" );
}


private void reportErrors( PrintWriter pw, String[] errors ) {
    pw.println( "<table id='errors' width='90%' style='background-color=yellow; " );
    pw.println( "   border-color: black; border-width: 2; border-style: solid'>" );
    pw.println( "<tr><td colspan='2'><b>Cannot open pool for betting:</b></td></tr>" );
    for (int i=0; i < errors.length; i++) {
        pw.println( "<tr><td width='5'>&nbsp;</td><td>" + errors[i] + "</td></tr>" );
    }
    pw.println( "</table>" );
}

Note that we are actually displaying two cells for each error. The first is blank, and is simply used for formatting, as many web designers tend to do. The test code will ignore this, so that if the page is later modified to use stylesheets to control its formatting, the test will be unaffected. For this same reason, the tests in this tutorial tend to ignore formatting issues in general, and only look at structural elements.

Closing the pool

If everything is valid, we should be able close the pool. This will be reflected by a change in state of the BettingPool object - which will later be used to change the options available to the users - and should forbid future changes to the pool itself. We will test this by verifying that the "save" submit buttons are no longer enabled:

public void testGoodPoolOpen() throws Exception {
    ServletRunner sr = new ServletRunner( "web.xml" );
    ServletUnitClient client = sr.newClient();
    client.setAuthorization( "aUser", "pool-admin" );
    WebResponse response = client.getResponse( "http://localhost/PoolEditor" );
    WebForm form = response.getFormWithID( "pool" );

    form.setParameter( "away1", "Detroit Lions" );
    form.setParameter( "home1", "Denver Broncos" );
    form.setParameter( "away3", "Indianapolis Colts" );
    form.setParameter( "home3", "Baltimore Ravens" );
    form.setParameter( "tiebreaker", "3" );
    form.getSubmitButton( "save", "Open Pool" ).click();                          // (1) click the submit button

    response = client.getResponse( "http://localhost/PoolEditor" );               // (2) retrieve the page separately
    form = response.getFormWithID( "pool" );
    assertNull( "Could still update the pool", form.getSubmitButton( "save" ) );  // (3) look for the buttons

    try {
        WebRequest request = form.getRequest();
        request.setParameter( "home3", "Philadelphia Eagles" );                   // (4) try to change an entry
        fail( "Could still edit the pool" );
    } catch (IllegalRequestParameterException e) {}
}

Note:

  1. Since we are not interested in the response this time (because we may ultimately have the browser forwarded to the main page), we simply click the submit button. This does the same as calling form.submit(), but does not return a response value.
  2. We come back to the form as though we were planning on editing it anew.
  3. We want to ensure that the submit buttons are disabled so the user cannot submit the form.
  4. We also verify that the fields are now marked readonly, which would prevent us from changing them. If the exception is not thrown, the test will be marked as failing.

We have to make changes in two places to make this behavior work. The following code change to printBody makes the form display read-only once the pool is open:

    for (int i = 0; i < games.length; i++) {
        pw.println( "<tr><td>" );
        pw.print( "<input name='home" + i + "' value='" + games[i].getHomeTeam() + "'" );
        pw.println( getReadOnlyFlag() + "></td>" );
        pw.print( "<td><input name='away" + i + "' value='" + games[i].getAwayTeam() + "'" );
        pw.println( getReadOnlyFlag() + "></td>" );
        pw.print( "<td><input type='radio' name='tiebreaker' value='" + i + "'" + getReadOnlyFlag() );
        if (i == BettingPool.getTieBreakerIndex()) pw.print( " checked" );
        pw.println( " /></td></tr>" );
    }
    pw.println( "</table>" );
    if (BettingPool.isEditable()) {
        pw.println( "<input type='submit' name='save' value='Save' />" );
        pw.println( "<input type='submit' name='save' value='Open Pool' />" );
    }
    pw.println( "</form>" );
}

private String getReadOnlyFlag() {
    return BettingPool.isEditable() ? "" : " readonly";
}

and we have to make a small change to doPost in order to mark the pool open:

            String[] errors = getValidationErrors();
            if (errors.length != 0) reportErrors( pw, errors );
            else {
                BettingPool.openPool();
            }
        }

The pool editor is now complete. In the next task, you will address access to the application.

httpunit-1.7+dfsg/doc/tutorial/task2.html0000644000175000017500000000233411014557542020445 0ustar twernertwerner HttpUnit Tutorial - control application access

Tutorial ->Task 2

Controlling access to the application

At this point, we have a working pool editor, accessible only to a user with the appropriate assigned role. Any other user will be refused when they try to access the editor. We would like to go further, and provide a common front page to the application for all users, which will provide links to the permitted pages only.

This is not written httpunit-1.7+dfsg/doc/tutorial/tutorial.css0000644000175000017500000000172611014557540021112 0ustar twernertwernerPRE { font-family: "courier new", courier; font-size: 8pt; margin-left: 2%; margin-right: 2%; padding-top: .5em; padding-bottom: .5em; padding-right: .5em; padding-left: .5em; border-color: black; border-width: 2; border-style: solid } PRE.test-code { background-color: #cccccc } PRE.servlet-code { background-color: #cceeee } OL { margin-top: 0 } P.goals { font-family: helvetica, ariel, sans-serif; font-size: x-small; background-color: #ffffdd; border-color: black; border-style: solid; border-top-width: 2px; border-bottom-width: 2px; border-left-width: 0px; border-right-width: 0px } P.location { font-family: helvetica, ariel, sans-serif; font-size: x-small; background-color: #ffff66; border-color: #dddddd; border-style: solid; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; border-top-width: 0px; border-bottom-width: 2px; border-left-width: 0px; border-right-width: 0px } UL { margin-top: 0 } httpunit-1.7+dfsg/doc/tutorial/web.xml0000644000175000017500000000141011014557540020022 0ustar twernertwerner Editor tutorial.PoolEditorServlet Editor /PoolEditor Administration /PoolEditor pool-admin BASIC Betting Pool httpunit-1.7+dfsg/doc/plans.txt0000644000175000017500000000050111014557540016536 0ustar twernertwerner ------------ fairly strightforward to find this, but action not clear: 2. define 'refreshRequest' property which is normally null, refreshInterval property httpunit-1.7+dfsg/doc/release_notes.html0000644000175000017500000025562611014557542020424 0ustar twernertwerner httpunit 1.7 release notes

HttpUnit release notes

Known problems:

  1. The "accept-charset" attribute for forms is ignored; the page content character set is used to encode any response. This behavior matches that currently used by IE and Navigator.
  2. Defining a form parameter with the same name or ID as a JavaScript Form function will cause that function not to be callable.

Limitations:

  1. JDK 1.4.2 or higher is required
  2. JavaScript support does not include some DOM properties
  3. The JavaScript assignment Document.cookie= does not restrict the cookie by path and domain
  4. Only table cells and explicit paragraphs are recognized as text blocks

Revision History:

Version 1.7 Released 2008-05-20

Acknowledgements:

This project would almost certainly have remained dormant without the extraordinary contributions of our new committer, Wolfgang Fahl. Wolfgang has been extremely active over the past few months, erasing the backlog in bug, patches, and enhancement requests, and generally improving the quality and energy of the project. In addition, thanks are due to:
  • Stefan Hbner for supplying a patch for URL-decoding of parameters in ServletUnit
  • Archimedes Trajano for supplying code to support non-JSSE SSL providers
  • Bobby Abraham for adding the capability of deleting a cookie manually
  • Rafal Krzewski for adding special handling for form actions containing a parameter named "action."
  • Michael Rudolf for adding support for connection and read timeouts.
  • Richard Lee for supporting xy parameter submission for unnamed image buttons.
  • Laurent Wozniak for address the handling of expired cookies
  • Matthew O. Smith for adding more sophisticated logging to ServletUnit
  • Mattias Jiderhamn for adding Javascript support for arbitrary attributes
  • Bjrn Beskow for adding Javascript support for 'onMouseUp' and 'onMouseDown' events
  • Jord Sonneveld for adding support for onBlur and onFocus events
  • Hugh Winkler for fixing getPathInfo decoding
  • David D. Kilzer for supporting direct invocation ot javascript events
  • Fabrizio Giustina for enabling html parsing of xml responses
  • Roger Lindsj for adding handling of empty error pages under JDK 1.5

Notes:

  1. Upgraded NekoHTML to 0.9.5
  2. Upgraded Xerces to 2.6.1
  3. Upgraded Rhino to 1.6R5
  4. The PostMethodWebRequest.setMimeEncoded method has been removed. Mime encoding, if desired, should now be specified when constructing the object.
  5. WebLink.click() now only returns the contents of the frame containing the link. Previously, if there was no event involved and the link included a frame reference, it would return the contents of the referenced frame.
  6. HttpUnit configuration management has been moved from CVS to subversion at http://httpunit.svn.sourceforge.net/svnroot/httpunit/trunk/httpunit
  7. The build now uses the Maven dependencies task (see http://maven.apache.org/ant-tasks.html) rather than keeping the dependent jars in the repository.
  8. When using the nekoHtml parser, tag and attribute names now default to lower case, rather than upper case as before
  9. Empty cells from tables are no longer automatically purged when searching for a table by its first non-blank cell

Problems fixed:

Content and Parsing:
  1. bug #1124047 - selecting a select option by index should now throw RuntimeException rather than IndexOutOfBounds if the index is bad
  2. bug #1212204 - WebRquest.getQueryString was ignoring parameters without values
  3. bug #1277797 - expired cookies are now removed from the client session
  4. bug #1283878 - in JDK 1.5, empty error pages were causing FileNotFoundException to be thrown
  5. bug #1371204 - there was no way to change or delete a server-supplied cookie from a test
  6. bug #1672385 - specifying HttpOnly on a cookie header was causing any specified cookies to be lost
  7. bug #1705925 - URL-encoded parameter values were not decoded properly if HttpUnitOptions.setDefaultCharacterSet() is set to something different than ISO-8859-1
  8. bug #1843978 - the value of a SELECT control could not be set if the web page defined a namespace URI
  9. bug #1895501 - the applet codebase was defaulting to the root directory, rather than the current directory
  10. bug #1954311 - WebForm.setParameter no longer throws NullPointerException when the control is a TextArea
  11. patch #1155415 - in some cases, automatic redirects could result in an infinite loop
  12. patch #1155792 - could not set the action for a form if its original action had a parameter named "action"
  13. patch #1281655 - attempts to parse xml as html were being rejected
  14. patch #1443333 - unnamed image buttons now submit positions as "x" and "y"
Javascript
  1. bug #1289151 - clicking a button was firing the 'onClick' event for disabled buttons
  2. bug #1396835 - increading the length of a select control was throwing an exception
PseudoServer
  1. PseudoServer was incorrectly parsing chunk lengths as decimal rather than hexadecimal
ServletUnit
  1. The implementation of ServletContext is now public, allowing it to be instantiated via reflection as needed
  2. bug #1165454 - HttpServletRequest.getScheme() now returns "https" for secure requests
  3. bug #1242640 - Causes of 500 errors are not included in the stack trace
  4. bug #1323031 - HttpServletRequest.getPathInfo was not properly decoding spaces in URLs

Additions:

Content and Parsing:
  1. Created a custom HttpUnit DOM
  2. Basic authentication now can support authorization only after challenge and different passwords for different realms.
  3. Added support for rudimentary (RFC 2109) digest authentication.
  4. Added "overrideContextType" property to ClientProperties to permit handling of files served with the wrong content type.
  5. Added HttpsProtocolSupport.useProvider to override the default selection of the JSSE for SSL support
  6. Added HttpsProtocolSupport.useIBM to select the SSL support provided by IBM WebSphere (which must be in the classpath)
  7. patch #844084 - added "sendReferer" property to ClientProperties to permit testing of sites when the referer header is blocked by a firewall or proxy server
  8. patch #1518901 - added methods to control connection and read timeouts.
  9. patch #1415415 - added (mime types for tiff and pdf)
  10. patch #1531005 - getElementsWithAttribute should now work with most attribute names
  11. bug #1476380 - cookies are now accepted even if their domain matches exactly
Javascript support
  1. patch #796961 - javascript events can now be directly invoked on elements
  2. patch #884146 - added support for the 'onMouseDown" and 'onMouseUp' events
  3. patch #1030851 - added support for 'onBlur' and 'onFocus' events
  4. patch #1653410 - added support for arbitrary element attributes
ServletUnit
  1. HttpRequest.getDateHeader() has been implemented; previously it always returned -1
  2. patch #1246438 - HttpRequest.getReader is now implemented
  3. patch #1864072 - now log to a user-specified output stream
Pseudoserver:
  1. Added WebResource.suppressAutomaticContentTypeHeader to permit generation of responses without the Content-Type header.
  2. Improved debugging messages and handle response timeouts.

Version 1.6.2 released 2006-03-27:

	  
    Acknowledgements:
        Thanks for Fabrizio Giustina for suggesting a way to make the TableRow object publically accessible.

    Problems fixed:
        1. bug #1063494 HTML entity replacement was looping indefinitely on strings with '&' and no ';'
        2. ServletContext.getRealPath() now handles relative paths that do not start with a "/"

    Additions:
        1. patch #1413171 Web table rows are now directly accessible in a TableRow element.
        2. Added support for Servlet API 2.4
        3. Implemented ServletContext.getServletContextName
        4. (PseudoServer) made HttpRequest class public

Version 1.6.1 released 2005-03-06

 
    Acknowledgements:
        Thanks to Hanson Char for identifying a JDK 1.5 incompatibility.
        Thanks to Satish Kolli for fixing bug #1040770
        Thanks to Fabrizio Guistina for supplying an implementation of locale handling for ServletUnitHttpResponse
        Thanks to Vladimir Korenev for providing an implementation for style.visibility, element.tagName, and element.nodeName
        Thanks to Yaqoub Jaiousi for identifying the problem with buttons outside of forms.

    Problems fixed:
        JDK compatibility
             1. bug #1039989 Did not compile with JDK 1.3. This bug was introduced in HttpUnit 1.6 and has now been corrected.
             2. Renamed local variables which conflicted with new JDK 1.5 keyword "enum."

        Content and Parsing
             3. bug #1046597 tables nested inside paragraphs were not being seen by the enclosing page. This bug was introduced
                in 1.6 and has now been corrected.
             4. bug #1074232 buttons outside of forms were only recognized if defined with the <button> tag, not <input>

        Window handling
             5. bug #1035949 Following a link from the top frame to a _parent target no longer results in a NullPointerException.

        JavaScript
             6. bug #1040508 Using the setCheckbox and toggleCheckbox methods was not triggering the onclick event
             7. bug #1040770 the Image.name JavaScript property is now supported
             8. bug #1047367 frames defined by javascript were not being detected.
             9. patch #1046516 property style.visibility is now supported
            10. bug #1073810 a null pointer exception is no longer thrown when javascript sets a control value to null
            11. bug #1052779 window.open() with javascript URL no longer throws a null pointer exception or class cast exception
            12. bug #1087180 setting a numeric value into a form parameter was appending a trailing decimal zero

        ServletUnit
            13. bug #1044820 ServletUnit now implements HttpServletResponse.getLocale() and setLocale()
            14. bug #1051123 ServletUnit handling of parameter encoding was not cleaning up url-encodings
            15. bug #1151277 only the first user-defined cookie was recognized in ServletUnit if multiple were set
            
        PseudoServer
            16. Made all WebResource constructors public

Version 1.6 released 2004-10-03

Acknowledgements:
    Thanks to Chris Hane for making it easier to add support for javascript properties and for providing support for
        getAttribute() to handle any property defined in the underlying Node.
    Thanks to Patrick Lightbody for adding JavaScript support for the Style object
    Thanks to Phil Zampino for finding a fixing a problem in PseudoServer's handling of very long requests.
    Thanks to Andrew Bickerton for adding the following JavaScript support:
        Form.length          - returns the number of controls in a form
        Control.type         - returns a test description of the control type
        Control.defaultValue - returns the default value for text controls
        Initial page tokenizing now skips JavaScript while looking for header tags
        Writing into an empty frame no longer corrupts all empty frames
    Thanks to Jarom Smith for finding some typos in the tutorial.
    Thanks to Jay Dunning for providing an implementation of HttpServletResponse.containsHeader
        and implementing support for ServletContextListeners.
    Thanks to Fabrizio Giustina for adding an entity-resolver to support local use of ServletUnit with a regular web.xml
    Thanks to Kazuaki Matsuhashi for correcting the handling of non-Latin link parameters
    Thanks to Dan Frankow for supplying an implementation of ServletContext.getMimeType and correcting the
        implementation of HttpSession.setAttribute when the value is null
    Thanks to Guillaume Dandurand for supplying code to get the onload event when the page
        is a frameset rather than a regular page.
    Thanks to Michael Corum for making the Button.disabled property settable from JavaScript.
    Thanks to Darrell DeBoer for providing a patch for select box functionality
    Thanks to Bart Vanhaute for finding a fixing an infinite recursion problem with frame loading.
    Thanks to Dave Brosius for adding hashCode to Cookie and QuerySpec

Additions:
    Content and Parsing
         1. rfe #766768: getText() methods now translate <br> tags as newlines.
         2. rfe #901172: content-types "text/xhtml" and "application/xhtml+xml" are now recognized as valid HTML
         3. rfe #974791: WebForm now supports submitNoButton to submit a form without any of its buttons. This permits
            testing of server response to a Javascript-style submit without using JavaScript.
         4. rfe #986876: The WebClient.addCookie method has been deprecated, since its behavior is actually a bit confusing
            and replaced with "putCookie" allowing subsequent the replacement of a cookie value defined by a previous
            call to "putCookie."
         5. patch #1026566 The Cookie class now implements hashCode properly.
         6. patch #879193: The name of a select box may now be treated as an array of options.
         7. patch #879193: Select now behaves as a multiselect listbox if it has size > 1 or if multiple is set and the size is not set to 1.
         8. Patch #795698: HTMLElement now supports a getAttribute method to return the value of any named attribute.
         9. WebResponse and TableCell now support getElementsWithAttribute to return all contained HTML elements
            with a specified attribute.
        10. setCheckbox() and toggleCheckbox() have now been expanded to select one of a group of checkboxes by specifying
            its name.
        11. WebForm now supports the newUnvalidatedRequest method, which should be used in preference to
            HttpUnitOptions.setParametersValidated( false ). This creates a web request copied from the form
            but not tied to it, so that parameters can be set without validation.
        12. Enhanced http logging to show target server, request header line, and received URL
        13. HTMLElement now supports a getText() method to return the text contents of any element
        14. WebResponse now supports getTextBlocks and getFirstMatchingTextBlock to retrieve headers and paragraphs from a page.
        15. HttpUnit now catches an attempt to load an included script from a page included with "getResource" rather than
            "getResponse."
        16. Click positions on image buttons may now be specified using one of:
                form.submit( button, x, y )
                button.click( x, y )
        17. Added preliminary support for lists
        18. Added convenience method setParameter( String, File ) to simplify file uploading
        19. A username and password may now be specified when accessing a proxy server.
    JavaScript
        20. Added support for javascript Input.tabindex and Text.maxlength properties (read-only)
        21. Added support for javascript HTMLElement.style property
    ServletUnit
        22. Patch #890995 - Implemented ServletUnitHttpResponse.containsHeader
        23. Patch #890936 - Added ServletContextListener support
        24. Added HttpSessionListener support
        25. Added support for ServletContextAttributeListener and HttpSessionAttributeListener
        26. Added support for filters
        27. rfe #909922: ServletUnit now supports HttpServletRequest.getHeaders
        28. patch #915296: Local copies of the 2.2 and 2.3 web.xml dtds are now consulted if specified,
            rather than connecting to the Sun website.
        29. ServletRunner now takes a reference to a web.xml as a File object in its constructor.
        30. ServletRunner and ServletUnitClient now support a getSession() method to return the HTTP session to be used
            by the next request or modified by the last request.
        31. ServletUnit now implements HttpSession.getServletContext().
    PseudoServer
        32. PseudoServer now pools its ServerSocket's in order to be more gracious regarding system resources. Pooling can
            be controlled via the properties: socketReleaseWaitTime and waitThreshhold.
        33. PseudoServer can now received chunked requests, and will not send a "Content-Length" header if a
            "Transfer-Encoding: chunked" has been defined.
        34. PseudoServer now accepts a full http URL to permit testing of interaction with proxy servers.

Problems fixed:
    Documentation
         1. bug #804585: the javascript documentation referred to the old location of the
                         getNextAlert and popNextAlert methods
         2. bug #804559: unimplemented links have been removed from the incomplete user manual.
         3. A number of typos in the tutorial have been corrected
    Content and Parsing
         4. bug #978770 Clicking on a button outside of a form is now supported
         5. bug #838947 Document.getElementById now returns null if no such element exists
         6. bug #957882: URL path elements containing leading '.' were being stripped of those periods.
         7. bug #830856: WebLink URLs broken across lines are now handled correctly
         8. bug #805921: WebForm.selectImageButtonPosition was misleadingly public and should not have been used.
            It has been made package-private, and new means are provided to submit positional image buttons (see additions).
         9. bug #982097: http urls being used as request parameters were being mangled
        10. bug #803041: HTML entity & now recognized in refresh URL tag
        11. bug #803095: Absolute URLs now supported in refresh URL tag
        12. bug #986397: Subframe included fragments in their source attributes now ignore those fragments when generating requests.
        13. bug #990914: WebFrame scriptables are now accessible by getElementById
        14. patch #995853: decode link parameters based on page character set
        15. When a form has no action specified and its URL contains parameters whose names match those of parameters
            in the form, the form values are used instead.
        16. Slashes in URL parameters were being misinterpeted as navigation
    Request handling
        17. The HeadMethodWebRequest was actually sending the GET method, as was any HeaderOnlyWebRequest.
        18. bug #964940 The Referer header was not being sent again if the original request was redirected
        19. bug #974380 When using a DNS listener, host header no longer includes ':-1' if the port is not specified
        20. bug #1032440: An explanatory exception is now thrown on an attempt to use a mailto: URL in a form submission
    Cookie handling
        21. bug #873169 - Cookie headers were generated with no space after the semicolon (unlike IE, Netscape, and Mozilla)
        22. Cookie domains without leading dots are now accepted, as per RFC 2965.
        23. bug #1025968: Cookies with max-age attribute will now expire (max-age=0 is treated as immediate expiration)
    Frame handling
        24. bug #737167: Nested frame names are now as specified, previous included names of parent frames.
        25. Return from a request that wrote to a new frame is now the result of that request, was the original page.
        26. Return from a request specifying an unknown frame now opens a new window; previously created a subframe
            in the requesting window.
        27. bug #1029139: infinite recursion in frameset page when a frame has src="#"
    JavaScript
        28. A frameset 'onload' event is now invoked after all of its subframes have been loaded
        29. HttpUnit no longer complains about not being able to find the Rhino jar (js.jar) if scripting is disabled
            before any pages are read.
        30. bug #823433: document.cookie now defaults to the empty string, like IE and Mozilla, rather than null
        31. Using JavaScript to write into an empty frame could change all empty frames to the same value
        32. Window.open() using an empty name was replacing the main window rather than creating a new one.
        33. Patch #812709: Support JavaScript changing "disabled" attribute on Buttons
        34. bug #861866: Support JavaScript changing "disabled" attribute on form controls
        35. Forms defined after a <script> section which accessed document.forms would not be found if document.forms
            was also accessed in a subsequent <script> section after the new form definition.
        36. bug #974675 Javascript function Window.open did not honor "_self" tag for window name.
        37. bug #960307 meta tags within <noscript> tags were not being ignored when scripting was disabled
        38. bug #959918: Javascript setting of numeric values included trailing zeros after the decimal point.
        39. bug #1013045: Form, Link, and Image id tags are now recognizable from JavaScript where a name tag would be
    ServletUnit
        40. ServletUnit now applies character encoding in interpreting post parameters
        41. Patch #873911: ServletContext.getMimeType is supported
        42. Patch #873914: HttpSession.setAttribute( name, null ) now properly removes the named attribute
        43. bug #872129: Cookie header set on a web request was ignored in servletunit
        44. HttpServletRequest.getCookies() method was only returning the first cookie defined in the request
        45. bug #1034067: ServletConfig.getServletName now returns the name specified in web.xml for registered servlets.
    PseudoServer
        46. PseudoServer now supports any method handled by a PseudoServlet. Previously, it only handled GET, POST, and PUT.
            It is simply necessary to override the getResponse method to make this work.
        47. PseudoServer would hang when sent a very long request.

    Notes:
        1. Upgraded NekoHTML to 0.9.1
        2. Upgraded Xerces to 2.4.0
        3. Upgraded Rhino to 1.5R4.1

Version 1.5.4 released 2003-08-21

Acknowledgements:
    Thanks to David D. Kilzer for:
         creating thorough tests for URLs containing navigation and showing a way to handle them, and
         submitting the WebLink.MATCH_TEXT predicate.
    Thanks to Lloyd McKenzie for finding a problem with listing cookie names and suggesting a fix.
    Thanks to Brian O'Kelley for supplying a way to disable use of the proxy server.

Additions:
    Content and Parsing
        1. WebResponse and TableCell now support getElementsWithName and getElementNames to look up HTML elements.
        2. Form.getOptions() now works for radio buttons and checkboxes - as long as the desired name is located after the control.
        3. rfe #723895: A new class CookieProperties now supports relaxing cookie matching rules for path, domain, or both.
        4. It is now possible to define a CookieListener on CookieProperties to watch for cookie rejection events
        5. rfe #751505: Add clearProxyServer() to disable the use of the proxy server
        6. rfe #744360: Added getFirstMatchingForm and getMatchingForms() methods to WebResponse and HTMLSegment
        7. rfe #756453: Made Button.isDisabled() method public
        8: rfe #717752: Added WebLink.MATCH_TEXT predicate to match link text exactly
        9. rfe #721424: You can now set checkbox values in a form via: setCheckbox(name,boolean) or toggleCheckbox(name).
                        These methods will throw an exception if the specified parameter is not a checkbox or if more than
                        one control  has the name.
    ServletUnit
       10. JUnitServlet now supports a value of 'xml' for the format parameter, generating a format compatible with
           ant's XMLResultFormatter
       11. You can now get the value of context parameters from a ServletRunner via the getContextParameter method
    PseudoServer
       12. PseudoServer now permits setting the maximum protocol level. If it is 1.0, all responses will be forced to
                        HTTP/1.0 no matter the protocol of the request.

Problems fixed:
    Content and Parsing
        1. bug #717280: URLs with "../" in them were not resolved properly
        2. bug #717640: <base> element was not being handled in the case when no host was specified.
        3. When setting a selection control, HttpUnit would always select a value matching its first option if possible,
           rather than taking the first valid value.
        4. bug #722788: WebForm.submit() was not invoking the 'onClick' event of the specified submit button.
        5. bug #721989: scripts did not see id attributes of form controls.
        6. bug #741965: cookies with explicit domain attributes are being rejected when their host is of the form HD
                        where D is the explicit domain attribute and H contains a dot. Apparently, most browsers ignore this
                        rule. Now, so does HttpUnit, if CookieProperties.setDomainMatchingStrict( false ) is called.
        7. bug #750846: Cannot retrieve all cookie names when both global and site-specific cookies are defined.
        8. gzip'ed responses were sometimes truncated.
    JavaScript
        9. bug #734133: javascript: URLs were ignored if "javascript:" is not all lower case.
   ServletUnit
       10. bug #744214: ServletUnit does not recognize subframes

Version 1.5.3 released 2004-04-04

 Acknowledgements:
    Thanks to Andrew Bickerton for:
          correcting the handling of document.open for non-HTML pages and new pages with base tags,
          correcting the document.write append problem,
          identifying the javascript parent frame update problem and suggesting a fix, and
          showing how to handle responses with content-length 0.
    Thanks to Brendan Boesen for:
          adding a method to access session IDs in ServletUnitContext, and
          correcting the session invalidation problem.
    Thanks to Daniel Jasmin for fixing the handling of applet loading from archives.
    Thanks to Mark Luty for supplying a test for the getElementsByName function.
    Thanks to Ron Webster for designing the new HttpUnit logo.
    Thanks to Sergey Bondarenko for supplying a test for getElementsByTagName
    Thanks to George Murnock for adding WebResponse.getMatchingTables()

Problems Fixed:
    Content and Parsing
        1. Bug #700889: Under certain cases, multiple <script> sections in a document caused a problem where
           only those HTML elements defined before the first one were actually available to the scripts.
        2. Bug #709979: Select.selectedIndex was returning -1 for a normal select box with no options explicitly selected.
        3. calling Document.open() on a non-HTML page no longer throws an exception.
        4. Rewriting a document now properly handles any <base> tags in the new document.
        5. Applets were not loading properly from applets if a codebase was specified in the <applet> tag.
        6. When loading a page triggered a script function which redirected to a new page in the same frame,
           the WebResponse returned from getResponse was the triggering page. It is now the redirected page.
        7. HttpUnit now handles refresh headers without explicit URLs, defaulting to refreshing the containing page.
        8. HttpUnit was delaying until a timeout when a zero-length response was received
    JavaScript
        9. calling document.write on a closed document was appending to rather than replacing its contents.
       10. Following a javascript link which updated a parent frame via manipulating the location was causing a 'NoSuchFrame'
           exception to be thrown.
       11. HttpUnit was chopping off javascript urls if they contained a '#' character.
    ServletUnit
       12. The Content-Length header was not being sent with requests.
       13. HttpServletRequest.getIntHeader() always returned -1.
       14. ServletUnit was creating a new session if the current one was not valid, even if "create" was not specified.
       15. ServletUnit had not implemented HttpServletRequest.getContentLength();
       16. ServletUnit had not implemented HttpServletRequest.getURL();
       17. ServletUnit was always supplying a charset parameter in the returned Content-Type header, even when not requested.

Additions:
    Content and Parsing
        1. WebResponse and TableCell now have getMatchingTables to return all tables matching the specified criteria.
    JavaScript
        2. <noscript> nodes in the body of a page now show their content if a <script> earlier in the page is not recognized.
        3. Select.value is now supported.
        4. Added WebForm.getButton() method using HTMLPredicate to permit more generalized button searches.
        5. Document.getElementsByName is now supported
        6. Added support for getElementsByTagName to Document and Form
    ServletUnit
        7. You can now get at the stored session IDs in ServletUnitContext.
        8. ServletUnit now supports HttpServletRequest.getRequestDispatch()
    PseudoServer
        9. PseudoServer now handles persistent connections.
    Extensibility
       10. ClientProperties now supports a listener which allows for the override of DNS mapping, allowing a client
           to supply an actual IP address for a host programatically. The original Host header will be retained.
       11. Added format parameter for JUnitServlet: values are "text" or "html"

Notes:
    1. The acceptCookies, acceptGzip, autoRefresh and autoForward properties have been moved from HttpUnitOptions
       to ClientProperties, permitting them to be set per WebClient rather than just globally. The old properties
       have been deprecated, and now access the defaults for ClientProperties. Tests which set the HttpUnitOptions
       properties before creating their WebClients will be unaffected.

Version 1.5.2 released 2003-03-03

Acknowledgements:
    Thanks to John Sinclair for noting the lack of line breaks in manifest.mf and proposing a fix
    Thanks to Bernhard Wagner for simplifying some string comparison code in ParsedHTML and WebTable
    Thanks to Bernhard Wagner for adding some parser customization code.
    Thanks to James Howe for noting the mispelling of the getElementById method
    Thanks to Alex Beggs for noting the mishandling of non-JavaScript scripts and providing a test case.
    Thanks to Navid Vahdat for ServletUnit fixes for invalid session handling and request dispatcher paths
    Thanks to Daniel Sheppard for identifying a problem with meta refresh tags.
    Thanks to Daniel Sheppard for correcting the return status for HttpServletResponse.sendRedirect
    Thanks to Daniel Sheppard, Navid Vahdat, and Ron Hanson for help in adding capabilities to the RequestDispatcher implementation.
    Thanks to Ron Hanson for catching the obsolete behavior of HttpServletRequest.setAttribute.
    Thanks to Raphael Corre for improving logging of transmitted headers
    Thanks to Jason Bedell for supplying an implementation for HttpSession.getValueNames.
    Thanks to Jianqin Qu for finding the getTableStartingWithPrefix bug when using NekoHTML
    Thanks to Scott Fleischman for providing tests for missing frame handling functionality
    Thanks to Artashes Aghajanyan for implementing error reporting for the NekoHTML parser

Problems Fixed:
    Packaging
        1. The manifest.mf file now has line breaks between properties
    Content and Parsing
        2. get...WithID was incorrectly doing case insensitive matches.  It is now case-sensitive, since that is the way
           the ID attribute is defined.
        3. Forms prematurely closed because of improper nesting will now contain any controls defined before the next form.
        4. Quotes in refresh URL meta tags are now recognized and stripped.
        5. Headers defined per request were not being logged
        6. WebResponse.getTableStartingWith and getTableStartingWithPrefix was trying to match newline characters when
           using the NekoHTML parser.
    JavaScript
        7. Bug #680695: Button.click() is now supported.
        8. Bug #680695: Form control ids are now usable to locate components.
        9. Scripts marked as something besides JavaScript are now ignored.
       10. Calling document.close() in the middle of an immediate script no longer replaces the current page.
       11. Opening a non-HTML window via Javascript no longer raises a NotHTMLException.
    ServletUnit
       12. Included and forwarded servlets now inherit parameters from their calling servlet.
       13. Included servlets now have access to their path information as attributes, as per the spec.
       14. Forwarded servlets now have access to their path information from the standard request methods, as required.
       15. All servlets within a web application now share the same instance of ServletContext, permitting attributes
           set by one servlet to be visible to other servlets.
       16. ServletUnit now creates a new session if the requested session exists but is marked invalid
       17. ServletUnit was interpreting the getRequestDispatcher path as an absolute path. It now correctly treats it
           as relative to the context root.
       18. ServletUnit now supports HttpSession.getValueNames().
       19. Calling HttpServletRequest.setAttribute in ServletUnit no longer throws an IllegalStateException if the value
           had previously been defined.

Additions:
    Content and Parsing
        1. You may call HTMLParserFactory.setPreserveTagCase and setReturnHTMLDocument to control whether the parser coerces
           the case of tags and attributes or returns a HTMLDocument object, respectively.
        2. HTMLParserFactory now supports methods to explicitly select the parser without playing with the class path.
           This includes support for additional parsers not bundled with HttpUnit.
        3. WebResponse and TableCell now support the getElementWithID method, which returns any supported HTMLElement,
           given its ID. Supported HTMLElement objects include WebForm, WebLink, WebTable, WebImage, WebApplet,
           FormControl, TableCell, and TableRow.
        4. Added getFragmentIdentifier() to WebRequestSource (parent of WebLink, WebForm, and WebImage)
        5. Added support for <iframe> tag. IFrames work just like regular frames, except that they are embedded in a response
           without a <frameset> tag. IFrame support is controlled by the ClientProperties.iframeSupported property.
        6. WebForm.isHiddenParameter returns true if all parameters with the specified name are hidden
        7. Frame handling is now more flexible, searching within a window for a target frame rather than just below the source frame.
        8. HTMLParserListeners and parser warnings now work with the NekoHTML parser.
    JavaScript
        9. All HTML elements with id attributes are now accessible
       10. The Form.target property is now supported
       11. Added support for document.getElementById
    ServletUnit
       12. ServletUnit now handles https requests, marking them as "secure."
       13. ServletUnit now supports HttpServletResponse.flushBuffer()
       14. InvocationContext now supports include and forwarded servlets: calling pushIncludeRequest or pushForwardRequest
           updates the servlet, request, and response properties of the context so that subsequent calls can be done from
           the dispatched servlet. Calling popRequest reverts to the dispatching servlet.
       15. ServletUnit now loads and initializes servlets specified with the <load-on-startup> element.
       16. HttpServletResponse methods reset(), resetBuffer(), and setBufferSize() are now implemented.
       17. ServletRunner.shutDown() will invoke the destroy() methods of any servlets which have been invoked
           through that servlet runner.
       18. ServletUnit now supports HttpServletRequest.getHeaderNames

Notes:
    1. Upgraded NekoHTML to 0.7.2 which no longer generates superfluous <form> tags.
    2. Removed a number of deprecated methods

Version 1.5.1 released 2002-12-18

Acknowledgements:
    Thanks to Geert Bevin for fixing a problem with comparing cookies
    Thanks to Troy Waldrep for pointing out the non-standard Refresh header definition accepted in popular browsers
    Thanks to Raul Benito Garcia for pointing out the problem with no-action forms accessed with URL parameters
    Thanks to Larry Hamel for supplying an ant target to run Example.java
    Thanks to Charles Mendis for finding the bug in the proxy support
    Thanks to Michael McCallum for adding handling for bad character-set headers and an ant target to build the examples
    Thanks to Neville Wylie for catching the top.parent and frame name index problems

Problems Fixed:
    Content and Parsing
        1. Adding both a "global" cookie and a server-based cookie with the same name caused a NullPointerException
        2. Simply removing the NekoHTML parser jar from the classpath was not enough to re-enable JTidy. Now it is.
        3. When a form obtained using parameters as part of the URL has no action, those parameters are now sent
           as part of the form submission.
        4. Bug #635273 Proxy port always interpreted as port 80 due to typo
        5. As of 1.5, HttpUnit was not building if NekoHTML was not in the classpath. This is now fixed.
        6. Bad character-set headers from servers would result in an UnsupportedEncodingException.
        7. Bug #638406 Multi-line values in form data were using the platform-specific line ending rather than CRLF.
        8. HttpUnit now ignores empty parameters on form actions, as IE and Netscape do.
        9. Table <th> elements were being handled *after* <td> elements in the same row
       10. Bug #641687: when neither NekoHTML.jar or Tidy.jar is in the classpath, a class not found exception was thrown

    JavaScript
       11. Bug #638306 Document.writeln was writing the value "13" rather than CRLF as its terminator.
       12. Bug #638304 Interframe dependancies for JavaScript at load time were causing frame data not to be found.
       13. Bug #637208 Link.click() no longer returns null when an 'onClick' event fails to return true.
       14. The parent attribute of the top frame was returning null rather than the frame.
       15. Frame names used as indexes into the Window.frames array were not being recognized.
       16. The <base> tag was not being used to find included scripts
       17. Multiple form parameters with the same name were only being treated as an array if they were checkboxes;
           otherwise, they were being ignored - this would result in a "undefined value has no properties" error message.
       18. Bug #644642: changes to form parameters made from immediate scripts were being discarded

Additions:
    Content and Parsing
        1. Added support for the Refresh header
        2. Added support for applet parameters and archives
        3. There is now an ant target to run the Example program.

    JavaScript
        4. Added support for the location.href property
        5. Added support for Document.open, Document.close, and Document.write / writeln for new documents
        6. The Rhino jar now includes a patch to improve error-reporting for unsupported DOM elements
        7. Added support for most subproperties of the Location object - mostly r/o, but some read/write
        8. Added support for Document.cookie

Notes:
    1. Upgraded NekoHTML to 0.7.1

Version 1.5. released 2002-11-03

Acknowledgements:
    Thanks to Ken Corbin for adding tests for disabled and read-only parameters.
    Thanks to Geert Bevin for fixing a problem with generation of cookie headers that affects some servers.
    Thanks to Richard Harris for adding support for the title attribute for links,
           for adding the JavaScript Navigator.platform property,
           for adding Javascript support for the Screen object,
           for pointing out the value of retaining the same ScriptingEngine instance for a ScriptableDelegate,
           for adding stubs for various unimplemented JavaScript Window properties.
           and for finding a case where the handling of JavaScript comments was not working.
    Thanks to Stefan Renz for describing the correct way to set up proxy servers in Java 2 and later.
    Thanks to Troy Waldrep for help with the new handling of response statuses and messages.
           and for fixing the JavaScript / HTML end-comment bug
    Thanks to Andy Clark for help using the NekoHTML filter capability.
    Thanks to EdA-qa mort-ora-y for findind and fixing the MIME-encoding bug


Notes:
    1. The NekoHTML parser is now supported. If it is present in the classpath, it will be used in preference to JTidy.
       Note that NekoHTML is a much more forgiving parser than JTidy, properly handling a lot of bad HTML that JTidy
       cannot. In addition, the Document class that NekoHTML creates is of type HTMLDocument. On the other hand,
       the HTMLErrorListener is not currently supporting the NekoHTML parser, although such support will be added if
       it is really needed.  NekoHTML is the current preferred parser and will probably be required to support certain
       JavaScript enhancements. Ultimately, it is possible that JTidy support will be dropped.
    2. The version of xerces now included in the distribution is 2.2, which is required for NekoHTML.
    3. The exception HttpServerNotFoundException has been removed. When no server is found, HttpUnit now throws the
       standard exception: java.net.UnknownHostException
    4. The required jars are now included in the distribution, so it is not necessary to download them separately.
       This was an oversight.


Problems fixed:
    Content and parsing
        1. The cookie header was being generated with a space after each ";" separator.
        2. AuthorizationRequiredException was being thrown even when exceptions on error status was disabled
        3. A bad certificate on an https connection was incorrectly being flagged as a no-such-server exception. This
           is fixed on JDK 1.4, due to a correct in the JDK. On previous versions of the JDK, HttpUnit is using a
           workaround, which cannot detect the difference.
        4. Bug #626822 Controls without names are no longer sent as part of a MIME-encoded message
    Internationalization
        5. When not using Latin-1 encoding, URL string characters *, _, and - were improperly being encoded
        6. Requests created by calling the web request constructors directly, rather than being derived from an HTML page
           were always using the Latin-1 encoding, rather than the user-specified default encoding.
    JavaScript
        7. Repeated requests for the same JavaScript domain objects returned new and different instances, thus
           preventing identity tests.
        8. Under certain circumstances, the first line of a JavaScript section was being treated as though commented out.
        9. JavaScript ending with --> rather than the proper end-comment // --> was being treated as a syntax error
       10. When a JavaScript event resulted in submitting a request and bypassed the normal mechanism, WebForm.submit and
           WebLink.click() did not return the changed page.
       11. Bug #618140 JavaScript access to the file submit control value was not working
    ServletUnit
       12. ServletUnit was not supporting mappings for the default servlet.
       13. ServletUnit now explicitly specifies its locale for generating dates as Locale.US to comply with RFC-1123


Additions:
    Content and parsing enhancements:
        1. WebForm now supports 'isReadOnlyParameter' and 'isDisabledParameter' which allow checking of the state of a
           particular form parameter. Note that if multiple controls exist with the same name, these methods only return
           true when all such controls are read-only or disabled, as appropriate.
        2. RFE #614397 <input> parameters with unrecognized type fields are now treated as text fields. This appears
           to match the behavior in most browsers.
        3. Links, forms, and images now have a readable title property.

    Web navigation enhancements:
        4. Following the "_blank" target now creates a new web window, with its own set of frames. Following links or submitting
           forms will update the window from which the request originated. Requests may also now be initiated from an open window.
           The list of open windows is a property of the web client.
        5. The mechanism for searching for tables has been expanded to permit arbitrary search criteria, similar to that
           for links.
        6. WebClient now supports a WebWindowListener which will be called when a new window is opened or closed.
        7. Added WebWindow.getOpenedWindow() to return a window by its name.
        8. You may now close a window by calling window.close(). This will trigger any active listeners. If the window closed
           the main window, another window will be promoted to that status.
        9. Added the HeadMethodWebRequest class to support HEAD method requests

    Security and state-management enhancements:
       10. The proxy server may now be specified by calling WebClient.setProxyServer. This should also ensure that the
           correct authorization header is sent.
       11. Cookies are now restricted by their origin server, rather than being sent on every request.
       12. A new package com.meterware.httpunit.cookies, now exists to support the cookie functionality.

    Scripting enhancements:
       13. The navigator object now supports the readable 'platform' property.
       14. The screen object is now supported, with properties availHeight and availWidth
       15. Added support for Location.replace()
       16. Added support for Window methods: open(), and close()
       17. Added support for Window properties: closed, frames, name, opener, top, parent, and <subframe-name>
       18. Added do-nothing stubs for the Window properties and functions: moveTo(), focus(), setTimeout()
       19. document.write and writeln are now supported for processing a page while it is being loaded. This only
           works if the default NekoHTML parser is being used.

    ServletUnit enhancements:
       20. RFE #585495 ServletUnit now supports HttpServletResponse.setContentLength.
       21. ServletUnit now implements HttpServletRequest.getLocale() and getLocales()

Version 1.4.6 released 2002-10-02

Acknowledgements:
    Thanks to Ville Skytt� for removing the test dependency on xerces.
    Thanks to Donald Ball for pointing out the problem with the behavior of Select.selectedIndex.
    Thanks to Jin Zhao for help in expanding the search possibilities for links.

Problems fixed:
    1. An attempt to set a non-existent parameter now correctly throws NoSuchParameterException rather
       than UnusedParameterValueException.
    2. Obtaining the URL from a javascript: request no longer throws MalformedURLException.
    3. Bug #604478 - setting the form action did not always update the predefined parameter list. This could cause a request
       to be sent with the wrong URL parameters.
    4. Form, Image, and Link names are now properly treated as case-sensitive within Javascript.
    5. A Javascript URL containing a question mark was incorrectly being URL-encoded.
    6. HTML comments at the start of a JavaScript were not being completely ignored
    7. Disabled form parameters were being submitted with requests and could be modified by setParameter calls.
    8. Bug #617065: using Javascript to set an option in a drop-down box does not unset other options.

Additions:
    Content and parsing enhancements:
       1. When no response is received from a server, HttpUnit will now throw HttpServerNotFoundException, which is a
          subclass of HttpNotFoundException. This should aid in diagnosing response failures.
       2. When a 404 (not found status) is received from a server, the accompanying message is now available
          from HttpNotFoundException.getResponseMessage().
       3. The mechanism for search for links has been expanded to permit arbitrary search criteria and to retrieve
          either the first match or all matches.
       4. Some per-client properties are now stored in a per-client object. Each new web client is initialized from the
          default, but may also be configured independently by retrieving the clientProperties object.

    Scripting enhancements:
       6. It is now possible to control the handling of script errors by calling HttpUnitOptions.setExceptionsThrownOnScriptError.
          If the exceptions are not thrown, the error messages will instead be available via HttpUnitOptions.getScriptErrorMessages()
       7. The forms, images, links, and Form.elements arrays now handle string indexes
       8. Select.selectedIndex is now read/write.
       9. Link.href is now read-write.
      10. The Navigator object is now supported.

Version 1.4.5 released 2002-08-30

Acknowledgements:
    Thanks to Steve Heath for an example on how to make JSPs work with ServletUnit.
    Thanks to Rajan Narasimhan for fixing the relative URL computation problem.
    Thanks to Sebastien Rosset for pointing out the case sensitivity problem with WebResponse.isHTML
    Thanks to Hans-Joerg Hessmann for a faster algorithm for the table lookups
    Thanks to Peter Royal for fixing the handling of query-only relative URLs and the IllegalStateException when
       scripting is disabled.
    Thanks to Michael Reardon for implementing the ServletUnit header method handling code and session.getAttributeNames
    Thanks to Geert Bevin for finding and fixing the ServletUnit POST parameters bug.
    Thanks to Geert Bevin for implementing ServletUnit support for HttpServletRequest.getParameterMap

Problems fixed:
    1. The "_parent" frame target should now be handled correctly.
    2. Relative URLs were not being computed properly when the base URL had a query string containing a slash.
    3. WebResponses are now recognized as HTML even if the content type is not lower case.
    4. A form request created after a call to getScriptableObject().setAction() now correctly uses the new action.
    5. Table lookups should be faster, especially for complex and large tables
    6. Embedded spaces in URLs are now encoded when a request is made
    7. Relative URLs beginning with "?" were not being handled properly.
    8. Disabling scripting result in IllegalStateException being thrown.
    9. Fixed handling of error statuses when information is still sent on input stream
   10. ServletUnit was not recognizing form parameters on a POST request which contained a query string in the URL.
   11. Submitting a request created with parameter validation disabled would send disabled parameters as well as enabled ones.
   12. WebRequest.getRequestParameterNames now returns only the names of the parameters that will be submitted with the request.

Additions:
    Content and parsing enhancements:
        1. The HttpUnitOption property 'acceptCookies' now controls whether cookies received from the server will be saved
           in a web client and sent on subsequent requests. The default is true.
        2. WebResponse and WebCell now support a new method, getImages, which returns an array of objects representing the
           image tags found.
        3. WebResponse now has a getImageWithName method
        4. WebForm.getButtons() now returns all form buttons, including reset buttons and generic buttons.
        5. WebResponse and TableCell now support getImageWithAltText to find an image with a specified value in its 'alt' attribute.
        6. WebForm supports getButtonWithID

    Web navigation enhancements:
        7. You may now follow a link by calling link.click() rather than client.getResponse( link.getRequest() ).
        8. You may now submit a form by calling form.submit() rather than client.getResponse( form.getRequest() ). In this
           case you must set any parameters directly into the form.
        9. You may now obtain the current page from a web client by calling client.getCurrentPage() rather than
           client.getFrameContents( "_top" );
       10. The SubmitButton class now supports a click() method to submit the form using that button.
       11. Reset buttons may now be clicked to reset the form

    ServletUnit enhancements:
       12. ServletContext.getRealPath is now supported.
       13. ServletUnit now supports JSPs. The JSP engine must be in the class path and identified by the
           HttpUnitOptions.scriptEngineClassName property (the default is Jasper). JSPs are expected to be in the current
           working directory unless a web.xml file is specified, in which case JSPs will be searched for in the application
           context directory.
       14. HttpServletResponse header methods: setHeader, addHeader, setIntHeader, addIntHeader,
           setDateHeader, and addDateHeader are now supported.
       15. HttpSession.getAttributeNames is now supported.
       16. HttpServletRequest.getParameterMap is now supported.

    Scripting enhancements:
       17. Much of JavaScript 1.1 is now supported. See <http://www.httpunit.org/doc/Javascript-support.html> for
           details.
       18. javascript: URLs are now supported.
       19. WebLink.mouseOver() will trigger the associated 'onMouseOver' event, if defined
       20. The JavaScript function Window.alert() adds messages to a queue. WebClient.getNextAlert() returns the next alert
           without affecting the queue. WebClient.popNextAlert() returns the next alert, removing it from the queue.
       21. WebClient.setDialogResponder() lets a user predefine responses to the JavaScript functions Window.confirm and
           Window.prompt. By default, these functions return true and the default value, respectively. A base class,
           DialogAdapter, provides default implementations of its methods.

    Extra Testing support:
       22. PseudoServer and associated classes are now publically available and in their own package, pseudoserver.

Notes:
   1. The class com.meterware.httpunit.ScriptableObject has been renamed as com.meterware.httpunit.scripting.ScriptableDelegate

Version 1.4.1 released 2002-06-20

Acknowledgements:
    Thanks to Stefan Renz for finding the file control value bug and providing a fix.
    Thanks to Frank Carver for extending base 64 encoding to handle character values > 127.
    Thanks to Yassen Damyanov for fixing a bug in the handling response headers
    Thanks to James Murty for adding caching of servlet instances and some XML parsing cleanup.
    Thanks to Robert Watkins for the content length test.
    Thanks to Jessica Sant for correcting the handling of error statuses in JDK 1.3.1-03

Problems fixed:
    1. Trying to get the value of a file parameter no longer results in a null pointer exception.
    2. Passwords with character values > 127 are now handled.
    3. Parameters were not being submitted for image buttons with no specified value
    4. Response headers were truncated to the first word only
    5. The servletunit tutorial failed with a NullPointerException in the first step.
    6. bug #570644: As of JDK 1.3.1-03, the behavior of HttpURLConnection was changed to throw an IOException when an
       error status is returned. This broke HttpUnit's handling of error codes. This has since been corrected.

Additions:
    Content and parsing additions
        1. HttpUnit now sends Accept-encoding: gzip unless disabled by a call to HttpUnitOptions.setAcceptGzip( false )
        2. It is now possible to set the action on a form using a mechanism which will support scripting in the future:
              form.getScriptableObject().setAction( newAction )
        3. It is now possible to set the value of a hidden field in a form using a mechanism which will support scripting
              in the future: form.getScriptableObject().setParameterValue( fieldName, newValue )
        4. A <select> control with a size attribute may now have its value undefined. The specification does not require
           this behavior, but both IE 5.5 and Netscape 6.2 do this.
        5. WebResponse.getForms now caches its result so that multiple calls will return the same set of objects.
        6. WebClient.sendRequest is now available as an alias for WebRequest.getResponse
        7. An IO exception is thrown if the content length does not match the actual received length for a response and
           content-length checking is enabled.

    ServletUnit enhancements
        8. ServletUnit now caches its servlet instances so that multiple invocations can use the same instance.  This more
           closely matches the servlet spec.
        9. Leading and trailing spaces in web.xml text nodes are now ignored.
       10. If no other mapping matches a servlet name in a URL, ServletUnit will try to treat it as a servlet class name.
           This means that you can use something like http://localhost/servlet/com.nowhere.MyServlet to access your servlet
           without explicitly registering it.
       11. ServletUnitHttpRequest now implements getInputStream and getContentType.
       12. ServletUnit now implements the HttpServletRequest.getServletPath and getPathInfo methods.

Notes:
    1. Hidden fields may not be modified through the setParameter call if parameter validation is enabled, since they
       cannot be modified through normal user interaction (in the absence of JavaScript). The getScriptableObject call
       provides a way around this.
    2. The version of JTidy included with this release is 4-Aug-2000-r7, which seems to have fewer problems with classloading;
       however, it is also described as a "less stable" pre-release.

Version 1.4. released 2002-03-06

Acknowledgements:
    Thanks to Didier Besset for correcting the WebForm methods: hasParameterNamed and hasParameterStartingWithPrefix
    Thanks to Stefan G. Renz for identifying the infinite loop bug in frame handling
    Thanks to Alex Chaffee for implementing context parameters for web.xml in ServletUnit
    Thanks to Jochen Hiller for supplying code to use jaxp to select a parser rather than being hardcoded to xerces
    Thanks to Oliver Imbusch for adding the WebClientListener behavior
    Thanks to Donald Ball for numerous additions to ServletUnit, including support for context paths, retrieval of
            the requestURI for a servlet request, and wild-card mapping of servlets.
    Thanks to Peter Royal for correcting handling of long line numbers in JTidyWriter, based on locale
    Thanks to Peter Rossbach for some documentation and build fixes


Problems fixed:
    1. hasParameterNamed and hasParameterStartingWithPrefix now check all types of parameters, not just <INPUT> fields
    2. (bug #492003) JTidyPrintWriter fails to parse columns
    3. Empty cookies were not being recognized.
    4. Parameters are now submitted in the order specified in the form, as long as parameter validation is not turned off.
    5. It is no longer permitted to change hidden parameters with parameter validation enabled.
    6. Subframes with the same names as others in the same tree no longer cause an infinite loop / stack overflow
    7. Link parameters are now sent in the proper order, as long as parameter validation is not turned off.
    8. Parameter validation is now done for requests built from links
    9. Control characters and spaces created by breaking HTML in the middle are now trimmed from link parameters.
   10. Forms with query strings included in the action attribute now are submitted with that string intact.
   11. (bug #490821) Javadoc generation no longer gives errors
   12. (bug #524627) Null pointer exception in NodeUtils.convertNBSP
   13. (bug #513051) Multiple headers with the same name are now handled independantly

Additions:
  Content and parsing enhancements:
      1. Disabled submit buttons are now detected, but requests cannot be made from them unless parameter validation is off.
      2. HttpUnit now handles multiple file form controls with the same name.
      3. WebResponse now has a getSubframeContents method which returns the contents of a subframe of the frame represented
         by the response.
      4. gzip-encoded responses are now handled

  ServletUnit enhancements
      5. ServletUnit now supports the web.xml <context-param> tag.
      6. ServletUnit now supports the HttpServletRequest.getRequestURI method
      7. ServletUnit now supports defining (and retrieving) a non-empty context path for a web application
      8. ServletUnit now supports wild-cards in web.xml servlet mapping
      9. ServletUnit now supports creating a RequestDispatcher from ServletContext to forward to other servlets.
         Support for this is rudimentary at present: query parameters on the request dispatcher create are ignored.

  Form manipulation enhancements:
     10. It is now possible to set values for a form directly into the WebForm object. All such changes will be validated.
         These will be used by any requests derived from the form.
     11. Parameters defined in form query strings are now included in the known parameters of a form and requests
         built from it.
     12. Form parameters can be reset to their initial values using WebForm.reset().
     13. You can now change the position of an image button click in a request with WebRequest.setImageButtonClickPosition()

  Test properties enhancements:
     14. You can now call HttpUnitOptions.setAutoRedirect( false ) to enable explicit testing of redirect requests.
     15. WebClient now has an exceptionsThrownOnErrorStatus property to control this behavior per client.

  Extensibility enhancements:
     16. HttpUnit can now use any jaxp-compliant parser, rather than just xerces.
     17. MessageBodyWebRequest's constructors and inner class are now public, allowing outside code to create new request classes.
     18. WebClient now exposes the protected method writeMessageBody to ease implementation of new subclasses
     19. WebClient can now accept a listener of type WebClientListener to report on each request sent and response received.

Notes:
    1. Parameter validation is now handled by the form. Requests created from the form while parameter validation is
       enabled will share the variable space of the form and therefore be validated. Requests created while validation
       is disabled will have their own variable space, which is initialized to that of the form.
    2. The decision as to whether a response will throw an exception if its status is 4xx or 5xx is now controlled by
       the exceptionsThrownOnErrorStatus property of WebClient and its subclasses (WebConversation, ServletUnitClient).
       This property is initialized from the HttpUnitOptions property of the same name when the WebClient object is
       created. This allows finer control over this behavior. Tests which depend on this setting should no longer
       interfere with one another.

Version 1.3.0 released 2001-11-28

Acknowledgements:
    Thanks to Oliver Imbusch for finding and fixing problems with parsing of encoded link parameter names and values and
        of link URLs with parameters and fragments.
    Thanks to Paul Frantz and Dave Glowacki for finding and fixing problems with parsing of link parameter names without values.
    Thanks to Didier Besset for new WebForm methods: hasParameterNamed and hasParameterStartingWithPrefix
    Thanks to Peter Robach for catching some typos in the tutorial.
    Thanks to Benoit Xhenseval for adding a mechanism to handle HTML parser errors.
    Thanks to Benoit Xhenseval for optimizing the use of DOMs and StringBuffers.
    Thanks to Bradley Smith for implementing getParameterNames in ServletUnit.

Problems fixed:
    1. Links with parameters whose names were encoded were being mis-parsed
    2. Links with empty parameter values were being mis-parsed
    3. Most references to TestCase.assert have been renamed to assertTrue in order to prepare for JDK 1.4 and JUnit 3.7
       compatibility. HttpUnitTest and ServletUnitTest implement assertTrue to continue support for JUnit 3.6 and earlier.
    4. ServletUnit was not decoding its request parameters and names
    5. ServletUnit's HttpRequest.getParameterNames method was not implemented
    7. WebSphere cookie values ending with "=" or "==" are now handled.
    8. HttpUnit should now be more tolerant of missing character encodings

Additions:
  Content and parsing enhancements
      1. It is now possible to check a WebForm for the presence of a named parameter.
      2. Disabled submit buttons may no longer be selected from a form
      3. When enabled, parameter validation now prevents changes to readonly controls.
      4. It is now possible to obtain the reason message associated with the status code, either from
         HttpException.getResponseMessageweb() or if exceptions are disabled, from WebResponse.getResponseMessage()
      5. HttpUnitOptions now has methods addHtmlErrorListener and removeHtmlErrorListener. If a listener is registered,
         it will be invoked for every error or warning generated by the parser, indicating the URL, line and column number
         of the error and a textual description of the problem.

  ServletUnit enhancements
      6. ServletUnit now compiles against Servlet 2.3
      7. ServletUnit now handles web.xml partially, supporting:
         a. mapping of exact paths to a servlet class
         b. protected URLs (exact paths only)
         c. Basic and Form authentication
         d. Servlet initialization parameters

   Documentation and Packaging
      8. There is now the beginnings of a tutorial, focused on ServletUnit but covering much of the HttpUnit API
         in doc/tutorial
      9. Archives are now rooted with the build name, following unix conventions

   Optimizations
     10. HttpUnit now pre-allocates StringBuffer instances to their most likely size
     11. DOMs are no longer copied when passed internally'
     12. ByteTag objects no longer allocate Hashtable unless required

Version 1.2.7 released 2001-10-25


Acknowledgements:
    Thanks to Chris Stevenson for identifying a problem with forms lacking an action
    Thanks to Drew Varner for more sophisticated cookie handling, including Set-Cookie2 code
    Thanks to David Karr for pointing out the problem with status code 3xx responses and
        suggesting a fix for it.
    Thanks to Dave Glowacki for the default content-type code.
    Thanks to Brett Neumeier for some Javadoc fixes and adding support for the non-standard "Charset" header
    Thanks to Richard Scothern for identiying the cause of problems with POST requests and older servlet engines.
    Thanks to Benoit Xhenseval for adding parameter detection in links, handling of meta and link tags,
        and selection of table cells by ID.
    Thanks to Mike Bracewell for noticing the incorrect loopback address in ServletUnitHttpRequest

Problems corrected:
    1. Forms with no action now default to the originating page
    2. cookies with embedded commas and quotes are now handled
    3. Status code 3xx responses no longer result in a null pointer exception when
       invoking getText or reading the input stream.
    4. The _self target now works for forms.
    5. Set-Cookie headers are now processed even on responses with 4xx and 5xx status
    6. WebForm.getOptionValues now returns the options in the order listed in the form for both selections and radio buttons.
    7. The refresh handling now recognizes requests with content syntax "<seconds>;<location>" or "<seconds>; URL=<location>"
    8. The http-equiv meta tag was incorrectly matched as "http_equiv"
    9. By default, POSTs included charset attributes which messed up some servlet engines
   10. WebRequest.isFileParameter is now functioning and public
   11. auto-redirect now handles relative URLs
   12. ServletUnit's HttpServletRequest implementation was returning "17.0.0.1" as the host address.

Additions:
    Content and parsing enhancements
        1. Added ID property to SubmitButton
        2. Added ID and name properties to WebLink
        3. May now search web responses for links by name or ID
        4. getParameter() and getParameterNames() now works for requests built from links with embedded parameters.
        5. Image map <area> tags are now recognized as links, whose text is equal to their 'alt' tag. This allows
           them to be retrieved using getLinkWith( altText ).
        6. Added getSubmitButtonWithID to WebForm
        7. Added getMethod and getAction to WebForm
        8. WebResponse.getMetaTagContent can be used to obtain the content of a meta tag (see the Javadoc)
        9. WebResponse.getStylesheet can be used to obtain the path to the stylesheet associated with a page.
       10. Added WebTable.getTableCellWithID

    Request submission enhancements:
       11. Added version of WebRequest.selectFile which allows clients to specify the file to upload using an input
           stream rather than an actual file.
       12. HttpUnitOptions now has a postIncludesCharset which can be set to true when working with newer servlet
           engines which can handle it (such as Tomcat 3.2 or later), and which may be important for internationalization.
       13. It is now possible to upload a file via a POST request not derived from a form. To do this, call
           PostMessageWebRequest.setMimeEncoded( true ) before calling selectFile.
       14. Requests may now have as many values for a text parameter name as the number of <INPUT> tags with that name.

    Response handling enhancements:
       15. It is now possible to see the response accompanying an error status by
           calling HttpUnitOptions.setExceptionsThrownOnErrorStatus( false ) before calling getResponse. This will
           prevent HttpUnit from throwing an exception in such cases. You can still check the status of the response by
           calling WebResponse.getStatusCode()
       16. Added getHeaderFieldNames to WebResponse
       17. The Set-Cookie2 header is now handled
       18. HttpUnitOptions.setDefaultContentType() lets you define a content-type to use when the web server does not
           supply a Content-Type header.
       19. Now recognizes a Charset header if no charset is specified in the Content-type header. There are some servers
           which send this non-standard header.

Version 1.2.6 released 2001-07-06

Acknowledgements:
    Thanks to Marcos Tarruella for adding a test case for the Base64 class

Additions:
    1. WebResponse.getRefreshRequest now returns a WebRequest object if a refresh URL
       was specified in the response header.
    2. WebResponse.getRefreshDelay specifies the delay found in the header, if any.
    3. HttpUnitOptions.setAutoRefresh controls whether the refresh URL is automatically followed.
    4. ServletUnit now supports HttpServletResponse.getOutputStream
    5. ServletUnit now supports <meta> tag parsing
    6. WebResponse.newResponse added to allow other libraries (such as Apache Cactus)
       to create WebResponse objects without using WebClient.

Problems corrected:
    1. The cookbook was missing parentheses for its constructors
    2. Updated the NearWords example to accomodate changes to the Merriam-Webster site

Version 1.2.5 released 2001-06-18

Acknowledgements:
    Thanks to Rolf Schmidiger for corrected behavior when failing to find a site
    Thanks to Tom Watkins, Deepa Dihr, Marcos Tarruella for their implementation of
       PutMethodWebRequest
    Thanks to Larry Hamel for writing the SSL FAQ

Additions:
    1. selectFile() now can infer file content type for the most common file extensions:
       text, txt, gif, jpg, jpeg, png, html, htm and zip.
    2. A new version of selectFile allows explicit specification of file content type
       which will override any inferred type.
    3. <button> tags are now recognized as submit buttons if their type is "submit"
       or not specified.
    4. Reading the character set from a <meta> tag is now supported.
    5. Added PutMethodWebRequest
    6. PostMethodWebRequest now has a constructor which allows its contents to be
       taken from an InputSource, like PutMethodWebRequest
    7. Added ServletUnitClient and InvocationContext to servletunit to
       permit more granular testing of servlets (still not well documented)
    8. Added getInputStream method in WebResponse to support non-text responses.
    9. Matching of text in web pages is now controlled by the HttpUnitOption property
       'matchesIgnoreCase'. The default behavior is as before - matches are not case sensitive

Problems corrected:
    1. Now throws HttpNotFoundException rather than NullPointerException when
       unable to connect to a web site
    2. I/O exceptions when accessing a site are now thrown, rather than being
       turned into RuntimeException.

Configuration changes:
    1. The build.xml file has been changed to use a specified directory of dependant jars
       rather than the system classpath. This requires at least ant 1.3. It is no longer
       necessary to specify the classpath parameter when running the unit tests.

Version 1.2.4 released 2001-05-05

Acknowledgements:
    Thanks to Jim Kimball for finding and fixing the redirection of subframes

Problems corrected:
    1. Redirection with subframes was incorrectly targeted at the top frame.
    2. No longer capitalizes all header names; this was necessary for
       compatibility with those servers that do not understand case-insensitive
       header names.
    3. Repeated requests to the same URL were not resending requests properly.
       This caused some problems with validation.
    4. Now correctly passes the full specification of uploaded files, rather than just the name.

Additions:
    1. Transmitted headers as well as received headers are now shown when loggingHttpHeaders
       is enabled.
    2. The GetMethodWebRequest and PostMethodWebRequest constructors which accept a target
       are now public.
    3. Added getID to WebForm
    4. Added getFormWithID to HTMLSegment interface

Version 1.2.3 released 2001-04-02

Acknowledgements:
    Thanks to Silvio Samadelli for improved cookie-recognition logic

Problems corrected:
    1. Under JDK 1.3, error headers would sometimes cause a FileNotFoundException
    2. Cookies containing '=' or wrapped in quotes are now recognized
    3. The JavaDoc now correctly shows the public methods in TableCell used for handling nested tables.
    4. The XML retrieval test is no longer run when Xerces is not in the classpath, rather than giving an error.
    5. File upload capability no longer depends on JavaMail and JAF, although its test does
    6. Non-conforming authentication headers are now assumed to be requesting Basic authentication

Additions:
    1. The Referer header is now sent for requests derived from links and forms.

Version 1.2.2 released 2001-01-08

Acknowledgements:
    Thanks to Rocky Rhodes for finding the multiple cookie bug
    Thanks to Scott Croco for correcting the response code problem
    Thanks to Ken MacLeod for finding the UTF-8 bug.

Additions:
    1. Initial implementation of file upload capability

Problems corrected:
    1. Multiple cookies were not being sent correctly
    2. When a response was received with a bad response code, it was treated either as a RuntimeException
       or a file not found exception.
    3. Creating a request from a form with an empty <select> tag was generating a SingleValuedParameterException.
    4. Corrected IllegalArgumentException: sun.io.CharToByteUTF-8 that happened in JDK 1.1.x

Version 1.2.1 released 2001-01-01

Acknowledgements:
    Thanks to Toyoshi Ushio for helping with the handling of non-English scripts and for translating the home page and cookbook into Japanese.

Problems corrected:
    1. Content-type charset attribute is now recognized, allowing for the proper handling of non-ascii html pages.
    2. Form submissions now use the page character set encoding.
    3. Old format cookie headers (with the expires=attribute) are now recognized.

Additions:
    1. Introductory ServletUnit functionality (parameters and sessions, but no JSP, no forwarding)
    2. Added getTableWithID method to WebResponse, ParsedHTML
    3. Added HttpUnitOptions.setDefaultCharacterSet to handle missing content charset headers, so as not to assume default encoding (iso-8859-1).
    4. WebConversation now has a new public base class: WebClient
    5. Any message header may now be defined, using: WebClient.setHeaderField and will be sent on all subsequent requests
    6. Forms may now be retrieved by their name attributes, using WebResponse.getFormWithName()

Version 1.2 released 2000-11-16

Acknowledgements:
    Thanks to Robert Krueger for providing an interface to the xerces parser for XML web responses.
    Thanks to Marco Tamanti and Gabriele Antonelli for suggesting ways to support file URLs

Problems corrected:
    1. Unnamed parameters are no longer submitted as part of a form request
    2. Searching for tables beginning with a string no longer aborts with NullPointerException if the table is missing cells
    3. A problem which caused WebResponse.java to fail compilation under JDK 1.1 has been corrected

Additions:
    1. Forms with multiple buttons are now supported, using the SubmitButton class.
    2. WebResponse now supports finding a table via its summary text, using getTableWithSummary().
    3. XML parsing is now supported. If WebResponse.getDOM is called for a non-HTML response (content type is not "text/html"),
       the xerces parser will be invoked to treat the response as XML.
    4. File URLs (file:xxx) are now supported

Version 1.1 released 2000-10-17

Acknowledgements:
    Thanks to Seth Ladd for specific exceptions from WebConversation.getResponse
    Thanks to Dave Glowacki for suggestions on convenience methods in WebResponse and WebLink,
                            and for correcting the set up of the https protocol handling.
    Thanks to Perry Doell for the methods to examine cookies on WebConversation
    Thanks to Ken Hygh for the proper handling of parameters with no specified type
    Thanks to Gabriel Hauser for finding a bug in the handling of parameter defaults

Problems corrected:
    1. The value parameter for checkboxes is no longer ignored
    2. Previously, getTableStartingWith[Prefix] only checked the nested tables in cell (0,0) of each outer table
    3. Parameters with no type specified are now properly handled as text
    4. Base tag is now handled to override defaults for page URL and target
    5. Empty parameter values are now handled

Additions:
    1. The license agreement is now available from the home page and javadoc
    2. Https support is now built in; however, it depends on the JSSE extension (not included).
       See http://java.sun.com/products/jsse.
    3. Frames are now supported. The WebConversation method has two methods: getFrameNames and getFrameContents which
       allow manipulation of frames.
    4. By default, WebRequest.setParameter will now throw IllegalRequestParameterException on any attempt
       to set a form parameter to a value not normally available from the browser.
    5. It is possible to modify the behavior of HttpUnit via static methods on HttpUnitOptions. This includes:
       o enabling parser warnings (disabled by default)
       o disabling parameter validation (enabled by default)
    6. WebConversation.getResponse now throws HttpException if any 4xx or 5xx code is returned. The exact code is
       available from the exception
    7. WebResponse.getTitle() returns the HTML title of the page
    8. WebLink.getURLString() returns the URL string specified by the link in its href attribute
    9. WebResponse.getURL() return the URL used to retrieve the page
   10. WebConversation now supports getCookieNames and getCookieValue to return the current cookies
   11. The WebResponse now can return the response code associated with it (2xx)
   12. Non-breaking spaces are converted to spaces on any conversion to text

Version 1.0 released 2000-09-01

Acknowledgements:
Thanks to Jan Ohrstrom for his additions to WebConversation

Problems corrected:
    1. Parsing a response would crash if there were no nodes inside a form
Additions:
    1. WebResponse.getOptions and getOptionValues now return the displayed and parameter value options
       available to the user in a <select>
    2. WebRespose.getLinkWith() and .getLinkWithImageText() can now be used to locate a link in a page
       based on its text or the ALT text attribute of an enclosed image
    3. WebConversation.setUserAgent allows httpunit to pretend to be a particular browser
    4. WebConversation.addCookie allows the test to include additional cookies for the servlets to respond to.
    5. WebLink.asText returns the text value of a link
    6. WebConversation now throws AuthorizationRequiredException when the web server rejects a request
       because of authorization problems.
    7. WebConversation now supports basic authentication via the setAuthorization method.

Version 0.9.5 released 2000-08-04

General:
    1. Nested tables are now supported (examples to follow) by using WebTable.getTableCell
    2. table columns and rows used only for formatting may now be ignored using WebTable.purgeEmptyCells
    3. It is now easy to find a table in a page based on the text in its first non-blank column and row,
       using WebResponse.getTableStartingWith
    4. All form controls should now be supported
    5. There is a preliminary cookbook available
Additions:
    1. Deprecated WebTable.getCell, new method is getCellAsText
    2. Added WebTable.getTableCell to return a cell which could contain nested tables or just a DOM to examine
    3. Added WebTable.asText to return a 2D representation of the table
    4. Added WebTable.purgeEmptyCells to eliminate meaningless spacing information
    5. Added copyright notices to most source files
    6. Added support for checkboxes, radio buttons, text areas, and selects

Version 0.9.1 released 2000-06-29

Additions:
    1. The PostMethodWebRequest class is now public.
    2. Row and column spans are now handled
    3. Formatting inside table cells is ignored in computing the text value of a cell

Version 0.9 released 2000-06-19

Additions:
    1. The parser may be tested during the build by issuing the command: 'ant test -Dclasspath="%classpath%"'

    2. WebResponse now can return an array of the top-level tables in the HTML response.
       Each table may now be asked for its size and the contents of each of its cells.

Version 0.8.2 released 2000-06-05

Additions:
    WebResponse now has a getDOM method which permits examination of the DOM equivalent of the response.

Version 0.8.1 released 2000-06-01

Problems corrected:
    Default parameter values are ignored
    Parameter values without explicit types were being ignored, rather than defaulting to TEXT
Additions:
    ExampleTest now demonstrates the use of httpunit and JUnit to test servlets
    NearWords demonstrates the use of httpunit to access web site functionality

Version 0.8 released 2000-05-03

Initial public release
httpunit-1.7+dfsg/doc/sslfaq.html0000644000175000017500000001212011014557542017041 0ustar twernertwerner

Using SSL with httpunit FAQ

Where can I get information on SSL?

from Sun on SSL
from Thawte, a certificate vendor
from the JSSE part of Sun's site

What are some tools for creating and modifying certificates?

openssl which is also described at pseudonym.org
keytool for java  

How do I create a certificate?

Create a self-signed cert via openssl, given an existing key and openssl config file:

    openssl req -new -out output.pem -key my_key.pem -days 9999 -x509 -config openssl.cnf

There's also a way to do this with the java "keytool" application.
 

How can I make my certificate trusted by the JVM?


If you purchased your SSL certificate from Verisign or Thawte, then it should be automatically trusted by the "trust file" within the JVM (Sun seems to ship JVMs with certs from these two suppliers).  If you created your own certificate, you'll need to import that cert into cacerts.

How can I import my existing certificate into the "trust file" for a JVM?


1.  Find the trusted file "cacerts" in your JRE, e.g.
    find /java_install -name "cacerts"

2. Copy that file to a backup
    cp cacerts cacerts.bak

3. Install your certificate into the trust file (note: the file cacerts ships from Sun with password "changeit")
    keytool -import -alias <mycompany> -file mycert.pem -keystore $JAVA_HOME/jre/lib/security/cacerts

4. Verify that your cert was imported:
    keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts

How can I use SSL in httpunit?

1. You need an SSL certificate intalled into the web server to be tested. That certificate must be trusted by the JVM of the test rig (httpunit). That certificate must have, as its Common Name, the exact domain name of the web server you want to secure (e.g. "www.foo.com" or "secure.foo.com". I have not had luck with certs like *.foo.com.)

2.  You must enable SSL support (i.e., support for URLs that start with "https") in your test rig's JVM. Some environments like Weblogic offer native SSL support, which is fast compared to pure java.  For Weblogic, set the property weblogic.security.ssl.enable=true in the config file and just start using URLs like "https://myhost".  Also, there is at least one free SSL implementation in java.
 

How can I use a free SSL implementation?

There is a free SSL implementation available in pure java from Sun , although it is relatively slow, especially in its creation of the random key to start an SSL connection (about 3 seconds on a 600Mz PIII).  To use this implementation, download the JSSE package from the Sun URL above, then:

1. Add the three key jars to your JVM's "ext" (extentions) directory; e.g.
    cp jcert.jar jnet.jar jsse.jar $JAVA_HOME/jre/lib/ext/

2. After the jars are in place, you must modify the file "java.security" to allow usage of the providers found within the jars. Find the file
   find $JAVA_HOME -name "java.security"

3.  Add the following line to the file java.security:
    security.provider.2=com.sun.net.ssl.internal.ssl.Provider

Then start using URLs like "https://myhost" within the test rig.  The HTTPS protocol will automatically cause new provider classes within the extention jars to be employed for a java.net.URL class and its related connections. Note that you should NOT add these jars to the CLASSPATH.  Javax jars are accessed by the JVM by their inclusion in the magic "ext" folder.
 

How do I solve a javax.net.ssl.SSLException: untrusted server cert chain?


See how to make your certificate trusted.
 


Compiled 12 Mar 2001 by larry hamel.  Please post corrections/comments to the httpunit discussion list. httpunit-1.7+dfsg/doc/todo.txt0000644000175000017500000000126411014557540016375 0ustar twernertwernerHigh priority: o Better JavaScript error reporting: use custom object rather than NOT_FOUND (verify evaluate to false...) o Writeable 'name' Javascript attribute o NoOp request when link is to same page w/o new parameters? o Disable content-type header in MIME encoding? Medium priority: o Support optional tags which hide their contents (as in OBJECT, etc.) o Check conformance with RFC 2109/2965 - not currently sending $Version=1 string o Documentation, Documentation Possibles: o Enable client code to write directly to the output stream of a message body request o Provide customization for table to text Low priority: o history on web window o Support digest HTTP Authentication httpunit-1.7+dfsg/examples/0000755000175000017500000000000011014557542015737 5ustar twernertwernerhttpunit-1.7+dfsg/examples/BrowserDisplayer.java0000644000175000017500000001166311014557542022111 0ustar twernertwernerimport com.meterware.httpunit.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; /** * This example is from http://m0smith.freeshell.org/blog-portletunit/2008/05/bare-bones-browser-launch-for-java-use * @author Matthew O. Smith * */ public class BrowserDisplayer { /** * Show the response in a browser. * * @param response * the response * @throws Exception * on error */ public static void showResponseInBrowser(WebResponse response) throws Exception { String text = response.getText(); File f = File.createTempFile("httpUnit", ".html"); f.deleteOnExit(); PrintWriter fod = new PrintWriter(new FileOutputStream(f)); fod.print(" "); fod.print(text); fod.close(); URL url = f.toURL(); openURL(url); } /** * Bare Bones Browser Launch Version 1.5 (December 10, 2005) By Dem * Pilafian. Supports: Mac OS X, GNU/Linux, Unix, Windows XP * * Example Usage: String url = "http://www.centerkey.com/"; * BareBonesBrowserLaunch.openURL(url); Public Domain Software -- Free to * Use as You Like * * @param url * the url to open * @throws ClassNotFoundException * getting class * @throws NoSuchMethodException * yes * @throws SecurityException * well * @throws InvocationTargetException * trying to invloke * @throws IllegalAccessException * trying to access * @throws IllegalArgumentException * bad arguement * @throws IOException * opening window * @throws InterruptedException waiting */ public static void openURL(URL url) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, IOException, InterruptedException { String osName = System.getProperty("os.name"); if (osName.startsWith("Mac OS")) { Class fileMgr = Class.forName("com.apple.eio.FileManager"); Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] {String.class }); openURL.invoke(null, new Object[] {url.toString() }); } else if (osName.startsWith("Windows")) { String cmdLine = "rundll32 url.dll,FileProtocolHandler " + url.toString(); Process exec = Runtime.getRuntime().exec(cmdLine); exec.waitFor(); } else { // assume Unix or Linux String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" }; String browser = null; for (int count = 0; count < browsers.length && browser == null; count++) { if (Runtime.getRuntime().exec(new String[] {"which", browsers[count] }).waitFor() == 0) { browser = browsers[count]; } } if (browser == null) { throw new IllegalStateException("Could not find web browser"); } else { Runtime.getRuntime().exec(new String[] {browser, url.toString() }); } } } /** * open a given url indirectly * @param params */ public static void main( String[] params ) { try { if (params.length < 1) { System.out.println( "Usage: java BrowserDisplay [url]" ); System.out.println( ""); System.out.println( "will demonstrate usage with the url 'http://www.meterware.com' now ..."); String[] defaultParams={"http://www.meterware.com"}; params=defaultParams; } // direct call first String url=params[0]; openURL(new URL(url)); // and now indirectly // create the conversation object which will maintain state for us WebConversation wc = new WebConversation(); // Obtain the main page on the meterware web site WebRequest request = new GetMethodWebRequest( url ); WebResponse response = wc.getResponse( request ); showResponseInBrowser(response); // find the link which contains the string "HttpUnit" and click it WebLink httpunitLink = response.getFirstMatchingLink( WebLink.MATCH_CONTAINED_TEXT, "HttpUnit" ); response = httpunitLink.click(); showResponseInBrowser(response); System.out.println("Your browser should show three pages now:"); System.out.println("1. a direct invocation of "+url); System.out.println("2. an indirect invocation of "+url+" via httpunit"); System.out.println("3. the result httpunit clicking the httpunit link on 2."); } catch (Exception e) { System.err.println( "Exception: " + e ); } } } httpunit-1.7+dfsg/examples/Example.java0000644000175000017500000000212211014557540020170 0ustar twernertwerner/** everything you need to start is in the com.meterware.httpunit package **/ import com.meterware.httpunit.*; /** This is a simple example of using HttpUnit to read and understand web pages. **/ public class Example { public static void main( String[] params ) { try { // create the conversation object which will maintain state for us WebConversation wc = new WebConversation(); // Obtain the main page on the meterware web site String url="http://www.meterware.com"; WebRequest request = new GetMethodWebRequest( url ); WebResponse response = wc.getResponse( request ); // find the link which contains the string "HttpUnit" and click it WebLink httpunitLink = response.getFirstMatchingLink( WebLink.MATCH_CONTAINED_TEXT, "HttpUnit" ); response = httpunitLink.click(); // print out the number of links on the HttpUnit main page System.out.println( "The HttpUnit main page '"+url+"' contains " + response.getLinks().length + " links" ); } catch (Exception e) { System.err.println( "Exception: " + e ); } } } httpunit-1.7+dfsg/examples/ExampleTest.java0000644000175000017500000000643111014557540021037 0ustar twernertwernerimport com.meterware.httpunit.*; import junit.framework.*; /** * An example of testing servlets using httpunit and JUnit. **/ public class ExampleTest extends TestCase { /** * run this testcase as a suite from the command line * @param args - ignored */ public static void main(String args[]) { junit.textui.TestRunner.run( suite() ); } /** * supply this test cases as part of a suite * @return */ public static Test suite() { return new TestSuite( ExampleTest.class ); } /** * constructor with name parameter needed for suite creation * @param name */ public ExampleTest( String name ) { super( name ); } /** * try getting a response for the given Conversation and Request * show an error message if a 404 error appears * @param conversation - the conversation to use * @param request * @return the response * @throws an Exception if getting the response fails */ public WebResponse tryGetResponse(WebConversation conversation,WebRequest request) throws Exception { WebResponse response=null; try { response = conversation.getResponse( request ); } catch (HttpNotFoundException nfe) { System.err.println("The URL '"+request.getURL()+"' is not active any more"); throw nfe; } return response; } /** * Verifies that the welcome page has exactly one form, with the single parameter, "name" **/ public void testWelcomePage() throws Exception { WebConversation conversation = new WebConversation(); WebRequest request = new GetMethodWebRequest( "http://www.meterware.com/servlet/TopSecret" ); WebResponse response = tryGetResponse(conversation, request ); WebForm forms[] = response.getForms(); assertEquals( 1, forms.length ); assertEquals( 1, forms[0].getParameterNames().length ); assertEquals( "name", forms[0].getParameterNames()[0] ); } /** * Verifies that submitting the login form without entering a name results in a page * containing the text "Login failed" **/ public void testBadLogin() throws Exception { WebConversation conversation = new WebConversation(); WebRequest request = new GetMethodWebRequest( "http://www.meterware.com/servlet/TopSecret" ); WebResponse response = tryGetResponse(conversation, request ); WebForm loginForm = response.getForms()[0]; request = loginForm.getRequest(); response = conversation.getResponse( request ); assertTrue( "Login not rejected", response.getText().indexOf( "Login failed" ) != -1 ); } /** * Verifies that submitting the login form with the name "master" results * in a page containing the text "Top Secret" **/ public void testGoodLogin() throws Exception { WebConversation conversation = new WebConversation(); WebRequest request = new GetMethodWebRequest( "http://www.meterware.com/servlet/TopSecret" ); WebResponse response = tryGetResponse(conversation, request ); WebForm loginForm = response.getForms()[0]; request = loginForm.getRequest(); request.setParameter( "name", "master" ); response = conversation.getResponse( request ); assertTrue( "Login not accepted", response.getText().indexOf( "You made it!" ) != -1 ); assertEquals( "Page title", "Top Secret", response.getTitle() ); } } httpunit-1.7+dfsg/examples/GoogleMapsExample.java0000644000175000017500000003014011014557542022151 0ustar twernertwerner/******************************************************************************************************************** * $Id: Cookie.java 859 2008-03-31 10:17:30Z wolfgang_fahl $ * * Copyright (c) 2008, Wolfgang Fahl, BITPlan GmbH (http://www.bitplan.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.StringReader; import java.io.Writer; import java.text.NumberFormat; import java.util.StringTokenizer; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.xml.serialize.DOMSerializer; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import com.meterware.httpunit.*; /** * get a Route from Google Maps and convert it as a GPX file * useable by Garmin tracking devices - can be imported in MapSource software then ... * */ public class GoogleMapsExample { /** * shall we show debug information? */ private boolean DEBUG=true; /** * get a Route description as a Garmin compatible GPX file * @param startPoint * @param destPoint */ public void getRouteAsGPX(String startPoint,String destPoint, String filename,boolean withDisplay) throws Exception { String kml=getRouteFromGoogleMaps(startPoint,destPoint,withDisplay,false); if (DEBUG) { System.out.println(kml); } // http://wiki.openstreetmap.org/index.php/JOSM // here is a so called open source kml to gpx converter // http://www.fish-track.com/?page_id=3 Document gpxdoc=convertKMLtoGPX(kml); // output the result xmlSerialize(gpxdoc,filename); } /** * create the xml output for the given document * @param document * @param filename * @throws Exception */ public void xmlSerialize(Document document,String filename) throws Exception { OutputFormat outputOptions = new OutputFormat(); // outputOptions.setOmitXMLDeclaration(true); outputOptions.setIndent( 4 ); outputOptions.setMethod( "xml" ); //if (System.getProperty("os.name").startsWith("Windows")) { outputOptions.setEncoding("ISO-8859-1"); Writer writer = new BufferedWriter(new FileWriter(new File(filename))); DOMSerializer serializer = new XMLSerializer( writer,outputOptions ); serializer.serialize( document ); writer.close(); } /** * get the subnode with the given tagname * @param parent * @param tagName * @return */ public Element getSubNode(Element parent,String tagName, boolean throwException) { NodeList subNodes=parent.getElementsByTagName(tagName); if (subNodes.getLength()!=1) { if (throwException) throw new RuntimeException("getSubNode failed for "+parent+" expected 1 child with tag name '"+tagName+"' but got "+subNodes.getLength()); else return null; } return (Element)subNodes.item(0); } /** * get the latitude and longitude from a route point * @param kmlRoutePoint * @return */ public String[] extractCoordinates(Element kmlRoutePoint) { String[] result=new String[2]; Element point=getSubNode(kmlRoutePoint,"Point",false); if (point==null) return null; Element coordNode=getSubNode(point,"coordinates",true); String coords=coordNode.getTextContent(); StringTokenizer coordSplitter=new StringTokenizer(coords,",",false); if (coordSplitter.countTokens()<=2) { throw new RuntimeException("extract coordinates failed for "+kmlRoutePoint+" expected at least two coordinates but got "+coordSplitter.countTokens()+" '"+coords+"'"); } result[0]=coordSplitter.nextToken(); result[1]=coordSplitter.nextToken(); return result; } /** * convert the given kml file to gpx format * @param kml - the kml version of the file * @return */ public Document convertKMLtoGPX(String kml) throws Exception { DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); DocumentBuilder builder= factory.newDocumentBuilder(); Document kmldoc = builder.parse(new InputSource(new StringReader(kml)) ); Document gpxdoc = builder.newDocument(); String comment="Converted by httpunit GoogleMapsExample"; gpxdoc.appendChild(gpxdoc.createComment(comment)); org.w3c.dom.Element root = gpxdoc.createElement("gpx"); root.setAttribute("xmlns", "http://www.topografix.com/GPX/1/1"); root.setAttribute("creator","KML2GPX Example by BITPlan"); root.setAttribute("version","1.1"); gpxdoc.appendChild(root); org.w3c.dom.Element metadata = gpxdoc.createElement("metadata"); org.w3c.dom.Element metadatalink = gpxdoc.createElement("link"); metadatalink.setAttribute("href","http://www.bitplan.com"); metadata.appendChild(metadatalink); org.w3c.dom.Element metadatatext = gpxdoc.createElement("text"); metadatatext.setTextContent("BITPlan GmbH, Willich, Germany"); metadatalink.appendChild(metadatatext); root.appendChild(metadata); org.w3c.dom.Element route = gpxdoc.createElement("rte"); root.appendChild(route); NodeList routePoints=kmldoc.getElementsByTagName("Placemark"); for (int i=0;i0) { String driveString=route.substring(drivePos); int unitPos=driveString.indexOf(unitLocale[i]); if (unitPos>0) { String distanceString=driveString.substring(1, unitPos+unitLocale[i].length()); int divPos; while ((divPos=distanceString.indexOf("

"))>0) { distanceString=distanceString.substring(divPos+5); } distanceString=distanceString.replace(" "," "); return distanceString; } } } return "?"; } /** * Start the Route as GPX converter with the given command line parameters * display usage with and example if no parameters are given * @param params */ public static void main( String[] params ) { try { if (params.length < 3) { System.out.println( "Usage: java RouteAsGPX [from] [to] ([filename]|'distance') [nodisplay]" ); System.out.println( " e.g. java RouteAsGPX sfo 94526 sfoexample.gpx"); System.out.println( " to get the route as a Garmin compatible GPX file"); System.out.println( " e.g. java RouteAsGPX sfo 94526 distance"); System.out.println( " to calculate the distance"); String[] defaultParams={"sfo","94526","distance"}; // defaultParams={"sfo","94526","sfoexample.gpx"}; params=defaultParams; System.out.println( "will demonstrate usage with the route "+defaultParams[0]+" - "+defaultParams[1]+" and store to "+defaultParams[2]); } GoogleMapsExample routeAsGPX=new GoogleMapsExample(); boolean withDisplay=true; if (params.length>=4) withDisplay=false; String startPoint=params[0]; String endPoint =params[1]; String filename =params[2]; if (filename.equals("distance")) { String distanceS=routeAsGPX.getDistance(startPoint, endPoint, withDisplay); // String distanceS=NumberFormat.getInstance().format(distance); System.out.println("The distance between "+startPoint+" and "+endPoint+" is "+distanceS); } else { routeAsGPX.getRouteAsGPX(startPoint, endPoint, filename,withDisplay); } } catch (Exception e) { System.err.println( "Exception: " + e ); e.printStackTrace(); } } } httpunit-1.7+dfsg/examples/NearWords.java0000644000175000017500000000630511014557540020510 0ustar twernertwernerimport com.meterware.httpunit.*; import java.io.*; import org.w3c.dom.*; import org.xml.sax.SAXException; /** * This class demonstrates using httpunit to use the functionality of a web set from a command * line. To use it, specify a single word with one or more characters replaced by '?'. The * program will use the Merriam-Webster web site to find all words which match the pattern. * * Note: this program is not robust, but should work is used properly. **/ public class NearWords { public static void main( String[] params ) { try { if (params.length < 1) { System.out.println( "Usage: java NearWords [pattern]" ); System.out.println( "where [pattern] may contain '?' to match any character" ); System.out.println( ""); System.out.println( "will demonstrate usage with the pattern 'test' now ..."); String[] defaultParams={"test"}; params=defaultParams; } WordSeeker seeker = new WordSeeker(); PrintStream err = new PrintStream( new FileOutputStream( "null.txt" ) ); System.setErr( err ); String[] words = seeker.getWordsMatching( params[0] ); for (int i=0; i < words.length; i++) { System.out.println( (i+1) + ". " + words[i] ); } } catch (Exception e) { System.err.println( "Exception: " + e ); } } } /** * subclass to seek words from the Merriam-Webster Online search * as of 2008-05-02 * */ class WordSeeker { public WordSeeker() { try { HttpUnitOptions.setScriptingEnabled(false); String url="http://www.m-w.com/"; System.out.println("visiting "+url); WebRequest request = new GetMethodWebRequest( url ); response = conversation.getResponse( request ); } catch (Exception e) { throw new RuntimeException( "Error retrieving form: " + e ); } } public String[] getWordsMatching( String pattern ) throws SAXException, IOException, java.net.MalformedURLException { System.out.println("getting Words matching '"+pattern+"'"); WebForm lookupForm = response.getFormWithID("search_form"); WebRequest request = lookupForm.getRequest(); request.setParameter( "va", pattern ); request.setParameter( "book", "Dictionary" ); response = conversation.getResponse( request ); return getOptionsFromResponse(); } private WebConversation conversation = new WebConversation(); private WebResponse response; private String[] getOptionsFromResponse() throws SAXException { String[] words; WebForm[] forms = response.getForms(); for (int i=0; i < forms.length; i++) { Element form = (Element) forms[i].getDOMSubtree(); NodeList nl = form.getElementsByTagName( "option" ); if (nl.getLength() == 0) continue; words = new String[ nl.getLength() ]; for (int j = 0; j < nl.getLength(); j++) { words[j] = nl.item(j).getFirstChild().getNodeValue(); } return words; } return new String[0]; } } httpunit-1.7+dfsg/examples/ProxySample.java0000644000175000017500000000414111014557542021065 0ustar twernertwerner/******************************************************************************************************************** * $Id: ProxySample.java 410 2002-11-08 02:18:54Z russgold $ * * Copyright (c) 2002, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.WebConversation; import junit.framework.TestCase; import junit.framework.TestSuite; /** * * @author Russell Gold **/ public class ProxySample extends TestCase { public static void main(String args[]) { junit.textui.TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( ProxySample.class ); } public ProxySample( String name ) { super( name ); } public void testProxyAccess() throws Exception { WebConversation wc = new WebConversation(); wc.setProxyServer( "www-proxy.us.oracle.com", 80 ); wc.getResponse( "http://www.meterware.com" ); } } httpunit-1.7+dfsg/jars/0000755000175000017500000000000011162002061015041 5ustar twernertwernerhttpunit-1.7+dfsg/lib/0000755000175000017500000000000011162002061014650 5ustar twernertwernerhttpunit-1.7+dfsg/src/0000755000175000017500000000000011014557540014706 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/0000755000175000017500000000000011014557540015464 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/0000755000175000017500000000000011014557540017457 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/0000755000175000017500000000000011014557542021340 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/controls/0000755000175000017500000000000011014557542023203 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/controls/IllegalParameterValueException.java0000644000175000017500000000702711014557542032142 0ustar twernertwernerpackage com.meterware.httpunit.controls; /******************************************************************************************************************** * $Id: IllegalParameterValueException.java 910 2008-04-06 06:30:11Z wolfgang_fahl $ * * Copyright (c) 2001-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.util.List; import com.meterware.httpunit.HttpUnitUtils; import com.meterware.httpunit.IllegalRequestParameterException; //============================= exception class IllegalParameterValueException ====================================== /** * This exception is thrown on an attempt to set a parameter to a value not permitted to it by the form. **/ public class IllegalParameterValueException extends IllegalRequestParameterException { /** * construct an IllegalParameterValueException * @param parameterName - the name of the parameter * @param badValue - the bad value that is not allowed * @param allowed - the list of allowed values */ public IllegalParameterValueException( String parameterName, String badValue, String[] allowed ) { _parameterName = parameterName; _badValue = badValue; _allowedValues = allowed; } /** * get the bad value from a list of Values * @param values * @return */ protected static String getBadValue(List values) { String result="unknown bad value"; if (values.size()>0) { Object badValue=values.get(0); result=badValue.toString(); } return result; } /** * * @param parameterName * @param values * @param allowed */ public IllegalParameterValueException( String parameterName, List values, String[] allowed ) { this(parameterName,getBadValue(values),allowed); } public String getMessage() { StringBuffer sb = new StringBuffer(HttpUnitUtils.DEFAULT_TEXT_BUFFER_SIZE); sb.append( "May not set parameter '" ).append( _parameterName ).append( "' to '" ); sb.append( _badValue ).append( "'. Value must be one of: { " ); for (int i = 0; i < _allowedValues.length; i++) { if (i != 0) sb.append( ", " ); sb.append( "'"+ _allowedValues[i] +"'" ); } sb.append( " }" ); return sb.toString(); } private String _parameterName; private String _badValue; private String[] _allowedValues; } httpunit-1.7+dfsg/src/com/meterware/httpunit/controls/SelectionFormControl.java0000644000175000017500000004376711014557540030177 0ustar twernertwernerpackage com.meterware.httpunit.controls; /******************************************************************************************************************** * $Id: SelectionFormControl.java 975 2008-05-16 19:44:48Z russgold $ * * Copyright (c) 2001-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.io.IOException; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.meterware.httpunit.FormControl; import com.meterware.httpunit.NodeUtils; import com.meterware.httpunit.WebForm; import com.meterware.httpunit.dom.HTMLSelectElementImpl; import com.meterware.httpunit.protocol.ParameterProcessor; import com.meterware.httpunit.scripting.ScriptableDelegate; import com.meterware.httpunit.scripting.SelectionOption; import com.meterware.httpunit.scripting.SelectionOptions; /** * FormControl for "Select" * moved here by wf for testability and visibility * see bugreport [ 1124057 ] Out of Bounds Exception should be avoided * */ public class SelectionFormControl extends FormControl { private final boolean _multiSelect; private final boolean _listBox; private Options _selectionOptions; public String getType() { return (isMultiValued()?MULTIPLE_TYPE:SINGLE_TYPE); } public SelectionFormControl( WebForm form, HTMLSelectElementImpl element ) { super( form, element ); if (!element.getNodeName().equalsIgnoreCase( "select" )) throw new RuntimeException( "Not a select element" ); int size = NodeUtils.getAttributeValue( element, "size", 0); _multiSelect = NodeUtils.isNodeAttributePresent( element, "multiple" ); _listBox = size > 1 || (_multiSelect && size != 1); _selectionOptions = _listBox ? (Options) new MultiSelectOptions( element ) : (Options) new SingleSelectOptions( element ); } public String[] getValues() { return _selectionOptions.getSelectedValues(); } public String[] getOptionValues() { return _selectionOptions.getValues(); } public String[] getDisplayedOptions() { return _selectionOptions.getDisplayedText(); } /** * Returns true if a single control can have multiple values. **/ public boolean isMultiValued() { return _multiSelect; } class Scriptable extends FormControl.Scriptable { /** * get the Object with the given property name * @param propertyName - the name of the property to get * @return the Object for the property */ public Object get( String propertyName ) { if (propertyName.equalsIgnoreCase( "options" )) { return _selectionOptions; } else if (propertyName.equalsIgnoreCase( "length" )) { return new Integer( getOptionValues().length ); } else if (propertyName.equalsIgnoreCase( "value" )) { return getSelectedValue(); } else if (propertyName.equalsIgnoreCase( "selectedIndex" )) { return new Integer( _selectionOptions.getFirstSelectedIndex() ); } else { return super.get( propertyName ); } } /** * get the Object at the given index * @param index - the index of the object to get * @return the object at the given index */ public Object get(int index) { return _selectionOptions.get( index ); } private String getSelectedValue() { String[] values = getValues(); return (values.length == 0 ? "" : values[0] ); } /** * set the property with the given name to the given value * @param propertyName - the name of the property to set * @param value - the value to assign to the property */ public void set( String propertyName, Object value ) { if (propertyName.equalsIgnoreCase( "value" )) { ArrayList values = new ArrayList(); values.add( value ); _selectionOptions.claimUniqueValues( values ); } else if (propertyName.equalsIgnoreCase( "selectedIndex" )) { if (!(value instanceof Number)) throw new RuntimeException( "selectedIndex must be set to an integer" ); _selectionOptions.setSelectedIndex( ((Number) value).intValue() ); } else if (propertyName.equalsIgnoreCase( "length" )) { _selectionOptions.setLength( ((Number) value).intValue() ); } else { super.set( propertyName, value ); } } } public ScriptableDelegate newScriptable() { return new Scriptable(); } void updateRequiredParameters( Hashtable required ) { if (isReadOnly()) required.put( getName(), getValues() ); } protected void addValues( ParameterProcessor processor, String characterSet ) throws IOException { if (isDisabled()) return; for (int i = 0; i < getValues().length; i++) { processor.addParameter( getName(), getValues()[i], characterSet ); } } protected void claimUniqueValue( List values ) { boolean changed = _selectionOptions.claimUniqueValues( values ); if (changed) sendOnChangeEvent(); } protected void reset() { _selectionOptions.reset(); } public static class Option extends ScriptableDelegate implements SelectionOption { private String _text =""; private String _value; private boolean _defaultSelected; private boolean _selected; private int _index; private Options _container; public Option() { } Option( String text, String value, boolean selected ) { _text = text; _value = value; _defaultSelected = _selected = selected; } void reset() { _selected = _defaultSelected; } void addValueIfSelected( List list ) { if (_selected) list.add( _value ); } void setIndex( Options container, int index ) { _container = container; _index = index; } //------------------------- SelectionOption methods ------------------------------ public void initialize( String text, String value, boolean defaultSelected, boolean selected ) { _text = text; _value = value; _defaultSelected = defaultSelected; _selected = selected; } public int getIndex() { return _index; } public String getText() { return _text; } public void setText( String text ) { _text = text; } public String getValue() { return _value; } public void setValue( String value ) { _value = value; } public boolean isDefaultSelected() { return _defaultSelected; } public void setSelected( boolean selected ) { _selected = selected; if (selected) _container.optionSet( _index ); } public boolean isSelected() { return _selected; } } public abstract class Options extends ScriptableDelegate implements SelectionOptions { private Option[] _options; Options( Node selectionNode ) { // BR [ 1843978 ] Accessing Options in a form is in lower case // calls for uppercase "option" here ... pending as of 2007-12-30 NodeList nl = ((Element) selectionNode).getElementsByTagName( "OPTION" ); _options = new Option[ nl.getLength() ]; for (int i = 0; i < _options.length; i++) { final String displayedText = getValue( nl.item(i).getFirstChild() ).trim(); _options[i] = new Option( displayedText, getOptionValue( nl.item(i), displayedText ), nl.item(i).getAttributes().getNamedItem( "selected" ) != null ); _options[i].setIndex( this, i ); } } /** * claim unique values from the given list of values * @param values - the list of values * @return */ boolean claimUniqueValues( List values ) { return claimUniqueValues( values, _options ); } protected abstract boolean claimUniqueValues( List values, Option[] options ); /** * report if there are no matches * be aware of [ 1100437 ] Patch for ClassCastException in FormControl * TODO implement patch if test get's available * @param values */ final protected void reportNoMatches( List values ) { if (!_listBox) { throw new IllegalParameterValueException( getName(), values, getOptionValues() ); } } String[] getSelectedValues() { ArrayList list = new ArrayList(); for (int i = 0; i < _options.length; i++) { _options[i].addValueIfSelected( list ); } if (!_listBox && list.isEmpty() && _options.length > 0) list.add( _options[0].getValue() ); return (String[]) list.toArray( new String[ list.size() ] ); } void reset() { for (int i = 0; i < _options.length; i++) { _options[i].reset(); } } String[] getDisplayedText() { String[] displayedText = new String[ _options.length ]; for (int i = 0; i < displayedText.length; i++) displayedText[i] = _options[i].getText(); return displayedText; } String[] getValues() { String[] values = new String[ _options.length ]; for (int i = 0; i < values.length; i++) values[i] = _options[i].getValue(); return values; } /** * Selects the matching item and deselects the others. **/ void setSelectedIndex( int index ) { for (int i = 0; i < _options.length; i++) { _options[ i ]._selected = (i == index); } } /** * Returns the index of the first item selected, or -1 if none is selected. */ int getFirstSelectedIndex() { for (int i = 0; i < _options.length; i++) { if (_options[i].isSelected()) return i; } return noOptionSelectedIndex(); } protected abstract int noOptionSelectedIndex(); public int getLength() { return _options.length; } /** * Modified by gklopp - 12/19/2005 * [ 1396835 ] Javascript : length of a select element cannot be increased * Bug corrected : The length can be greater than the original length */ public void setLength( int length ) { if (length < 0) return; Option[] newArray = new Option[ length ]; System.arraycopy( _options, 0, newArray, 0, Math.min( length, _options.length ) ); for (int i = _options.length; i < length; i++) { newArray[i] = new Option(); } _options = newArray; } public void put( int i, SelectionOption option ) { if (i < 0) return; if (option == null) { if (i >= _options.length) return; deleteOptionsEntry( i ); } else { if (i >= _options.length) { i = _options.length; expandOptionsArray(); } _options[i] = (Option) option; _options[i].setIndex( this, i ); if (option.isSelected()) ensureUniqueOption( _options, i); } } protected abstract void ensureUniqueOption( Option[] options, int i ); private void deleteOptionsEntry( int i ) { Option[] newArray = new Option[ _options.length-1 ]; System.arraycopy( _options, 0, newArray, 0, i ); System.arraycopy( _options, i+1, newArray, i, newArray.length - i ); _options = newArray; } private void expandOptionsArray() { Option[] newArray = new Option[ _options.length+1 ]; System.arraycopy( _options, 0, newArray, 0, _options.length ); _options = newArray; } /** * get the Object at the given index * check that the index is not out of bounds * @param index - the index of the object to get * @throw RuntimeException if index is out of bounds * @since [ 1124057 ] Out of Bounds Exception should be avoided * */ public Object get( int index ) { // if the index is out of bounds if (index < 0 || index >= _options.length) { // create a user friendly error message String msg="invalid index "+index+" for Options "; // by listing all possible options for (int i = 0; i < _options.length; i++) { msg=msg+(_options[i]._text); if (i<_options.length-1) msg=msg+","; } // for // now throw a RunTimeException that would // have happened anyways with a less friendly message throw new RuntimeException(msg); } // if return _options[ index ]; } // get /** Invoked when an option is set true. **/ void optionSet( int i ) { ensureUniqueOption( _options, i); } private String getOptionValue( Node optionNode, String displayedText ) { NamedNodeMap nnm = optionNode.getAttributes(); if (nnm.getNamedItem( "value" ) != null) { return getValue( nnm.getNamedItem( "value" ) ); } else { return displayedText; } } private String getValue( Node node ) { return (node == null) ? "" : emptyIfNull( node.getNodeValue() ); } } class SingleSelectOptions extends Options { public SingleSelectOptions( Node selectionNode ) { super( selectionNode ); } protected void ensureUniqueOption( Option[] options, int i ) { for (int j = 0; j < options.length; j++) { options[j]._selected = (i == j); } } protected int noOptionSelectedIndex() { return 0; } /** * claim the values * be aware of [ 1100437 ] Patch for ClassCastException in FormControl * TODO implement patch if test get's available - the (String) cast might fail */ protected boolean claimUniqueValues( List values, Option[] options ) { boolean changed = false; for (int i = 0; i < values.size(); i++) { String value = (String) values.get( i ); for (int j = 0; j < options.length; j++) { boolean selected = value.equals( options[j].getValue() ); if (selected != options[j].isSelected()) changed = true; options[j].setSelected( selected ); if (selected) { values.remove( value ); for (++j; j < options.length; j++) options[j].setSelected( false ); return changed; } } } reportNoMatches( values ); return changed; } } class MultiSelectOptions extends Options { public MultiSelectOptions( Node selectionNode ) { super( selectionNode ); } protected void ensureUniqueOption( Option[] options, int i ) {} protected int noOptionSelectedIndex() { return -1; } protected boolean claimUniqueValues( List values, Option[] options ) { boolean changed = false; for (int i = 0; i < options.length; i++) { final boolean newValue = values.contains( options[i].getValue() ); if (newValue != options[i].isSelected()) changed = true; options[i].setSelected( newValue ); if (newValue) values.remove( options[i].getValue() ); } return changed; } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/0000755000175000017500000000000011014557542022774 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/Cookie.java0000644000175000017500000001722711014557540025057 0ustar twernertwernerpackage com.meterware.httpunit.cookies; /******************************************************************************************************************** * $Id: Cookie.java 982 2008-05-20 19:47:44Z russgold $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.Map; import java.util.Iterator; import java.util.TimeZone; import java.net.URL; /** * An HTTP client-side cookie. * @author Russell Gold **/ public class Cookie { private String _name; private String _value; private String _path; private String _domain; private long _expiredTime; /** * @return the _expiredTime in milliseconds */ public long getExpiredTime() { return _expiredTime; } /** * DateFormat to be used to format original Netscape cookies */ private final static DateFormat originalCookieFormat = new SimpleDateFormat("EEE,dd-MMM-yyyy HH:mm:ss z", Locale.US); static { originalCookieFormat.setTimeZone(TimeZone.getTimeZone("GMT")); } /** * Constructs a cookie w/o any domain or path restrictions. * @param name - the name of the cookie * @param value - the value of the cookie */ Cookie( String name, String value ) { _name = name; _value = value; } /** * construct a cookie with domain and path restrictions * @param name * @param value * @param domain * @param path */ Cookie( String name, String value, String domain, String path) { this(name, value); _path = path; _domain = domain; } /** * Constructs a cookie w/o any domain or path restrictions. * @param name - the name of the cookie * @param value - the value of the cookie * @param attributes - a map of attributes for the cookie */ Cookie( String name, String value, Map attributes ) { this( name, value ); for (Iterator iterator = attributes.keySet().iterator(); iterator.hasNext();) { String key = (String) iterator.next(); String attributeValue = (String) attributes.get( key ); if (key.equalsIgnoreCase( "path" )) { _path = attributeValue; } else if (key.equalsIgnoreCase( "domain" )) { _domain = attributeValue; } else if (key.equalsIgnoreCase( "max-age" )) { _expiredTime = System.currentTimeMillis() + getAgeInMsec( attributeValue ); } else if (key.equalsIgnoreCase( "expires" )) { _expiredTime = getAgeInMsecFromDate( attributeValue ); } } } /** * get the age of the cookie in Milliseconds from a string representaiton in seconds * @param maxAgeValue - the string with the age in seconds * @return - the integer millisecond value or 0 if conversion fails */ private int getAgeInMsec( String maxAgeValue ) { try { return 1000 * Integer.parseInt( maxAgeValue ); } catch (NumberFormatException e) { return 0; } } /** * return the age of a cookie in milliesconds from a string formatted date value * @param dateValue - the string to parse * @return - milliseconds as integer or 0 if parsing fails */ private long getAgeInMsecFromDate( String dateValue ) { try { // SimpleDateFormat isn't thread-safe synchronized(originalCookieFormat) { long age=originalCookieFormat.parse( dateValue ).getTime(); return age; } } catch (ParseException e) { return 0; } } /** * Returns the name of this cookie. */ public String getName() { return _name; } /** * Returns the value associated with this cookie. */ public String getValue() { return _value; } /** * Sets the value associated with this cookie. */ public void setValue(String value) { _value = value; } /** * Returns the path to which this cookie is restricted. */ public String getPath() { return _path; } /** * Returns the domain to which this cookie may be sent. */ public String getDomain() { return _domain; } void setPath( String path ) { _path = path; } void setDomain( String domain ) { _domain = domain; } public int hashCode() { int hashCode = _name.hashCode(); if (_domain != null) hashCode ^= _domain.hashCode(); if (_path != null) hashCode ^= _path.hashCode(); return hashCode; } public boolean equals( Object obj ) { return obj.getClass() == getClass() && equals( (Cookie) obj ); } private boolean equals( Cookie other ) { return _name.equalsIgnoreCase( other._name ) && equalProperties( getDomain(), other.getDomain() ) && equalProperties( getPath(), other.getPath() ); } private boolean equalProperties( String first, String second ) { return first == second || (first != null && first.equals( second )); } /** * check whether the cookie is expired * @return true if the _expiredTime is higher than the current System time */ public boolean isExpired() { boolean expired=_expiredTime != 0 && _expiredTime <= System.currentTimeMillis(); return expired; } /** * may this cookie be sent to the given url? * @param url - the unform resource locator to check * @return true if the cookie is not expired and the path is accepted if a domain is set */ public boolean mayBeSentTo( URL url ) { if (getDomain() == null) return true; if (isExpired()) return false; return acceptHost( getDomain(), url.getHost() ) && acceptPath( getPath(), url.getPath() ); } private boolean acceptPath( String pathPattern, String hostPath ) { return !CookieProperties.isPathMatchingStrict() || hostPath.startsWith( pathPattern ); } /** * accept host if the given hostName fits to the given hostPattern * @param hostPattern * @param hostName * @return true if there is a fit */ private static boolean acceptHost( String hostPattern, String hostName ) { return hostPattern.equalsIgnoreCase( hostName ) || (hostPattern.startsWith( "." ) && hostName.endsWith( hostPattern )); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/CookieJar.java0000644000175000017500000005155111014557542025514 0ustar twernertwernerpackage com.meterware.httpunit.cookies; /******************************************************************************************************************** * $Id: CookieJar.java 951 2008-05-02 10:11:40Z wolfgang_fahl $ * * Copyright (c) 2002-2004,2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.io.IOException; import java.io.StreamTokenizer; import java.io.StringReader; import java.net.URL; import java.util.*; /** * A collection of HTTP cookies, which can interact with cookie and set-cookie header values. * * @author Russell Gold * @author Drew Varner **/ public class CookieJar { private static final int DEFAULT_HEADER_SIZE = 80; private ArrayList _cookies = new ArrayList(); private ArrayList _globalCookies = new ArrayList(); private CookiePress _press; /** * Creates an empty cookie jar. */ public CookieJar() { _press = new CookiePress( null ); } /** * Creates a cookie jar which is initially populated with cookies parsed from the Set-Cookie and * Set-Cookie2 header fields. *

* Note that the parsing does not strictly follow the specifications, but * attempts to imitate the behavior of popular browsers. Specifically, * it allows cookie values to contain commas, which the * Netscape standard does not allow for, but which is required by some servers. *

*/ public CookieJar( CookieSource source ) { _press = new CookiePress( source.getURL() ); findCookies( source.getHeaderFields( "Set-Cookie" ), new RFC2109CookieRecipe() ); findCookies( source.getHeaderFields( "Set-Cookie2" ), new RFC2965CookieRecipe() ); } /** * find the cookies in the given Header String array * @param cookieHeader - the strings to look for cookies * @param recipe - the recipe to use */ private void findCookies( String cookieHeader[], CookieRecipe recipe ) { for (int i = 0; i < cookieHeader.length; i++) { recipe.findCookies( cookieHeader[i] ); } } /** * Empties this cookie jar of all contents. */ public void clear() { _cookies.clear(); _globalCookies.clear(); } /** * Defines a cookie to be sent to the server on every request. This bypasses the normal mechanism by which only * certain cookies are sent based on their host and path. * @deprecated as of 1.6, use #putCookie **/ public void addCookie( String name, String value ) { _globalCookies.add( new Cookie( name, value ) ); } /** * Defines a cookie to be sent to the server on every request. This bypasses the normal mechanism by which only * certain cookies are sent based on their host and path. * * Values of null will result in the cookie being removed. Any other value will leave the * cookie unchanged expect for the value. * * @since 1.6 **/ public void putCookie( String name, String value ) { boolean foundCookie = false; for (Iterator iterator = _globalCookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) { foundCookie = true; if (value != null) { cookie.setValue(value); } else { iterator.remove(); } } } for (Iterator iterator = _cookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) { foundCookie = true; if (value != null) { cookie.setValue(value); } else { iterator.remove(); } } } // only add it if it does not already exist if (foundCookie == false) { _globalCookies.add( new Cookie( name, value ) ); } } /** * Define a non-global cookie. This cookie can be overwritten by subsequent cookie definitions * in http headers. This cookie definition requires a domain and path. If a global cookie is * defined with the same name, this cookie is not added. */ public void putSingleUseCookie(String name, String value, String domain, String path) { for (Iterator iterator = _globalCookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) return; } for (Iterator iterator = _cookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) iterator.remove(); } _cookies.add( new Cookie( name, value, domain, path) ); } /** * Returns the name of all the active cookies in this cookie jar. **/ public String[] getCookieNames() { final int numGlobalCookies = _globalCookies.size(); String[] names = new String[ _cookies.size() + numGlobalCookies ]; for (int i = 0; i < numGlobalCookies; i++) { names[i] = ((Cookie) _globalCookies.get(i)).getName(); } for (int i = numGlobalCookies; i < names.length; i++) { names[i] = ((Cookie) _cookies.get( i-numGlobalCookies )).getName(); } return names; } /** * Returns a collection containing all of the cookies in this jar. */ public Collection getCookies() { final Collection collection = (Collection) _cookies.clone(); collection.addAll( _globalCookies ); return collection; } /** * Returns the value of the specified cookie. * @param name - the name of the cookie to get the value for * @return the value of the cookie **/ public String getCookieValue( String name ) { Cookie cookie = getCookie( name ); return cookie == null ? null : cookie.getValue(); } /** * Returns the value of the specified cookie. **/ public Cookie getCookie( String name ) { if (name == null) throw new IllegalArgumentException( "getCookieValue: no name specified" ); for (Iterator iterator = _cookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) return cookie; } for (Iterator iterator = _globalCookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) return cookie; } return null; } /** * Returns the value of the cookie header to be sent to the specified URL. * Will return null if no compatible cookie is defined. **/ public String getCookieHeaderField( URL targetURL ) { if (_cookies.isEmpty() && _globalCookies.isEmpty()) return null; StringBuffer sb = new StringBuffer( DEFAULT_HEADER_SIZE ); HashSet restrictedCookies = new HashSet(); for (Iterator i = _cookies.iterator(); i.hasNext();) { Cookie cookie = (Cookie) i.next(); if (!cookie.mayBeSentTo( targetURL )) continue; restrictedCookies.add( cookie.getName() ); if (sb.length() != 0) sb.append( "; " ); sb.append( cookie.getName() ).append( '=' ).append( cookie.getValue() ); } for (Iterator i = _globalCookies.iterator(); i.hasNext();) { Cookie cookie = (Cookie) i.next(); if (restrictedCookies.contains( cookie.getName() )) continue; if (sb.length() != 0) sb.append( "; " ); sb.append( cookie.getName() ).append( '=' ).append( cookie.getValue() ); } return sb.length() == 0 ? null : sb.toString(); } /** * Updates the cookies maintained in this cookie jar with those in another cookie jar. Any duplicate cookies in * the new jar will replace those in this jar. **/ public void updateCookies( CookieJar newJar ) { for (Iterator i = newJar._cookies.iterator(); i.hasNext();) { addUniqueCookie( (Cookie) i.next() ); } } /** * Add the cookie to this jar, replacing any previous matching cookie. */ void addUniqueCookie( Cookie cookie ) { _cookies.remove( cookie ); _cookies.add( cookie ); } /** * base class for the cookie recipies - there are two different implementations * of this */ abstract class CookieRecipe { /** * Extracts cookies from a cookie header. Works in conjunction with a cookie press class, which actually creates * the cookies and adds them to the jar as appropriate. * * 1. Parse the header into tokens, separated by ',' and ';' (respecting single and double quotes) * 2. Process tokens from the end: * a. if the token contains an '=' we have a name/value pair. Add them to the cookie press, which * will decide if it is a cookie name or an attribute name. * b. if the token is a reserved word, flush the cookie press and continue. * c. otherwise, add the token to the cookie press, passing along the last character of the previous token. */ void findCookies( String cookieHeader ) { Vector tokens = getCookieTokens( cookieHeader ); for (int i = tokens.size() - 1; i >= 0; i--) { String token = (String) tokens.elementAt( i ); int equalsIndex = getEqualsIndex( token ); if (equalsIndex != -1) { _press.addTokenWithEqualsSign( this, token, equalsIndex ); } else if (isCookieReservedWord( token )) { _press.clear(); } else { _press.addToken( token, lastCharOf( (i == 0) ? "" : (String) tokens.elementAt( i - 1 ) ) ); } } } private char lastCharOf( String string ) { return (string.length() == 0) ? ' ' : string.charAt( string.length()-1 ); } /** * Returns the index (if any) of the equals sign separating a cookie name from the its value. * Equals signs at the end of the token are ignored in this calculation, since they may be * part of a Base64-encoded value. */ private int getEqualsIndex( String token ) { if (!token.endsWith( "==" )) { return token.indexOf( '=' ); } else { return getEqualsIndex( token.substring( 0, token.length()-2 ) ); } } /** * Tokenizes a cookie header and returns the tokens in a * Vector. * handles the broken syntax for expires= fields ... * @param cookieHeader - the header to read * @return a Vector of cookieTokens as name=value pairs **/ private Vector getCookieTokens(String cookieHeader) { StringReader sr = new StringReader(cookieHeader); StreamTokenizer st = new StreamTokenizer(sr); Vector tokens = new Vector(); // clear syntax tables of the StreamTokenizer st.resetSyntax(); // set all characters as word characters st.wordChars(0,Character.MAX_VALUE); // set up characters for quoting st.quoteChar( '"' ); //double quotes st.quoteChar( '\'' ); //single quotes // set up characters to separate tokens st.whitespaceChars(59,59); //semicolon // and here we run into trouble ... // see http://www.mnot.net/blog/2006/10/27/cookie_fun // ... Notice something about the above? It uses a comma inside of the date, // without quoting the value. This makes it difficult for generic processors to handle the Set-Cookie header. st.whitespaceChars(44,44); //comma try { while (st.nextToken() != StreamTokenizer.TT_EOF) { String tokenContent=st.sval; // fix expires comma delimiter token problem if (tokenContent.toLowerCase().startsWith("expires=")) { if (st.nextToken() != StreamTokenizer.TT_EOF) { tokenContent+=","+st.sval; } // if } // if tokenContent=tokenContent.trim(); tokens.addElement( tokenContent ); } } catch (IOException ioe) { // this will never happen with a StringReader } sr.close(); return tokens; } abstract protected boolean isCookieAttribute( String stringLowercase ); abstract protected boolean isCookieReservedWord( String token ); } /** * cookie Factory - creates cookies for URL s * */ class CookiePress { private StringBuffer _value = new StringBuffer(); private HashMap _attributes = new HashMap(); private URL _sourceURL; /** * create a cookie press for the given URL * @param sourceURL */ public CookiePress( URL sourceURL ) { _sourceURL = sourceURL; } void clear() { _value.setLength(0); _attributes.clear(); } void addToken( String token, char lastChar ) { _value.insert( 0, token ); if (lastChar != '=') _value.insert( 0, ',' ); } /** * add from a token * @param recipe - the recipe to use * @param token - the token to use * @param equalsIndex - the position of the equal sign */ void addTokenWithEqualsSign( CookieRecipe recipe, String token, int equalsIndex ) { String name = token.substring( 0, equalsIndex ).trim(); String value= token.substring( equalsIndex + 1 ).trim(); _value.insert( 0, value ); if (recipe.isCookieAttribute( name.toLowerCase() )) { _attributes.put( name.toLowerCase(), _value.toString() ); } else { addCookieIfValid( new Cookie( name, _value.toString(), _attributes ) ); _attributes.clear(); } _value.setLength(0); } /** * add the given cookie if it is valid * @param cookie */ private void addCookieIfValid( Cookie cookie ) { if (acceptCookie( cookie )) addUniqueCookie( cookie ); } /** * accept the given cookie * @param cookie * @return */ private boolean acceptCookie( Cookie cookie ) { if (cookie.getPath() == null) { cookie.setPath( getParentPath( _sourceURL.getPath() ) ); } else { int status = getPathAttributeStatus( cookie.getPath(), _sourceURL.getPath() ); if (status != CookieListener.ACCEPTED) { reportCookieRejected( status, cookie.getPath(), cookie.getName() ); return false; } } if (cookie.getDomain() == null) { cookie.setDomain( _sourceURL.getHost() ); } else if (!CookieProperties.isDomainMatchingStrict() && cookie.getDomain().equalsIgnoreCase( _sourceURL.getHost() )) { cookie.setDomain( _sourceURL.getHost() ); } else { int status = getDomainAttributeStatus( cookie.getDomain(), _sourceURL.getHost() ); if (status != CookieListener.ACCEPTED) { reportCookieRejected( status, cookie.getDomain(), cookie.getName() ); return false; } } return true; } private String getParentPath( String path ) { int rightmostSlashIndex = path.lastIndexOf( '/' ); return rightmostSlashIndex < 0 ? "/" : path.substring( 0, rightmostSlashIndex ); } private int getPathAttributeStatus( String pathAttribute, String sourcePath ) { if (!CookieProperties.isPathMatchingStrict() || sourcePath.length() == 0 || sourcePath.startsWith( pathAttribute )) { return CookieListener.ACCEPTED; } else { return CookieListener.PATH_NOT_PREFIX; } } /** * get the domainAttribute Status for the given domainAttribute with the given sourceHost * @see http://wp.netscape.com/newsref/std/cookie_spec.html * @param domainAttribute * @param sourceHost * @return */ private int getDomainAttributeStatus( String domainAttribute, String sourceHost ) { // patch according to [ 1476380 ] Cookies incorrectly rejected despite valid domain if (domainAttribute.equals(sourceHost)) { return CookieListener.ACCEPTED; } if (!domainAttribute.startsWith(".")) domainAttribute = '.' + domainAttribute; if (domainAttribute.lastIndexOf('.') == 0) { return CookieListener.DOMAIN_ONE_DOT; } else if (!sourceHost.endsWith( domainAttribute )) { return CookieListener.DOMAIN_NOT_SOURCE_SUFFIX; } else if (CookieProperties.isDomainMatchingStrict() && sourceHost.lastIndexOf( domainAttribute ) > sourceHost.indexOf( '.' )) { return CookieListener.DOMAIN_TOO_MANY_LEVELS; } else { return CookieListener.ACCEPTED; } } private boolean reportCookieRejected( int reason, String attribute, String source ) { CookieProperties.reportCookieRejected( reason, attribute, source ); return false; } } /** * Parses cookies according to * RFC 2109 * *
* These cookies come from the Set-Cookie: header **/ class RFC2109CookieRecipe extends CookieRecipe { /** * check whether the given lower case String is a cookie attribute * @param stringLowercase - the string to check * @return true - if the string is the name of a valid cookie attribute */ protected boolean isCookieAttribute( String stringLowercase ) { return stringLowercase.equals("path") || stringLowercase.equals("domain") || stringLowercase.equals("expires") || stringLowercase.equals("comment") || stringLowercase.equals("max-age") || stringLowercase.equals("version"); } protected boolean isCookieReservedWord( String token ) { return token.equalsIgnoreCase( "secure" ); } } /** * Parses cookies according to * RFC 2965 * *
* These cookies come from the Set-Cookie2: header **/ class RFC2965CookieRecipe extends CookieRecipe { protected boolean isCookieAttribute( String stringLowercase ) { return stringLowercase.equals("path") || stringLowercase.equals("domain") || stringLowercase.equals("comment") || stringLowercase.equals("commenturl") || stringLowercase.equals("max-age") || stringLowercase.equals("version") || stringLowercase.equals("$version") || stringLowercase.equals("port"); } protected boolean isCookieReservedWord( String token ) { return token.equalsIgnoreCase( "discard" ) || token.equalsIgnoreCase( "secure" ); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/CookieListener.java0000644000175000017500000000465511014557540026566 0ustar twernertwernerpackage com.meterware.httpunit.cookies; /******************************************************************************************************************** * $Id: CookieListener.java 606 2004-03-02 10:51:39Z russgold $ * * Copyright (c) 2003-2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ /** * An interface for classes which can listen for cookies being rejected and the reason. * * @author Russell Gold */ public interface CookieListener { /** Indicates that the cookie was accepted. **/ public final static int ACCEPTED = 0; /** Indicates that the domain attribute has only one dot. **/ public final static int DOMAIN_ONE_DOT = 2; /** Indicates that the domain attribute is not a suffix of the source domain issuing the cookie. **/ public final static int DOMAIN_NOT_SOURCE_SUFFIX = 3; /** Indicates that the source domain has an extra dot beyond those defined in the domain attribute. **/ public final static int DOMAIN_TOO_MANY_LEVELS = 4; /** Indicates that the source path does not begin with the path attribute. **/ public final static int PATH_NOT_PREFIX = 5; /** * Invoked when a cookie is rejected by HttpUnit. **/ void cookieRejected( String cookieName, int reason, String attribute ); } httpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/CookieProperties.java0000644000175000017500000000766311014557540027137 0ustar twernertwernerpackage com.meterware.httpunit.cookies; import java.util.ArrayList; import java.util.List; import java.util.Iterator; /******************************************************************************************************************** * $Id: CookieProperties.java 595 2004-02-12 13:03:24Z russgold $ * * Copyright (c) 2003-2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ /** * Controls behavior for cookies. */ public class CookieProperties { /** If true, domain matching follows the spec. If false, permits any domain which is a prefix of the host. **/ private static boolean _domainMatchingStrict = true; /** If true, path matching follows the spec. If false, permits any path. **/ private static boolean _pathMatchingStrict = true; /** A collection of listeners for cookie events. **/ private static ArrayList _listeners; public static void reset() { _domainMatchingStrict = true; _pathMatchingStrict = true; _listeners = null; } /** * Returns true (the default) if cookies should be rejected if they specify a domain which is not a suffix * of the host domain or does not contain all of the dots in that host domain name * (see RFC2965). */ public static boolean isDomainMatchingStrict() { return _domainMatchingStrict; } /** * Specifies whether strict domain name matching must be followed. */ public static void setDomainMatchingStrict( boolean domainMatchingStrict ) { _domainMatchingStrict = domainMatchingStrict; } /** * Returns true (the default) if cookies should be rejected if they specify a path which is not a prefix * of the request path (see RFC2965). */ public static boolean isPathMatchingStrict() { return _pathMatchingStrict; } /** * Specifies whether strict path name matching must be followed. */ public static void setPathMatchingStrict( boolean pathMatchingStrict ) { _pathMatchingStrict = pathMatchingStrict; } /** * Adds a listener for cookie events. */ public static void addCookieListener( CookieListener listener ) { if (_listeners == null) _listeners = new ArrayList(); synchronized( _listeners ) { _listeners.add( listener ); } } public static void reportCookieRejected( int reason, String attribute, String source ) { if (_listeners == null) return; List listeners; synchronized( _listeners ) { listeners = (List) _listeners.clone(); } for (Iterator i = listeners.iterator(); i.hasNext();) { ((CookieListener) i.next()).cookieRejected( source, reason, attribute ); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/CookieSource.java0000644000175000017500000000360311014557540026231 0ustar twernertwernerpackage com.meterware.httpunit.cookies; /******************************************************************************************************************** * $Id: CookieSource.java 383 2002-10-17 23:52:49Z russgold $ * * Copyright (c) 2002, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.net.URL; /** * This interface represents a source from which to parse out cookies. * * @author Russell Gold **/ public interface CookieSource { /** * Returns the URL which invoked this response. **/ URL getURL(); /** * Returns the values for the specified header field. If no such field is defined, will return an empty array. **/ String[] getHeaderFields( String fieldName ); } httpunit-1.7+dfsg/src/com/meterware/httpunit/cookies/package.html0000644000175000017500000000175511014557540025263 0ustar twernertwerner

Classes to support cookie handling. Supports the HTTP state mechanism. The central class of this package is the {@link com.meterware.httpunit.cookies.CookieJar}, which acts as a repository of {@link com.meterware.httpunit.cookies.Cookie} objects. There are two main ways to get cookies into the CookieJar. The first is to construct the CookieJar, passing a {@link com.meterware.httpunit.cookies.CookieSource} to its constructor. This will cause the CookieJar to parse the Set-Cookie headers from the source object. The second is to copy them from another CookieJar through use of the {@link com.meterware.httpunit.cookies.CookieJar#updateCookies updateCookies(CookieJar)} method.

The CookieJar can also produce a Cookie header to be sent as part of a request. The {@link com.meterware.httpunit.cookies.CookieJar#getCookieHeaderField} method will select any cookies that it has which can be sent to the specified URL and assemble them into an appropriate header.

httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/0000755000175000017500000000000011014557542022117 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/dom/AbstractDomComponent.java0000644000175000017500000000606111014557540027051 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Header$ * * Copyright (c) 2007-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.javascript.ScriptingEngineImpl; import com.meterware.httpunit.scripting.ScriptingEngine; import com.meterware.httpunit.scripting.ScriptableDelegate; import org.mozilla.javascript.Scriptable; /** * @author Russell Gold */ public abstract class AbstractDomComponent extends ScriptingEngineImpl implements Scriptable { private static int _anonymousFunctionNum; public String getClassName() { return getClass().getName(); } public ScriptingEngine newScriptingEngine( ScriptableDelegate child ) { throw new UnsupportedOperationException( ); } public void clearCaches() {} public boolean has( String name, Scriptable start ) { return super.has( name, start ) || ScriptingSupport.hasNamedProperty( this, getJavaPropertyName( name ), start ); } public Object get( String propertyName, Scriptable scriptable ) { Object result = super.get( propertyName, scriptable ); if (result != NOT_FOUND) return result; return ScriptingSupport.getNamedProperty( this, getJavaPropertyName( propertyName ), scriptable ); } protected String getJavaPropertyName( String propertyName ) { return propertyName; } public void put( String propertyName, Scriptable initialObject, Object value ) { super.put( propertyName, initialObject, value ); ScriptingSupport.setNamedProperty( this, getJavaPropertyName( propertyName ), value ); } protected static String createAnonymousFunctionName() { return "anon_" + (++_anonymousFunctionNum); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/AttrImpl.java0000644000175000017500000000730511014557540024521 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: AttrImpl.java 772 2006-12-01 16:54:18Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.*; /** * * @author Russell Gold **/ public class AttrImpl extends NodeImpl implements Attr { private String _name; private String _value = ""; private boolean _specified = false; private Element _ownerElement; static AttrImpl createAttribute( DocumentImpl owner, String name ) { AttrImpl attribute = new AttrImpl(); attribute.initialize( owner, name ); return attribute; } public static Attr createAttribute( DocumentImpl owner, String namespaceURI, String qualifiedName ) { AttrImpl attribute = new AttrImpl(); attribute.initialize( owner, qualifiedName ); return attribute; } protected void initialize( DocumentImpl owner, String name ) { super.initialize( owner ); _name = name; } public String getNodeName() { return getName(); } public String getNodeValue() throws DOMException { return getValue(); } public void setNodeValue( String nodeValue ) throws DOMException { setValue( nodeValue ); } public short getNodeType() { return ATTRIBUTE_NODE; } public String getName() { return _name; } public boolean getSpecified() { return _specified; } public String getValue() { return _value; } public void setValue( String value ) throws DOMException { _value = value; _specified = true; } public Element getOwnerElement() { return _ownerElement; } void setOwnerElement( Element ownerElement ) { _ownerElement = ownerElement; } public static Node importNode( Document document, Attr attr ) { Attr attribute = document.createAttributeNS( attr.getNamespaceURI(), attr.getName() ); attribute.setValue( attr.getValue() ); return attribute; } //------------------------------------- DOM level 3 methods ------------------------------------------------------------ public TypeInfo getSchemaTypeInfo() { return null; //To change body of implemented methods use File | Settings | File Templates. } public boolean isId() { return false; //To change body of implemented methods use File | Settings | File Templates. } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/AttributeNameAdjusted.java0000644000175000017500000000110311014557540027203 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: AttributeNameAdjusted.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2005, Russell Gold * *******************************************************************************************************************/ /** * @author Russell Gold */ public interface AttributeNameAdjusted { String getJavaAttributeName( String attributeName ); } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/CDATASectionImpl.java0000644000175000017500000000426111014557542025750 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: CDATASectionImpl.java 772 2006-12-01 16:54:18Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.CDATASection; import org.w3c.dom.Node; /** * * @author Russell Gold **/ public class CDATASectionImpl extends TextImpl implements CDATASection { public static CDATASection createCDATASection( DocumentImpl ownerDocument, String data ) { CDATASectionImpl cdataSection = new CDATASectionImpl(); cdataSection.initialize( ownerDocument, data ); return cdataSection; } public static Node importNode( DocumentImpl document, CDATASection cdataSection ) { return document.createCDATASection( cdataSection.getData() ); } public String getNodeName() { return "#cdata-section"; } public short getNodeType() { return CDATA_SECTION_NODE; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/CharacterDataImpl.java0000644000175000017500000000507711014557542026303 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: CharacterDataImpl.java 819 2008-01-03 13:35:21Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.CharacterData; import org.w3c.dom.DOMException; import org.w3c.dom.Node; import java.util.ArrayList; /** * * @author Russell Gold **/ abstract public class CharacterDataImpl extends NodeImpl implements CharacterData { private String _data; protected void initialize( DocumentImpl ownerDocument, String data ) { super.initialize( ownerDocument ); _data = data; } public String getData() throws DOMException { return _data; } public void setData( String data ) throws DOMException { if (data == null) data = ""; _data = data; } public int getLength() { return _data.length(); } public String substringData( int offset, int count ) throws DOMException { return null; } public void appendData( String arg ) throws DOMException { } public void insertData( int offset, String arg ) throws DOMException { } public void deleteData( int offset, int count ) throws DOMException { } public void replaceData( int offset, int count, String arg ) throws DOMException { } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/CommentImpl.java0000644000175000017500000000513211014557540025205 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: CommentImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.w3c.dom.Comment; /** * * @author Russell Gold **/ public class CommentImpl extends CharacterDataImpl implements Comment { static CommentImpl createComment( DocumentImpl ownerDocument, String data ) { CommentImpl comment = new CommentImpl(); comment.initialize( ownerDocument, data ); return comment; } public static Node importNode( DocumentImpl document, Comment comment ) { return document.createComment( comment.getData() ); } public String getNodeName() { return "#comment"; } public String getNodeValue() throws DOMException { return getData(); } public void setNodeValue( String nodeValue ) throws DOMException { setData( nodeValue ); } public short getNodeType() { return COMMENT_NODE; } protected NodeImpl getChildIfPermitted( Node proposedChild ) { throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "Comment nodes may not have children" ); } void appendContents( StringBuffer sb ) { sb.append( getData() ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/DocumentImpl.java0000644000175000017500000001652311014557540025367 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: DocumentImpl.java 781 2007-06-17 17:31:49Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.*; import org.w3c.dom.html.HTMLElement; import java.util.Iterator; /** * * @author Russell Gold **/ public class DocumentImpl extends NodeImpl implements Document { private Element _documentElement; static DocumentImpl createDocument() { DocumentImpl document = new DocumentImpl(); document.initialize(); return document; } protected void initialize() {} public String getNodeName() { return "#document"; } public String getNodeValue() throws DOMException { return null; } public void setNodeValue( String nodeValue ) throws DOMException { } public short getNodeType() { return DOCUMENT_NODE; } public Document getOwnerDocument() { return this; } public DocumentType getDoctype() { return null; } public DOMImplementation getImplementation() { return null; } public Element getDocumentElement() { return _documentElement; } void setDocumentElement( Element documentElement ) { if (_documentElement != null) throw new IllegalStateException( "A document may have only one root" ); _documentElement = documentElement; appendChild( documentElement ); } public Element createElement( String tagName ) throws DOMException { return ElementImpl.createElement( this, tagName ); } public DocumentFragment createDocumentFragment() { throw new UnsupportedOperationException( "DocumentFragment creation not supported "); } public Text createTextNode( String data ) { return TextImpl.createText( this, data ); } public Comment createComment( String data ) { return CommentImpl.createComment( this, data ); } public CDATASection createCDATASection( String data ) throws DOMException { return CDATASectionImpl.createCDATASection( this, data ); } public ProcessingInstruction createProcessingInstruction( String target, String data ) throws DOMException { return ProcessingInstructionImpl.createProcessingImpl( this, target, data ); } public Attr createAttribute( String name ) throws DOMException { return AttrImpl.createAttribute( this, name ); } public EntityReference createEntityReference( String name ) throws DOMException { throw new UnsupportedOperationException( "EntityReference creation not supported "); } public Node importNode( Node importedNode, boolean deep ) throws DOMException { switch (importedNode.getNodeType()) { case Node.ATTRIBUTE_NODE: return AttrImpl.importNode( this, (Attr) importedNode ); case Node.CDATA_SECTION_NODE: return CDATASectionImpl.importNode( this, (CDATASection) importedNode ); case Node.COMMENT_NODE: return CommentImpl.importNode( this, (Comment) importedNode ); case Node.ELEMENT_NODE: return ElementImpl.importNode( this, (Element) importedNode, deep ); case Node.PROCESSING_INSTRUCTION_NODE: return ProcessingInstructionImpl.importNode( this, (ProcessingInstruction) importedNode ); case Node.TEXT_NODE: return TextImpl.importNode( this, (Text) importedNode ); default: throw new DOMException( DOMException.NOT_SUPPORTED_ERR, "Cannot import node type " + importedNode.getNodeType() ); } } public Element getElementById( String elementId ) { for (Iterator each = preOrderIterator(); each.hasNext();) { Node node = (Node) each.next(); if (!(node instanceof HTMLElement)) continue; HTMLElement element = (HTMLElement) node; if (elementId.equals( element.getId() )) return element; } return null; } public Element createElementNS( String namespaceURI, String qualifiedName ) throws DOMException { return ElementImpl.createElement( this, namespaceURI, qualifiedName ); } public Attr createAttributeNS( String namespaceURI, String qualifiedName ) throws DOMException { return AttrImpl.createAttribute( this, namespaceURI, qualifiedName ); } public NodeList getElementsByTagNameNS( String namespaceURI, String localName ) { if (namespaceURI != null) throw new UnsupportedOperationException( "Namespaces are not supported" ); return getElementsByTagName( localName ); } void importChildren( Node original, Node copy ) { NodeList children = original.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node childCopy = importNode( children.item(i), /* deep */ true ); copy.appendChild( childCopy ); } } //------------------------------------- DOM level 3 methods ------------------------------------------------------------ public String getInputEncoding() { return null; } public String getXmlEncoding() { return null; } public Node renameNode( Node n, String namespaceURI, String qualifiedName ) throws DOMException { return null; } public boolean getXmlStandalone() { return false; } public void setXmlStandalone( boolean xmlStandalone ) throws DOMException { } public String getXmlVersion() { return null; } public void setXmlVersion( String xmlVersion ) throws DOMException { } public boolean getStrictErrorChecking() { return false; } public void setStrictErrorChecking( boolean strictErrorChecking ) { } public String getDocumentURI() { return null; } public void setDocumentURI( String documentURI ) { } public Node adoptNode( Node source ) throws DOMException { return null; } public DOMConfiguration getDomConfig() { return null; } public void normalizeDocument() { } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/DocumentTypeImpl.java0000644000175000017500000000513011014557542026223 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: DocumentTypeImpl.java 754 2006-03-28 00:52:15Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.DocumentType; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.DOMException; import java.util.ArrayList; /** * * @author Russell Gold **/ public class DocumentTypeImpl extends NodeImpl implements DocumentType { //---------------------------------------------- DocumentType methods -------------------------------------------------- public NamedNodeMap getEntities() { return null; } public String getInternalSubset() { return null; } public String getName() { return null; } public NamedNodeMap getNotations() { return null; } public String getPublicId() { return null; } public String getSystemId() { return null; } //------------------------------------------------ NodeImpl methods ---------------------------------------------------- public String getNodeName() { return null; } public short getNodeType() { return 0; } public String getNodeValue() throws DOMException { return null; } public void setNodeValue( String nodeValue ) throws DOMException { } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/DomBasedScriptingEngineFactory.java0000644000175000017500000001236211014557540031003 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: DomBasedScriptingEngineFactory.java 833 2008-03-28 12:24:08Z wolfgang_fahl $ * * Copyright (c) 2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.javascript.JavaScript; import com.meterware.httpunit.javascript.ScriptingEngineImpl; import com.meterware.httpunit.javascript.JavaScript.Window; import com.meterware.httpunit.scripting.ScriptingEngineFactory; import com.meterware.httpunit.scripting.ScriptingHandler; import com.meterware.httpunit.scripting.ScriptingEngine; import com.meterware.httpunit.HttpUnitUtils; import com.meterware.httpunit.WebResponse; import com.meterware.httpunit.HTMLElement; import java.util.ArrayList; import java.util.logging.Logger; import org.w3c.dom.Document; import org.w3c.dom.html.HTMLDocument; import org.w3c.dom.html.HTMLBodyElement; import org.xml.sax.SAXException; import org.mozilla.javascript.Context; import org.mozilla.javascript.EcmaError; import org.mozilla.javascript.Function; import org.mozilla.javascript.JavaScriptException; import org.mozilla.javascript.Scriptable; /** * The scripting engine factory which relies directly on the DOM. */ public class DomBasedScriptingEngineFactory implements ScriptingEngineFactory { /** * check whether this ScriptingEngineFactory is enabled */ public boolean isEnabled() { try { Class.forName( "org.mozilla.javascript.Context" ); return true; } catch (Exception e) { Logger.getLogger( "httpunit.org" ).warning( "Rhino classes (js.jar) not found - Javascript disabled" ); return false; } } /** * associate me with a webresponse * @param response - the WebResponse to use */ public void associate( WebResponse response ) { try { // JavaScript.run( response ); // can't do this (yet?) } catch (RuntimeException e) { throw e; } catch (Exception e) { HttpUnitUtils.handleException(e); throw new RuntimeException( e.toString() ); } } /** * load * @param response */ public void load( WebResponse response ) { Function onLoadEvent=null; try { Context context = Context.enter(); context.initStandardObjects( null ); HTMLDocument htmlDocument = ((DomWindow) response.getScriptingHandler()).getDocument(); if (!(htmlDocument instanceof HTMLDocumentImpl)) return; HTMLBodyElementImpl body = (HTMLBodyElementImpl) htmlDocument.getBody(); if (body == null) return; onLoadEvent = body.getOnloadEvent(); if (onLoadEvent == null) return; onLoadEvent.call( context, body, body, new Object[0] ); } catch (JavaScriptException e) { ScriptingEngineImpl.handleScriptException(e, onLoadEvent.toString()); // HttpUnitUtils.handleException(e); } catch (EcmaError ee) { //throw ee; ScriptingEngineImpl.handleScriptException(ee, onLoadEvent.toString()); } finally { Context.exit(); } } /** * setter for the throwExceptions flag * @param throwExceptions - true if Exceptions should be thrown */ public void setThrowExceptionsOnError( boolean throwExceptions ) { JavaScript.setThrowExceptionsOnError( throwExceptions ); } /** * getter for the throwExceptions flag * @return - true if Exceptions should be thrown */ public boolean isThrowExceptionsOnError() { return JavaScript.isThrowExceptionsOnError(); } public String[] getErrorMessages() { return ScriptingEngineImpl.getErrorMessages(); } public void clearErrorMessages() { ScriptingEngineImpl.clearErrorMessages(); } public ScriptingHandler createHandler( HTMLElement elementBase ) { return (ScriptingHandler) elementBase.getNode(); } public ScriptingHandler createHandler( WebResponse response ) { return response.createDomScriptingHandler(); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/DomListener.java0000644000175000017500000000325611014557542025215 0ustar twernertwernerpackage com.meterware.httpunit.dom; import org.w3c.dom.Node; import org.w3c.dom.Element; /******************************************************************************************************************** * $Id: DomListener.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ /** * @author Russell Gold */ public interface DomListener { void propertyChanged( Element changedElement, String propertyName ); } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/DomWindow.java0000644000175000017500000001324511014557542024676 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: DomWindow.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.io.IOException; import java.net.URL; import org.xml.sax.SAXException; import org.mozilla.javascript.Scriptable; import org.w3c.dom.html.HTMLDocument; import com.meterware.httpunit.scripting.ScriptingHandler; /** * @author Russell Gold */ public class DomWindow extends AbstractDomComponent implements Scriptable { private DomWindowProxy _proxy; private HTMLDocumentImpl _document; /** * construct me from a document * @param document */ public DomWindow( HTMLDocumentImpl document ) { _document = document; } public DomWindow( DomWindowProxy implementation ) { _proxy = implementation; } public void setProxy( DomWindowProxy proxy ) { _proxy = proxy; } public DomWindow getWindow() { return this; } public DomWindow getSelf() { return this; } public HTMLDocument getDocument() { return _document; } /** * Returns the document associated with this window. Uses the same name as that used by elements in the DOM. */ public HTMLDocument getOwnerDocument() { return _document; } /** * Opens a named window. * @param urlString the location (relative to the current page) from which to populate the window. * @param name the name of the window. * @param features special features for the window. * @param replace if true, replaces the contents of an existing window. * @return a new populated window object */ public DomWindow open( String urlString, String name, String features, boolean replace ) { try { if (_proxy==null) { throw new RuntimeException("DomWindow.open failed for '"+name+"' _proxy is null"); } DomWindowProxy newWindow=_proxy.openNewWindow( name, urlString ); if (newWindow==null) { // throw new RuntimeException("DomWindow.open failed for '"+name+"','"+urlString+"' openNewWindow returned null"); return null; } ScriptingHandler result=newWindow.getScriptingHandler(); return (DomWindow) result; } catch (IOException e) { return null; } catch (SAXException e) { return null; } } /** * Closes the current window. Has no effect if this "window" is actually a nested frame. */ public void close() { _proxy.close(); } /** * Displays an alert box with the specified message. * @param message the message to display */ public void alert( String message ) { _proxy.alert( message ); } /** * Displays a prompt, asking for a yes or no answer and returns the answer. * @param prompt the prompt text to display * @return true if the user answered 'yes' */ public boolean confirm( String prompt ) { return _proxy.confirm( prompt ); } /** * Displays a promptand returns the user's textual reply, which could be the default reply. * @param message the prompt text to display * @param defaultResponse the response to return if the user doesn't enter anything * @return the reply selected by the user. */ public String prompt( String message, String defaultResponse ) { return _proxy.prompt( message, defaultResponse ); } public void setTimeout( int timeout ) { } public void focus() { } public void moveTo( int x, int y ) { } protected String getDocumentWriteBuffer() { return _document.getWriteBuffer().toString(); } protected void discardDocumentWriteBuffer() { _document.clearWriteBuffer(); } boolean replaceText( String string, String mimeType ) { return _proxy.replaceText( string, mimeType ); } URL getUrl() { return _proxy.getURL(); } void submitRequest( HTMLElementImpl sourceElement, String method, String location, String target, byte[] requestBody ) throws IOException, SAXException { _proxy.submitRequest( sourceElement, method, location, target, null ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/DomWindowProxy.java0000644000175000017500000000511211014557540025730 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: DomWindowProxy.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.scripting.ScriptingHandler; import com.meterware.httpunit.protocol.MessageBody; import java.io.IOException; import java.net.URL; import org.xml.sax.SAXException; /** * @author Russell Gold */ public interface DomWindowProxy { DomWindowProxy openNewWindow( String name, String relativeUrl ) throws IOException, SAXException; ScriptingHandler getScriptingHandler(); void close(); void alert( String message ); boolean confirm( String message ); String prompt( String prompt, String defaultResponse ); /** * Returns the URL associated with the window. * @return the URL associated with the window. */ URL getURL(); /** * Replaces the text in the window with the specified text and content type. Returns false if unable * to do the replacement. */ boolean replaceText( String text, String contentType ); DomWindowProxy submitRequest( HTMLElementImpl sourceElement, String method, String location, String target, MessageBody requestBody ) throws IOException, SAXException; } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/ElementImpl.java0000644000175000017500000002071711014557542025204 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: ElementImpl.java 839 2008-03-29 23:30:13Z wolfgang_fahl $ * * Copyright (c) 2004-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.*; import java.util.Hashtable; import java.util.ArrayList; import java.util.Iterator; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; /** * * @author Russell Gold **/ public class ElementImpl extends NamespaceAwareNodeImpl implements Element { private Hashtable _attributes = new Hashtable(); private ArrayList _listeners = new ArrayList( ); static ElementImpl createElement( DocumentImpl owner, String tagName ) { ElementImpl element = new ElementImpl(); element.initialize( owner, tagName ); return element; } public static Element createElement( DocumentImpl owner, String namespaceURI, String qualifiedName ) { ElementImpl element = new ElementImpl(); element.initialize( owner, namespaceURI, qualifiedName ); return element; } public void addDomListener( DomListener listener ) { synchronized (_listeners) { _listeners.add( listener ); } } protected void reportPropertyChanged( String propertyName ) { ArrayList listeners; synchronized( _listeners ) { listeners = (ArrayList) _listeners.clone(); } for (Iterator each = listeners.iterator(); each.hasNext();) { ((DomListener) each.next()).propertyChanged( this, propertyName ); } } //---------------------------------------- Element methods ------------------------------------------------------------- public short getNodeType() { return ELEMENT_NODE; } public String getNodeValue() throws DOMException { return null; } public void setNodeValue( String nodeValue ) throws DOMException { } public boolean hasAttributes() { return !_attributes.isEmpty(); } public NamedNodeMap getAttributes() { return new NamedNodeMapImpl( _attributes ); } /** * get the attribute with the given name * @param name - the name of the attribute to get */ public String getAttribute( String name ) { Attr attr = getAttributeNode( name ); return attr == null ? "" : attr.getValue(); } public void setAttribute( String name, String value ) throws DOMException { if (value.equals( getAttribute( name ))) return; Attr attribute = getOwnerDocument().createAttribute( name ); attribute.setValue( value ); setAttributeNode( attribute ); reportPropertyChanged( name ); } /** * get the event Handler script for the event e.g. onchange, onmousedown, onclick, onmouseup * execute the script if it's assigned by calling doEvent for the script * @param eventName * @return */ public boolean handleEvent(String eventName) { // check whether onclick is activated if (eventName.toLowerCase().equals("onclick")) { handleEvent("onmousedown"); } String eventScript = getAttribute( eventName ); boolean result=doEventScript(eventScript); if (eventName.toLowerCase().equals("onclick")) { handleEvent("onmouseup"); } return result; } public void setAttributeNS( String namespaceURI, String qualifiedName, String value ) throws DOMException { Attr attribute = getOwnerDocument().createAttributeNS( namespaceURI, qualifiedName ); attribute.setValue( value ); setAttributeNodeNS( attribute ); } public void removeAttribute( String name ) throws DOMException { _attributes.remove( name ); } public Attr getAttributeNode( String name ) { return (Attr) _attributes.get( name ); } public Attr setAttributeNode( Attr newAttr ) throws DOMException { if (newAttr.getOwnerDocument() != getOwnerDocument()) throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, "attribute must be from the same document as the element" ); ((AttrImpl) newAttr).setOwnerElement( this ); AttrImpl oldAttr = (AttrImpl) _attributes.put( newAttr.getName(), newAttr ); if (oldAttr != null) oldAttr.setOwnerElement( null ); return oldAttr; } public Attr setAttributeNodeNS( Attr newAttr ) throws DOMException { if (newAttr.getOwnerDocument() != getOwnerDocument()) throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, "attribute must be from the same document as the element" ); ((AttrImpl) newAttr).setOwnerElement( this ); AttrImpl oldAttr = (AttrImpl) _attributes.put( newAttr.getName(), newAttr ); if (oldAttr != null) oldAttr.setOwnerElement( null ); return oldAttr; } public Attr removeAttributeNode( Attr oldAttr ) throws DOMException { if (!_attributes.containsValue( oldAttr)) throw new DOMException( DOMException.NOT_FOUND_ERR, "Specified attribute is not defined for this element" ); AttrImpl removedAttr = (AttrImpl) _attributes.remove( oldAttr.getName() ); if (removedAttr != null) removedAttr.setOwnerElement( null ); return removedAttr; } public boolean hasAttribute( String name ) { return _attributes.containsKey( name ); } // ----------------------- namespaces are not supported at present -------------------------------- public String getAttributeNS( String namespaceURI, String localName ) { return null; } public void removeAttributeNS( String namespaceURI, String localName ) throws DOMException { } public Attr getAttributeNodeNS( String namespaceURI, String localName ) { return null; } public NodeList getElementsByTagNameNS( String namespaceURI, String localName ) { return null; } public boolean hasAttributeNS( String namespaceURI, String localName ) { return false; } public static Element importNode( DocumentImpl document, Element original, boolean deep ) { Element copy = document.createElementNS( original.getNamespaceURI(), original.getTagName() ); NamedNodeMap attributes = original.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { copy.setAttributeNode( (Attr) document.importNode( attributes.item(i), false ) ); } if (deep) document.importChildren( original, copy ); return copy; } //------------------------------------- DOM level 3 methods ------------------------------------------------------------ public TypeInfo getSchemaTypeInfo() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setIdAttribute( String name, boolean isId ) throws DOMException { //To change body of implemented methods use File | Settings | File Templates. } public void setIdAttributeNS( String namespaceURI, String localName, boolean isId ) throws DOMException { //To change body of implemented methods use File | Settings | File Templates. } public void setIdAttributeNode( Attr idAttr, boolean isId ) throws DOMException { //To change body of implemented methods use File | Settings | File Templates. } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLAnchorElementImpl.java0000644000175000017500000001162511014557542027022 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLAnchorElementImpl.java 840 2008-03-29 23:53:21Z wolfgang_fahl $ * * Copyright (c) 2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLAnchorElement; import java.net.URL; import java.net.MalformedURLException; /** * * @author Russell Gold **/ public class HTMLAnchorElementImpl extends HTMLElementImpl implements HTMLAnchorElement { ElementImpl create() { return new HTMLAnchorElementImpl(); } public String getCharset() { return getAttributeWithNoDefault( "charset" ); } public String getHref() { String relativeLocation = getAttributeWithNoDefault( "href" ); if (relativeLocation.indexOf( ':' ) > 0 || relativeLocation.equals( "#" )) { return relativeLocation; } else { try { return new URL( ((HTMLDocumentImpl) getOwnerDocument()).getBaseUrl(), relativeLocation ).toExternalForm(); } catch (MalformedURLException e) { return e.toString(); } } } public String getHreflang() { return getAttributeWithNoDefault( "hreflang" ); } public String getRel() { return getAttributeWithNoDefault( "rel" ); } public String getRev() { return getAttributeWithNoDefault( "rev" ); } public String getTarget() { return getAttributeWithNoDefault( "target" ); } public String getType() { return getAttributeWithNoDefault( "type" ); } public void setCharset( String charset ) { setAttribute( "charset", charset ); } public void setHref( String href ) { setAttribute( "href", href ); } public void setHreflang( String hreflang ) { setAttribute( "hreflang", hreflang ); } public void setRel( String rel ) { setAttribute( "rel", rel ); } public void setRev( String rev ) { setAttribute( "rev", rev ); } public void setTarget( String target ) { setAttribute( "target", target ); } public void setType( String type ) { setAttribute( "type", type ); } /** * simulate blur */ public void blur() { handleEvent("onblur"); } /** * simulate focus; */ public void focus() { handleEvent("onfocus"); } public String getAccessKey() { return getAttributeWithNoDefault( "accesskey" ); } public String getCoords() { return getAttributeWithNoDefault( "coords" ); } public String getName() { return getAttributeWithNoDefault( "name" ); } public String getShape() { return getAttributeWithNoDefault( "shape" ); } public int getTabIndex() { return getIntegerAttribute( "tabindex" ); } public void setAccessKey( String accessKey ) { setAttribute( "accesskey", accessKey ); } public void setCoords( String coords ) { setAttribute( "coords", coords ); } public void setName( String name ) { setAttribute( "name", name ); } public void setShape( String shape ) { setAttribute( "shape", shape ); } public void setTabIndex( int tabIndex ) { setAttribute( "tabindex", tabIndex ); } public void doClickAction() { if (null == getHref() || getHref().startsWith( "#" )) return; try { ((HTMLDocumentImpl) getOwnerDocument()).getWindow().submitRequest( this, "GET", getHref(), getTarget(), new byte[0] ); } catch (Exception e) { throw new RuntimeException( "Error clicking link: " + e ); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLAppletElementImpl.java0000644000175000017500000001131611014557540027030 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLAppletElementImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, 2008 Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLAppletElement; /** * @author Russell Gold */ public class HTMLAppletElementImpl extends HTMLElementImpl implements HTMLAppletElement { ElementImpl create() { return new HTMLAppletElementImpl(); } public String getAlign() { return getAttributeWithNoDefault( "align" ); } public void setAlign( String align ) { setAttribute( "align", align ); } public String getAlt() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setAlt( String alt ) { //To change body of implemented methods use File | Settings | File Templates. } public String getArchive() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setArchive( String archive ) { //To change body of implemented methods use File | Settings | File Templates. } public String getCode() { return getAttributeWithNoDefault( "code" ); } public void setCode( String code ) { setAttribute( "code", code ); } /** * get the codebase of this applet * modified for bug report [ 1895501 ] Handling no codebase attribute in APPLET tag */ public String getCodeBase() { return getAttributeWithDefault( "codebase", "." ); } public void setCodeBase( String codeBase ) { setAttribute( "codebase", codeBase ); } public String getHeight() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setHeight( String height ) { //To change body of implemented methods use File | Settings | File Templates. } public String getHspace() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setHspace( String hspace ) { //To change body of implemented methods use File | Settings | File Templates. } public String getName() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setName( String name ) { //To change body of implemented methods use File | Settings | File Templates. } public String getObject() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setObject( String object ) { //To change body of implemented methods use File | Settings | File Templates. } public String getVspace() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setVspace( String vspace ) { //To change body of implemented methods use File | Settings | File Templates. } public String getWidth() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setWidth( String width ) { //To change body of implemented methods use File | Settings | File Templates. } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLAreaElementImpl.java0000644000175000017500000000662511014557540026462 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLAreaElementImpl.java 781 2007-06-17 17:31:49Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLAreaElement; import java.net.URL; import java.net.MalformedURLException; /** * * @author Russell Gold **/ public class HTMLAreaElementImpl extends HTMLElementImpl implements HTMLAreaElement { ElementImpl create() { return new HTMLAreaElementImpl(); } public String getHref() { try { return new URL( ((HTMLDocumentImpl) getOwnerDocument()).getWindow().getUrl(), getAttributeWithNoDefault( "href" ) ).toExternalForm(); } catch (MalformedURLException e) { return e.toString(); } } public String getTarget() { return getAttributeWithNoDefault( "target" ); } public void setHref( String href ) { setAttribute( "href", href ); } public void setTarget( String target ) { setAttribute( "target", target ); } public String getAccessKey() { return getAttributeWithNoDefault( "accesskey" ); } public String getCoords() { return getAttributeWithNoDefault( "coords" ); } public String getShape() { return getAttributeWithNoDefault( "shape" ); } public int getTabIndex() { return getIntegerAttribute( "tabindex" ); } public void setAccessKey( String accessKey ) { setAttribute( "accesskey", accessKey ); } public void setCoords( String coords ) { setAttribute( "coords", coords ); } public void setShape( String shape ) { setAttribute( "shape", shape ); } public void setTabIndex( int tabIndex ) { setAttribute( "tabindex", tabIndex ); } public String getAlt() { return getAttributeWithNoDefault( "alt" ); } public boolean getNoHref() { return getBooleanAttribute( "nohref" ); } public void setAlt( String alt ) { setAttribute( "alt", alt ); } public void setNoHref( boolean noHref ) { setAttribute( "nohref", noHref ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLBaseElementImpl.java0000644000175000017500000000406111014557540026454 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLBaseElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLBaseElement; /** * * @author Russell Gold **/ public class HTMLBaseElementImpl extends HTMLElementImpl implements HTMLBaseElement { ElementImpl create() { return new HTMLBaseElementImpl(); } public String getHref() { return getAttributeWithNoDefault( "href" ); } public String getTarget() { return getAttributeWithNoDefault( "target" ); } public void setHref( String href ) { setAttribute( "href", href ); } public void setTarget( String target ) { setAttribute( "target", target ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLBodyElementImpl.java0000644000175000017500000000654411014557542026511 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLBodyElementImpl.java 839 2008-03-29 23:30:13Z wolfgang_fahl $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLBodyElement; import org.mozilla.javascript.Function; import org.mozilla.javascript.Scriptable; /** * * @author Russell Gold **/ public class HTMLBodyElementImpl extends HTMLElementImpl implements HTMLBodyElement { private HTMLEventHandler _onLoad = new HTMLEventHandler( this, "onload" ); ElementImpl create() { return new HTMLBodyElementImpl(); } /** * * @return the onload event */ public Function getOnloadEvent() { if (getParentScope() == null && getOwnerDocument() instanceof Scriptable) setParentScope( (Scriptable) getOwnerDocument() ); return _onLoad.getHandler(); } //----------------------------------------- HTMLBodyElement methods ---------------------------------------------------- public String getALink() { return getAttributeWithNoDefault( "aLink" ); } public String getBackground() { return getAttributeWithNoDefault( "background" ); } public String getBgColor() { return getAttributeWithNoDefault( "bgColor" ); } public String getLink() { return getAttributeWithNoDefault( "link" ); } public String getText() { return getAttributeWithNoDefault( "text" ); } public String getVLink() { return getAttributeWithNoDefault( "vLink" ); } public void setALink( String aLink ) { setAttribute( "aLink", aLink ); } public void setBackground( String background ) { setAttribute( "background", background ); } public void setBgColor( String bgColor ) { setAttribute( "bgColor", bgColor ); } public void setLink( String link ) { setAttribute( "link", link ); } public void setText( String text ) { setAttribute( "text", text ); } public void setVLink( String vLink ) { setAttribute( "vLink", vLink ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLButtonElementImpl.java0000644000175000017500000000435011014557540027056 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLSelectElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLButtonElement; /** * @author Russell Gold */ public class HTMLButtonElementImpl extends HTMLControl implements HTMLButtonElement { ElementImpl create() { return new HTMLButtonElementImpl(); } public String getAccessKey() { return getAttributeWithNoDefault( "accesskey" ); } public void setAccessKey( String accessKey ) { setAttribute( "accesskey", accessKey ); } public String getValue() { return getAttributeWithNoDefault( "value" ); } public void setValue( String value ) { setAttribute( "value", value ); } public String getType() { return getAttributeWithDefault( "type", "submit" ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLCollectionImpl.java0000644000175000017500000000740011014557540026363 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLCollectionImpl.java 781 2007-06-17 17:31:49Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLCollection; import org.w3c.dom.html.HTMLElement; import org.w3c.dom.html.HTMLFormElement; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.Scriptable; /** * * @author Russell Gold **/ public class HTMLCollectionImpl extends ScriptableObject implements HTMLCollection { private NodeList _list; public static HTMLCollectionImpl createHTMLCollectionImpl( NodeList list ) { HTMLCollectionImpl htmlCollection = new HTMLCollectionImpl(); htmlCollection.initialize( list ); return htmlCollection; } private void initialize( NodeList list ) { _list = list; } //------------------------------------------ HTMLCollection methods -------------------------------------------------- public int getLength() { return _list.getLength(); } public Node item( int index ) { return _list.item( index ); } public Node namedItem( String name ) { if (name == null) return null; Node nodeByName = null; for (int i = 0; null == nodeByName && i < getLength(); i++) { Node node = item(i); if (!(node instanceof HTMLElementImpl)) continue; if (name.equalsIgnoreCase( ((HTMLElement) node).getId() )) return node; if (name.equalsIgnoreCase( ((HTMLElementImpl) node).getAttributeWithNoDefault( "name" )) ) nodeByName = node; } return nodeByName; } //------------------------------------------ ScriptableObject methods -------------------------------------------------- public String getClassName() { return getClass().getName(); } public Object get( String propertyName, Scriptable scriptable ) { Object result = super.get( propertyName, scriptable ); if (result != NOT_FOUND) return result; Object namedProperty = ScriptingSupport.getNamedProperty( this, propertyName, scriptable ); if (namedProperty != NOT_FOUND) return namedProperty; Node namedItem = namedItem( propertyName ); return namedItem == null ? NOT_FOUND : namedItem; } public Object get( int index, Scriptable start ) { if (index < 0 || index >= _list.getLength()) return NOT_FOUND; return item( index ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLContainerDelegate.java0000644000175000017500000001026211014557540027023 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLContainerDelegate.java 912 2008-04-06 07:25:00Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLCollection; import org.w3c.dom.Node; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import com.meterware.httpunit.ParsedHTML; import java.util.ArrayList; import java.util.Iterator; /** * @author Russell Gold */ class HTMLContainerDelegate { private NodeImpl.IteratorMask _iteratorMask = NodeImpl.SKIP_IFRAMES; HTMLContainerDelegate( NodeImpl.IteratorMask iteratorMask ) { _iteratorMask = iteratorMask; } /** * get Links for a given Node * @param rootNode * @return */ HTMLCollection getLinks( NodeImpl rootNode ) { ArrayList elements = new ArrayList(); for (Iterator each = rootNode.preOrderIteratorAfterNode( _iteratorMask ); each.hasNext();) { Node node = (Node) each.next(); if (node.getNodeType() != Node.ELEMENT_NODE) continue; if (ParsedHTML.isWebLink(node)) { elements.add( node ); } } return HTMLCollectionImpl.createHTMLCollectionImpl( new NodeListImpl( elements ) ); } HTMLCollection getForms( NodeImpl rootNode ) { ArrayList elements = new ArrayList(); for (Iterator each = rootNode.preOrderIteratorAfterNode( _iteratorMask ); each.hasNext();) { Node node = (Node) each.next(); if (node.getNodeType() != Node.ELEMENT_NODE) continue; if ("form".equalsIgnoreCase( ((Element) node).getTagName() )) { elements.add( node ); } } return HTMLCollectionImpl.createHTMLCollectionImpl( new NodeListImpl( elements ) ); } HTMLCollection getAnchors( NodeImpl rootNode ) { NodeList nodeList = rootNode.getElementsByTagName( "A" ); ArrayList elements = new ArrayList(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item( i ); if (node.getAttributes().getNamedItem( "name" ) != null) { elements.add( node ); } } return HTMLCollectionImpl.createHTMLCollectionImpl( new NodeListImpl( elements ) ); } HTMLCollection getImages( NodeImpl rootNode ) { ArrayList elements = new ArrayList(); rootNode.appendElementsWithTags( new String[] {"img"}, elements ); return HTMLCollectionImpl.createHTMLCollectionImpl( new NodeListImpl( elements ) ); } HTMLCollection getApplets( NodeImpl rootNode ) { ArrayList elements = new ArrayList(); rootNode.appendElementsWithTags( new String[] {"applet"}, elements ); return HTMLCollectionImpl.createHTMLCollectionImpl( new NodeListImpl( elements ) ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLContainerElement.java0000644000175000017500000000343511014557540026706 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLContainerElement.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLCollection; /** * @author Russell Gold */ public interface HTMLContainerElement { HTMLCollection getLinks(); HTMLCollection getImages(); HTMLCollection getApplets(); HTMLCollection getForms(); HTMLCollection getAnchors(); } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLControl.java0000644000175000017500000000746211014557540025076 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLControl.java 783 2007-07-22 16:08:45Z russgold $ * * Copyright (c) 2004-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.Node; import org.w3c.dom.html.HTMLFormElement; import org.w3c.dom.html.HTMLCollection; import java.util.Iterator; import java.io.IOException; import com.meterware.httpunit.protocol.ParameterProcessor; /** * * @author Russell Gold **/ public class HTMLControl extends HTMLElementImpl { public boolean getDisabled() { return getBooleanAttribute( "disabled" ); } public HTMLFormElement getForm() { Node parent = getParentNode(); while (parent != null && !("form".equalsIgnoreCase( parent.getNodeName() ))) parent = parent.getParentNode(); if (parent != null) return (HTMLFormElement) parent; for (Iterator here = preOrderIterator(); here.hasNext();) { Object o = here.next(); if (o instanceof HTMLFormElement) return getPreviousForm( (HTMLFormElement) o ); } return getLastFormInDocument(); } private HTMLFormElement getPreviousForm( HTMLFormElement nextForm ) { HTMLCollection forms = getHtmlDocument().getForms(); for (int i = 0; i < forms.getLength(); i++) { if (nextForm == forms.item( i )) return i == 0 ? null : (HTMLFormElement) forms.item( i-1 ); } return null; } private HTMLFormElement getLastFormInDocument() { HTMLCollection forms = getHtmlDocument().getForms(); return forms.getLength() == 0 ? null : (HTMLFormElement) forms.item( forms.getLength()-1 ); } public String getName() { return getAttributeWithNoDefault( "name" ); } public boolean getReadOnly() { return getBooleanAttribute( "readonly" ); } public int getTabIndex() { return getIntegerAttribute( "tabindex" ); } public String getType() { return getAttributeWithDefault( "type", "text" ); } public void setDisabled( boolean disabled ) { setAttribute( "disabled", disabled ); } public void setName( String name ) { setAttribute( "name", name ); } public void setReadOnly( boolean readOnly ) { setAttribute( "readonly", readOnly ); } public void setTabIndex( int tabIndex ) { setAttribute( "tabindex", tabIndex ); } public void reset() {} void addValues( ParameterProcessor processor, String characterSet ) throws IOException {} public void silenceSubmitButton() {} } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLDocumentImpl.java0000644000175000017500000002574011014557540026055 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLDocumentImpl.java 829 2008-03-28 10:17:35Z wolfgang_fahl $ * * Copyright (c) 2004-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.*; import org.w3c.dom.*; import org.w3c.dom.Node; import org.mozilla.javascript.*; import java.util.Hashtable; import java.util.Iterator; import java.util.ArrayList; import java.net.URL; import java.net.MalformedURLException; /** * * @author Russell Gold **/ public class HTMLDocumentImpl extends DocumentImpl implements HTMLDocument, HTMLContainerElement { private static Hashtable _exemplars = new Hashtable(); private DomWindow _window; private StringBuffer _writeBuffer; private HTMLContainerDelegate _containerDelegate = new HTMLContainerDelegate( SKIP_IFRAMES ); public void setIFramesEnabled( boolean enabled ) { _containerDelegate = new HTMLContainerDelegate( enabled ? SKIP_IFRAMES : null ); } public Object get( String propertyName, Scriptable scriptable ) { if (propertyName.equals( "document" )) return this; Object result = super.get( propertyName, scriptable ); if (result != NOT_FOUND) return result; Element element = getElementById( propertyName ); if (element != null) return element; NodeList elements = getElementsByName( propertyName ); if (elements.getLength() >= 1) return elements.item( 0 ); return ScriptingSupport.getNamedProperty( this, getJavaPropertyName( propertyName ), scriptable ); } public void put( String propertyName, Scriptable initialObject, Object value ) { ScriptingSupport.setNamedProperty( this, getJavaPropertyName( propertyName ), value ); } //------------------------------------------ HTMLContainerElement methods ---------------------------------------------- public HTMLCollection getLinks() { return _containerDelegate.getLinks( this ); } public HTMLCollection getImages() { return _containerDelegate.getImages( this ); } public HTMLCollection getApplets() { return _containerDelegate.getApplets( this ); } public HTMLCollection getForms() { return _containerDelegate.getForms( this ); } public HTMLCollection getAnchors() { return _containerDelegate.getAnchors( this ); } //-------------------------------------------- HTMLDocument methods ---------------------------------------------------- public String getTitle() { HTMLTitleElement result = getTitleElement(); return result == null ? "" : result.getText(); } private HTMLTitleElement getTitleElement() { HTMLTitleElement result = null; NodeList titleNodes = getElementsByTagName( "title" ); for (int i = 0; i < titleNodes.getLength(); i++) { Node node = titleNodes.item( i ); if (node instanceof HTMLTitleElement) { result = ((HTMLTitleElement) node); } } return result; } private HTMLHeadElement getHeadElement() { NodeList headNodes = getElementsByTagName( "head" ); for (int i = 0; i < headNodes.getLength(); i++) { Node node = headNodes.item( i ); if (node instanceof HTMLHeadElement) { return ((HTMLHeadElement) node); } } HTMLHeadElement head = (HTMLHeadElement) createElement( "head" ); getHtmlElement().appendChild( head ); return head; } private HTMLHtmlElement getHtmlElement() { NodeList htmlNodes = getElementsByTagName( "html" ); for (int i = 0; i < htmlNodes.getLength(); i++) { Node node = htmlNodes.item( i ); if (node instanceof HTMLHtmlElement) { return ((HTMLHtmlElement) node); } } HTMLHtmlElement html = (HTMLHtmlElement) createElement( "html" ); appendChild( html ); return html; } public void setTitle( String title ) { HTMLTitleElement titleElement = getTitleElement(); if (titleElement != null) { titleElement.setText( title ); } else { titleElement = (HTMLTitleElement) createElement( "title" ); titleElement.setText( title ); getHeadElement().appendChild( titleElement ); } } public String getReferrer() { return null; } public String getDomain() { return null; } public String getURL() { return null; } public HTMLElement getBody() { NodeList bodyNodes = getElementsByTagName( "body" ); for (int i = 0; i < bodyNodes.getLength(); i++) { Node node = bodyNodes.item( i ); if (node instanceof HTMLBodyElement) { return ((HTMLBodyElement) node); } } return null; } public void setBody( HTMLElement body ) { getHtmlElement().appendChild( body ); } public String getCookie() { return null; } public void setCookie( String cookie ) { } public void open() { } public void close() { if (getWindow().replaceText( getWriteBuffer().toString(), getMimeType()) ) clearWriteBuffer(); } private String getMimeType() { return "text/html"; } public void write( String text ) { getWriteBuffer().append( text ); } public void writeln( String text ) { getWriteBuffer().append( text ).append( (char) 0x0d ).append( (char) 0x0a ); } public NodeList getElementsByName( String elementName ) { ArrayList elements = new ArrayList(); for (Iterator each = preOrderIterator(); each.hasNext();) { Node node = (Node) each.next(); if (!(node instanceof HTMLElementImpl)) continue; HTMLElementImpl element = (HTMLElementImpl) node; if (elementName.equals( element.getAttributeWithNoDefault( "name" ) )) elements.add( element ); } return new NodeListImpl( elements ); } public Element createElement( String tagName ) throws DOMException { ElementImpl element = getExemplar( tagName ).create(); element.initialize( this, toNodeCase( tagName ) ); return element; } public Element createElementNS( String namespaceURI, String qualifiedName ) throws DOMException { ElementImpl element = getExemplar( qualifiedName ).create(); element.initialize( this, namespaceURI, toNodeCase( qualifiedName ) ); return element; } public NodeList getElementsByTagName( String name ) { return super.getElementsByTagName( toNodeCase( name ) ); } public Node cloneNode( boolean deep ) { HTMLDocumentImpl copy = new HTMLDocumentImpl(); if (deep) copy.importChildren( this, copy ); return copy; } private static HTMLElementImpl getExemplar( String tagName ) { HTMLElementImpl impl = (HTMLElementImpl) _exemplars.get( tagName.toLowerCase() ); if (impl == null) impl = new HTMLElementImpl(); return impl; } String toNodeCase( String nodeName ) { return nodeName.toUpperCase(); } HTMLContainerDelegate getContainerDelegate() { return _containerDelegate; } static { _exemplars.put( "html", new HTMLHtmlElementImpl() ); _exemplars.put( "head", new HTMLHeadElementImpl() ); _exemplars.put( "link", new HTMLLinkElementImpl() ); _exemplars.put( "title", new HTMLTitleElementImpl() ); _exemplars.put( "meta", new HTMLMetaElementImpl() ); _exemplars.put( "base", new HTMLBaseElementImpl() ); _exemplars.put( "style", new HTMLStyleElementImpl() ); _exemplars.put( "body", new HTMLBodyElementImpl() ); _exemplars.put( "form", new HTMLFormElementImpl() ); _exemplars.put( "select", new HTMLSelectElementImpl() ); _exemplars.put( "option", new HTMLOptionElementImpl() ); _exemplars.put( "input", new HTMLInputElementImpl() ); _exemplars.put( "button", new HTMLButtonElementImpl() ); _exemplars.put( "textarea", new HTMLTextAreaElementImpl() ); _exemplars.put( "a", new HTMLAnchorElementImpl() ); _exemplars.put( "area", new HTMLAreaElementImpl() ); _exemplars.put( "img", new HTMLImageElementImpl() ); _exemplars.put( "td", new HTMLTableCellElementImpl() ); _exemplars.put( "th", new HTMLTableCellElementImpl() ); _exemplars.put( "tr", new HTMLTableRowElementImpl() ); _exemplars.put( "table", new HTMLTableElementImpl() ); _exemplars.put( "p", new HTMLParagraphElementImpl() ); _exemplars.put( "iframe", new HTMLIFrameElementImpl() ); _exemplars.put( "applet", new HTMLAppletElementImpl() ); } /** * get the Window * @return the window */ public DomWindow getWindow() { // if there is now window yet if (_window == null) { // create a window for this document _window = new DomWindow( this ); setParentScope( _window ); } return _window; } StringBuffer getWriteBuffer() { if (_writeBuffer == null) _writeBuffer = new StringBuffer(); return _writeBuffer; } public void clearWriteBuffer() { _writeBuffer = null; } URL getBaseUrl() { NodeList list = getElementsByTagName( "base" ); if (list.getLength() == 0) return getWindow().getUrl(); HTMLBaseElement base = (HTMLBaseElement) list.item( 0 ); try { return new URL( getWindow().getUrl(), base.getHref() ); } catch (MalformedURLException e) { return getWindow().getUrl(); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLElementImpl.java0000644000175000017500000001056311014557540025665 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLElementImpl.java 782 2007-07-03 01:13:34Z russgold $ * * Copyright (c) 2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLElement; import org.w3c.dom.NodeList; import org.w3c.dom.Attr; /** * @author Russell Gold */ public class HTMLElementImpl extends ElementImpl implements HTMLElement { public final static String UNSPECIFIED_ATTRIBUTE = null; ElementImpl create() { return new HTMLElementImpl(); } public void click() { doClickAction(); } public void doClickAction() {} public String getId() { return getAttributeWithNoDefault( "id" ); } public void setId( String id ) { setAttribute( "id", id ); } public String getTitle() { return getAttributeWithNoDefault( "title" ); } public void setTitle( String title ) { setAttribute( "title", title ); } public String getLang() { return getAttributeWithNoDefault( "lang" ); } public void setLang( String lang ) { setAttribute( "lang", lang ); } public String getDir() { return getAttributeWithNoDefault( "dir" ); } public void setDir( String dir ) { setAttribute( "dir", dir ); } public String getClassName() { return getAttributeWithNoDefault( "class" ); } public void setClassName( String className ) { setAttribute( "class", className ); } public NodeList getElementsByTagName( String name ) { return super.getElementsByTagName( ((HTMLDocumentImpl) getOwnerDocument()).toNodeCase( name ) ); } //---------------------------------------------- protected methods ----------------------------------------------------- final protected String getAttributeWithDefault( String attributeName, String defaultValue ) { if (hasAttribute( attributeName )) return getAttribute( attributeName ); return defaultValue; } final protected String getAttributeWithNoDefault( String attributeName ) { if (hasAttribute( attributeName )) return getAttribute( attributeName ); return UNSPECIFIED_ATTRIBUTE; } protected boolean getBooleanAttribute( String name ) { Attr attr = getAttributeNode( name ); return attr != null && !attr.getValue().equalsIgnoreCase( "false" ); } protected int getIntegerAttribute( String name ) { String value = getAttribute( name ); return value.length() == 0 ? 0 : Integer.parseInt( value ); } protected int getIntegerAttribute( String name, int defaultValue ) { String value = getAttribute( name ); return value.length() == 0 ? defaultValue : Integer.parseInt( value ); } protected void setAttribute( String name, boolean disabled ) { setAttribute( name, disabled ? "true" : "false" ); } protected void setAttribute( String name, int value ) { setAttribute( name, Integer.toString( value ) ); } HTMLDocumentImpl getHtmlDocument() { return (HTMLDocumentImpl) getOwnerDocument(); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLEventHandler.java0000644000175000017500000000545111014557542026033 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Header$ * * Copyright (c) 2007-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.mozilla.javascript.Function; import org.mozilla.javascript.Context; /** * the handler for HTML events * @author Russell Gold */ class HTMLEventHandler { private HTMLElementImpl _baseElement; private String _handlerName; private Function _handler; /** * create a handler for the given HTML Event * @param baseElement * @param handlerName */ public HTMLEventHandler( HTMLElementImpl baseElement, String handlerName ) { _baseElement = baseElement; _handlerName = handlerName; } /** * set the handler Function for this event Handler * @param handler */ void setHandler( Function handler ) { _handler = handler; } /** * get the (cached) handler Function for this event Handler * on first access compile the function * @return */ Function getHandler() { if (_handler == null) { String attribute = _baseElement.getAttributeWithNoDefault( _handlerName ); if (attribute != null && Context.getCurrentContext() != null) { _handler = Context.getCurrentContext().compileFunction( _baseElement, "function " + AbstractDomComponent.createAnonymousFunctionName() + "() { " + attribute + "}", "httpunit", 0, null ); } } return _handler; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLFormElementImpl.java0000644000175000017500000001701611014557540026511 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLFormElementImpl.java 856 2008-03-31 09:09:12Z wolfgang_fahl $ * * Copyright (c) 2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLFormElement; import org.w3c.dom.html.HTMLCollection; import org.w3c.dom.Node; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Element; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import java.util.ArrayList; import java.util.Iterator; import java.net.URL; import java.io.IOException; import com.meterware.httpunit.scripting.FormScriptable; import com.meterware.httpunit.protocol.URLEncodedString; /** * * @author Russell Gold **/ public class HTMLFormElementImpl extends HTMLElementImpl implements HTMLFormElement, FormScriptable { ElementImpl create() { return new HTMLFormElementImpl(); } //------------------------------- ScriptableObject methods ---------------------------------------------------------- public Object get( String propertyName, Scriptable scriptable ) { HTMLCollection elements = getElements(); for (int i=0; i < elements.getLength(); i++) { Node node = elements.item( i ); NamedNodeMap attributes = node.getAttributes(); AttrImpl nameAttribute = (AttrImpl) attributes.getNamedItem( "name" ); if (nameAttribute != null && propertyName.equals( nameAttribute.getValue() )) return node; AttrImpl idAttribute = (AttrImpl) attributes.getNamedItem( "id" ); if (idAttribute != null && propertyName.equals( idAttribute.getValue() )) return node; } return super.get( propertyName, scriptable ); } //------------------------------- HTMLFormElement methods ---------------------------------------------------------- public String getAcceptCharset() { return getAttributeWithDefault( "accept-charset", "UNKNOWN" ); } public void setAcceptCharset( String acceptCharset ) { setAttribute( "accept-charset", acceptCharset ); } public String getAction() { return getAttribute( "action" ); } public void setAction( String action ) { setAttribute( "action", action ); } public void setParameterValue( String name, String value ) { Object control = get( name, null ); if (control instanceof ScriptableObject) ((ScriptableObject) control).put( "value", this, value ); } public String getEnctype() { return getAttributeWithDefault( "enctype", "application/x-www-form-urlencoded" ); } public void setEnctype( String enctype ) { setAttribute( "enctype", enctype ); } public String getMethod() { return getAttributeWithDefault( "method", "get" ); } public void setMethod( String method ) { setAttribute( "method", method ); } /** * getter for the name * @see org.w3c.dom.html.HTMLFormElement#getName() */ public String getName() { String result=getAttributeWithNoDefault( "name" ); if (result==null) result=this.getId(); return result; } public void setName( String name ) { setAttribute( "name", name ); } public String getTarget() { return getAttributeWithNoDefault( "target" ); } public void setTarget( String target ) { setAttribute( "target", target ); } public HTMLCollection getElements() { ArrayList elements = new ArrayList(); String[] names = new String[]{"INPUT", "TEXTAREA", "BUTTON", "SELECT"}; for (Iterator each = preOrderIteratorAfterNode(); each.hasNext();) { Node node = (Node) each.next(); if (node instanceof HTMLFormElement) break; if (node.getNodeType() != ELEMENT_NODE) continue; String tagName = ((Element) node).getTagName(); for (int i = 0; i < names.length; i++) { if (tagName.equalsIgnoreCase( names[i] )) elements.add( node ); } } return HTMLCollectionImpl.createHTMLCollectionImpl( new NodeListImpl( elements ) ); } public int getLength() { return 0; } public void reset() { HTMLCollection elements = getElements(); for (int i = 0; i < elements.getLength(); i++) { Node node = elements.item(i); if (node instanceof HTMLControl) ((HTMLControl) node).reset(); } } public void submit() { doSubmitAction(); } /** * Handles the actual form submission - does not handle the "submit" event. */ void doSubmitAction() { try { if ("get".equalsIgnoreCase( getMethod() )) { getDomWindow().submitRequest( this, getMethod(), getEffectiveUrl(), getTarget(), new byte[0] ); } else if ("post".equalsIgnoreCase( getMethod() )) { getDomWindow().submitRequest( this, getMethod(), getAction(), getTarget(), new byte[0] ); } } catch (Exception e) { throw new RuntimeException( "Error submitting form: " + e ); } finally { silenceSubmitButtons(); } } private void silenceSubmitButtons() { HTMLCollection controls = getElements(); for (int i = 0; i < controls.getLength(); i++) { ((HTMLControl) controls.item( i )).silenceSubmitButton(); } } private String getEffectiveUrl() throws IOException { StringBuffer spec = new StringBuffer( getAction() ); if ("get".equalsIgnoreCase( getMethod() )) { URLEncodedString parameters = new URLEncodedString(); HTMLCollection controls = getElements(); for (int i = 0; i < controls.getLength(); i++) { ((HTMLControl) controls.item( i )).addValues( parameters, "us-ascii" ); } if ((spec.indexOf( "?" ) >= 0) && !(spec.toString().endsWith( "?" ))) { spec.append( '&' ); } else { spec.append( '?' ); } spec.append( parameters.getString() ); } return new URL( getDomWindow().getUrl(), spec.toString() ).toExternalForm(); } private DomWindow getDomWindow() { return ((HTMLDocumentImpl) getOwnerDocument()).getWindow(); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLHeadElementImpl.java0000644000175000017500000000360711014557542026452 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLHeadElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLHeadElement; /** * * @author Russell Gold **/ public class HTMLHeadElementImpl extends HTMLElementImpl implements HTMLHeadElement { ElementImpl create() { return new HTMLHeadElementImpl(); } public String getProfile() { return getAttributeWithNoDefault( "profile" ); } public void setProfile( String profile ) { setAttribute( "profile", profile ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLHtmlElementImpl.java0000644000175000017500000000361011014557540026505 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLHtmlElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLHtmlElement; /** * * @author Russell Gold **/ public class HTMLHtmlElementImpl extends HTMLElementImpl implements HTMLHtmlElement { ElementImpl create() { return new HTMLHtmlElementImpl(); } public String getVersion() { return getAttributeWithNoDefault( "version" ); } public void setVersion( String version ) { setAttribute( "version", version ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLIFrameElementImpl.java0000644000175000017500000001113411014557542026746 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLIFrameElementImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLIFrameElement; import org.w3c.dom.Document; /** * @author Russell Gold */ public class HTMLIFrameElementImpl extends HTMLElementImpl implements HTMLIFrameElement { ElementImpl create() { return new HTMLIFrameElementImpl(); } public String getAlign() { return getAttributeWithNoDefault( "align" ); } public void setAlign( String align ) { setAttribute( "align", align ); } public String getFrameBorder() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setFrameBorder( String frameBorder ) { //To change body of implemented methods use File | Settings | File Templates. } public String getHeight() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setHeight( String height ) { //To change body of implemented methods use File | Settings | File Templates. } public String getLongDesc() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setLongDesc( String longDesc ) { //To change body of implemented methods use File | Settings | File Templates. } public String getMarginHeight() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setMarginHeight( String marginHeight ) { //To change body of implemented methods use File | Settings | File Templates. } public String getMarginWidth() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setMarginWidth( String marginWidth ) { //To change body of implemented methods use File | Settings | File Templates. } public String getName() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setName( String name ) { //To change body of implemented methods use File | Settings | File Templates. } public String getScrolling() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setScrolling( String scrolling ) { //To change body of implemented methods use File | Settings | File Templates. } public String getSrc() { return getAttributeWithNoDefault( "src" ); } public void setSrc( String src ) { setAttribute( "src", src ); } public String getWidth() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setWidth( String width ) { //To change body of implemented methods use File | Settings | File Templates. } public Document getContentDocument() { return null; //To change body of implemented methods use File | Settings | File Templates. } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLImageElementImpl.java0000644000175000017500000000773411014557540026636 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLImageElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLImageElement; /** * * @author Russell Gold **/ public class HTMLImageElementImpl extends HTMLElementImpl implements HTMLImageElement { ElementImpl create() { return new HTMLImageElementImpl(); } public String getAlign() { return getAttributeWithNoDefault( "align" ); } public String getAlt() { return getAttributeWithNoDefault( "alt" ); } public String getBorder() { return getAttributeWithNoDefault( "border" ); } public String getHeight() { return getAttributeWithNoDefault( "height" ); } public String getHspace() { return getAttributeWithNoDefault( "hspace" ); } public boolean getIsMap() { return getBooleanAttribute( "ismap" ); } public String getLongDesc() { return getAttributeWithNoDefault( "longdesc" ); } public String getLowSrc() { return null; } public String getName() { return getAttributeWithNoDefault( "name" ); } public String getSrc() { return getAttributeWithNoDefault( "src" ); } public String getUseMap() { return getAttributeWithNoDefault( "usemap" ); } public String getVspace() { return getAttributeWithNoDefault( "vspace" ); } public String getWidth() { return getAttributeWithNoDefault( "width" ); } public void setAlign( String align ) { setAttribute( "align", align ); } public void setAlt( String alt ) { setAttribute( "alt", alt ); } public void setBorder( String border ) { setAttribute( "border", border ); } public void setHeight( String height ) { setAttribute( "height", height ); } public void setHspace( String hspace ) { setAttribute( "hspace", hspace ); } public void setIsMap( boolean isMap ) { setAttribute( "ismap", isMap ); } public void setLongDesc( String longDesc ) { setAttribute( "longdesc", longDesc ); } public void setLowSrc( String lowSrc ) { } public void setName( String name ) { setAttribute( "name", name ); } public void setSrc( String src ) { setAttribute( "src", src ); } public void setUseMap( String useMap ) { setAttribute( "usemap", useMap ); } public void setVspace( String vspace ) { setAttribute( "vspace", vspace ); } public void setWidth( String width ) { setAttribute( "width", width ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLInputElementImpl.java0000644000175000017500000002467011014557542026713 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLInputElementImpl.java 840 2008-03-29 23:53:21Z wolfgang_fahl $ * * Copyright (c) 2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLInputElement; import org.w3c.dom.html.HTMLCollection; import org.w3c.dom.DOMException; import org.w3c.dom.Node; import com.meterware.httpunit.protocol.ParameterProcessor; import java.io.IOException; /** * * @author Russell Gold **/ public class HTMLInputElementImpl extends HTMLControl implements HTMLInputElement { private String _value; private Boolean _checked; private TypeSpecificBehavior _behavior; ElementImpl create() { return new HTMLInputElementImpl(); } /** * simulate blur */ public void blur() { handleEvent("onblur"); } /** * simulate focus; */ public void focus() { handleEvent("onfocus"); } public void doClickAction() { getBehavior().click(); } public void select() { } public String getAccept() { return getAttributeWithNoDefault( "accept" ); } public String getAccessKey() { return getAttributeWithNoDefault( "accessKey" ); } public String getAlign() { return getAttributeWithDefault( "align", "bottom" ); } public String getAlt() { return getAttributeWithNoDefault( "alt" ); } public boolean getChecked() { return getBehavior().getChecked(); } public boolean getDefaultChecked() { return getBooleanAttribute( "checked" ); } public String getDefaultValue() { return getAttributeWithNoDefault( "value" ); } public int getMaxLength() { return getIntegerAttribute( "maxlength" ); } public String getSize() { return getAttributeWithNoDefault( "size" ); } public String getSrc() { return getAttributeWithNoDefault( "src" ); } public String getUseMap() { return getAttributeWithNoDefault( "useMap" ); } public void setAccept( String accept ) { setAttribute( "accept", accept ); } public void setAccessKey( String accessKey ) { setAttribute( "accessKey", accessKey ); } public void setAlign( String align ) { setAttribute( "align", align ); } public void setAlt( String alt ) { setAttribute( "alt", alt ); } public void setChecked( boolean checked ) { getBehavior().setChecked( checked ); } public void setDefaultChecked( boolean defaultChecked ) { setAttribute( "checked", defaultChecked ); } public void setDefaultValue( String defaultValue ) { setAttribute( "value", defaultValue ); } public void setMaxLength( int maxLength ) { setAttribute( "maxlength", maxLength ); } public void setSize( String size ) { setAttribute( "size", size ); } public void setSrc( String src ) { setAttribute( "src", src ); } public void setUseMap( String useMap ) { setAttribute( "useMap", useMap ); } public String getValue() { return getBehavior().getValue(); } public void setValue( String value ) { getBehavior().setValue( value ); } public void reset() { getBehavior().reset(); } public void setAttribute( String name, String value ) throws DOMException { super.setAttribute( name, value ); if (name.equalsIgnoreCase( "type" )) selectBehavior( getType().toLowerCase() ); } void addValues( ParameterProcessor processor, String characterSet ) throws IOException { getBehavior().addValues( getName(), processor, characterSet ); } public void silenceSubmitButton() { getBehavior().silenceSubmitButton(); } void setState( boolean checked ) { _checked = checked ? Boolean.TRUE : Boolean.FALSE; } static boolean equals( String s1, String s2 ) { return s1 == null ? s2 == null : s1.equals( s2 ); } private void selectBehavior( String type ) { if (type == null || type.equals( "text") || type.equals( "password" ) || type.equals( "hidden" )) { _behavior = new EditableTextBehavior( this ); } else if (type.equals( "checkbox" )) { _behavior = new CheckboxBehavior( this ); } else if (type.equals( "radio" )) { _behavior = new RadioButtonBehavior( this ); } else if (type.equals( "reset" )) { _behavior = new ResetButtonBehavior( this ); } else if (type.equals( "submit" )) { _behavior = new SubmitButtonBehavior( this ); } else { _behavior = new DefaultBehavior( this ); } } private TypeSpecificBehavior getBehavior() { if (_behavior == null) selectBehavior( getType().toLowerCase() ); return _behavior; } interface TypeSpecificBehavior { void setValue( String value ); String getValue(); void reset(); void click(); boolean getChecked(); void setChecked( boolean checked ); void addValues( String name, ParameterProcessor processor, String characterSet ) throws IOException; void silenceSubmitButton(); } class DefaultBehavior implements TypeSpecificBehavior { private HTMLElementImpl _element; public DefaultBehavior( HTMLElementImpl element ) { _element = element; } public String getValue() { return _value != null ? _value : getDefaultValue(); } public void setValue( String value ) { if (HTMLInputElementImpl.equals( value, _value )) return; _value = value; reportPropertyChanged( "value" ); } public boolean getChecked() { return getDefaultChecked(); } public void setChecked( boolean checked ) {} public void reset() {} public void click() {} protected void reportPropertyChanged( String propertyName ) { _element.reportPropertyChanged( propertyName ); } public void addValues( String name, ParameterProcessor processor, String characterSet ) throws IOException { processor.addParameter( name, getValue(), characterSet ); } public void silenceSubmitButton() {} } class EditableTextBehavior extends DefaultBehavior { public EditableTextBehavior( HTMLElementImpl element ) { super( element ); } public void reset() { _value = null; } } class SubmitButtonBehavior extends DefaultBehavior { private boolean _sendWithSubmit; public SubmitButtonBehavior( HTMLElementImpl element ) { super( element ); } public void click() { _sendWithSubmit = true; ((HTMLFormElementImpl) getForm()).doSubmitAction(); } public void addValues( String name, ParameterProcessor processor, String characterSet ) throws IOException { if (!_sendWithSubmit) return; super.addValues( name, processor, characterSet ); } public void silenceSubmitButton() { _sendWithSubmit = false; } } class CheckboxBehavior extends DefaultBehavior { public CheckboxBehavior( HTMLElementImpl element ) { super( element ); } public boolean getChecked() { return _checked != null ? _checked.booleanValue() : getDefaultChecked(); } public void setChecked( boolean checked ) { setState( checked ); } public void reset() { _checked = null; } public void click() { setChecked( !getChecked() ); } public void addValues( String name, ParameterProcessor processor, String characterSet ) throws IOException { if (!getDisabled() && getChecked()) processor.addParameter( name, getFormValue(), characterSet ); } private String getFormValue() { return _value == null ? "on" : _value; } } class RadioButtonBehavior extends CheckboxBehavior { public RadioButtonBehavior( HTMLElementImpl element ) { super( element ); } public void setChecked( boolean checked ) { if (checked) { HTMLCollection elements = getForm().getElements(); for (int i = 0; i < elements.getLength(); i++) { Node node = elements.item(i); if (!(node instanceof HTMLInputElementImpl)) continue; HTMLInputElementImpl input = (HTMLInputElementImpl) node; if (getName().equals( input.getName() ) && input.getType().equalsIgnoreCase( "radio" )) input.setState( false ); } } setState( checked ); } public void click() { setChecked( true ); } } class ResetButtonBehavior extends DefaultBehavior { public ResetButtonBehavior( HTMLElementImpl element ) { super( element ); } public void click() { getForm().reset(); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLLinkElementImpl.java0000644000175000017500000000651111014557540026501 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLLinkElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLLinkElement; /** * * @author Russell Gold **/ public class HTMLLinkElementImpl extends HTMLElementImpl implements HTMLLinkElement { ElementImpl create() { return new HTMLLinkElementImpl(); } public String getCharset() { return getAttributeWithNoDefault( "charset" ); } public boolean getDisabled() { return getBooleanAttribute( "disabled" ); } public String getHref() { return getAttributeWithNoDefault( "href" ); } public String getHreflang() { return getAttributeWithNoDefault( "hreflang" ); } public String getMedia() { return getAttributeWithDefault( "media", "screen" ); } public String getRel() { return getAttributeWithNoDefault( "rel" ); } public String getRev() { return getAttributeWithNoDefault( "rev" ); } public String getTarget() { return getAttributeWithNoDefault( "target" ); } public String getType() { return getAttributeWithNoDefault( "type" ); } public void setCharset( String charset ) { setAttribute( "charset", charset ); } public void setDisabled( boolean disabled ) { setAttribute( "disabled", disabled ); } public void setHref( String href ) { setAttribute( "href", href ); } public void setHreflang( String hreflang ) { setAttribute( "hreflang", hreflang ); } public void setMedia( String media ) { setAttribute( "media", media ); } public void setRel( String rel ) { setAttribute( "rel", rel ); } public void setRev( String rev ) { setAttribute( "rev", rev ); } public void setTarget( String target ) { setAttribute( "target", target ); } public void setType( String type ) { setAttribute( "type", type ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLMetaElementImpl.java0000644000175000017500000000470511014557542026477 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLMetaElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLMetaElement; /** * * @author Russell Gold **/ public class HTMLMetaElementImpl extends HTMLElementImpl implements HTMLMetaElement { ElementImpl create() { return new HTMLMetaElementImpl(); } public String getContent() { return getAttributeWithNoDefault( "content" ); } public String getHttpEquiv() { return getAttributeWithNoDefault( "http-equiv" ); } public String getName() { return getAttributeWithNoDefault( "name" ); } public String getScheme() { return getAttributeWithNoDefault( "scheme" ); } public void setContent( String content ) { setAttribute( "content", content ); } public void setHttpEquiv( String httpEquiv ) { setAttribute( "http-equiv", httpEquiv ); } public void setName( String name ) { setAttribute( "name", name ); } public void setScheme( String scheme ) { setAttribute( "scheme", scheme ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLOptionElementImpl.java0000644000175000017500000000777411014557540027070 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLOptionElementImpl.java 783 2007-07-22 16:08:45Z russgold $ * * Copyright (c) 2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLOptionElement; import org.w3c.dom.Node; import com.meterware.httpunit.protocol.ParameterProcessor; import java.io.IOException; /** * * @author Russell Gold **/ public class HTMLOptionElementImpl extends HTMLControl implements HTMLOptionElement { private Boolean _selected; ElementImpl create() { return new HTMLOptionElementImpl(); } public boolean getDefaultSelected() { return getBooleanAttribute( "selected" ); } public int getIndex() { return getSelect().getIndexOf( this ); } public void setIndex( int i ) {}; // obsolete - required for compatibility with JDK 1.3 public String getLabel() { return getAttributeWithNoDefault( "label" ); } public boolean getSelected() { return _selected != null ? _selected.booleanValue() : getDefaultSelected(); } public String getText() { return asText(); } public void setDefaultSelected( boolean defaultSelected ) { } public void setLabel( String label ) { setAttribute( "label", label ); } public void setSelected( boolean selected ) { if (selected && getSelect().getType().equals( HTMLSelectElementImpl.TYPE_SELECT_ONE)) getSelect().clearSelected(); _selected = selected ? Boolean.TRUE : Boolean.FALSE; } private HTMLSelectElementImpl getSelect() { Node parent = getParentNode(); while (parent != null && !("select".equalsIgnoreCase( parent.getNodeName() ))) parent = parent.getParentNode(); return (HTMLSelectElementImpl) parent; } public String getValue() { return getAttributeWithNoDefault( "value" ); } public void setValue( String value ) { setAttribute( "value", value ); } public void reset() { _selected = null; } void addValueIfSelected( ParameterProcessor processor, String name, String characterSet ) throws IOException { if (getSelected()) { String value = getValue(); if (value == null) value = readDisplayedValue(); processor.addParameter( name, value, characterSet ); } } private String readDisplayedValue() { Node nextSibling = getNextSibling(); while (nextSibling != null && nextSibling.getNodeType() != Node.TEXT_NODE && nextSibling.getNodeType() != Node.ELEMENT_NODE) nextSibling = nextSibling.getNextSibling(); if (nextSibling == null || nextSibling.getNodeType() != Node.TEXT_NODE) return ""; return nextSibling.getNodeValue(); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLParagraphElementImpl.java0000644000175000017500000000557311014557540027520 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLParagraphElementImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLParagraphElement; import org.w3c.dom.html.HTMLCollection; /** * @author Russell Gold */ public class HTMLParagraphElementImpl extends HTMLElementImpl implements HTMLParagraphElement, HTMLContainerElement { ElementImpl create() { return new HTMLParagraphElementImpl(); } //------------------------------------------ HTMLContainerElement methods ---------------------------------------------- public HTMLCollection getLinks() { return getHtmlDocument().getContainerDelegate().getLinks( this ); } public HTMLCollection getImages() { return getHtmlDocument().getContainerDelegate().getImages( this ); } public HTMLCollection getApplets() { return getHtmlDocument().getContainerDelegate().getApplets( this ); } public HTMLCollection getForms() { return getHtmlDocument().getContainerDelegate().getForms( this ); } public HTMLCollection getAnchors() { return getHtmlDocument().getContainerDelegate().getAnchors( this ); } //----------------------------------------- HTMLParagraphElement methods ----------------------------------------------- public String getAlign() { return getAttributeWithNoDefault( "align" ); } public void setAlign( String align ) { setAttribute( "align", align ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLSelectElementImpl.java0000644000175000017500000001243311014557542027025 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLSelectElementImpl.java 902 2008-04-04 19:12:18Z wolfgang_fahl $ * * Copyright (c) 2004,2006-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLSelectElement; import org.w3c.dom.html.HTMLElement; import org.w3c.dom.html.HTMLCollection; import org.w3c.dom.html.HTMLOptionElement; import org.w3c.dom.DOMException; import com.meterware.httpunit.protocol.ParameterProcessor; import java.io.IOException; /** * * @author Russell Gold **/ public class HTMLSelectElementImpl extends HTMLControl implements HTMLSelectElement { public static final String TYPE_SELECT_ONE = "select-one"; public static final String TYPE_SELECT_MULTIPLE = "select-multiple"; ElementImpl create() { return new HTMLSelectElementImpl(); } public void add( HTMLElement element, HTMLElement before ) throws DOMException { } /** * simulate blur */ public void blur() { handleEvent("onblur"); } /** * simulate focus; */ public void focus() { handleEvent("onfocus"); } public String getType() { return isMultiSelect() ? TYPE_SELECT_MULTIPLE : TYPE_SELECT_ONE; } private boolean isMultiSelect() { return (getMultiple() && getSize() > 1); } public int getLength() { return getOptions().getLength(); } public boolean getMultiple() { return getBooleanAttribute( "multiple" ); } public HTMLCollection getOptions() { return HTMLCollectionImpl.createHTMLCollectionImpl( getElementsByTagName( getHtmlDocument().toNodeCase( "option" ) ) ); } public int getSelectedIndex() { HTMLCollection options = getOptions(); for (int i = 0; i < options.getLength(); i++) { if (((HTMLOptionElement)options.item(i)).getSelected()) return i; } return isMultiSelect() ? -1 : 0; } public String getValue() { HTMLCollection options = getOptions(); for (int i = 0; i < options.getLength(); i++) { HTMLOptionElement optionElement = ((HTMLOptionElement)options.item(i)); if (optionElement.getSelected()) return optionElement.getValue(); } return (isMultiSelect() || options.getLength() == 0) ? null : ((HTMLOptionElement)options.item(0)).getValue(); } public int getSize() { return getIntegerAttribute( "size" ); } public void remove( int index ) { } public void setMultiple( boolean multiple ) { setAttribute( "multiple", multiple ); } public void setSelectedIndex( int selectedIndex ) { HTMLCollection options = getOptions(); for (int i = 0; i < options.getLength(); i++) { HTMLOptionElementImpl optionElement = (HTMLOptionElementImpl) options.item(i); optionElement.setSelected( i == selectedIndex ); } } public void setSize( int size ) { setAttribute( "size", size ); } int getIndexOf( HTMLOptionElementImpl option ) { HTMLCollection options = getOptions(); for (int i = 0; i < options.getLength(); i++) { if (options.item(i) == option) return i; } throw new IllegalStateException( "option is not part of this select" ); } void clearSelected() { setSelectedIndex( -1 ); } void addValues( ParameterProcessor processor, String characterSet ) throws IOException { HTMLCollection options = getOptions(); String name = getName(); for (int i = 0; i < options.getLength();i++) { ((HTMLOptionElementImpl) options.item( i )).addValueIfSelected( processor, name, characterSet ); } } public void setValue( String value ) { setAttribute( "value", value ); } public void reset() { HTMLCollection options = getOptions(); for (int i = 0; i < options.getLength(); i++) { HTMLControl optionElement = (HTMLControl) options.item(i); optionElement.reset(); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLStyleElementImpl.java0000644000175000017500000000437511014557540026712 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLStyleElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLStyleElement; /** * * @author Russell Gold **/ public class HTMLStyleElementImpl extends HTMLElementImpl implements HTMLStyleElement { ElementImpl create() { return new HTMLStyleElementImpl(); } public boolean getDisabled() { return getBooleanAttribute( "disabled" ); } public String getMedia() { return getAttributeWithDefault( "media", "screen" ); } public String getType() { return getAttributeWithNoDefault( "type" ); } public void setDisabled( boolean disabled ) { setAttribute( "disabled", disabled ); } public void setMedia( String media ) { setAttribute( "media", media ); } public void setType( String type ) { setAttribute( "type", type ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLTableCellElementImpl.java0000644000175000017500000001335711014557542027443 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLTableCellElementImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLTableCellElement; import org.w3c.dom.html.HTMLCollection; /** * @author Russell Gold */ public class HTMLTableCellElementImpl extends HTMLElementImpl implements HTMLTableCellElement, HTMLContainerElement, AttributeNameAdjusted { ElementImpl create() { return new HTMLTableCellElementImpl(); } //------------------------------------------ HTMLContainerElement methods ---------------------------------------------- public HTMLCollection getLinks() { return getHtmlDocument().getContainerDelegate().getLinks( this ); } public HTMLCollection getImages() { return getHtmlDocument().getContainerDelegate().getImages( this ); } public HTMLCollection getApplets() { return getHtmlDocument().getContainerDelegate().getApplets( this ); } public HTMLCollection getForms() { return getHtmlDocument().getContainerDelegate().getForms( this ); } public HTMLCollection getAnchors() { return getHtmlDocument().getContainerDelegate().getAnchors( this ); } //-------------------------------------------- HTMLTableCellElement methods -------------------------------------------- public String getAbbr() { return getAttributeWithNoDefault( "abbr" ); } public void setAbbr( String abbr ) { setAttribute( "abbr", abbr ); } public String getAlign() { return getAttributeWithNoDefault( "align" ); } public void setAlign( String align ) { setAttribute( "align", align ); } public String getAxis() { return getAttributeWithNoDefault( "axis" ); } public void setAxis( String axis ) { setAttribute( "axis", axis ); } public String getBgColor() { return getAttributeWithNoDefault( "bgColor" ); } public void setBgColor( String bgColor ) { setAttribute( "bgColor", bgColor ); } public int getCellIndex() { return 0; //To change body of implemented methods use File | Settings | File Templates. } public String getCh() { return getAttributeWithDefault( "char", "." ); } public void setCh( String ch ) { setAttribute( "char", ch ); } public String getChOff() { return getAttributeWithNoDefault( "charoff" ); } public void setChOff( String chOff ) { setAttribute( "charoff", chOff ); } public int getColSpan() { return getIntegerAttribute( "colspan", 1 ); } public void setColSpan( int colSpan ) { setAttribute( "colspan", colSpan ); } public String getHeaders() { return getAttributeWithNoDefault( "headers" ); } public void setHeaders( String headers ) { setAttribute( "headers", headers ); } public String getHeight() { return getAttributeWithNoDefault( "height" ); } public void setHeight( String height ) { setAttribute( "height", height ); } public boolean getNoWrap() { return getBooleanAttribute( "nowrap" ); } public void setNoWrap( boolean noWrap ) { setAttribute( "nowrap", noWrap ); } public int getRowSpan() { return getIntegerAttribute( "rowspan", 1 ); } public void setRowSpan( int rowSpan ) { setAttribute( "rowspan", rowSpan ); } public String getScope() { return getAttributeWithNoDefault( "scope" ); } public void setScope( String scope ) { setAttribute( "scope", scope ); } public String getVAlign() { return getAttributeWithDefault( "valign", "middle" ); } public void setVAlign( String vAlign ) { setAttribute( "valign", vAlign ); } public String getWidth() { return getAttributeWithNoDefault( "width" ); } public void setWidth( String width ) { setAttribute( "width", width ); } public String getJavaAttributeName( String attributeName ) { if (attributeName.equals( "char" )) return "ch"; if (attributeName.equals( "charoff" )) return "choff"; return attributeName; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLTableElementImpl.java0000644000175000017500000001372511014557540026640 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLTableElementImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.*; import org.w3c.dom.DOMException; /** * @author Russell Gold */ public class HTMLTableElementImpl extends HTMLElementImpl implements HTMLTableElement { ElementImpl create() { return new HTMLTableElementImpl(); } public String getAlign() { return getAttributeWithDefault( "align", "center" ); } public void setAlign( String align ) { setAttribute( "align", align ); } public String getBgColor() { return getAttributeWithNoDefault( "bgColor" ); } public void setBgColor( String bgColor ) { setAttribute( "bgColor", bgColor ); } public String getBorder() { return getAttributeWithNoDefault( "border" ); } public void setBorder( String border ) { setAttribute( "border", border ); } public String getCellPadding() { return getAttributeWithNoDefault( "cellpadding" ); } public void setCellPadding( String cellPadding ) { setAttribute( "cellpadding", cellPadding ); } public String getCellSpacing() { return getAttributeWithNoDefault( "cellspacing" ); } public void setCellSpacing( String cellSpacing ) { setAttribute( "cellspacing", cellSpacing ); } public String getFrame() { return getAttributeWithDefault( "frame", "void" ); } public void setFrame( String frame ) { setAttribute( "frame", frame ); } public String getRules() { return getAttributeWithDefault( "rules", "none" ); } public void setRules( String rules ) { setAttribute( "rules", rules ); } public String getSummary() { return getAttributeWithNoDefault( "summary" ); } public void setSummary( String summary ) { setAttribute( "summary", summary ); } public String getWidth() { return getAttributeWithNoDefault( "width" ); } public void setWidth( String width ) { setAttribute( "width", width ); } public HTMLElement createCaption() { return null; //To change body of implemented methods use File | Settings | File Templates. } public HTMLElement createTFoot() { return null; //To change body of implemented methods use File | Settings | File Templates. } public HTMLElement createTHead() { return null; //To change body of implemented methods use File | Settings | File Templates. } public void deleteCaption() { //To change body of implemented methods use File | Settings | File Templates. } public void deleteRow( int index ) throws DOMException { //To change body of implemented methods use File | Settings | File Templates. } public void deleteTFoot() { //To change body of implemented methods use File | Settings | File Templates. } public void deleteTHead() { //To change body of implemented methods use File | Settings | File Templates. } public HTMLTableCaptionElement getCaption() { return null; //To change body of implemented methods use File | Settings | File Templates. } public HTMLCollection getRows() { return HTMLCollectionImpl.createHTMLCollectionImpl( getElementsByTagName( "tr" ) ); } public HTMLCollection getTBodies() { return null; //To change body of implemented methods use File | Settings | File Templates. } public HTMLTableSectionElement getTFoot() { return null; //To change body of implemented methods use File | Settings | File Templates. } public HTMLTableSectionElement getTHead() { return null; //To change body of implemented methods use File | Settings | File Templates. } public HTMLElement insertRow( int index ) throws DOMException { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setCaption( HTMLTableCaptionElement caption ) { //To change body of implemented methods use File | Settings | File Templates. } public void setTFoot( HTMLTableSectionElement tFoot ) { //To change body of implemented methods use File | Settings | File Templates. } public void setTHead( HTMLTableSectionElement tHead ) { //To change body of implemented methods use File | Settings | File Templates. } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLTableRowElementImpl.java0000644000175000017500000000753411014557542027333 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLTableRowElementImpl.java 908 2008-04-05 08:24:51Z wolfgang_fahl $ * * Copyright (c) 2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLTableRowElement; import org.w3c.dom.html.HTMLCollection; import org.w3c.dom.html.HTMLElement; import org.w3c.dom.DOMException; /** * @author Russell Gold */ public class HTMLTableRowElementImpl extends HTMLElementImpl implements HTMLTableRowElement, AttributeNameAdjusted { ElementImpl create() { return new HTMLTableRowElementImpl(); } public String getAlign() { return getAttributeWithNoDefault( "align" ); } public void setAlign( String align ) { setAttribute( "align", align ); } public String getBgColor() { return getAttributeWithNoDefault( "bgColor" ); } public void setBgColor( String bgColor ) { setAttribute( "bgColor", bgColor ); } public String getCh() { return getAttributeWithDefault( "char", "." ); } public void setCh( String ch ) { setAttribute( "char", ch ); } public String getChOff() { return getAttributeWithNoDefault( "charoff" ); } public void setChOff( String chOff ) { setAttribute( "charoff", chOff ); } public String getVAlign() { return getAttributeWithDefault( "valign", "middle" ); } public void setVAlign( String vAlign ) { setAttribute( "valign", vAlign ); } public void deleteCell( int index ) throws DOMException { //To change body of implemented methods use File | Settings | File Templates. } public HTMLCollection getCells() { return HTMLCollectionImpl.createHTMLCollectionImpl( getElementsByTagNames( new String[] { "td", "th " } ) ); } public int getRowIndex() { return 0; //To change body of implemented methods use File | Settings | File Templates. } public int getSectionRowIndex() { return 0; //To change body of implemented methods use File | Settings | File Templates. } public HTMLElement insertCell( int index ) throws DOMException { return null; //To change body of implemented methods use File | Settings | File Templates. } public String getJavaAttributeName( String attributeName ) { if (attributeName.equals( "char" )) return "ch"; if (attributeName.equals( "charoff" )) return "choff"; return attributeName; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLTextAreaElementImpl.java0000644000175000017500000000643011014557542027323 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLTextAreaElementImpl.java 840 2008-03-29 23:53:21Z wolfgang_fahl $ * * Copyright (c) 2004-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLTextAreaElement; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * * @author Russell Gold **/ public class HTMLTextAreaElementImpl extends HTMLControl implements HTMLTextAreaElement { private String _value; ElementImpl create() { return new HTMLTextAreaElementImpl(); } /** * simulate blur */ public void blur() { handleEvent("onblur"); } /** * simulate focus; */ public void focus() { handleEvent("onfocus"); } public String getAccessKey() { return getAttributeWithNoDefault( "accesskey" ); } public int getCols() { return getIntegerAttribute( "cols" ); } public String getDefaultValue() { Node node = getFirstChild(); if (node == null || node.getNodeType() != Node.TEXT_NODE) return null; return node.getNodeValue(); } public int getRows() { return getIntegerAttribute( "rows" ); } public void select() { } public void setAccessKey( String accessKey ) { setAttribute( "accesskey", accessKey ); } public void setCols( int cols ) { setAttribute( "cols", cols ); } public void setDefaultValue( String defaultValue ) { Text textNode = getOwnerDocument().createTextNode( defaultValue ); Node child = getFirstChild(); if (child == null) { appendChild( textNode ); } else { replaceChild( textNode, child ); } } public void setRows( int rows ) { setAttribute( "rows", rows ); } public String getValue() { return _value != null ? _value : getDefaultValue(); } public void setValue( String value ) { _value = value; } public void reset() { _value = null; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/HTMLTitleElementImpl.java0000644000175000017500000000472611014557540026673 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: HTMLTitleElementImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.html.HTMLTitleElement; import org.w3c.dom.NodeList; import org.w3c.dom.Text; /** * * @author Russell Gold **/ public class HTMLTitleElementImpl extends HTMLElementImpl implements HTMLTitleElement { ElementImpl create() { return new HTMLTitleElementImpl(); } public String getText() { Text contentNode = getContentNode(); return contentNode == null ? "" : contentNode.getData(); } private Text getContentNode() { NodeList childNodes = getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { if (childNodes.item(i).getNodeType() == TEXT_NODE) return (Text) childNodes.item(i); } return null; } public void setText( String text ) { Text newChild = getOwnerDocument().createTextNode( text ); Text oldChild = getContentNode(); if (oldChild == null) { appendChild( newChild ); } else { replaceChild( newChild, oldChild ); } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/NamedNodeMapImpl.java0000644000175000017500000000522111014557540026072 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: NamedNodeMapImpl.java 754 2006-03-28 00:52:15Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.DOMException; import java.util.Hashtable; /** * * @author Russell Gold **/ public class NamedNodeMapImpl implements NamedNodeMap { private Hashtable _items; private Node[] _itemArray; NamedNodeMapImpl( Hashtable items ) { _items = (Hashtable) items.clone(); _itemArray = (Node[]) _items.values().toArray( new Node[ _items.size() ] ); } public Node getNamedItem( String name ) { return (Node) _items.get( name ); } public Node setNamedItem( Node arg ) throws DOMException { return null; } public Node removeNamedItem( String name ) throws DOMException { return null; } public Node item( int index ) { return _itemArray[ index ]; } public int getLength() { return _items.size(); } public Node getNamedItemNS( String namespaceURI, String localName ) { return null; } public Node setNamedItemNS( Node arg ) throws DOMException { return null; } public Node removeNamedItemNS( String namespaceURI, String localName ) throws DOMException { return null; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/NamespaceAwareNodeImpl.java0000644000175000017500000000520311014557542027266 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: NamespaceAwareNodeImpl.java 825 2008-03-27 19:54:12Z wolfgang_fahl $ * * Copyright (c) 2006-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ /** * * @author Russell Gold **/ public abstract class NamespaceAwareNodeImpl extends NodeImpl { private String _tagName; private String _localName; private String _namespaceUri; protected void initialize( DocumentImpl owner, String tagName ) { initialize( owner ); _localName = _tagName = tagName; } /** * initialize the name space * @param owner * @param namespaceURI * @param qualifiedName */ protected void initialize( DocumentImpl owner, String namespaceURI, String qualifiedName ) { initialize( owner ); _tagName = qualifiedName; _namespaceUri = namespaceURI; if (qualifiedName.indexOf(':') < 0) { _localName = qualifiedName; } else { _localName = qualifiedName.substring( qualifiedName.indexOf(':') + 1 ); } setParentScope(owner); } public String getNodeName() { return getTagName(); } public String getTagName() { return _tagName; } public String getNamespaceURI() { return _namespaceUri; } public String getLocalName() { return _localName; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/NodeImpl.java0000644000175000017500000003230111014557540024466 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: NodeImpl.java 839 2008-03-29 23:30:13Z wolfgang_fahl $ * * Copyright (c) 2004-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.*; import org.w3c.dom.html.HTMLIFrameElement; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; /** * * @author Russell Gold **/ abstract public class NodeImpl extends AbstractDomComponent implements Node { private DocumentImpl _ownerDocument; private NodeImpl _parentNode; private NodeImpl _firstChild; private NodeImpl _nextSibling; private NodeImpl _previousSibling; private Hashtable _userData = new Hashtable( ); static IteratorMask SKIP_IFRAMES = new IteratorMask() { public boolean skipSubtree( Node subtreeRoot ) { return subtreeRoot instanceof HTMLIFrameElement; } }; protected void initialize( DocumentImpl ownerDocument ) { if (_ownerDocument != null) throw new IllegalStateException( "NodeImpl already initialized" ); if (ownerDocument == null) throw new IllegalArgumentException( "No owner document specified" ); _ownerDocument = ownerDocument; } //------------------------------------------ ScriptableObject methods -------------------------------------------------- //------------------------------------------ ScriptingEngine methods -------------------------------------------------- //----------------------------------------------- Node methods --------------------------------------------------------- public Node getParentNode() { return _parentNode; } public NodeList getChildNodes() { ArrayList list = new ArrayList(); for (NodeImpl child = _firstChild; child != null; child = child._nextSibling) { list.add( child ); } return new NodeListImpl( list ); } public Node getFirstChild() { return _firstChild; } public Node getLastChild() { if (_firstChild == null) return null; Node child = _firstChild; while (child.getNextSibling() != null) child = child.getNextSibling(); return child; } public Node getPreviousSibling() { return _previousSibling; } public Node getNextSibling() { return _nextSibling; } public NamedNodeMap getAttributes() { return null; } public Document getOwnerDocument() { return _ownerDocument; } public Node insertBefore( Node newChild, Node refChild ) throws DOMException { NodeImpl refChildNode = (NodeImpl) refChild; if (refChildNode.getParentNode() != this) throw new DOMException( DOMException.NOT_FOUND_ERR, "Must specify an existing child as the reference" ); NodeImpl newChildNode = getChildIfPermitted( newChild ); removeFromTree( newChildNode ); newChildNode._parentNode = this; if (refChildNode._previousSibling == null) { _firstChild = newChildNode; } else { refChildNode._previousSibling.setNextSibling( newChildNode ); } newChildNode.setNextSibling( refChildNode ); return newChildNode; } private void removeFromTree( NodeImpl childNode ) { if (childNode._parentNode != null) { if (childNode._previousSibling != null) { childNode._previousSibling.setNextSibling( childNode._nextSibling ); } else { childNode._parentNode._firstChild = childNode._nextSibling; childNode._nextSibling._previousSibling = null; } childNode._parentNode = null; } } public Node replaceChild( Node newChild, Node oldChild ) throws DOMException { insertBefore( newChild, oldChild ); return removeChild( oldChild ); } public Node removeChild( Node oldChild ) throws DOMException { if (oldChild.getParentNode() != this) throw new DOMException( DOMException.NOT_FOUND_ERR, "May only remove a node from its own parent" ); removeFromTree( (NodeImpl) oldChild ); return oldChild; } public Node appendChild( Node newChild ) throws DOMException { if (newChild == null) throw new IllegalArgumentException( "child to append may not be null" ); NodeImpl childNode = getChildIfPermitted( newChild ); removeFromTree( childNode ); childNode._parentNode = this; if (_firstChild == null) { _firstChild = childNode; } else { ((NodeImpl) getLastChild()).setNextSibling( childNode ); } return newChild; } protected NodeImpl getChildIfPermitted( Node proposedChild ) { if (!(proposedChild instanceof NodeImpl)) throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, "Specified node is from a different DOM implementation" ); NodeImpl childNode = (NodeImpl) proposedChild; if (getOwnerDocument() != childNode._ownerDocument) throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, "Specified node is from a different document" ); for (Node parent = this; parent != null; parent = parent.getParentNode()) { if (proposedChild == parent) throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "May not add node as its own descendant" ); } return childNode; } private void setNextSibling( NodeImpl sibling ) { _nextSibling = sibling; if (sibling != null) sibling._previousSibling = this; } public boolean hasChildNodes() { return _firstChild != null; } public Node cloneNode( boolean deep ) { return getOwnerDocument().importNode( this, deep ); } public void normalize() { } public boolean isSupported( String feature, String version ) { return false; } public String getNamespaceURI() { return null; } public String getPrefix() { return null; } public void setPrefix( String prefix ) throws DOMException { } public String getLocalName() { return null; } public boolean hasAttributes() { return false; } //------------------------------------ DOM level 3 methods ------------------------------------------------------------- public Object setUserData( String key, Object data, UserDataHandler handler ) { return _userData.put( key, data ); } public Object getUserData( String key ) { return _userData.get( key ); } public Object getFeature( String feature, String version ) { return null; } public boolean isEqualNode( Node arg ) { return false; //To change body of implemented methods use File | Settings | File Templates. } public String lookupNamespaceURI( String prefix ) { return null; //To change body of implemented methods use File | Settings | File Templates. } public String getBaseURI() { return null; //To change body of implemented methods use File | Settings | File Templates. } public short compareDocumentPosition( Node other ) throws DOMException { return 0; //To change body of implemented methods use File | Settings | File Templates. } public String getTextContent() throws DOMException { return null; //To change body of implemented methods use File | Settings | File Templates. } public void setTextContent( String textContent ) throws DOMException { //To change body of implemented methods use File | Settings | File Templates. } public boolean isSameNode( Node other ) { return this == other; } public String lookupPrefix( String namespaceURI ) { return null; //To change body of implemented methods use File | Settings | File Templates. } public boolean isDefaultNamespace( String namespaceURI ) { return false; //To change body of implemented methods use File | Settings | File Templates. } //----------------------------------------- implementation internals --------------------------------------------------- public NodeList getElementsByTagName( String name ) { ArrayList matchingElements = new ArrayList(); appendElementsWithTag( name, matchingElements ); return new NodeListImpl( matchingElements ); } private void appendElementsWithTag( String name, ArrayList matchingElements ) { for (Node child = getFirstChild(); child != null; child = child.getNextSibling()) { if (child.getNodeType() != ELEMENT_NODE) continue; if (name.equals( "*" ) || ((Element) child).getTagName().equalsIgnoreCase( name )) matchingElements.add( child ); ((NodeImpl) child).appendElementsWithTag( name, matchingElements ); } } protected NodeList getElementsByTagNames( String[] names ) { ArrayList matchingElements = new ArrayList(); appendElementsWithTags( names, matchingElements ); return new NodeListImpl( matchingElements ); } void appendElementsWithTags( String[] names, ArrayList matchingElements ) { for (Node child = getFirstChild(); child != null; child = child.getNextSibling()) { if (child.getNodeType() != ELEMENT_NODE) continue; String tagName = ((Element) child).getTagName(); for (int i = 0; i < names.length; i++) { if (tagName.equalsIgnoreCase( names[i] )) matchingElements.add( child ); } ((NodeImpl) child).appendElementsWithTags( names, matchingElements ); } } String asText() { StringBuffer sb = new StringBuffer(); appendContents( sb ); return sb.toString(); } void appendContents( StringBuffer sb ) { NodeList nl = getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { ((NodeImpl) nl.item(i)).appendContents( sb ); } } public Iterator preOrderIterator() { return new PreOrderIterator( this ); } public Iterator preOrderIterator( IteratorMask mask ) { return new PreOrderIterator( this, mask ); } public Iterator preOrderIteratorAfterNode() { return new PreOrderIterator( PreOrderIterator.nextNode( this ) ); } public Iterator preOrderIteratorAfterNode( IteratorMask mask ) { return new PreOrderIterator( PreOrderIterator.nextNode( this ), mask ); } protected String getJavaPropertyName( String propertyName ) { if (propertyName.equals( "document" )) { return "ownerDocument"; } else { return propertyName; } } interface IteratorMask { boolean skipSubtree( Node subtreeRoot ); } static class PreOrderIterator implements Iterator { private NodeImpl _nextNode; private IteratorMask _mask; PreOrderIterator( NodeImpl currentNode ) { _nextNode = currentNode; } PreOrderIterator( NodeImpl currentNode, IteratorMask mask ) { this( currentNode ); _mask = mask; } public boolean hasNext() { return null != _nextNode; } public Object next() { NodeImpl currentNode = _nextNode; _nextNode = nextNode( _nextNode ); while (_mask != null && _nextNode != null && _mask.skipSubtree( _nextNode )) _nextNode = nextSubtree( _nextNode ); return currentNode; } public void remove() { throw new java.lang.UnsupportedOperationException(); } static NodeImpl nextNode( NodeImpl node ) { if (node._firstChild != null) return node._firstChild; return nextSubtree( node ); } private static NodeImpl nextSubtree( NodeImpl node ) { if (node._nextSibling != null) return node._nextSibling; while (node._parentNode != null) { node = node._parentNode; if (node._nextSibling != null) return node._nextSibling; } return null; } } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/NodeListImpl.java0000644000175000017500000000456111014557542025333 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: NodeListImpl.java 781 2007-06-17 17:31:49Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.Scriptable; import java.util.List; /** * * @author Russell Gold **/ public class NodeListImpl extends ScriptableObject implements NodeList { private List _list; public NodeListImpl( List list ) { _list = list; } public Node item( int index ) { return (Node) _list.get( index ); } public int getLength() { return _list.size(); } public String getClassName() { return NodeListImpl.class.getName(); } public Object get( String name, Scriptable start ) { if ("length".equals( name )) return new Integer( getLength() ); return NOT_FOUND; } public Object get( int index, Scriptable start ) { if (index < 0 || index >= getLength()) return NOT_FOUND; return item( index ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/ProcessingInstructionImpl.java0000644000175000017500000000576211014557540030172 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: ProcessingInstructionImpl.java 772 2006-12-01 16:54:18Z russgold $ * * Copyright (c) 2006, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.DOMException; import org.w3c.dom.Node; /** * * @author Russell Gold **/ public class ProcessingInstructionImpl extends NodeImpl implements ProcessingInstruction { private String _target; private String _data; public static ProcessingInstruction createProcessingImpl( DocumentImpl ownerDocument, String target, String data ) { ProcessingInstructionImpl instruction = new ProcessingInstructionImpl(); instruction.initialize( ownerDocument, target, data ); return instruction; } private void initialize( DocumentImpl ownerDocument, String target, String data ) { super.initialize( ownerDocument ); _target = target; _data = data; } public static Node importNode( DocumentImpl document, ProcessingInstruction processingInstruction ) { return createProcessingImpl( document, processingInstruction.getTarget(), processingInstruction.getData() ); } public String getNodeName() { return _target; } public String getNodeValue() throws DOMException { return _data; } public void setNodeValue( String string ) throws DOMException { setData( string ); } public short getNodeType() { return PROCESSING_INSTRUCTION_NODE; } public String getTarget() { return _target; } public String getData() { return _data; } public void setData( String string ) throws DOMException { _data = string; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/ScriptingSupport.java0000644000175000017500000001662711014557540026333 0ustar twernertwernerpackage com.meterware.httpunit.dom; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.FunctionObject; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.util.Hashtable; /** * Utilities to support scripting. */ class ScriptingSupport { /** A non-null method value to be used to indicate that we have already looked up and failed to find one. **/ private static final Method NO_SUCH_PROPERTY = ScriptingSupport.class.getDeclaredMethods()[0]; private static final Object[] NO_ARGS = new Object[0]; /** map of classes to maps of string to function objects. **/ private static Hashtable _classFunctionMaps = new Hashtable(); /** map of classes to maps of string to getter methods. **/ private static Hashtable _classGetterMaps = new Hashtable(); /** map of classes to maps of string to setter methods. **/ private static Hashtable _classSetterMaps = new Hashtable(); static boolean hasNamedProperty( Object element, String javaPropertyName, Scriptable scriptable ) { Method getter = getPropertyGetter( element.getClass(), javaPropertyName ); if (getter != NO_SUCH_PROPERTY) { return true; } else { Object function = getFunctionObject( element.getClass(), javaPropertyName, scriptable ); return function != null; } } static Object getNamedProperty( Object element, String javaPropertyName, Scriptable scriptable ) { Method getter = getPropertyGetter( element.getClass(), javaPropertyName ); if (getter == NO_SUCH_PROPERTY) { Object function = getFunctionObject( element.getClass(), javaPropertyName, scriptable ); return function == null ? Scriptable.NOT_FOUND : function; } try { return getter.invoke( element, NO_ARGS ); } catch (IllegalAccessException e) { return Scriptable.NOT_FOUND; } catch (InvocationTargetException e) { return Scriptable.NOT_FOUND; } } private static FunctionObject getFunctionObject( Class aClass, String methodName, Scriptable scriptable ) { Hashtable functionMap = (Hashtable) _classFunctionMaps.get( aClass ); if (functionMap == null) { _classFunctionMaps.put( aClass, functionMap = new Hashtable() ); } Object result = functionMap.get( methodName ); if (result == NO_SUCH_PROPERTY) return null; if (result != null) return (FunctionObject) result; Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (method.getName().equalsIgnoreCase( methodName )) { FunctionObject function = new FunctionObject( methodName, method, scriptable ); functionMap.put( methodName, function ); return function; } } functionMap.put( methodName, NO_SUCH_PROPERTY ); return null; } private static Method getPropertyGetter( Class aClass, String propertyName ) { Hashtable methodMap = (Hashtable) _classGetterMaps.get( aClass ); if (methodMap == null) { _classGetterMaps.put( aClass, methodMap = new Hashtable() ); } Method result = (Method) methodMap.get( propertyName ); if (result != null) return result; Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (method.getParameterTypes().length > 0) continue; if (method.getName().equalsIgnoreCase( "is" + propertyName ) || method.getName().equalsIgnoreCase( "get" + propertyName )) { methodMap.put( propertyName, method ); return method; } } methodMap.put( propertyName, NO_SUCH_PROPERTY ); return NO_SUCH_PROPERTY; } static void setNamedProperty( AbstractDomComponent element, String javaPropertyName, Object value ) { Method setter = getPropertySetter( element.getClass(), javaPropertyName, value ); if (setter == NO_SUCH_PROPERTY) return; try { setter.invoke( element, new Object[] { adjustedForSetter( value, setter ) } ); } catch (IllegalAccessException e) { /* do nothing */ } catch (InvocationTargetException e) { /* do nothing */ } } private static Object adjustedForSetter( Object value, Method setter ) { if (value == null) return null; Class targetValueClass = setter.getParameterTypes()[0]; if (targetValueClass.equals( String.class )) return value.toString(); if (!(value instanceof Number) || !isNumericParameter( targetValueClass )) return value; if (targetValueClass.getName().equals("int")) return new Integer( ((Number) value).intValue() ); if (targetValueClass.getName().equals("byte")) return new Byte( ((Number) value).byteValue() ); if (targetValueClass.getName().equals("long")) return new Long( ((Number) value).longValue() ); if (targetValueClass.getName().equals("short")) return new Short( ((Number) value).shortValue() ); if (targetValueClass.getName().equals("float")) return new Float( ((Number) value).intValue() ); if (targetValueClass.getName().equals("double")) return new Double( ((Number) value).intValue() ); return value; } static Method getPropertySetter( Class aClass, String propertyName, Object value ) { Hashtable methodMap = (Hashtable) _classSetterMaps.get( aClass ); if (methodMap == null) { _classSetterMaps.put( aClass, methodMap = new Hashtable() ); } Method result = (Method) methodMap.get( propertyName ); if (result != null) return result; String setterName = "set" + Character.toUpperCase( propertyName.charAt( 0 ) ) + propertyName.substring(1); Method[] methods = aClass.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (method.getName().equalsIgnoreCase( setterName ) && method.getParameterTypes().length == 1 && isConvertableTo( value.getClass(), method.getParameterTypes()[0] )) { methodMap.put( propertyName, method ); return method; } } methodMap.put( propertyName, NO_SUCH_PROPERTY ); return NO_SUCH_PROPERTY; } /** * check whether the valueType is convertable to the parameterType * @param valueType * @param parameterType * @return */ public static boolean isConvertableTo( Class valueType, Class parameterType ) { if (valueType.equals( parameterType )) return true; if (parameterType.equals( String.class )) return true; if (valueType.equals( String.class ) && isNumericParameter( parameterType )) return true; if (Number.class.isAssignableFrom( valueType ) && isNumericParameter( parameterType )) return true; if (valueType.equals(Boolean.class )&¶meterType.equals(boolean .class)) return true; return valueType.equals( String.class ) && parameterType.equals( Boolean.class ); } private static boolean isNumericParameter( Class parameterType ) { if (parameterType.isPrimitive() && !(parameterType.equals( boolean.class ))) return true; return Number.class.isAssignableFrom( parameterType ); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/dom/TextImpl.java0000644000175000017500000000632711014557542024540 0ustar twernertwernerpackage com.meterware.httpunit.dom; /******************************************************************************************************************** * $Id: TextImpl.java 767 2006-07-06 04:02:07Z russgold $ * * Copyright (c) 2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.dom.Text; import org.w3c.dom.DOMException; import org.w3c.dom.Node; /** * * @author Russell Gold **/ public class TextImpl extends CharacterDataImpl implements Text { static TextImpl createText( DocumentImpl ownerDocument, String data ) { TextImpl text = new TextImpl(); text.initialize( ownerDocument, data ); return text; } public String getNodeName() { return "#text"; } public String getNodeValue() throws DOMException { return getData(); } public void setNodeValue( String nodeValue ) throws DOMException { setData( nodeValue ); } public short getNodeType() { return TEXT_NODE; } protected NodeImpl getChildIfPermitted( Node proposedChild ) { throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "Text nodes may not have children" ); } public Text splitText( int offset ) throws DOMException { return null; } public static Node importNode( DocumentImpl document, Text text ) { return document.createTextNode( text.getData() ); } void appendContents( StringBuffer sb ) { sb.append( getData() ); } //------------------------------------- DOM level 3 methods ------------------------------------------------------------ public boolean isElementContentWhitespace() { return false; //To change body of implemented methods use File | Settings | File Templates. } public String getWholeText() { return null; //To change body of implemented methods use File | Settings | File Templates. } public Text replaceWholeText( String content ) throws DOMException { return null; //To change body of implemented methods use File | Settings | File Templates. } } httpunit-1.7+dfsg/src/com/meterware/httpunit/javascript/0000755000175000017500000000000011014557542023506 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/javascript/JavaScript.java0000644000175000017500000010260411014557542026422 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: JavaScript.java 907 2008-04-05 08:16:49Z wolfgang_fahl $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.*; import com.meterware.httpunit.scripting.*; import java.lang.reflect.InvocationTargetException; import java.io.IOException; import java.net.URL; import org.mozilla.javascript.*; import org.xml.sax.SAXException; /** * This class is the Rhino-compatible implementation of the JavaScript DOM objects. * * @author Russell Gold **/ public class JavaScript { private static boolean _throwExceptionsOnError = true; public static boolean isThrowExceptionsOnError() { return _throwExceptionsOnError; } public static void setThrowExceptionsOnError( boolean throwExceptionsOnError ) { _throwExceptionsOnError = throwExceptionsOnError; } /** * Initiates JavaScript execution for the specified web response. */ public static void run( WebResponse response ) throws IllegalAccessException, InstantiationException, InvocationTargetException, ClassDefinitionException, NotAFunctionException, PropertyException, SAXException, JavaScriptException { Context context = Context.enter(); // suggest bug fix for large java scripts see // bug report [ 1216567 ] Exception for large javascripts // by Grzegorz Lukasik // and context.setOptimizationLevel(HttpUnitOptions.getJavaScriptOptimizationLevel()); Scriptable scope = context.initStandardObjects( null ); initHTMLObjects( scope ); Window w = (Window) context.newObject( scope, "Window" ); w.initialize( null, response.getScriptableObject() ); } /** * Runs the onload event for the specified web response. */ public static void load( WebResponse response ) throws ClassDefinitionException, InstantiationException, IllegalAccessException, InvocationTargetException, PropertyException, JavaScriptException, SAXException, NotAFunctionException { if (!(response.getScriptableObject().getScriptEngine() instanceof JavaScriptEngine)) run( response ); response.getScriptableObject().load(); } private static void initHTMLObjects( Scriptable scope ) throws IllegalAccessException, InstantiationException, InvocationTargetException, ClassDefinitionException, PropertyException { ScriptableObject.defineClass( scope, Window.class ); ScriptableObject.defineClass( scope, Document.class ); ScriptableObject.defineClass( scope, Style.class ); ScriptableObject.defineClass( scope, Location.class ); ScriptableObject.defineClass( scope, Navigator.class ); ScriptableObject.defineClass( scope, Screen.class ); ScriptableObject.defineClass( scope, Link.class ); ScriptableObject.defineClass( scope, Form.class ); ScriptableObject.defineClass( scope, Control.class ); ScriptableObject.defineClass( scope, Link.class ); ScriptableObject.defineClass( scope, Image.class ); ScriptableObject.defineClass( scope, Options.class ); ScriptableObject.defineClass( scope, Option.class ); ScriptableObject.defineClass( scope, ElementArray.class ); ScriptableObject.defineClass( scope, HTMLElement.class ); } /** * abstract Engine for JavaScript */ abstract static class JavaScriptEngine extends ScriptingEngineImpl { protected ScriptableDelegate _scriptable; protected JavaScriptEngine _parent; /** * initialize JavaScript for the given ScriptEngine * @parent - the Script Engine to use * @scriptable - the scriptable object to do the initialization for */ void initialize( JavaScriptEngine parent, ScriptableDelegate scriptable ) throws SAXException, PropertyException, JavaScriptException, NotAFunctionException { _scriptable = scriptable; _scriptable.setScriptEngine( this ); _parent = parent; if (parent != null) setParentScope( parent ); } String getName() { return _scriptable instanceof NamedDelegate ? ((NamedDelegate) _scriptable).getName() : ""; } String getID() { return _scriptable instanceof IdentifiedDelegate ? ((IdentifiedDelegate) _scriptable).getID() : ""; } /** * get the event Handler script for the event e.g. onchange, onmousedown, onclick, onmouseup * execute the script if it's assigned by calling doEvent for the script * @param eventName * @return */ public boolean handleEvent(String eventName) { return _scriptable.handleEvent(eventName); } public boolean has( String propertyName, Scriptable scriptable ) { return super.has( propertyName, scriptable ) || (_scriptable != null && _scriptable.get( propertyName ) != null); } public Object get( String propertyName, Scriptable scriptable ) { Object result = super.get( propertyName, scriptable ); if (result != NOT_FOUND) return result; if (_scriptable == null) return NOT_FOUND; return convertIfNeeded( _scriptable.get( propertyName ) ); } public Object get( int i, Scriptable scriptable ) { Object result = super.get( i, scriptable ); if (result != NOT_FOUND) return result; if (_scriptable == null) return NOT_FOUND; return convertIfNeeded( _scriptable.get( i ) ); } private Object convertIfNeeded( final Object property ) { if (property == null) return NOT_FOUND; if (property instanceof ScriptableDelegate[]) return toScriptable( (ScriptableDelegate[]) property ); if (!(property instanceof ScriptableDelegate)) return property; return toScriptable( (ScriptableDelegate) property ); } private Object toScriptable( ScriptableDelegate[] list ) { Object[] delegates = new Object[ list.length ]; for (int i = 0; i < delegates.length; i++) { delegates[i] = toScriptable( list[i] ); } return Context.getCurrentContext().newArray( this, delegates ); } public void put( String propertyName, Scriptable scriptable, Object value ) { if (_scriptable == null || _scriptable.get( propertyName ) == null) { super.put( propertyName, scriptable, value ); } else { _scriptable.set( propertyName, value ); } } public String toString() { return (_scriptable == null ? "prototype " : "") + getClassName(); } public ScriptingEngine newScriptingEngine( ScriptableDelegate child ) { try { return (ScriptingEngine) toScriptable( child ); } catch (Exception e) { HttpUnitUtils.handleException(e); throw new RuntimeException( e.toString() ); } } public void clearCaches() { } protected static String toStringIfNotUndefined( Object object ) { return (object == null || Undefined.instance.equals( object )) ? null : object.toString(); } /** * Converts a scriptable delegate obtained from a subobject into the appropriate Rhino-compatible Scriptable. **/ final Object toScriptable( ScriptableDelegate delegate ) { if (delegate == null) { return NOT_FOUND; } else if (delegate.getScriptEngine() instanceof Scriptable) { return (Scriptable) delegate.getScriptEngine(); } else { try { JavaScriptEngine element = (JavaScriptEngine) Context.getCurrentContext().newObject( this, getScriptableClassName( delegate ) ); element.initialize( this, delegate ); return element; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RhinoException( e ); } } } /** * get the classname of the given ScriptableDelegate * @param delegate - the object to get the class name for * @return - the simple local class name for the delegate e.g. Window, Document, Form, Link, Image, Options, Option, Control, HTMLElement * @throws an IllegalArgumentException if the delegate is not known */ private String getScriptableClassName( ScriptableDelegate delegate ) { if (delegate instanceof WebResponse.Scriptable) return "Window"; if (delegate instanceof HTMLPage.Scriptable) return "Document"; if (delegate instanceof FormScriptable) return "Form"; if (delegate instanceof WebLink.Scriptable) return "Link"; if (delegate instanceof WebImage.Scriptable) return "Image"; if (delegate instanceof SelectionOptions) return "Options"; if (delegate instanceof SelectionOption) return "Option"; if (delegate instanceof Input) return "Control"; if (delegate instanceof DocumentElement) return "HTMLElement"; throw new IllegalArgumentException( "Unknown ScriptableDelegate class: " + delegate.getClass() ); } protected ElementArray toElementArray( ScriptingHandler[] scriptables ) { JavaScriptEngine[] elements = new JavaScriptEngine[ scriptables.length ]; for (int i = 0; i < elements.length; i++) { elements[ i ] = (JavaScriptEngine) toScriptable( (ScriptableDelegate) scriptables[ i ] ); } ElementArray result = ElementArray.newElementArray( this ); result.initialize( elements ); return result; } } static public class Window extends JavaScriptEngine { private Document _document; private Navigator _navigator; private Location _location; private Screen _screen; private ElementArray _frames; public String getClassName() { return "Window"; } public Window jsGet_window() { return this; } public Window jsGet_self() { return this; } public Document jsGet_document() { if (_document == null) { _document = (Document) toScriptable( getDelegate().getDocument() ); } return _document; } public Scriptable jsGet_frames() throws SAXException, PropertyException, JavaScriptException, NotAFunctionException { if (_frames == null) { WebResponse.Scriptable scriptables[] = getDelegate().getFrames(); Window[] frames = new Window[ scriptables.length ]; for (int i = 0; i < frames.length; i++) { frames[ i ] = (Window) toScriptable( scriptables[ i ] ); } _frames = (ElementArray) Context.getCurrentContext().newObject( this, "ElementArray" ); _frames.initialize( frames ); } return _frames; } public Navigator jsGet_navigator() { return _navigator; } public Screen jsGet_screen() { return _screen; } public Location jsGet_location() { return _location; } public void jsSet_location( String relativeURL ) throws IOException, SAXException { setLocation( relativeURL ); } void setLocation( String relativeURL ) throws IOException, SAXException { getDelegate().setLocation( relativeURL ); } /** * initialize JavaScript for the given ScriptEngine * @parent - the Script Engine to use * @scriptable - the scriptable object to do the initialization for */ void initialize( JavaScriptEngine parent, ScriptableDelegate scriptable ) throws JavaScriptException, NotAFunctionException, PropertyException, SAXException { super.initialize( parent, scriptable ); _location = (Location) Context.getCurrentContext().newObject( this, "Location" ); _location.initialize(this, ((WebResponse.Scriptable) scriptable).getURL() ); _navigator = (Navigator) Context.getCurrentContext().newObject( this, "Navigator" ); _navigator.setClientProperties( getDelegate().getClientProperties() ); _screen = (Screen) Context.getCurrentContext().newObject( this, "Screen" ); _screen.setClientProperties( getDelegate().getClientProperties() ); } /** * javascript alert handling * @param message - the alert message */ public void jsFunction_alert( String message ) { getDelegate().alertUser( message ); } public boolean jsFunction_confirm( String message ) { return getDelegate().getConfirmationResponse( message ); } public String jsFunction_prompt( String message, String defaultResponse ) { return getDelegate().getUserResponse( message, defaultResponse ); } public void jsFunction_moveTo( int x, int y ) { } public void jsFunction_focus() { } public void jsFunction_setTimeout() { } public void jsFunction_close() { getDelegate().closeWindow(); } public Window jsFunction_open( Object url, String name, String features, boolean replace ) throws PropertyException, JavaScriptException, NotAFunctionException, IOException, SAXException { WebResponse.Scriptable delegate = getDelegate().open( toStringIfNotUndefined( url ), name, features, replace ); return delegate == null ? null : (Window) toScriptable( delegate ); } public void clearCaches() { if (_document != null) _document.clearCaches(); } protected String getDocumentWriteBuffer() { return jsGet_document().getWriteBuffer().toString(); } protected void discardDocumentWriteBuffer() { jsGet_document().clearWriteBuffer(); } private WebResponse.Scriptable getDelegate() { return (WebResponse.Scriptable) _scriptable; } } /** * Document script handling */ static public class Document extends JavaScriptEngine { private ElementArray _forms; private ElementArray _links; private ElementArray _images; private StringBuffer _writeBuffer; private String _mimeType; public String getClassName() { return "Document"; } public void clearCaches() { _forms = _links = _images = null; } public String jsGet_title() throws SAXException { return getDelegate().getTitle(); } public Scriptable jsGet_images() throws SAXException{ if (_images == null) _images = toElementArray( getDelegate().getImages() ); return _images; } public Scriptable jsGet_links() throws SAXException { if (_links == null) _links = toElementArray( getDelegate().getLinks() ); return _links; } public Scriptable jsGet_forms() throws SAXException { if (_forms == null) _forms = toElementArray( getDelegate().getForms() ); return _forms; } public Object jsFunction_getElementById( String id ) { ScriptableDelegate elementWithID = getDelegate().getElementWithID( id ); return elementWithID == null ? null : toScriptable( elementWithID ); } public Object jsFunction_getElementsByName( String name ) { return toElementArray( getDelegate().getElementsByName( name ) ); } public Object jsFunction_getElementsByTagName( String name ) { return toElementArray( getDelegate().getElementsByTagName( name ) ); } public Object jsGet_location() { return _parent == null ? NOT_FOUND : getWindow().jsGet_location(); } public void jsSet_location( String urlString ) throws IOException, SAXException { if (urlString.startsWith( "color" )) return; getWindow().setLocation( urlString ); } public String jsGet_cookie() { return getDelegate().getCookie(); } public void jsSet_cookie( String cookieSpec ) { final int equalsIndex = cookieSpec.indexOf( '=' ); if (equalsIndex <0) return; int endIndex = cookieSpec.indexOf( ";", equalsIndex ); if (endIndex < 0) endIndex = cookieSpec.length(); String name = cookieSpec.substring( 0, equalsIndex ); String value = cookieSpec.substring( equalsIndex+1, endIndex ); getDelegate().setCookie( name, value ); } private Window getWindow() { return ((Window) _parent); } public void jsFunction_open( Object mimeType ) { _mimeType = toStringIfNotUndefined( mimeType ); } public void jsFunction_close() { if (getDelegate().replaceText( getWriteBuffer().toString(), _mimeType == null ? "text/html" : _mimeType )) { getWriteBuffer().setLength(0); } } public void jsFunction_write( String string ) { getWriteBuffer().append( string ); } public void jsFunction_writeln( String string ) { getWriteBuffer().append( string ).append( (char) 0x0D ).append( (char) 0x0A ); } protected StringBuffer getWriteBuffer() { if (_writeBuffer == null) _writeBuffer = new StringBuffer(); return _writeBuffer; } protected void clearWriteBuffer() { _writeBuffer = null; } private HTMLPage.Scriptable getDelegate() { return (HTMLPage.Scriptable) _scriptable; } } static public class Location extends JavaScriptEngine { private URL _url; private Window _window; public String getClassName() { return "Location"; } void initialize( Window window, URL url ) { _window = window; _url = url; } public void jsFunction_replace( String urlString ) throws IOException, SAXException { _window.setLocation( urlString ); } public String jsGet_href() { return toString(); } public void jsSet_href( String urlString ) throws SAXException, IOException { _window.setLocation( urlString ); } public String jsGet_protocol() { return _url.getProtocol() + ':'; } public String jsGet_host() { return _url.getHost() + ':' + _url.getPort(); } public String jsGet_hostname() { return _url.getHost(); } public String jsGet_port() { return String.valueOf( _url.getPort() ); } public String jsGet_pathname() { return _url.getPath(); } public void jsSet_pathname( String newPath ) throws SAXException, IOException { if (!newPath.startsWith( "/" )) newPath = '/' + newPath; URL newURL = new URL( _url, newPath ); _window.setLocation( newURL.toExternalForm() ); } public String jsGet_search() { return '?' + _url.getQuery(); } public void jsSet_search( String newSearch ) throws SAXException, IOException { if (!newSearch.startsWith( "?" )) newSearch = '?' + newSearch; _window.setLocation( jsGet_protocol() + "//" + jsGet_host() + jsGet_pathname() + newSearch ); } /** * Returns the default value of this scriptable object. In this case, it returns simply the URL as a string. * Note that this method is necessary, since Rhino will only call the toString method directly if there are no * Rhino methods defined (jsGet_*, jsFunction_*, etc.) */ public Object getDefaultValue( Class typeHint ) { return _url.toExternalForm(); } public String toString() { return _url.toExternalForm(); } } static public class Style extends JavaScriptEngine { private String _display = "inline"; private String _visibility = "visible"; public String getClassName() { return "Style"; } public String jsGet_display() { return _display; } public void jsSet_display( String display ) { _display = display; } public String jsGet_visibility() { return _visibility; } public void jsSet_visibility( String visibility ) { _visibility = visibility; } } static public class Navigator extends JavaScriptEngine { private ClientProperties _clientProperties; public String getClassName() { return "Navigator"; } void setClientProperties( ClientProperties clientProperties ) { _clientProperties = clientProperties; } public String jsGet_appName() { return _clientProperties.getApplicationName(); } public String jsGet_appCodeName() { return _clientProperties.getApplicationCodeName(); } public String jsGet_appVersion() { return _clientProperties.getApplicationVersion(); } public String jsGet_userAgent() { return _clientProperties.getUserAgent(); } public String jsGet_platform() { return _clientProperties.getPlatform(); } public Object[] jsGet_plugins() { return new Object[0]; } public boolean jsFunction_javaEnabled() { return false; // no support is provided for applets at present } } static public class Screen extends JavaScriptEngine { private ClientProperties _clientProperties; void setClientProperties( ClientProperties clientProperties ) { _clientProperties = clientProperties; } public String getClassName() { return "Screen"; } public int jsGet_availWidth() { return _clientProperties.getAvailableScreenWidth(); } public int jsGet_availHeight() { return _clientProperties.getAvailHeight(); } } static public class ElementArray extends ScriptableObject { private JavaScriptEngine _contents[] = new HTMLElement[0]; static ElementArray newElementArray( Scriptable parent ) { try { return (ElementArray) Context.getCurrentContext().newObject( parent, "ElementArray" ); } catch (PropertyException e) { throw new RhinoException( e ); } catch (NotAFunctionException e) { throw new RhinoException( e ); } catch (JavaScriptException e) { throw new RhinoException( e ); } } public ElementArray() { } void initialize( JavaScriptEngine[] contents ) { _contents = contents; } public int jsGet_length() { return _contents.length; } public String getClassName() { return "ElementArray"; } public Object get( int i, Scriptable scriptable ) { if (i >= 0 && i < _contents.length) { return _contents[i]; } else { return super.get( i, scriptable ); } } public Object get( String name, Scriptable scriptable ) { for (int i = 0; i < _contents.length; i++) { JavaScriptEngine content = _contents[ i ]; if (name.equalsIgnoreCase( content.getID() )) return content; } for (int i = 0; i < _contents.length; i++) { JavaScriptEngine content = _contents[ i ]; if (name.equalsIgnoreCase( content.getName() )) return content; } return super.get( name, scriptable ); } protected JavaScriptEngine[] getContents() { return _contents; } } /** * HTML Element support for JavaScript */ static public class HTMLElement extends JavaScriptEngine { private Style _style; private Document _document; public String getClassName() { return "HTMLElement"; } public Document jsGet_document() { return _document; } public Style jsGet_style() { return _style; } /** * arbitrary attribute access * @param attributeName * @return */ public Object jsFunction_getAttribute(String attributeName) { return _scriptable.get(attributeName); } void initialize( JavaScriptEngine parent, ScriptableDelegate scriptable ) throws JavaScriptException, NotAFunctionException, PropertyException, SAXException { super.initialize( parent, scriptable ); _document = (Document) parent; _style = (Style) Context.getCurrentContext().newObject( this, "Style" ); } } static public class Image extends HTMLElement { public String getClassName() { return "Image"; } } static public class Link extends HTMLElement { public Document jsGet_document() { return super.jsGet_document(); } public String getClassName() { return "Link"; } } static public class Form extends HTMLElement { private ElementArray _controls; public String getClassName() { return "Form"; } public String jsGet_name() { return getDelegate().getName(); } public String jsGet_action() { return getDelegate().getAction(); } public void jsSet_action( String action ) { getDelegate().setAction( action ); } public Scriptable jsGet_elements() throws PropertyException, NotAFunctionException, JavaScriptException { if (_controls == null) { initializeControls(); } return _controls; } public Object jsFunction_getElementsByTagName( String name ) throws SAXException { return toElementArray( getDelegate().getElementsByTagName( name ) ); } public void jsFunction_submit() throws IOException, SAXException { getDelegate().submit(); } public void jsFunction_reset() throws IOException, SAXException { getDelegate().reset(); } private void initializeControls() throws PropertyException, NotAFunctionException, JavaScriptException { ScriptableDelegate scriptables[] = getDelegate().getElementDelegates(); Control[] controls = new Control[ scriptables.length ]; for (int i = 0; i < controls.length; i++) { controls[ i ] = (Control) toScriptable( scriptables[ i ] ); } _controls = (ElementArray) Context.getCurrentContext().newObject( this, "ElementArray" ); _controls.initialize( controls ); } private WebForm.Scriptable getDelegate() { return (WebForm.Scriptable) _scriptable; } } /** * Javascript support for any control */ static public class Control extends JavaScriptEngine { private Form _form; public String getClassName() { return "Control"; } public Form jsGet_form() { return _form; } public void jsFunction_focus() {} public void jsFunction_select() {} /** * click via javascript * @throws IOException * @throws SAXException */ public void jsFunction_click() throws IOException, SAXException { getDelegate().click(); } private Input getDelegate() { return (Input) _scriptable; } /** Support getting value of arbitrary attribute */ public Object jsFunction_getAttribute( String attributeName ) throws JavaScriptException { return getDelegate().get( attributeName ); } /** Support getting value of arbitrary attribute */ public void jsFunction_setAttribute( String attributeName, Object value ) throws JavaScriptException { getDelegate().setAttribute( attributeName, value ); } /** Support getting value of arbitrary attribute */ public void jsFunction_removeAttribute( String attributeName ) throws JavaScriptException { getDelegate().removeAttribute( attributeName ); } /** Allow calling onchange() from within a JavaScript function */ public void jsFunction_onchange() throws JavaScriptException { Input myInput=this.getDelegate(); myInput.sendOnChangeEvent(); } void initialize( JavaScriptEngine parent, ScriptableDelegate scriptable ) throws JavaScriptException, NotAFunctionException, PropertyException, SAXException { super.initialize( parent, scriptable ); if (parent instanceof Form) _form = (Form) parent; } } static public class Options extends JavaScriptEngine { public String getClassName() { return "Options"; } public int jsGet_length() { return getDelegate().getLength(); } public void jsSet_length( int length ) { getDelegate().setLength( length ); } public void put( int i, Scriptable scriptable, Object object ) { if (object == null) { getDelegate().put( i, null ); } else { if (!(object instanceof Option)) throw new IllegalArgumentException( "May only add an Option to this array" ); Option option = (Option) object; getDelegate().put( i, option.getDelegate() ); } } private SelectionOptions getDelegate() { return (SelectionOptions) _scriptable; } } static public class Option extends JavaScriptEngine { public String getClassName() { return "Option"; } public void jsConstructor( String text, String value, boolean defaultSelected, boolean selected ) { _scriptable = WebResponse.newDelegate( "Option" ); getDelegate().initialize( text, value, defaultSelected, selected ); } public int jsGet_index() { return getDelegate().getIndex(); } public String jsGet_text() { return getDelegate().getText(); } public void jsSet_text( String text ) { getDelegate().setText( text ); } public String jsGet_value() { return getDelegate().getValue(); } public void jsSet_value( String value ) { getDelegate().setValue( value ); } public boolean jsGet_selected() { return getDelegate().isSelected(); } public void jsSet_selected( boolean selected ) { getDelegate().setSelected( selected ); } public boolean jsGet_defaultSelected() { return getDelegate().isDefaultSelected(); } SelectionOption getDelegate() { return (SelectionOption) _scriptable; } } } /** * special exception for the Rhino Javscript engine */ class RhinoException extends RuntimeException { private Exception _cause; public RhinoException( Exception cause ) { _cause = cause; } public String getMessage() { return "Rhino exception: " + _cause; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/javascript/JavaScriptEngineFactory.java0000644000175000017500000000735611014557540031106 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: JavaScriptEngineFactory.java 907 2008-04-05 08:16:49Z wolfgang_fahl $ * * Copyright (c) 2002,2008 Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.HttpUnitUtils; import com.meterware.httpunit.WebResponse; import com.meterware.httpunit.HTMLElement; import com.meterware.httpunit.scripting.ScriptingEngineFactory; import com.meterware.httpunit.scripting.ScriptableDelegate; import com.meterware.httpunit.scripting.ScriptingHandler; /** * An implementation of the scripting engine factory which selects a Rhino-based implementation of JavaScript. * * @author Russell Gold **/ public class JavaScriptEngineFactory implements ScriptingEngineFactory { public boolean isEnabled() { try { Class.forName( "org.mozilla.javascript.Context" ); return true; } catch (Exception e) { System.err.println( "Rhino classes (js.jar) not found - Javascript disabled" ); return false; } } public void associate( WebResponse response ) { try { JavaScript.run( response ); } catch (RuntimeException e) { throw e; } catch (Exception e) { HttpUnitUtils.handleException(e); throw new RuntimeException( e.toString() ); } } public void load( WebResponse response ) { try { JavaScript.load( response ); } catch (RuntimeException e) { throw e; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException( e.toString() ); } } public void setThrowExceptionsOnError( boolean throwExceptions ) { JavaScript.setThrowExceptionsOnError( throwExceptions ); } public boolean isThrowExceptionsOnError() { return JavaScript.isThrowExceptionsOnError(); } public String[] getErrorMessages() { return ScriptingEngineImpl.getErrorMessages(); } public void clearErrorMessages() { ScriptingEngineImpl.clearErrorMessages(); } public ScriptingHandler createHandler( HTMLElement elementBase ) { ScriptableDelegate delegate = elementBase.newScriptable(); delegate.setScriptEngine( elementBase.getParentDelegate().getScriptEngine( delegate ) ); return delegate; } public ScriptingHandler createHandler( WebResponse response ) { return response.createJavascriptScriptingHandler(); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/javascript/ScriptingEngineImpl.java0000644000175000017500000001647111014557540030272 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: ScriptingEngineImpl.java 839 2008-03-29 23:30:13Z wolfgang_fahl $ * * Copyright (c) 2006-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.mozilla.javascript.*; import com.meterware.httpunit.scripting.ScriptingEngine; import com.meterware.httpunit.HttpUnitUtils; import com.meterware.httpunit.ScriptException; import java.util.ArrayList; /** * * @author Russell Gold **/ public abstract class ScriptingEngineImpl extends ScriptableObject implements ScriptingEngine { private final static Object[] NO_ARGS = new Object[0]; private static ArrayList _errorMessages = new ArrayList(); static public void clearErrorMessages() { _errorMessages.clear(); } static public String[] getErrorMessages() { return (String[]) _errorMessages.toArray( new String[ _errorMessages.size() ] ); } /** * handle Exceptions * @param e - the exception to handle * @param badScript - the script that caused the problem */ static public void handleScriptException( Exception e, String badScript ) { final String errorMessage = badScript + " failed: " + e; if (!(e instanceof EcmaError) && !(e instanceof EvaluatorException)) { HttpUnitUtils.handleException(e); throw new RuntimeException( errorMessage ); } else if (JavaScript.isThrowExceptionsOnError()) { HttpUnitUtils.handleException(e); throw new ScriptException( errorMessage ); } else { _errorMessages.add( errorMessage ); } } //--------------------------------------- ScriptingEngine methods ------------------------------------------------------ public boolean supportsScriptLanguage( String language ) { return language == null || language.toLowerCase().startsWith( "javascript" ); } /** * run the given script * @param language - the language of the script * @param script - the script to run */ public String runScript( String language, String script ) { if (!supportsScriptLanguage( language )) return ""; try { script = script.trim(); if (script.startsWith( "" )) script = script.substring( 0, script.lastIndexOf( "-->" )); } Context context = Context.enter(); context.initStandardObjects( null ); context.evaluateString( this, script, "httpunit", 0, null ); return getDocumentWriteBuffer(); } catch (Exception e) { handleScriptException( e, "Script '" + script + "'" ); return ""; } finally { discardDocumentWriteBuffer(); Context.exit(); } } /** * handle the event that has the given script attached * by compiling the eventScript as a function and executing it * @param eventScript - the script to use * @deprecated since 1.7 - use doEventScript instead */ public boolean doEvent( String eventScript ) { return doEventScript(eventScript); } /** * handle the event that has the given script attached * by compiling the eventScript as a function and executing it * @param eventScript - the script to use */ public boolean doEventScript( String eventScript ) { if (eventScript.length() == 0) { return true; } else { try { Context context = Context.enter(); context.initStandardObjects( null ); context.setOptimizationLevel( -1 ); // wrap the eventScript into a function Function f = context.compileFunction( this, "function x() { " + eventScript + "}", "httpunit", 0, null ); // call the function with no arguments Object result = f.call( context, this, this, NO_ARGS ); // return the result of the function or false if it is not boolean return (!(result instanceof Boolean)) || ((Boolean) result).booleanValue(); } catch (Exception e) { handleScriptException( e, "Event '" + eventScript + "'" ); return false; } finally { Context.exit(); } } // if } /** * get the event Handler script for the event e.g. onchange, onmousedown, onclick, onmouseup * execute the script if it's assigned by calling doEvent for the script * @param eventName * @return */ public boolean handleEvent(String eventName) { throw new RuntimeException("pseudo - abstract handleEvent called "); } /** * Evaluates the specified string as JavaScript. Will return null if the script has no return value. * @param expression - the expression to evaluate */ public Object evaluateExpression( String expression ) { try { Context context = Context.enter(); context.initStandardObjects( null ); Object result = context.evaluateString( this, expression, "httpunit", 0, null ); return (result == null || result instanceof Undefined) ? null : result; } catch (Exception e) { handleScriptException( e, "URL '" + expression + "'" ); return null; } finally { Context.exit(); } } //------------------------------------------ protected methods --------------------------------------------------------- protected String getDocumentWriteBuffer() { throw new IllegalStateException( "may not run runScript() from " + getClass() ); } protected void discardDocumentWriteBuffer() { throw new IllegalStateException( "may not run runScript() from " + getClass() ); } private String withoutFirstLine( String script ) { for (int i=0; i < script.length(); i++) { if (isLineTerminator( script.charAt(i) )) return script.substring( i ).trim(); } return ""; } private boolean isLineTerminator( char c ) { return c == 0x0A || c == 0x0D; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/0000755000175000017500000000000011014557542023003 5ustar twernertwernerhttpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/DocumentAdapter.java0000644000175000017500000000453311014557542026732 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: DocumentAdapter.java 778 2007-05-16 19:07:49Z russgold $ * * Copyright (c) 2002-2007, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.scripting.ScriptableDelegate; import com.meterware.httpunit.scripting.ScriptingHandler; import org.w3c.dom.Document; import org.w3c.dom.html.HTMLDocument; import java.io.IOException; /** * * @author Russell Gold **/ public interface DocumentAdapter { /** * Records the root (Document) node. */ public void setDocument( HTMLDocument document ); /** * Returns the contents of an included script, given its src attribute. * @param srcAttribute the relative URL for the included script * @return the contents of the script. * @throws java.io.IOException if there is a problem retrieving the script */ public String getIncludedScript( String srcAttribute ) throws IOException; /** * Returns the Scriptable object associated with the document */ public ScriptingHandler getScriptingHandler(); } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/HTMLParser.java0000644000175000017500000000557411014557542025602 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: HTMLParser.java 855 2008-03-31 08:54:13Z wolfgang_fahl $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.xml.sax.SAXException; import java.net.URL; import java.io.IOException; /** * A front end to a DOM parser that can handle HTML. * * @since 1.5.2 * @author Russell Gold * @author Bernhard Wagner **/ public interface HTMLParser { /** * Parses the specified text string as a Document, registering it in the HTMLPage. * Any error reporting will be annotated with the specified URL. */ public void parse( URL baseURL, String pageText, DocumentAdapter adapter ) throws IOException, SAXException; /** * Removes any string artifacts placed in the text by the parser. For example, a parser may choose to encode * an HTML entity as a special character. This method should convert that character to normal text. */ public String getCleanedText( String string ); /** * Returns true if this parser supports preservation of the case of tag and attribute names. */ public boolean supportsPreserveTagCase(); /** * Returns true if this parser supports forcing the upper/lower case of tag and attribute names. */ public boolean supportsForceTagCase(); /** * Returns true if this parser can return an HTMLDocument object. */ public boolean supportsReturnHTMLDocument(); /** * Returns true if this parser can display parser warnings. */ public boolean supportsParserWarnings(); } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/HTMLParserFactory.java0000644000175000017500000002317211014557542027124 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: HTMLParserFactory.java 855 2008-03-31 08:54:13Z wolfgang_fahl $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.util.Vector; /** * Factory for creating HTML parsers. Parser customization properties can be specified but do not necessarily work * for every parser type. * * @since 1.5.2 * @author Russell Gold * @author Bernhard Wagner **/ abstract public class HTMLParserFactory { private static Vector _listeners = new Vector(); private static HTMLParser _jtidyParser; private static HTMLParser _nekoParser; private static HTMLParser _htmlParser; private static boolean _preserveTagCase; private static boolean _returnHTMLDocument; private static boolean _parserWarningsEnabled; // for parsers that support forcing Case private static boolean _forceUpper; private static boolean _forceLower; /** * Resets all settings to their default values. This includes the parser selection. */ public static void reset() { _preserveTagCase = false; _returnHTMLDocument = true; _parserWarningsEnabled = false; _htmlParser = null; _forceUpper = false; _forceLower = false; } /** * Selects the JTidy parser, if present. */ public static void useJTidyParser() { if (_jtidyParser == null) throw new RuntimeException( "JTidy parser not available" ); _htmlParser = _jtidyParser; } /** * Selects the NekoHTML parser, if present. */ public static void useNekoHTMLParser() { if (_nekoParser == null) throw new RuntimeException( "NekoHTML parser not available" ); _htmlParser = _nekoParser; } /** * Specifies the parser to use. */ public static void setHTMLParser( HTMLParser htmlParser ) { _htmlParser = htmlParser; } /** * Returns the current selected parser. */ public static HTMLParser getHTMLParser() { if (_htmlParser == null) { if (_nekoParser != null) { _htmlParser = _nekoParser; } else if (_jtidyParser != null) { _htmlParser = _jtidyParser; } else { throw new RuntimeException( "No HTML parser found. Make sure that either nekoHTML.jar or Tidy.jar is in the in classpath" ); } } return _htmlParser; } /** * Returns true if the current parser will preserve the case of HTML tags and attributes. */ public static boolean isPreserveTagCase() { return _preserveTagCase && getHTMLParser().supportsPreserveTagCase(); } /** * Specifies whether the parser should preserve the case of HTML tags and attributes. Not every parser can * support this capability. Note that enabling this will disable support for the HTMLDocument class. * override any previous behaviour configured by calling {@link #setForceUpperCase(boolean)} or * {@link #setForceLowerCase(boolean)} * @see #setReturnHTMLDocument * @see #setForceUpperCase(boolean) * @see #setForceLowerCase(boolean) */ public static void setPreserveTagCase( boolean preserveTagCase ) { _preserveTagCase = preserveTagCase; if (preserveTagCase) { _forceLower = false; _forceUpper = false; } } /** * Returns true if the current parser will return an HTMLDocument object rather than a Document object. */ public static boolean isReturnHTMLDocument() { return _returnHTMLDocument && !isPreserveTagCase() && getHTMLParser().supportsReturnHTMLDocument(); } /** * Specifies whether the parser should return an HTMLDocument object rather than a Document object. * Not every parser can support this capability. Note that enabling this will disable preservation of tag case. * and/or the forcing of the tag case to upper or lower case. * @see #setPreserveTagCase * @see #setForceUpperCase(boolean) * @see #setForceLowerCase(boolean) */ public static void setReturnHTMLDocument( boolean returnHTMLDocument ) { _returnHTMLDocument = returnHTMLDocument; if (returnHTMLDocument) { _preserveTagCase = false; _forceLower = false; _forceUpper = false; } } /** * Specifies whether the parser should force the case of HTML tags and attributes to be upper case. Not * every parser can support this capability. Note that enabling this will disable support for the * HTMLDocument class and override any previous behaviour configured by enabling * {@link #setPreserveTagCase(boolean)} or {@link #setForceLowerCase(boolean)} * @see #setReturnHTMLDocument * @see #setPreserveTagCase(boolean) * @see #setForceLowerCase(boolean) * @param forceUpper * boolean indicating whether to enable this functionality */ public static void setForceUpperCase(boolean forceUpper) { _forceUpper = forceUpper; if (_forceUpper) { _forceLower = false; _preserveTagCase = false; // _returnHTMLDocument = false; } } /** * Return true if the current parser will support forcing the tags and attributes to upper case * @return boolean flag */ public static boolean getForceUpperCase() { return _forceUpper && getHTMLParser().supportsPreserveTagCase(); } /** * Specifies whether the parser should force the case of HTML tags and attributes to lower case. Not * every parser can support this capability. Note that enabling this will disable support for the * HTMLDocument class and override any previous behaviour configured by enabling * {@link #setPreserveTagCase(boolean)} or {@link #setForceUpperCase(boolean)} * @see #setReturnHTMLDocument * @see #setPreserveTagCase(boolean) * @see #setForceUpperCase(boolean) * @param forceLower * boolean indicating whether to enable this functionality */ public static void setForceLowerCase(boolean forceLower) { _forceLower = forceLower; if (_forceLower) { _forceUpper = false; _preserveTagCase = false; // _returnHTMLDocument = false; } } /** * Return true if the current parser will support forcing the tags and attributes to lower case * @return boolean flag */ public static boolean getForceLowerCase() { return _forceLower && getHTMLParser().supportsPreserveTagCase(); } /** * Returns true if parser warnings are enabled. **/ public static boolean isParserWarningsEnabled() { return _parserWarningsEnabled && getHTMLParser().supportsParserWarnings(); } /** * If true, tells the parser to display warning messages. The default is false (warnings are not shown). **/ public static void setParserWarningsEnabled( boolean enabled ) { _parserWarningsEnabled = enabled; } /** * Remove an HTML Parser listener. **/ public static void removeHTMLParserListener( HTMLParserListener el ) { _listeners.removeElement( el ); } /** * Add an HTML Parser listener. **/ public static void addHTMLParserListener( HTMLParserListener el ) { _listeners.addElement( el ); } //------------------------------------- package protected members ------------------------------------------------------ /** * Get the list of Html Error Listeners **/ static Vector getHTMLParserListeners() { return _listeners; } private static HTMLParser loadParserIfSupported( final String testClassName, final String parserClassName ) { try { Class.forName( testClassName ); return (HTMLParser) Class.forName( parserClassName ).newInstance(); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (ClassNotFoundException e) { } return null; } static { _jtidyParser = loadParserIfSupported( "org.w3c.tidy.Parser", "com.meterware.httpunit.parsing.JTidyHTMLParser" ); _nekoParser = loadParserIfSupported( "org.cyberneko.html.HTMLConfiguration", "com.meterware.httpunit.parsing.NekoHTMLParser" ); reset(); } } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/HTMLParserListener.java0000644000175000017500000000513611014557542027302 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: HTMLParserListener.java 447 2002-12-25 15:23:11Z russgold $ * * Copyright (c) 2002, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.net.URL; /** * A listener for messages from the HTMLParser. This provides a mechanism to watch for errors and warnings generated * during parsing. * * @author Russell Gold * @author Benoit Xhenseval **/ public interface HTMLParserListener { /** * Invoked when the parser wishes to report a warning. * @param url the location of the document to which the warning applies. * @param msg the warning message * @param line the line in the document on which the problematic HTML was found * @param column the column in the document on which the problematic HTML was found */ void warning( URL url, String msg, int line, int column ); /** * Invoked when the parser wishes to report an error. * @param url the location of the document to which the error applies. * @param msg the warning message * @param line the line in the document on which the problematic HTML was found * @param column the column in the document on which the problematic HTML was found */ void error( URL url, String msg, int line, int column ); } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/JTidyHTMLParser.java0000644000175000017500000000732511014557540026540 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: JTidyHTMLParser.java 855 2008-03-31 08:54:13Z wolfgang_fahl $ * * Copyright (c) 2002,2004,2008 Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.w3c.tidy.Tidy; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.html.HTMLDocument; import org.xml.sax.SAXException; import java.net.URL; import java.io.IOException; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import com.meterware.httpunit.dom.HTMLDocumentImpl; /** * * @author Russell Gold **/ class JTidyHTMLParser implements HTMLParser { public void parse( URL pageURL, String pageText, DocumentAdapter adapter ) throws IOException, SAXException { try { Document jtidyDocument = getParser( pageURL ).parseDOM( new ByteArrayInputStream( pageText.getBytes( UTF_ENCODING ) ), null ); HTMLDocument htmlDocument = new HTMLDocumentImpl(); NodeList nl = jtidyDocument.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node importedNode = nl.item(i); if (importedNode.getNodeType() != Node.DOCUMENT_TYPE_NODE) htmlDocument.appendChild( htmlDocument.importNode( importedNode, true ) ); } adapter.setDocument( htmlDocument ); } catch (UnsupportedEncodingException e) { throw new RuntimeException( "UTF-8 encoding failed" ); } } public String getCleanedText( String string ) { return (string == null) ? "" : string.replace( NBSP, ' ' ); } public boolean supportsPreserveTagCase() { return false; } public boolean supportsForceTagCase() { return false; } public boolean supportsReturnHTMLDocument() { return true; } public boolean supportsParserWarnings() { return true; } final private static char NBSP = (char) 160; // non-breaking space, defined by JTidy final private static String UTF_ENCODING = "UTF-8"; private static Tidy getParser( URL url ) { Tidy tidy = new Tidy(); tidy.setCharEncoding( org.w3c.tidy.Configuration.UTF8 ); tidy.setQuiet( true ); tidy.setShowWarnings( HTMLParserFactory.isParserWarningsEnabled() ); if (!HTMLParserFactory.getHTMLParserListeners().isEmpty()) { tidy.setErrout( new JTidyPrintWriter( url ) ); } return tidy; } } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/JTidyPrintWriter.java0000644000175000017500000001505311014557540027105 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: JTidyPrintWriter.java 698 2004-10-05 11:29:52Z russgold $ * * Copyright (c) 2001-2002, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.util.StringTokenizer; import java.util.Enumeration; import java.io.PrintWriter; import java.net.URL; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; /** * Basic "parser" for the JTidy error output. Will get the line and column number as well * as the message. It assumes that an error or warning is to be logged once println() has been * called or if a string starts with "line" * * @author Benoit Xhenseval * @author Peter Royal **/ class JTidyPrintWriter extends PrintWriter { /** * DecimalFormat.getNumberInstance() should provide us with a proper formatter for the default locale. The * integers returned from JTidy contain the appropriate decimal separator for the current locale. */ private static final NumberFormat INTEGER_FORMAT = DecimalFormat.getNumberInstance(); JTidyPrintWriter( URL pageURL ) { super(System.out); _url = pageURL; } public void print(boolean b) { print(String.valueOf(b)); } public void print(char c) { print(String.valueOf(c)); } public void print(char[] s) { print(String.valueOf(s)); } public void print(double d) { print(String.valueOf(d)); } public void print(float f) { print(String.valueOf(f)); } public void print(int i) { print(String.valueOf(i)); } public void print(long l) { print(String.valueOf(l)); } public void print(Object obj) { print(obj.toString()); } /** * Detects a new log if starting with "line", a warning if message starts with "Warning" * and an error if it starts with "Error" **/ public void print(String s) { if (s.startsWith("line")) { if (!_logged && _line > 0 && _msg!=null && _msg.length()>0) { log(); // log previous!!! } _logged = false; // new error.... StringTokenizer tok = new StringTokenizer(s); // skip first "line" tok.nextToken(); // get line _line = parseInteger(tok.nextToken()); // skip second "column" tok.nextToken(); // get column _column = parseInteger(tok.nextToken()); } else if (s.startsWith("Warning")) { _error = false; _msg = s; } else if (s.startsWith("Error")) { _error = true; _msg = s; } else { // non structured msg _msg += s; } } private int parseInteger( String integer ) { try { return INTEGER_FORMAT.parse( integer ).intValue(); } catch (ParseException e) { throw new NumberFormatException( "Unable to parse integer [int: " + integer + ", error: " + e.getMessage() ); } } public void println() { if (!_logged) { log(); } } public void println(boolean x) { print(String.valueOf(x)); println(); } public void println(char c) { print(String.valueOf(c)); println(); } public void println(char[] c) { print(String.valueOf(c)); println(); } public void println(double d) { print(String.valueOf(d)); println(); } public void println(float f) { print(String.valueOf(f)); println(); } public void println(int i) { print(String.valueOf(i)); println(); } public void println(long l) { print(String.valueOf(l)); println(); } public void println(Object o) { print(o.toString()); println(); } public void println(String s) { print(s); println(); } //----------------------------------------------- private members ------------------------------------------------------ private int _line = -1; private int _column = -1; private String _msg = ""; private boolean _error = false; private boolean _logged = false; private URL _url; /** * reports the warning or error and then resets the current error/warning. **/ private void log() { //System.out.println("Logging........................."); if (_error) { reportError(_msg,_line,_column); } else { reportWarning(_msg,_line,_column); } _logged = true; _line = -1; _column=-1; _msg=""; } private void reportError( String msg, int line, int column ) { Enumeration listeners = HTMLParserFactory.getHTMLParserListeners().elements(); while (listeners.hasMoreElements()) { ((HTMLParserListener) listeners.nextElement()).error( _url, msg, line, column ); } } private void reportWarning( String msg, int line, int column ) { Enumeration listeners = HTMLParserFactory.getHTMLParserListeners().elements(); while (listeners.hasMoreElements()) { ((HTMLParserListener) listeners.nextElement()).warning( _url, msg, line, column ); } } }httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/NekoDOMParser.java0000644000175000017500000002113011014557540026252 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: NekoDOMParser.java 855 2008-03-31 08:54:13Z wolfgang_fahl $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.scripting.ScriptingHandler; import com.meterware.httpunit.dom.HTMLDocumentImpl; import java.net.URL; import java.io.IOException; import java.util.Enumeration; import org.cyberneko.html.HTMLConfiguration; import org.apache.xerces.xni.parser.XMLDocumentFilter; import org.apache.xerces.xni.parser.XMLErrorHandler; import org.apache.xerces.xni.parser.XMLParseException; import org.apache.xerces.xni.XNIException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.w3c.dom.Element; import org.w3c.dom.html.HTMLDocument; /** * * * @author Russell Gold * @author Artashes Aghajanyan **/ class NekoDOMParser extends org.apache.xerces.parsers.DOMParser implements ScriptHandler { // private static final String HTML_DOCUMENT_CLASS_NAME = "org.apache.html.dom.HTMLDocumentImpl"; /** Error reporting feature identifier. */ private static final String REPORT_ERRORS = "http://cyberneko.org/html/features/report-errors"; /** Augmentations feature identifier. */ private static final String AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations"; /** Filters property identifier. */ private static final String FILTERS = "http://cyberneko.org/html/properties/filters"; /** Element case settings. possible values: "upper", "lower", "match" */ private static final String TAG_NAME_CASE = "http://cyberneko.org/html/properties/names/elems"; /** Attribute case settings. possible values: "upper", "lower", "no-change" */ private static final String ATTRIBUTE_NAME_CASE = "http://cyberneko.org/html/properties/names/attrs"; private DocumentAdapter _documentAdapter; /** * construct a new NekoDomParser with the given adapter and url * @param adapter * @param url * @return - the new parser * patch [ 1211154 ] NekoDOMParser default to lowercase by Dan Allen * patch [ 1176688 ] Allow configuration of neko parser properties by James Abley */ static NekoDOMParser newParser( DocumentAdapter adapter, URL url ) { final HTMLConfiguration configuration = new HTMLConfiguration(); if (!HTMLParserFactory.getHTMLParserListeners().isEmpty() || HTMLParserFactory.isParserWarningsEnabled()) { configuration.setErrorHandler( new ErrorHandler( url ) ); configuration.setFeature( REPORT_ERRORS, true); } configuration.setFeature( AUGMENTATIONS, true ); final ScriptFilter javaScriptFilter = new ScriptFilter( configuration ); configuration.setProperty( FILTERS, new XMLDocumentFilter[] { javaScriptFilter } ); if (HTMLParserFactory.isPreserveTagCase()) { configuration.setProperty( TAG_NAME_CASE, "match" ); configuration.setProperty( ATTRIBUTE_NAME_CASE, "no-change" ); } else { configuration.setProperty( TAG_NAME_CASE, "lower" ); configuration.setProperty( ATTRIBUTE_NAME_CASE, "lower" ); if (HTMLParserFactory.getForceUpperCase()) { configuration.setProperty(TAG_NAME_CASE, "upper"); configuration.setProperty(ATTRIBUTE_NAME_CASE, "upper"); } // this is the default as of patch [ 1211154 ] ... just for people who rely on patch [ 1176688 ] if (HTMLParserFactory.getForceLowerCase()) { configuration.setProperty(TAG_NAME_CASE, "lower"); configuration.setProperty(ATTRIBUTE_NAME_CASE, "lower"); } } try { final NekoDOMParser domParser = new NekoDOMParser( configuration, adapter ); domParser.setFeature( DEFER_NODE_EXPANSION, false ); if (HTMLParserFactory.isReturnHTMLDocument()) domParser.setProperty( DOCUMENT_CLASS_NAME, HTMLDocumentImpl.class.getName() ); javaScriptFilter.setScriptHandler( domParser ); return domParser; } catch (SAXNotRecognizedException e) { throw new RuntimeException( e.toString() ); } catch (SAXNotSupportedException e) { throw new RuntimeException( e.toString() ); } } private Element getCurrentElement() { try { return (Element) getProperty( CURRENT_ELEMENT_NODE ); } catch (SAXNotRecognizedException e) { throw new RuntimeException( CURRENT_ELEMENT_NODE + " property not recognized" ); } catch (SAXNotSupportedException e) { e.printStackTrace(); throw new RuntimeException( CURRENT_ELEMENT_NODE + " property not supported" ); } } NekoDOMParser( HTMLConfiguration configuration, DocumentAdapter adapter ) { super( configuration ); _documentAdapter = adapter; } public String getIncludedScript( String srcAttribute ) { try { return _documentAdapter.getIncludedScript( srcAttribute ); } catch (IOException e) { throw new ScriptException( e ); } } public boolean supportsScriptLanguage( String language ) { return getScriptingHandler().supportsScriptLanguage( language ); } public String runScript( final String language, final String scriptText ) { getScriptingHandler().clearCaches(); return getScriptingHandler().runScript( language, scriptText ); } private ScriptingHandler getScriptingHandler() { _documentAdapter.setDocument( (HTMLDocument) getCurrentElement().getOwnerDocument() ); return _documentAdapter.getScriptingHandler(); } static class ScriptException extends RuntimeException { private IOException _cause; public ScriptException( IOException cause ) { _cause = cause; } public IOException getException() { return _cause; } } } class ErrorHandler implements XMLErrorHandler { private URL _url = null; ErrorHandler( URL url ) { _url = url; } public void warning( String domain, String key, XMLParseException warningException ) throws XNIException { if (HTMLParserFactory.isParserWarningsEnabled()) { System.out.println( "At line " + warningException.getLineNumber() + ", column " + warningException.getColumnNumber() + ": " + warningException.getMessage() ); } Enumeration listeners = HTMLParserFactory.getHTMLParserListeners().elements(); while (listeners.hasMoreElements()) { ((HTMLParserListener) listeners.nextElement()).warning( _url, warningException.getMessage(), warningException.getLineNumber(), warningException.getColumnNumber() ); } } public void error( String domain, String key, XMLParseException errorException ) throws XNIException { Enumeration listeners = HTMLParserFactory.getHTMLParserListeners().elements(); while (listeners.hasMoreElements()) { ((HTMLParserListener) listeners.nextElement()).error( _url, errorException.getMessage(), errorException.getLineNumber(), errorException.getColumnNumber() ); } } public void fatalError( String domain, String key, XMLParseException fatalError ) throws XNIException { error( domain, key, fatalError ); throw fatalError; } }httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/NekoHTMLParser.java0000644000175000017500000000604311014557540026405 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: NekoHTMLParser.java 855 2008-03-31 08:54:13Z wolfgang_fahl $ * * Copyright (c) 2002-2004,2008 Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import org.xml.sax.SAXException; import org.xml.sax.InputSource; import org.w3c.dom.Document; import org.w3c.dom.html.HTMLDocument; import java.net.URL; import java.io.IOException; import java.io.StringReader; /** * * @author Russell Gold * @author Bernhard Wagner * @author Artashes Aghajanyan **/ class NekoHTMLParser implements HTMLParser { /** * parse the given URL with the given pageText using the given document adapter * @param pageURL * @param pageText * @param adapter */ public void parse( URL pageURL, String pageText, DocumentAdapter adapter ) throws IOException, SAXException { try { NekoDOMParser parser = NekoDOMParser.newParser( adapter, pageURL ); parser.parse( new InputSource( new StringReader( pageText ) ) ); Document doc=parser.getDocument(); adapter.setDocument( (HTMLDocument)doc ); } catch (NekoDOMParser.ScriptException e) { throw e.getException(); } } public String getCleanedText( String string ) { return (string == null) ? "" : string.replace( NBSP, ' ' ); } public boolean supportsPreserveTagCase() { return false; } public boolean supportsForceTagCase() { return false; } public boolean supportsReturnHTMLDocument() { return true; } public boolean supportsParserWarnings() { return true; } final private static char NBSP = (char) 160; // non-breaking space, defined by nekoHTML } httpunit-1.7+dfsg/src/com/meterware/httpunit/parsing/ScriptFilter.java0000644000175000017500000001360511014557542026265 0ustar twernertwernerpackage com.meterware.httpunit.parsing; /******************************************************************************************************************** * $Id: ScriptFilter.java 754 2006-03-28 00:52:15Z russgold $ * * Copyright (c) 2002, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import java.io.IOException; import java.io.StringReader; import org.apache.xerces.xni.Augmentations; import org.apache.xerces.xni.QName; import org.apache.xerces.xni.XMLAttributes; import org.apache.xerces.xni.XMLLocator; import org.apache.xerces.xni.XMLString; import org.apache.xerces.xni.XNIException; import org.apache.xerces.xni.parser.XMLInputSource; import org.cyberneko.html.HTMLConfiguration; import org.cyberneko.html.filters.DefaultFilter; /** * A filter to interpret JavaScript script blocks, based on the sample Scripts program provided by NekoHTML. * * @author Russell Gold **/ class ScriptFilter extends DefaultFilter { /** The NekoHTML configuration. */ private HTMLConfiguration _configuration; /** A string buffer to collect the script. */ private StringBuffer _activeScriptBlock; /** The name of the current script language. **/ private String _scriptLanguage; /** The system identifier of the source document. */ private String _systemID = ""; /** The number of the current script. */ private int _scriptIndex; /** The parser in which this filter is running. **/ private ScriptHandler _scriptHandler; /** Constructs a script object with the specified configuration. */ ScriptFilter( HTMLConfiguration config ) { _configuration = config; } public void setScriptHandler( ScriptHandler scriptHandler ) { _scriptHandler = scriptHandler; } public void startDocument( XMLLocator locator, String encoding, Augmentations augs ) throws XNIException { _activeScriptBlock = null; _systemID = (locator == null) ? "" : (locator.getLiteralSystemId() + "_"); _scriptIndex = 0; super.startDocument( locator, encoding, augs ); } /** * Invoked for a start element. If the element is a
2+a+b
httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/0000755000175000017500000000000011014557542023676 5ustar twernertwernerhttpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/AbstractJavaScriptTest.java0000644000175000017500000000363011014557542031135 0ustar twernertwernerpackage com.meterware.httpunit.javascript; import com.meterware.httpunit.HttpUnitTest; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebResponse; /** * Created by IntelliJ IDEA. * User: russgold * Date: May 16, 2008 * Time: 3:20:40 PM * To change this template use File | Settings | File Templates. */ public class AbstractJavaScriptTest extends HttpUnitTest {// set to true to get the static HTML Code on System.err public static boolean debugHTML=false; public AbstractJavaScriptTest( String name ) { super( name ); } /** * test the given javaScript code by putting it into a function and calling it * as a prerequisite make the html code snippet available in the body of the page * @param script - some javascript code to be called in a function * @param html - a html code snippet * @return * @throws Exception */ public WebConversation doTestJavaScript(String script,String html) throws Exception { defineResource( "OnCommand.html", "" + "" + html+"\n"+ "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); if (debugHTML) { System.err.println(response.getText()+"\n"); } response.getLinkWith( "go" ).click(); return wc; } /** * test the given javaScript code by putting it into a function * and calling it * @param script the script to test * @return the web client on which the test was run */ public WebConversation doTestJavaScript(String script) throws Exception { return doTestJavaScript(script,""); } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/DocumentScriptingTest.java0000644000175000017500000005451011014557542031047 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: DocumentScriptingTest.java 975 2008-05-16 19:44:48Z russgold $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import junit.framework.TestSuite; import junit.textui.TestRunner; import com.meterware.httpunit.*; public class DocumentScriptingTest extends HttpUnitTest { public static void main( String args[] ) { TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( DocumentScriptingTest.class ); } public DocumentScriptingTest( String name ) { super( name ); } public void testDocumentTitle() throws Exception { defineResource( "OnCommand.html", "Amazing!" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "Window title is Amazing!", wc.popNextAlert() ); } public void testDocumentFindForms() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "found 1 form(s)", wc.popNextAlert() ); assertEquals( "Alert message", "found form 'realform'", wc.popNextAlert() ); assertEquals( "Alert message", "found form 'forms[\'realform\']'", wc.popNextAlert() ); assertEquals( "Alert message", "did not find form 'noform'", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } public void testDocumentFindLinks() throws Exception { defineResource( "OnCommand.html", "" + "" + "first" + "second" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "found 2 link(s)", wc.popNextAlert() ); assertEquals( "Alert message", "found link 'reallink'", wc.popNextAlert() ); assertEquals( "Alert message", "found link 'links[reallink]'", wc.popNextAlert() ); assertEquals( "Alert message", "did not find link 'nolink'", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } public void testJavaScriptObjectIdentity() throws Exception { defineResource( "OnCommand.html", "" + "" + "first" + "second" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "they are the same", wc.popNextAlert() ); } public void testCaseSensitiveNames() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "" + "1" + "2" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinkWithName( "first" ).mouseOver(); assertEquals( "form action", "run", wc.popNextAlert() ); response.getLinkWithName( "second" ).mouseOver(); assertEquals( "link href", getHostPath() + "/sample.html", wc.popNextAlert() ); } public void testLinkMouseOverEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); WebLink link = response.getLinks()[0]; assertEquals( "initial parameter value", "blue", form.getParameterValue( "color" ) ); link.mouseOver(); assertEquals( "changed parameter value", "green", form.getParameterValue( "color" ) ); } public void testLinkClickEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); WebLink link = response.getLinks()[0]; assertEquals( "initial parameter value", "blue", form.getParameterValue( "color" ) ); link.click(); assertEquals( "changed parameter value", "green", form.getParameterValue( "color" ) ); } /** * test a mouse event on a link * @throws Exception */ public void testLinkMouseDownEvent() throws Exception { defineResource( "nothing.html", ""); defineResource( "OnMouseDown.html", "" + "" + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnMouseDown.html" ); WebForm form = response.getFormWithName( "realform" ); WebLink link = response.getLinks()[0]; assertEquals( "initial parameter value", "blue", form.getParameterValue( "color" ) ); link.click(); assertEquals( "changed parameter value", "green", form.getParameterValue( "color" ) ); } /** * Verifies that a link which simply specifies a * fragment identifier does not cause a new request to be sent to the * server, so that the current response is unchanged. * @throws Exception */ public void testHashDestinationOnClickEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); WebLink link = response.getLinks()[0]; assertEquals( "initial parameter value", "blue", form.getParameterValue( "color" ) ); response = link.click(); assertEquals( "changed parameter value", "green", response.getFormWithName( "realform" ).getParameterValue( "color" ) ); } /** * check on MouseDownEvent handling * @throws Exception */ public void testHashDestinationOnMouseDownEvent() throws Exception { defineResource( "OnMouseDown.html", "" + "" + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnMouseDown.html" ); WebForm form = response.getFormWithName( "realform" ); WebLink link = response.getLinks()[0]; assertEquals( "initial parameter value", "blue", form.getParameterValue( "color" ) ); response = link.click(); assertEquals( "changed parameter value", "green", response.getFormWithName( "realform" ).getParameterValue( "color" ) ); } public void testLinkProperties() throws Exception { defineResource( "somewhere.html?with=values", "you made it!" ); defineResource( "OnCommand.html", "" + "" + "" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebLink link = response.getLinkWithName( "target" ); assertEquals( "initial value", "nowhere.html", link.getURLString() ); response.getLinkWithName( "control" ).click(); assertEquals( "changed reference", getHostPath() + "/somewhere.html?with=values", link.getRequest().getURL().toExternalForm() ); response = link.click(); assertEquals( "New page", "you made it!", response.getText() ); } public void testLinkIndexes() throws Exception { defineResource( "OnCommand.html", "" + "" + "green" + "" + " Guide" + " Search" + "" + "green" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", getHostPath() + "/demo.html", wc.popNextAlert() ); assertEquals( "Alert message", getHostPath() + "/guide.html", wc.popNextAlert() ); assertEquals( "Alert message", getHostPath() + "/search.html", wc.popNextAlert() ); assertEquals( "Alert message", getHostPath() + "/sample.html", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } public void testDocumentFindImages() throws Exception { defineResource( "OnCommand.html", "\n" + "\n" + "\n" + "\n" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "found 2 images(s)", wc.popNextAlert() ); assertEquals( "Alert message", "found image 'realimage'", wc.popNextAlert() ); assertEquals( "Alert message", "found image 'images[realimage]'", wc.popNextAlert() ); assertEquals( "Alert message", "did not find image 'noimage'", wc.popNextAlert() ); assertEquals( "Alert message", "2ndimage", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } public void testImageSwap() throws Exception { defineResource( "OnCommand.html", "" + "" + "" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebImage image = response.getImageWithName( "theImage" ); WebLink link = response.getLinks()[0]; assertEquals( "initial image source", "initial.gif", image.getSource() ); link.mouseOver(); assertEquals( "changed image source", "new.jpg", image.getSource() ); } public void testWriteToNewDocument() throws Exception { defineWebPage( "OnCommand", "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebLink link = response.getLinks()[0]; link.click(); WebWindow ww = wc.getOpenWindow( "sample"); assertEquals( "Generated page", "You made it!", ww.getCurrentPage().getText() ); assertEquals( "Content Type", "text/plain", ww.getCurrentPage().getContentType() ); link.click(); assertEquals( "Generated page", "You made it!", ww.getCurrentPage().getText() ); assertEquals( "Empty page", "", wc.getOpenWindow("empty").getCurrentPage().getText() ); } public void testSetDocumentReparse() throws Exception { defineResource( "index.html", "" + "" + "
" + "" + ""); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/index.html" ); assertEquals("No of forms", response.getForms().length, 1); assertEquals("JavaScript no of forms", "No of forms: 1", wc.popNextAlert()); } public void testTagProperty() throws Exception { defineResource( "start.html", "" + "
here" + "
" + "
" + "
" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/start.html" ); assertElementTags( wc, "0", "1"); assertElementTags( wc, "1", "3"); } private void assertElementTags( WebConversation wc, String number, final String counts) { assertEquals( "form '" + number + "' message", "form with number " + number + " has " + counts +" inputs", wc.popNextAlert() ); } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/FormScriptingTest.java0000644000175000017500000027222411014557540030176 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: FormScriptingTest.java 914 2008-04-06 16:35:03Z russgold $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.*; import com.meterware.httpunit.controls.SelectionFormControl; import com.meterware.httpunit.protocol.UploadFileSpec; import com.meterware.pseudoserver.PseudoServlet; import com.meterware.pseudoserver.WebResource; import java.io.IOException; import java.io.File; import java.util.ArrayList; import java.util.List; import junit.textui.TestRunner; import junit.framework.TestSuite; import org.xml.sax.SAXException; /** * * @author Russell Gold **/ public class FormScriptingTest extends HttpUnitTest { public static void main( String args[] ) { TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( FormScriptingTest.class ); } public FormScriptingTest( String name ) { super( name ); } /** * test to access form name in java script * @throws Exception */ public void testFormNameProperty() throws Exception { defineWebPage( "OnCommand", "
" + "" + "" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Message 1", "the_form_with_name", wc.popNextAlert() ); assertEquals( "Message 2", "the_form_with_id", wc.popNextAlert() ); } /** * test to access attributes from java script * @throws Exception */ public void testGetAttributeForBody() throws Exception { if (HttpUnitOptions.DEFAULT_SCRIPT_ENGINE_FACTORY.equals(HttpUnitOptions.ORIGINAL_SCRIPTING_ENGINE_FACTORY)) { // TODO try making this work return; } defineWebPage( "OnCommand", "test\n"+ "\n"+ "\n"+ "background color?
\n"+ "text color?
\n"+ "linkcolor non visited
\n"+ "link color activated links?\n"+ "link color non visited
\n"+ ""); WebConversation wc = new WebConversation(); WebResponse response=wc.getResponse( getHostPath() + "/OnCommand.html" ); // the page for testing externally // System.err.println(response.getText()); WebLink[] links=response.getLinks(); for (int i=0;itest\n"+ "\n"+ " "); WebConversation wc = new WebConversation(); WebResponse response=wc.getResponse( getHostPath() + "/OnCommand.html" ); // the page for testing externally // System.err.println(response.getText()); WebLink[] links=response.getLinks(); for (int i=0;i" + "" + "" + " " + " " + " " + "" + "elements" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); final WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", null, form.getParameterValue( "ready" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Message 1", "form has 3 elements", wc.popNextAlert() ); assertEquals( "Message 2", "value is Initial Text", wc.popNextAlert() ); assertEquals( "Message 3", "index is 1", wc.popNextAlert() ); assertEquals( "Changed state", "on", form.getParameterValue( "ready" ) ); } /** * test clicking on a span * inspired by Mail from Christoph to developer mailinglist of 2008-04-01 */ public void testClickSpan() throws Exception { defineResource( "OnCommand.html", "" + "" + "
489
"+ ""); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); String elementNames[]=response.getElementNames(); HTMLElement elements[]=response.getElementsByTagName("span"); assertTrue("Two span elements should be found ",elements.length==2); HTMLElement span1=elements[0]; String onclick="crtCtrla(this, \"rim_ModuleSearchResult=Drilldown=key_\", null, null);"; assertEquals(span1.getAttribute("onclick"),onclick); span1.handleEvent("onclick"); String alert=wc.popNextAlert(); assertEquals("function should have been triggered to alert",alert,"rim_ModuleSearchResult=Drilldown=key_"); elements=response.getElementsWithAttribute("onclick", onclick); int expected=1; // TODO check how 2 could be correct ... expected=2; assertTrue(expected+"elements should be found ",elements.length==expected); span1=elements[0]; span1.handleEvent("onclick"); alert=wc.popNextAlert(); assertEquals("function should have been triggered to alert",alert,"rim_ModuleSearchResult=Drilldown=key_"); // TODO remove this part span1=elements[1]; span1.handleEvent("onclick"); alert=wc.popNextAlert(); assertEquals("function should have been triggered to alert",alert,"rim_ModuleSearchResult=Drilldown=key_"); } public void testResetViaScript() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); form.setParameter( "color", "blue" ); response.getLinks()[ 0 ].click(); assertEquals( "Value after reset", "green", form.getParameterValue( "color" ) ); } public void testOnResetEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); form.setParameter( "color", "blue" ); form.getButtonWithID( "clear" ).click(); assertEquals( "Value after reset", "green", form.getParameterValue( "color" ) ); assertEquals( "Alert message", "Ran the event", wc.popNextAlert() ); form.setParameter( "color", "blue" ); response.getLinks()[ 0 ].click(); assertEquals( "Value after reset", "green", form.getParameterValue( "color" ) ); assertNull( "Event ran unexpectedly", wc.getNextAlert() ); } public void testSubmitViaScript() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + " " + "
" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[ 0 ].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } /** * Verifies bug #959918 */ public void testNumericParameterSetting1() throws Exception { defineResource( "DoIt?id=1234", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "" + "" + "
" + " View Asset" + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[ 0 ].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } /** * Verifies bug #1087180 */ public void testNumericParameterSetting2() throws Exception { defineResource( "DoIt.html?id=1234", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "" + "" + "
" + " View Asset" + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[ 0 ].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } /** * Verifies bug #1073810 (Null pointer exception if javascript sets control value to null) */ public void testNullParameterSetting() throws Exception { defineResource( "OnCommand.html", "" + "" + "" + "" + "
" + " View Asset" + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[ 0 ].click(); } /** * test changing form Action from JavaScript * @throws Exception */ public void testFormActionFromJavaScript() throws Exception { // pending Patch 1155792 wf 2007-12-30 // TODO activate in due course dotestFormActionFromJavaScript("param"); } /** * verify bug 1155792 ] problems setting form action from javascript [patch] */ public void xtestFormActionFromJavaScript2() throws Exception { // pending Patch 1155792 wf 2007-12-30 // TODO activate in due course dotestFormActionFromJavaScript("action"); } /** * test doing a form action from Javascript * @param paramName * @throws Exception */ public void dotestFormActionFromJavaScript(String paramName) throws Exception { if (HttpUnitOptions.DEFAULT_SCRIPT_ENGINE_FACTORY.equals(HttpUnitOptions.ORIGINAL_SCRIPTING_ENGINE_FACTORY)) { return; } defineWebPage("foo","foocontent"); defineResource("bar.html","" + "
"+ "
"+ " go"); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/foo.html" ); String fooContent=wc.getCurrentPage().getText(); // System.err.println(fooContent); response = wc.getResponse( getHostPath() + "/bar.html" ); try { response.getLinks()[ 0 ].click(); String result=wc.getCurrentPage().getText(); // System.err.println(result); assertEquals( "Result of submit", fooContent, result ); } catch (RuntimeException rte) { // TODO activate this test // There is currently a // org.mozilla.javascript.JavaScriptException: com.meterware.httpunit.HttpNotFoundException: Error on HTTP request: 404 unable to find /foo.html [http://localhost:1929/foo.html] // here fail("There should be no "+rte.getMessage()+" Runtime exception here"); } } /** * test indirect invocation * feature request * [ 796961 ] Support indirect invocation of JavaScript events on elements * by David D. Kilzer * @throws Exception */ public void testIndirectEventInvocation() throws Exception { defineResource( "OnCommand.html", "" + "
" + "" + "" + "
" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "testForm" ); assertEquals( "field one equals field two", form.getParameterValue("one"), form.getParameterValue( "two" ) ); } /** * test disabling a submit button via script * @throws Exception */ public void testEnablingDisabledSubmitButtonViaScript() throws Exception { defineResource( "DoIt?color=green&change=success", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); assertSubmitButtonDisabled( form ); assertDisabledSubmitButtonCanNotBeClicked( form ); form = runJavaScriptToToggleEnabledStateOfButton( form, wc ); assertSubmitButtonEnabled( form ); clickSubmitButtonToProveThatItIsEnabled( form ); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testDisablingEnabledSubmitButtonViaScript() throws Exception { defineResource( "DoIt?color=green&change=success", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); assertSubmitButtonEnabled( form ); form = runJavaScriptToToggleEnabledStateOfButton( form, wc ); assertNotNull( form ); assertSubmitButtonDisabled( form ); assertDisabledSubmitButtonCanNotBeClicked( form ); } public void testEnablingDisabledNormalButtonViaScript() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); assertNormalButtonDisabled( form, "changee" ); assertDisabledNormalButtonCanNotBeClicked( form, "changee" ); form = runJavaScriptToToggleEnabledStateOfButton( form, wc ); assertNormalButtonEnabled( form, "changee" ); clickButtonToProveThatItIsEnabled( form, "changee" ); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testDisablingEnableddNormalButtonViaScript() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); assertNormalButtonEnabled( form, "changee" ); form = runJavaScriptToToggleEnabledStateOfButton( form, wc ); assertNormalButtonDisabled( form, "changee" ); assertDisabledNormalButtonCanNotBeClicked( form, "changee" ); } /** * also fix for [ 1124024 ] Formcontrol and isDisabled should be public * by wolfgang fahl * @param form */ private void assertSubmitButtonDisabled( WebForm form ) { assertTrue( "Button should have been Disabled", form.getSubmitButton( "change" ).isDisabled() ); } private void assertNormalButtonDisabled( WebForm form, String buttonID ) { assertTrue( "Button should have been Disabled", form.getButtonWithID( buttonID ).isDisabled() ); } private void assertSubmitButtonEnabled( WebForm form ) { assertFalse( "Button should have been enabled or NOT-Disabled", form.getSubmitButton( "change" ).isDisabled() ); } private void assertNormalButtonEnabled( WebForm form, String buttonID ) { assertFalse( "Button should have been enabled or NOT-Disabled", form.getButtonWithID( buttonID ).isDisabled() ); } /** * click submit button to prove that it is enabled * @param form * @throws IOException * @throws SAXException */ private void clickSubmitButtonToProveThatItIsEnabled( WebForm form ) throws IOException, SAXException { WebResponse response = form.submit(); assertNotNull( response ); } private void clickButtonToProveThatItIsEnabled( WebForm form, String buttonID ) throws IOException, SAXException { form.getButtonWithID( buttonID ).click(); } /** * change the enable State of Button via Javascript * @param form * @param wc * @return * @throws IOException * @throws SAXException */ private WebForm runJavaScriptToToggleEnabledStateOfButton( WebForm form, WebConversation wc ) throws IOException, SAXException { Button enableChange = form.getButtonWithID( "enableChange" ); enableChange.click(); WebResponse currentPage = wc.getCurrentPage(); form = currentPage.getFormWithName( "spectrum" ); return form; } private void assertDisabledSubmitButtonCanNotBeClicked( WebForm form ) { try { SubmitButton button = form.getSubmitButton( "change" ); form.submit( button ); } catch (Exception e) { String msg=e.getMessage(); assertTrue(msg.indexOf( "The specified button (name='change' value='success' is disabled and may not be used to submit this form" ) > -1 ); } } private void assertDisabledNormalButtonCanNotBeClicked( WebForm form, String buttonID ) { try { Button button = form.getButtonWithID( buttonID ); button.click(); } catch (Exception e) { assertTrue( e.toString().indexOf( "Button 'changee' is disabled and may not be clicked" ) > -1 ); } } public void testEnablingDisabledRadioButtonViaScript() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "" + "" + "" + "" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "spectrum" ); assertMatchingSet( "Color choices", new String[] { "red" }, form.getOptionValues( "color" ) ); try { form.setParameter( "color", "green" ); fail( "Should not have been able to set color" ); } catch (Exception e) {} form.getScriptableObject().doEventScript( "document.spectrum.color[1].disabled=false" ); assertMatchingSet( "Color choices", new String[] { "red", "green" }, form.getOptionValues( "color" ) ); form.setParameter( "color", "green" ); } public void testSubmitViaScriptWithPostParams() throws Exception { defineResource( "/servlet/TestServlet?param3=value3¶m4=value4", new PseudoServlet() { public WebResource getPostResponse() { return new WebResource( "You made it!", "text/plain" ); } } ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "" + "Submit" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testSubmitButtonlessFormViaScript() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[ 0 ].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testSubmitViaScriptButton() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getFormWithName( "spectrum" ).getButtons()[0].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testDisabledScriptButton() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); try { response.getFormWithName( "spectrum" ).getButtons()[0].click(); fail( "Should not have permitted click of disabled button" ); } catch (IllegalStateException e) {} } public void testUpdateBeforeSubmit() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getFormWithName( "spectrum" ).getButtons()[0].click(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testSubmitButtonScript() throws Exception { defineResource( "DoIt?color=green", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getFormWithName( "spectrum" ).submit(); assertEquals( "Result of submit", "You made it!", wc.getCurrentPage().getText() ); } public void testSetFormTextValue() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); assertEquals( "color parameter value", "green", form.getParameterValue( "color" ) ); } /** * test for onMouseDownEvent support patch 884146 * by Bjrn Beskow - bbeskow * @throws Exception */ public void testCheckboxOnMouseDownEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "
blue" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", null, form.getParameterValue( "color" ) ); assertEquals( "Alert message before change", null, wc.getNextAlert() ); form.removeParameter( "color" ); assertEquals( "Alert message w/o change", null, wc.getNextAlert() ); form.setParameter( "color", "blue" ); assertEquals( "Alert after change", "color-blue is now true", wc.popNextAlert() ); form.removeParameter( "color" ); assertEquals( "Alert after change", "color-blue is now false", wc.popNextAlert() ); assertEquals( "Changed state", null, form.getParameterValue( "color" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Final state", "blue", form.getParameterValue( "color" ) ); assertEquals( "Alert message after JavaScript change", null, wc.getNextAlert() ); } /** * test the onChange event * @throws Exception */ public void testSetFormTextOnChangeEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", "blue", form.getParameterValue( "color" ) ); assertEquals( "Alert message before change", null, wc.getNextAlert() ); form.setParameter( "color", "red" ); assertEquals( "Alert after change", "color is now red", wc.popNextAlert() ); assertEquals( "Changed state", "red", form.getParameterValue( "color" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Final state", "green", form.getParameterValue( "color" ) ); assertEquals( "Alert message after JavaScript change", null, wc.getNextAlert() ); } public void testCheckboxProperties() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "clear" + "set" + "change" + "report" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); response.getLinkWithName( "report" ).mouseOver(); verifyCheckbox( /* default */ wc, false, /* checked */ false, /* value */ "good" ); assertEquals( "initial parameter value", null, form.getParameterValue( "ready" ) ); response.getLinkWithName( "set" ).mouseOver(); assertEquals( "changed parameter value", "good", form.getParameterValue( "ready" ) ); response.getLinkWithName( "clear" ).mouseOver(); assertEquals( "final parameter value", null, form.getParameterValue( "ready" ) ); response.getLinkWithName( "change" ).mouseOver(); assertEquals( "final parameter value", null, form.getParameterValue( "ready" ) ); response.getLinkWithName( "report" ).mouseOver(); verifyCheckbox( /* default */ wc, false, /* checked */ false, /* value */ "waiting" ); form.setParameter( "ready", "waiting" ); } public void testIndexedCheckboxProperties() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "" + "" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getFormWithName( "realform" ); verifyCheckbox( /* default */ wc, true, /* checked */ true, /* value */ "good" ); verifyCheckbox( /* default */ wc, false, /* checked */ false, /* value */ "bad" ); } private void verifyCheckbox( WebClient wc, boolean defaultChecked, boolean checked, String value ) { assertEquals( "Message " + 1 + "-1", "checkbox ready default = " + defaultChecked, wc.popNextAlert() ); assertEquals( "Message " + 1 + "-2", "checkbox ready checked = " + checked, wc.popNextAlert() ); assertEquals( "Message " + 1 + "-3", "checkbox ready value = " + value, wc.popNextAlert() ); } public void testCheckboxOnClickEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "blue" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", null, form.getParameterValue( "color" ) ); assertEquals( "Alert message before change", null, wc.getNextAlert() ); form.removeParameter( "color" ); assertEquals( "Alert message w/o change", null, wc.getNextAlert() ); form.setParameter( "color", "blue" ); assertEquals( "Alert after change", "color-blue is now true", wc.popNextAlert() ); form.removeParameter( "color" ); assertEquals( "Alert after change", "color-blue is now false", wc.popNextAlert() ); assertEquals( "Changed state", null, form.getParameterValue( "color" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Final state", "blue", form.getParameterValue( "color" ) ); assertEquals( "Alert message after JavaScript change", null, wc.getNextAlert() ); } public void testSetCheckboxOnClickEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); form.toggleCheckbox( "color" ); assertEquals( "Alert after change", "color-blue is now true", wc.popNextAlert() ); form.setCheckbox( "color", false ); assertEquals( "Alert after change", "color-blue is now false", wc.popNextAlert() ); } /** * test the radio button properties via index * @throws Exception */ public void testIndexedRadioProperties() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + "" + "" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getFormWithName( "realform" ); verifyRadio( /* default */ wc, true, /* checked */ true, /* value */ "good" ); verifyRadio( /* default */ wc, false, /* checked */ false, /* value */ "bad" ); } /** * test onMouseDownEvent for radio buttons * @throws Exception */ public void testRadioOnMouseDownEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "blue" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", "red", form.getParameterValue( "color" ) ); assertEquals( "Alert message before change", null, wc.getNextAlert() ); form.setParameter( "color", "red" ); assertEquals( "Alert message w/o change", null, wc.getNextAlert() ); form.setParameter( "color", "blue" ); assertEquals( "Alert after change", "color is now blue", wc.popNextAlert() ); form.setParameter( "color", "red" ); assertEquals( "Alert after change", "color is now red", wc.popNextAlert() ); assertEquals( "Changed state", "red", form.getParameterValue( "color" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Final state", "blue", form.getParameterValue( "color" ) ); assertEquals( "Alert message after JavaScript change", null, wc.getNextAlert() ); } private void verifyRadio( WebClient wc, boolean defaultChecked, boolean checked, String value ) { assertEquals( "Message " + 1 + "-1", "radio ready default = " + defaultChecked, wc.popNextAlert() ); assertEquals( "Message " + 1 + "-2", "radio ready checked = " + checked, wc.popNextAlert() ); assertEquals( "Message " + 1 + "-3", "radio ready value = " + value, wc.popNextAlert() ); } public void testRadioOnClickEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + "
" + "blue" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", "red", form.getParameterValue( "color" ) ); assertEquals( "Alert message before change", null, wc.getNextAlert() ); form.setParameter( "color", "red" ); assertEquals( "Alert message w/o change", null, wc.getNextAlert() ); form.setParameter( "color", "blue" ); assertEquals( "Alert after change", "color is now blue", wc.popNextAlert() ); form.setParameter( "color", "red" ); assertEquals( "Alert after change", "color is now red", wc.popNextAlert() ); assertEquals( "Changed state", "red", form.getParameterValue( "color" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Final state", "blue", form.getParameterValue( "color" ) ); assertEquals( "Alert message after JavaScript change", null, wc.getNextAlert() ); } public void testFormActionProperty() throws Exception { WebConversation wc = new WebConversation(); defineWebPage( "Default", "
" + "" + "" + "
" + "tell" + "show" ); WebResponse page = wc.getResponse( getHostPath() + "/Default.html" ); page.getLinkWithName( "doShow" ).click(); assertEquals( "Current action", "ask", wc.popNextAlert() ); page.getLinkWithName( "doTell" ).click(); WebRequest request = page.getForms()[0].getRequest(); request.setParameter( "age", "23" ); assertEquals( getHostPath() + "/tell?age=23", request.getURL().toExternalForm() ); } public void testFormTargetProperty() throws Exception { WebConversation wc = new WebConversation(); defineWebPage( "Default", "
" + "" + "" + "
" + "tell" + "show" ); WebResponse page = wc.getResponse( getHostPath() + "/Default.html" ); page.getLinkWithName( "doShow" ).click(); assertEquals( "Initial target", "_top", wc.popNextAlert() ); page.getLinkWithName( "doTell" ).click(); page.getLinkWithName( "doShow" ).click(); assertEquals( "Current target", "_blank", wc.popNextAlert() ); WebRequest request = page.getForms()[0].getRequest(); assertEquals( "_blank", request.getTarget() ); } public void testFormValidationOnSubmit() throws Exception { defineResource( "doIt?color=pink", "You got it!", "text/plain" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); form.submit(); assertEquals( "Alert message", "wrong color", wc.popNextAlert() ); assertSame( "Current response", response, wc.getCurrentPage() ); form.setParameter( "color", "pink" ); WebResponse newResponse = form.submit(); assertEquals( "Result of submit", "You got it!", newResponse.getText() ); } public void testFormSelectReadableProperties() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "which" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "1st message", "select has 2 options", wc.popNextAlert() ); assertEquals( "2nd message", "select still has 2 options", wc.popNextAlert() ); assertEquals( "3rd message", "select option 0 is red", wc.popNextAlert() ); assertEquals( "4th message", "select 2nd option value is 3", wc.popNextAlert() ); assertEquals( "5th message", "blue selected", wc.popNextAlert() ); assertEquals( "6th message", "blue selected again", wc.popNextAlert() ); response.getLinks()[0].mouseOver(); assertEquals( "before change message", "selected #1", wc.popNextAlert() ); response.getFormWithName( "the_form" ).setParameter( "choices", "1" ); response.getLinks()[0].mouseOver(); assertEquals( "after change message", "selected #0", wc.popNextAlert() ); } /** * test that in case of an Index out of bounds problem an exception is thrown * with a meaningful message (not nullpointer exception) * Bug report [ 1124057 ] Out of Bounds Exception should be avoided * by Wolfgang Fahl of 2005-02-16 17:25 * */ public void testSelectIndexOutOfBoundsCatching() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "which" + "" ); WebConversation wc = new WebConversation(); boolean oldDebug= HttpUnitUtils.setEXCEPTION_DEBUG(false); try { WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); fail("There should be a runtime exeption here"); // java.lang.RuntimeException: Event 'viewSelect( document.the_form.choices )' failed: java.lang.RuntimeException: invalid index 5 for Options redblue, } catch (java.lang.RuntimeException rte) { assertTrue(rte.getMessage().indexOf("invalid index 5 for Options red,blue")>0); } finally { HttpUnitUtils.setEXCEPTION_DEBUG(oldDebug); } } public void testFormSelectDefaults() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + " " + " " + " " + "
" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "1st message", "first default index= 0", wc.popNextAlert() ); assertEquals( "2nd message", "second default index= -1", wc.popNextAlert() ); assertEquals( "3rd message", "third default index= -1", wc.popNextAlert() ); assertEquals( "4th message", "fourth default index= 0", wc.popNextAlert() ); } public void testFileSubmitProperties() throws Exception { File file = new File( "temp.html" ); defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "which" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].mouseOver(); assertEquals( "1st message", "file selected is []", wc.popNextAlert() ); WebForm form = response.getFormWithName( "the_form" ); form.setParameter( "file", new UploadFileSpec[] { new UploadFileSpec( file ) } ); response.getLinks()[0].mouseOver(); assertEquals( "2nd message", "file selected is [" + file.getAbsolutePath() + "]", wc.popNextAlert() ); } public void testFormSelectOnChangeEvent() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "reset" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); final WebForm form = response.getFormWithName( "the_form" ); assertEquals( "Initial state", "blue", form.getParameterValue( "choices" ) ); assertEquals( "Alert message before change", null, wc.getNextAlert() ); form.setParameter( "choices", "red" ); assertEquals( "Alert after change", "Selected index is 0", wc.popNextAlert() ); form.setParameter( "choices", "blue" ); assertEquals( "Alert after change", "Selected index is 1", wc.popNextAlert() ); assertEquals( "Initial state", "blue", form.getParameterValue( "choices" ) ); response.getLinks()[ 0 ].click(); assertEquals( "Final state", "red", form.getParameterValue( "choices" ) ); assertEquals( "Alert message after JavaScript change", null, wc.getNextAlert() ); } public void testFormSelectWriteableProperties() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "initial selection", "1", form.getParameterValue( "choices" ) ); response.getLinks()[0].click(); assertEquals( "Notification", "Selected index is 0", wc.popNextAlert() ); } public void testFormSelectDefaultProperties() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "
green" + "red" + "red" + "orange" + "azure" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertEquals( "initial selection", "3", form.getParameterValue( "choices" ) ); response.getLinks()[0].click(); assertEquals( "2nd selection", "5", form.getParameterValue( "choices" ) ); response.getLinks()[1].click(); assertEquals( "3rd selection", "1", form.getParameterValue( "choices" ) ); response.getLinks()[2].click(); assertEquals( "4th selection", "9", form.getParameterValue( "choices" ) ); assertMatchingSet( "Displayed options", new String[] { "red", "blue", "green", "azure" }, form.getOptions( "choices" ) ); response.getLinks()[3].click(); assertMatchingSet( "Modified options", new String[] { "orange", "blue", "green", "azure" }, form.getOptions( "choices" ) ); response.getLinks()[4].click(); assertEquals( "5th selection", "7", form.getParameterValue( "choices" ) ); } public void testFormSelectOverwriteOptions() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "shorter" + "weed" + "replace" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "the_form" ); assertMatchingSet( "initial values", new String[] { "1", "2", "3", "5" }, form.getOptionValues( "choices" ) ); assertMatchingSet( "initial text", new String[] { "red", "yellow", "blue", "green" }, form.getOptions( "choices" ) ); response.getLinks()[0].mouseOver(); assertMatchingSet( "modified values", new String[] { "1", "2", "3" }, form.getOptionValues( "choices" ) ); assertMatchingSet( "modified text", new String[] { "red", "yellow", "blue" }, form.getOptions( "choices" ) ); response.getLinks()[1].mouseOver(); assertMatchingSet( "weeded values", new String[] { "1", "3" }, form.getOptionValues( "choices" ) ); assertMatchingSet( "weeded text", new String[] { "red", "blue" }, form.getOptions( "choices" ) ); response.getLinks()[2].mouseOver(); assertMatchingSet( "replaced values", new String[] { "a", "c", "x", "q" }, form.getOptionValues( "choices" ) ); assertMatchingSet( "replaced text", new String[] { "apache", "comanche", "sioux", "iriquois" }, form.getOptions( "choices" ) ); } public void testAccessAcrossFrames() throws Exception { defineResource( "First.html", "" + "" ); defineWebPage( "Second", "
" + "
" ); defineResource( "Frames.html", "Initial" + "" + " " + " " + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/Frames.html" ); assertEquals( "Alert message", "value: new1", wc.popNextAlert() ); } public void testSetFromEmbeddedScript() throws Exception { defineWebPage( "OnCommand", "
" + "" + "
" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Form parameter value", "new", response.getForms()[0].getParameterValue( "testfield") ); } public void testSubmitFromJavaScriptLink() throws Exception { defineResource( "test2.txt?Submit=Submit", "You made it!", "text/plain" ); defineWebPage( "OnCommand", "
" + " " + " Link" + "
" ); WebConversation wc = new WebConversation(); WebResponse wr = wc.getResponse( getHostPath() + "/OnCommand.html" ); wr.getLinkWith( "Link" ).click(); } public void testSubmitOnLoad() throws Exception { defineResource( "test2.txt?Submit=Submit", "You made it!", "text/plain" ); defineResource( "OnCommand.html", "" + "
" + " " + "
" ); WebConversation wc = new WebConversation(); WebResponse wr = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "current page URL", getHostPath() + "/test2.txt?Submit=Submit", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "current page", "You made it!", wc.getCurrentPage().getText() ); assertEquals( "returned page URL", getHostPath() + "/test2.txt?Submit=Submit", wr.getURL().toExternalForm() ); assertEquals( "returned page", "You made it!", wr.getText() ); } public void testSelectValueProperty() throws Exception { defineResource( "OnCommand.html", "" + "" + "
" + " " + "
" + "elements" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertEquals( "Message 1", "selected item is blue", wc.popNextAlert() ); response.getScriptingHandler().doEventScript( "document.the_form.choices.value='red'" ); response.getLinks()[0].click(); assertEquals( "Message 2", "selected item is red", wc.popNextAlert() ); } public void testElementsByIDProperty() throws Exception { defineResource( "index.html", "\n" + "\n" + "JavaScript Form Elements by ID String Test\n" + "\n" + "\n" + "\n" + "

JavaScript Form Elements by ID String Test

\n" + "
\n" + " \n" + "
\n" + "\n" + "\n" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/index.html" ); WebForm form = response.getFormWithName( "formName" ); assertEquals( "Changed value", "Hello World!", form.getParameterValue( "inputName" ) ); } /** * Test that JavaScript can correctly access the 'type' property for every kind of form control. * @throws Exception */ public void testElementTypeAccess() throws Exception { defineWebPage( "Default", "" + "
" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "
" + "\n"); String[] expectedTypes = new String[]{ "text", "textarea", "password", "submit", "reset", "button", "checkbox", "radio", "select-one", "select-multiple", "file", "image", "hidden", "button", "submit", "reset", "submit" }; final PromptCollector collector = new PromptCollector(); WebConversation wc = new WebConversation(); wc.setDialogResponder(collector); wc.getResponse( getHostPath() + "/Default.html" ); assertMatchingSet("Set of types on form", expectedTypes, collector.confirmPromptsSeen.toArray()); } static class PromptCollector implements DialogResponder { public List confirmPromptsSeen = new ArrayList(); public List responsePromptSeen = new ArrayList(); public boolean getConfirmation(String confirmationPrompt) { confirmPromptsSeen.add(confirmationPrompt); return true; } public String getUserResponse(String prompt, String defaultResponse) { responsePromptSeen.add(prompt); return null; } } /** * Test that the length (number of controls) of a form can be accessed from JavaScript. * @throws Exception */ public void testFormLength () throws Exception { defineWebPage("Default", "" + "
" + " " + " " + "
" + "\n"); String[] expectedPrompts = new String[]{"2"}; final PromptCollector collector = new PromptCollector(); WebConversation wc = new WebConversation(); wc.setDialogResponder(collector); wc.getResponse( getHostPath() + "/Default.html" ); assertMatchingSet("Length of form", expectedPrompts, collector.confirmPromptsSeen.toArray()); } /** * Verifies that it is possible to increase the size of a select control. * @throws Exception on any unexpected error */ public void testIncreaseSelectLength() throws Exception { defineWebPage("Default", "" + "
" + " " + " " + "
" + "a\n" + "a\n"); WebConversation wc = new WebConversation(); WebResponse wr = wc.getResponse( getHostPath() + "/Default.html" ); wr.getLinks()[ 0 ].click(); assertEquals( "1st message", "select has 1 options", wc.popNextAlert() ); assertEquals( "2nd message", "last option is Select Job Role", wc.popNextAlert() ); wr.getLinks()[ 1 ].click(); wr.getLinks()[ 0 ].click(); assertEquals( "3rd message", "select has 2 options", wc.popNextAlert() ); assertEquals( "4th message", "last option is here", wc.popNextAlert() ); } /** * Test that the JavaScript 'value' and 'defaultValue' properties of a text input are distinct. * 'defaultValue' should represent the 'value' attribute of the input element. * 'value' should initially match 'defaultValue', but setting it should not affect the 'defaultValue'. * @throws Exception */ public void testElementDefaultValue () throws Exception { defineWebPage("Default", "" + "
" + " " + " " + " " + "
" + "\n"); String[] expectedValues = new String[]{"Alpha", "Bravo", "Charlie", "Alpha", "Bravo", "Charlie", "Charles"}; final PromptCollector collector = new PromptCollector(); WebConversation wc = new WebConversation(); wc.setDialogResponder(collector); wc.getResponse( getHostPath() + "/Default.html" ); assertMatchingSet("Values seen by JavaScript", expectedValues, collector.confirmPromptsSeen.toArray()); } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/FrameScriptingTest.java0000644000175000017500000002761611014557540030330 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: FrameScriptingTest.java 659 2004-08-08 17:38:19Z russgold $ * * Copyright (c) 2003-2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.*; import junit.framework.Test; import junit.framework.TestSuite; /** * More complex tests of frame functionality. * * @author
Andrew Bickerton * @author Russell Gold **/ public class FrameScriptingTest extends HttpUnitTest { private WebConversation _wc; public static void main(String args[]) { junit.textui.TestRunner.run( suite() ); } public static Test suite() { return new TestSuite( FrameScriptingTest.class ); } public FrameScriptingTest( String name ) { super( name ); } public void setUp() throws Exception { super.setUp(); _wc = new WebConversation(); defineWebPage( "Simple", "This is a trivial page." ); defineResource("image.gif", new byte[]{0, 1, 0, 1}, "image/gif"); defineWebPage("Menu/Page/Target", "Target page"); StringBuffer buff = new StringBuffer(); buff.append("This frame contains JavaScript that re-writes the \"red\" frame if it exists.\n"); buff.append("\n"); defineWebPage("frameRewriter", buff.toString()); } /** * Creates and returns the lines of HTML to represent a menu page with * a <base ...> tag and one link. * Used where the formulated HTML is to be embedded in JavaScript. * @param baseUrlString URL string to be used in the href of the 'base' tag. * @param linkUrlString URL string to be used in the href of the link. * @return String array representing the lines of HTML. */ private String[] getMenuHtmlLines(String baseUrlString, String linkUrlString) { return new String[]{ "Menu", "", "", "", "This is the menu.
", "Link to target page.", ""}; } /** * Creates and returns HTML to represent a menu page with a <base ...> tag and one link. * @param baseUrlString URL string to be used in the href of the 'base' tag. * @param linkUrlString URL string to be used in the href of the link. * @return String representing the HTML. */ private String getMenuHtml(final String baseUrlString, final String linkUrlString) { final String[] menuLines = getMenuHtmlLines(baseUrlString, linkUrlString); StringBuffer pageBuffer = new StringBuffer(); for (int i = 0; i < menuLines.length; i++) { String line = menuLines[i]; pageBuffer.append(line).append("\n"); } return pageBuffer.toString(); } /** * (Re)defines the web page 'Frames.html', which is a frameset containing 'red' and 'blue' frames. * @param redSrc The source URL string for the 'red' frame. * @param blueSrc The source URL string for the 'blue' frame. */ private void redefineFrames(String redSrc, String blueSrc) { defineResource("Frames.html", "Frameset" + "" + " " + " " + ""); } /** * Test that an image can be used as the source for a frame within a frameset. */ public void testImageInFrame() throws Exception { redefineFrames("/image.gif", "Simple.html"); _wc.getResponse( getHostPath() + "/Frames.html" ); WebResponse redFrame = _wc.getFrameContents("red"); assertEquals("Red frame content-type", "image/gif", redFrame.getContentType()); } /** * Test that a link within a frame that contains a <base ...> element is handled correctly. */ public void testFrameContainingBaseElement() throws Exception { final String TARGET_TITLE = "Somewhere/Else/Target"; defineWebPage( TARGET_TITLE, "This is the target page." ); defineWebPage( "Main", "This is a simple page."); defineResource( "BaseRelLinker.html", getMenuHtml(getHostPath() + "/Somewhere/Near/", "../Else/Target.html") ); redefineFrames("BaseRelLinker.html", "Main.html"); _wc.getResponse( getHostPath() + "/Frames.html" ); WebLink link = _wc.getFrameContents( "red" ).getLinks()[0]; link.click(); assertEquals("Content of blue frame after link click", TARGET_TITLE, _wc.getFrameContents("blue").getTitle()); } /** * Test correct handling of a link within a frame that has been re-written by JavaScript, * and which contains a <base ...> element. */ public void testFrameRewrittenToUseBaseElement() throws Exception { redefineFrames("/Simple.html", "frameRewriter.html"); _wc.getResponse(getHostPath() + "/Frames.html"); WebLink link = _wc.getFrameContents("red").getLinks()[0]; link.click(); assertEquals("Content of blue frame after clicking menu link", "Menu/Page/Target", _wc.getFrameContents("blue").getTitle()); } /** * Test correct handling of a link within a frame that has been re-written by JavaScript over an image, * and which contains a <base ...> element. */ public void testImageFrameRewrittenToUseBaseElement() throws Exception { redefineFrames("/image.gif", "frameRewriter.html"); _wc.getResponse(getHostPath() + "/Frames.html"); WebLink link = _wc.getFrameContents("red").getLinks()[0]; link.click(); assertEquals("Content of blue frame after clicking menu link", "Menu/Page/Target", _wc.getFrameContents("blue").getTitle()); } /** * Verifies that a javascript URL which triggers refresh to the parent of a frame resolves with something sensible. */ public void testJavaScriptURLToParentFrame() throws Exception { defineResource( "Frames.html", "Initial" + "" + " " + " " + "" ); defineWebPage( "Linker", "This is a trivial page with one link" ); defineResource( "Form", "This is a page with nothing we care about"); defineResource( "Target", "You made it!", "text/plain" ); _wc.getResponse( getHostPath() + "/Frames.html" ); WebResponse result = _wc.getFrameContents( "red" ).getLinkWith( "one link" ).click(); assertEquals( "Result of click", "You made it!", result.getText() ); } /** * Verifies that when JavaScript overwrites an empty frame, other empty frames stay empty. */ public void testJavaScriptOverwritingBlankFrame() throws Exception { defineResource("Frames.html", "Initial" + "" + " " + " " + " " + ""); defineWebPage("Writer", "This page overwrites an empty frame. "); _wc.getResponse(getHostPath() + "/Frames.html"); assertEquals("Links in green frame", 1, _wc.getFrameContents("green").getLinks().length); assertEquals("Links in blue frame", 0, _wc.getFrameContents("blue").getLinks().length); } /** * Verifies that the onload event of a frameset can access subframes. */ public void testFrameOnLoadEvent() throws Exception { defineWebPage( "OneForm", "
"); defineResource("Frames.html", "" + " " + " " + ""); _wc.getResponse(getHostPath() + "/Frames.html"); assertEquals( "On load message", "nothing special", _wc.popNextAlert() ); } /** * Verifies that the onload event of a frameset runs even if there is a noframes tag present that contains a body tag. */ public void testFrameOnLoadEventWithNoFrames() throws Exception { defineWebPage( "OneForm", "
"); defineResource("Frames.html", "" + " " + " " + " <body></body>" + ""); _wc.getResponse(getHostPath() + "/Frames.html"); assertEquals( "On load message", "nothing special", _wc.popNextAlert() ); } /** * Verifies that IFrames can be found using their id. */ public void testIFrameAccessById() throws Exception { defineWebPage( "Frames", "" + "" ); _wc.getResponse(getHostPath() + "/Frames.html"); } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/HTMLElementTest.java0000644000175000017500000002012211014557540027452 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: HTMLElementTest.java 781 2007-06-17 17:31:49Z russgold $ * * Copyright (c) 2002-2003, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import junit.textui.TestRunner; import junit.framework.TestSuite; import com.meterware.httpunit.*; /** * * @author Russell Gold **/ public class HTMLElementTest extends HttpUnitTest { public static void main( String args[] ) { TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( HTMLElementTest.class ); } public HTMLElementTest( String name ) { super( name ); } public void testIDProperty() throws Exception { defineResource( "start.html", "" + "" + "
here" + "
" + "
" + "
" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/start.html" ); assertElementTitle( wc, "id", "there", "second" ); assertElementTitle( wc, "id", "perform", "fifth" ); assertElementTitle( wc, "id", "doIt", "sixth" ); assertElementTitle( wc, "id", "grouping", "third" ); assertElementTitle( wc, "id", "aCell", "fourth" ); assertElementTitle( wc, "id", "myDiv", "first" ); } public void testElementByIdReturnsNull() throws Exception { defineResource( "start.html", "" + "" + "
here" + "
" + "
" + "
" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/start.html" ); assertEquals( "Null test alert", "It returned null", wc.popNextAlert() ); } public void testNameProperty() throws Exception { defineResource( "start.html", "" + "" + "here" + "
" + "
" + "
" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/start.html" ); assertElementTitle( wc, "name", "there", "second" ); assertElementTitle( wc, "name", "perform", "fifth" ); assertElementTitle( wc, "name", "doIt", "sixth" ); assertElementTitle( wc, "name", "input", "input1" ); assertElementTitle( wc, "name", "input", "input2" ); } public void testNamePropertyWithIdAttribute() throws Exception { defineResource( "start.html", "" + "" + "here" + "
" + "" + "
" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/start.html" ); assertElementTitle( wc, "name", "there", "second" ); assertElementTitle( wc, "name", "perform", "fifth" ); assertElementTitle( wc, "name", "seeme", "haha" ); } private void assertElementTitle( WebConversation wc, String propertyName, final String id, final String title ) { assertEquals( "element '" + id + "' message", "element with " + propertyName + ' ' + id + " has title " + title, wc.popNextAlert() ); } public void testElementProperties() throws Exception { defineWebPage( "start", "
" + " " + "
" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/start.html" ); assertEquals( "tabindex", "1", response.getScriptingHandler().evaluateExpression( "document.perform.name.tabindex").toString() ); assertEquals( "maxlength", "20", response.getScriptingHandler().evaluateExpression( "document.perform.name.maxlength").toString() ); } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/JavaScriptTestSuite.java0000644000175000017500000000415511014557540030464 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: JavaScriptTestSuite.java 488 2003-03-07 05:04:05Z russgold $ * * Copyright (c) 2002-2003, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import junit.framework.Test; import junit.framework.TestSuite; /** * Master suite for testing JavaScript support * * @author Russell Gold **/ public class JavaScriptTestSuite { public static void main( String[] args ) { junit.textui.TestRunner.run( suite() ); } public static Test suite() { TestSuite result = new TestSuite(); result.addTest( ScriptingTest.suite() ); result.addTest( DocumentScriptingTest.suite() ); result.addTest( FormScriptingTest.suite() ); result.addTest( FrameScriptingTest.suite() ); result.addTest( HTMLElementTest.suite() ); return result; } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/NekoEnhancedScriptingTest.java0000644000175000017500000002273411014557540031614 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: NekoEnhancedScriptingTest.java 874 2008-04-01 17:08:32Z wolfgang_fahl $ * * Copyright (c) 2002-2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import junit.framework.TestSuite; import junit.textui.TestRunner; import com.meterware.httpunit.*; /** * Tests that work under NekoHTML but not JTidy due to the ability to do script processing during parsing. * * @author Russell Gold **/ public class NekoEnhancedScriptingTest extends HttpUnitTest { public static void main( String args[] ) { TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( NekoEnhancedScriptingTest.class ); } public NekoEnhancedScriptingTest( String name ) { super( name ); } public void testEmbeddedDocumentWrite() throws Exception { defineResource( "OnCommand.html", "something" + "" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebLink link = response.getLinkWithID( "here" ); assertNotNull( "The link was not found", link ); assertEquals( "Link contents", "something", link.getText() ); } public void testEmbeddedDocumentWriteWithClose() throws Exception { defineResource( "OnCommand.html", "something" + "" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebLink link = response.getLinkWithID( "here" ); assertNotNull( "The link was not found", link ); assertEquals( "Link contents", "something", link.getText() ); } public void testUnknownScript() throws Exception { defineWebPage( "FunkyScript", "" + "" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse wr = wc.getResponse( getHostPath() + "/FunkyScript.html" ); assertNotNull( "No default script link found", wr.getLinkWith( "Default JavaScript Working" ) ); assertNotNull( "No default script link found", wr.getLinkWith( "JavaScript Working" ) ); assertNotNull( "No default script link found", wr.getLinkWith( "JavaScript 1.2 Working" ) ); assertNull( "VBScript link found", wr.getLinkWith( "VBScript" ) ); } /** * test no script sections * @throws Exception */ public void testNoScriptSections() throws Exception { defineResource( "OnCommand.html", "something" + "" + "" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebLink link = response.getLinkWithID( "here" ); assertNotNull( "The link was not found", link ); assertEquals( "Link contents", "something", link.getText() ); assertNull( "Should not have found link in noscript", response.getLinkWithID( "there" ) ); HttpUnitOptions.setScriptingEnabled( false ); response = wc.getResponse( getHostPath() + "/OnCommand.html" ); link = response.getLinkWithID( "there" ); assertNotNull( "The link was not found", link ); assertEquals( "Link contents", "anything", link.getText() ); assertNull( "Should not have found scripted link", response.getLinkWithID( "here" ) ); } /** * Verifies that nodes defined before a script section are available to that script section, even if a preceding * script section has caused them to be cached. Currently does not work with JTidy since there is no way to parse * only to a specific position in the document. It may be possible to fix this with some logic changes... */ public void testFormsCaching() throws Exception { defineWebPage( "OnCommand", "
" + " " + "
" + "" + "
" + " " + "
" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Message 1", "blue", wc.popNextAlert() ); assertEquals( "Message 2", "3", wc.popNextAlert() ); } /** * Verifies that a script can write part of the frameset. */ public void testScriptedFrames() throws Exception { defineWebPage( "OneForm", "
"); defineResource("Frames.html", "" + " " + " " + ""); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/Frames.html" ); assertMatchingSet( "Loaded frames", new String[] { "_top", "green", "blue" }, wc.getFrameNames() ); } } httpunit-1.7+dfsg/test/com/meterware/httpunit/javascript/ScriptingTest.java0000644000175000017500000017434311014557540027355 0ustar twernertwernerpackage com.meterware.httpunit.javascript; /******************************************************************************************************************** * $Id: ScriptingTest.java 975 2008-05-16 19:44:48Z russgold $ * * Copyright (c) 2002-2008, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/ import com.meterware.httpunit.*; import junit.framework.Assert; import junit.framework.TestSuite; import junit.textui.TestRunner; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * @author Russell Gold * @author Wolfgang Fahl - for compiling patches from the Source Forge web site 2008-03 **/ public class ScriptingTest extends AbstractJavaScriptTest { public static void main( String args[] ) { TestRunner.run( suite() ); } public static TestSuite suite() { return new TestSuite( ScriptingTest.class ); } public ScriptingTest( String name ) { super( name ); } public void testJavaScriptURLWithValue() throws Exception { defineResource( "OnCommand.html", "" + "" + "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertEquals( "New page", "You made it!", wc.getCurrentPage().getText() ); assertEquals( "New URL", "javascript:\"You made it!\"", wc.getCurrentPage().getURL().toExternalForm() ); } public void testJavaScriptURLWithNoValue() throws Exception { defineResource( "OnCommand.html", "" + "" + "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebResponse myPage = response.getLinks()[0].click(); assertEquals( "Alert message", "Hi there!", wc.popNextAlert() ); assertEquals( "Current page URL", getHostPath() + "/OnCommand.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "Returned page URL", getHostPath() + "/OnCommand.html", myPage.getURL().toExternalForm() ); } public void testInitialJavaScriptURL() throws Exception { WebConversation wc = new WebConversation(); GetMethodWebRequest request = new GetMethodWebRequest( "javascript:alert( 'Hi there!' )" ); assertEquals( "Javascript URL", "javascript:alert( 'Hi there!' )", request.getURL().toExternalForm() ); wc.getResponse( request ); assertEquals( "Alert message", "Hi there!", wc.popNextAlert() ); } public void testJavaScriptURLWithVariables() throws Exception { defineResource( "OnCommand.html", "" + "" + "go" + "
" + " " + "
" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertEquals( "New page", "Our winner is... George of the Jungle", wc.getCurrentPage().getText() ); } public void testJavaScriptURLWithQuestionMark() throws Exception { defineResource( "/appname/HandleAction/report?type=C", "You made it!" ); defineResource( "OnCommand.html", "" + "" + "go" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertEquals( "New page", "You made it!", wc.getCurrentPage().getText() ); } /** * test for bug report [ 1508516 ] Javascript method: "undefined" is not supported * @throws Exception */ public void testUndefined() throws Exception { WebConversation wc=doTestJavaScript("if (typeof(xyzDefinitelyNotDefined) == 'undefined') {\n"+ "alert ('blabla');\n"+ "return;\n"+ "}"); assertEquals( "Alert message", "blabla", wc.popNextAlert() ); } /** * test for bug report [ 1153066 ] Eternal loop while processing javascript * by Serguei Khramtchenko 2005-02-27 * @throws Exception */ public void testAvoidEndlessLoop() throws Exception { WebConversation wc=doTestJavaScript("document.location='#node_selected';"); } /** * test javascript call to an included function * @throws Exception */ public void testJavaScriptURLWithIncludedFunction() throws Exception { defineResource( "saycheese.js", "function sayCheese() { alert( \"Cheese!\" ); }" ); defineResource( "OnCommand.html", "" + "" + "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinkWith( "go" ).click(); assertEquals( "Alert message", "Cheese!", wc.popNextAlert() ); } /** * test javascript call to an included function * @throws Exception */ public void testJavaScriptURLWithIncludedFunction2() throws Exception { defineResource( "saycheese.js", "function sayCheese() { alert( \"Cheese!\" ); }" ); defineResource( "callcheese.js", "function callCheese() { sayCheese(); }" ); defineResource( "OnCommand.html", "\n"+ "\n"+ "\n"+ "" + " go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinkWith( "go" ).click(); assertEquals( "Alert message", "Cheese!", wc.popNextAlert() ); } public void testJavaScriptURLInNewWindow() throws Exception { defineWebPage( "OnCommand", "\n" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); Button button1 = (Button) response.getElementWithID( "nowindow" ); Button button2 = (Button) response.getElementWithID( "withwindow" ); button1.click(); assertEquals( "Alert message 1", "hi", wc.popNextAlert() ); button2.click(); assertEquals( "Alert message 2", "hi", wc.popNextAlert() ); } public void testSingleCommandOnLoad() throws Exception { defineResource( "OnCommand.html", "" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertNotNull( "No alert detected", wc.getNextAlert() ); assertEquals( "Alert message", "Ouch!", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } /** * test for bug report [ 1161922 ] setting window.onload has no effect * by Kent Tong * @throws Exception */ public void testWindowOnload() throws Exception { String html="\n"+ "\n"+ "\n"+ "
\n"+ "\n"+ "go" + "
\n"+ "\n"+ "\n"; defineResource( "OnCommand.html", html); WebConversation wc = new WebConversation(); WebResponse response=wc.getResponse( getHostPath() + "/OnCommand.html" ); assertNotNull( "No alert detected", wc.getNextAlert() ); assertEquals( "Alert message", "windowload", wc.popNextAlert() ); response.getLinks()[0].click(); assertEquals( "Alert message", "click", wc.popNextAlert() ); } /** * check that setExceptionsThrownOnScriptError can be set to false * by trying onLoad with an undefined function * @throws Exception */ public void testOnLoadErrorBypass() throws Exception { defineResource( "OnCommand.html", "" + "" + "" + "" ); WebConversation wc = new WebConversation(); HttpUnitOptions.setExceptionsThrownOnScriptError( false ); HttpUnitOptions.clearScriptErrorMessages(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Number of images on page", 1, response.getImages().length ); assertEquals( "Number of script failures logged", 1, HttpUnitOptions.getScriptErrorMessages().length ); } /** * test for bug[ 1055450 ] Error loading included script aborts entire request * by Renaud Waldura */ public void testIncludeErrorBypass() throws Exception { // purposely we don't have it here // defineResource( "saycheese.js", "function sayCheese() { alert( \"Cheese!\" ); }" ); defineResource( "OnCommand.html", "" + "" + "go" + "" ); HttpUnitOptions.setExceptionsThrownOnScriptError( true); HttpUnitOptions.clearScriptErrorMessages(); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); boolean oldDebug= HttpUnitUtils.setEXCEPTION_DEBUG(false); try { response.getLinkWith( "go" ).click(); fail("there should have been an exception"); } catch (Throwable th) { // java.lang.RuntimeException: Error clicking link: com.meterware.httpunit.ScriptException: URL 'javascript:sayCheese()' failed: org.mozilla.javascript.EcmaError: ReferenceError: "sayCheese" is not defined. assertTrue("is not defined should be found in message",th.getMessage().indexOf("not defined")>0); } finally { HttpUnitUtils.setEXCEPTION_DEBUG(oldDebug); } HttpUnitOptions.setExceptionsThrownOnScriptError( false); HttpUnitOptions.clearScriptErrorMessages(); response.getLinkWith( "go" ).click(); String messages[]=HttpUnitOptions.getScriptErrorMessages(); assertTrue("there should be one message",messages.length==1); String message=messages[0]; assertTrue("is not defined should be found",message.indexOf("is not defined")>0); } public void testConfirmationDialog() throws Exception { defineWebPage( "OnCommand", "" ); defineResource( "NextPage", "Got the next page!" ); WebConversation wc = new WebConversation(); WebResponse wr = wc.getResponse( getHostPath() + "/OnCommand.html" ); wc.setDialogResponder( new DialogAdapter() { public boolean getConfirmation( String confirmationPrompt ) { assertEquals( "Confirmation prompt", "go on?", confirmationPrompt ); return false; } } ); wr.getLinkWithID( "go" ).click(); assertEquals( "Current page", wr, wc.getCurrentPage() ); wc.setDialogResponder( new DialogAdapter() ); wr.getLinkWithID( "go" ).click(); assertEquals( "Page after confirmation", "Got the next page!", wc.getCurrentPage().getText() ); } public void testPromptDialog() throws Exception { defineWebPage( "OnCommand", "" ); defineResource( "NextPage", "Got the next page!" ); WebConversation wc = new WebConversation(); WebResponse wr = wc.getResponse( getHostPath() + "/OnCommand.html" ); wr.getLinkWithID( "go" ).click(); assertEquals( "Current page", wr, wc.getCurrentPage() ); wc.setDialogResponder( new DialogAdapter() { public String getUserResponse( String prompt, String defaultResponse ) { assertEquals( "Confirmation prompt", "go on?", prompt ); assertEquals( "Default response", "no", defaultResponse ); return "yes"; } } ); wr.getLinkWithID( "go" ).click(); assertEquals( "Page after confirmation", "Got the next page!", wc.getCurrentPage().getText() ); } public void testFunctionCallOnLoad() throws Exception { defineResource( "OnCommand.html", "" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "Cheese!", wc.popNextAlert() ); } public void testComment() throws Exception { defineResource( "OnCommand.html", "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); } public void testIncludedFunction() throws Exception { defineResource( "saycheese.js", "function sayCheese() { alert( \"Cheese!\" ); }" ); defineResource( "OnCommand.html", "" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "Cheese!", wc.popNextAlert() ); } public void testIncludedFunctionWithBaseTag() throws Exception { defineResource( "scripts/saycheese.js", "function sayCheese() { alert( \"Cheese!\" ); }" ); defineResource( "OnCommand.html", "" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message", "Cheese!", wc.popNextAlert() ); } public void testWindowOpen() throws Exception { defineResource( "Target.txt", "You made it!", "text/plain" ); defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "go" + "go" + "" ); final ArrayList windowsOpened = new ArrayList(); WebConversation wc = new WebConversation(); wc.addWindowListener( new WebWindowListener() { public void windowOpened( WebClient client, WebWindow window ) { windowsOpened.add( window ); } public void windowClosed( WebClient client, WebWindow window ) {} } ); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertFalse( "No window opened", windowsOpened.isEmpty() ); final WebWindow openedWindow = (WebWindow) windowsOpened.get( 0 ); assertEquals( "New window message", "You made it!", openedWindow.getCurrentPage().getText() ); assertEquals( "New window name", "sample", openedWindow.getName() ); response.getLinks()[2].click(); assertEquals( "Alert message", "window is not closed", wc.popNextAlert() ); response.getLinks()[1].click(); assertTrue( "Window was not closed", openedWindow.isClosed() ); response.getLinks()[2].click(); assertEquals( "Alert message", "window is closed", wc.popNextAlert() ); } public void testWindowOpenWithEmptyName() throws Exception { defineResource( "Target.txt", "You made it!", "text/plain" ); defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "go" + "go" + "" ); final ArrayList windowsOpened = new ArrayList(); WebConversation wc = new WebConversation(); wc.addWindowListener( new WebWindowListener() { public void windowOpened( WebClient client, WebWindow window ) { windowsOpened.add( window ); } public void windowClosed( WebClient client, WebWindow window ) {} } ); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertFalse( "No window opened", windowsOpened.isEmpty() ); final WebWindow openedWindow = (WebWindow) windowsOpened.get( 0 ); assertEquals( "New window message", "You made it!", openedWindow.getCurrentPage().getText() ); assertEquals( "New window name", "", openedWindow.getName() ); response.getLinks()[2].click(); assertEquals( "Alert message", "window is not closed", wc.popNextAlert() ); response.getLinks()[1].click(); assertTrue( "Window was not closed", openedWindow.isClosed() ); response.getLinks()[2].click(); assertEquals( "Alert message", "window is closed", wc.popNextAlert() ); } public void testWindowOpenWithSelf() throws Exception { defineResource( "Target.txt", "You made it!", "text/plain" ); defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "go" + "go" + "" ); final ArrayList windowsOpened = new ArrayList(); WebConversation wc = new WebConversation(); wc.addWindowListener( new WebWindowListener() { public void windowOpened( WebClient client, WebWindow window ) { windowsOpened.add( window ); } public void windowClosed( WebClient client, WebWindow window ) {} } ); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertTrue( "Opened a new window", windowsOpened.isEmpty() ); assertEquals( "New window message", "You made it!", wc.getCurrentPage().getText() ); assertEquals( "Number of open windows", 1, wc.getOpenWindows().length ); } public void testJavascriptURLWithFragment() throws Exception { defineResource( "Target.txt", "You made it!", "text/plain" ); defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "" ); final ArrayList windowsOpened = new ArrayList(); WebConversation wc = new WebConversation(); wc.addWindowListener( new WebWindowListener() { public void windowOpened( WebClient client, WebWindow window ) { windowsOpened.add( window ); } public void windowClosed( WebClient client, WebWindow window ) {} } ); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertFalse( "No window opened", windowsOpened.isEmpty() ); final WebWindow openedWindow = (WebWindow) windowsOpened.get( 0 ); assertEquals( "New window message", "You made it!", openedWindow.getCurrentPage().getText() ); } public void testWindowOpenNoContents() throws Exception { defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "" ); final ArrayList windowsOpened = new ArrayList(); WebConversation wc = new WebConversation(); wc.addWindowListener( new WebWindowListener() { public void windowOpened( WebClient client, WebWindow window ) { windowsOpened.add( window ); } public void windowClosed( WebClient client, WebWindow window ) {} } ); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertFalse( "No window opened", windowsOpened.isEmpty() ); final WebWindow openedWindow = (WebWindow) windowsOpened.get( 0 ); assertEquals( "New window message", "", openedWindow.getCurrentPage().getText() ); assertEquals( "New window name", "sample", openedWindow.getName() ); assertEquals( "Window by name", openedWindow, wc.getOpenWindow( "sample" ) ); } public void testWindowReopen() throws Exception { defineResource( "Target.html", "You made it!" ); defineResource( "Revise.html", "You changed it!" ); defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "go" + "" ); final ArrayList windowsOpened = new ArrayList(); WebConversation wc = new WebConversation(); wc.addWindowListener( new WebWindowListener() { public void windowOpened( WebClient client, WebWindow window ) { windowsOpened.add( window ); } public void windowClosed( WebClient client, WebWindow window ) {} } ); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].click(); assertEquals( "New window message", "You made it!", ((WebWindow) windowsOpened.get( 0 )).getCurrentPage().getText() ); response.getLinks()[1].click(); assertEquals( "Number of window openings", 1, windowsOpened.size() ); assertEquals( "Changed window message", "You changed it!", ((WebWindow) windowsOpened.get( 0 )).getCurrentPage().getText() ); } public void testOpenedWindowProperties() throws Exception { defineResource( "Target.html", "" + "" ); defineResource( "OnCommand.html", "Amazing!" + "" + "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "main window name", "main", wc.getMainWindow().getName() ); assertEquals( "main window alert", "opener not defined", wc.popNextAlert() ); response.getLinks()[0].click(); assertEquals( "1st alert", "name=sample", wc.popNextAlert() ); assertEquals( "2nd alert", "opener name=main", wc.popNextAlert() ); } public void testFrameProperties() throws Exception { HttpUnitOptions.setExceptionsThrownOnScriptError( false ); defineWebPage( "Linker", "This is a trivial page with one link" ); defineResource( "Target.html", "" + "show" + "" ); defineWebPage( "Form", "This is a page with a simple form: " + "
" + "a link"); defineResource( "Frames.html", "Initial" + "" + " " + " " + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/Frames.html" ); WebResponse blue = wc.getFrameContents( "blue" ); blue.getLinkWith( "show" ).click(); assertEquals( "1st alert", "name=blue", wc.popNextAlert() ); assertEquals( "2nd alert", "top url=" + getHostPath() + "/Frames.html", wc.popNextAlert() ); assertEquals( "3rd alert", "1st frame=red", wc.popNextAlert() ); assertEquals( "4th alert", "2nd frame=blue", wc.popNextAlert() ); assertEquals( "5th alert", "parent url=" + getHostPath() + "/Frames.html", wc.popNextAlert() ); assertEquals( "6th alert", "top.parent=" + getHostPath() + "/Frames.html", wc.popNextAlert() ); assertEquals( "7th alert", "indexed frame=red", wc.popNextAlert() ); } public void testLocationProperty() throws Exception { defineResource( "Target.html", "You made it!" ); defineResource( "location.js", "function show() {" + "alert('Window location is ' + window.location);" + "alert('Document location is ' + document.location);" + "alert('Window location.href is ' + window.location.href);" + "}" ); defineResource( "OnCommand.html", "Amazing!" + "" + "" + "" + "go" + "go" + "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message 1", "Window location is " + getHostPath() + "/OnCommand.html", wc.popNextAlert() ); assertEquals( "Alert message 2", "Document location is " + getHostPath() + "/OnCommand.html", wc.popNextAlert() ); assertEquals( "Alert message 3", "Window location.href is " + getHostPath() + "/OnCommand.html", wc.popNextAlert() ); response.getLinks()[0].mouseOver(); assertEquals( "2nd page URL", getHostPath() + "/Target.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "2nd page", "You made it!", wc.getCurrentPage().getText() ); response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[1].mouseOver(); assertEquals( "3rd page URL", getHostPath() + "/Target.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "3rd page", "You made it!", wc.getCurrentPage().getText() ); response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[2].mouseOver(); assertEquals( "4th page URL", getHostPath() + "/Target.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "4th page", "You made it!", wc.getCurrentPage().getText() ); response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getScriptingHandler().doEventScript( "window.location.href='" + getHostPath() + "/Target.html'" ); assertEquals( "5th page URL", getHostPath() + "/Target.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "5th page", "You made it!", wc.getCurrentPage().getText() ); } public void testLocationPropertyOnLoad() throws Exception { defineResource( "Target.html", "You made it!" ); defineResource( "OnCommand.html", "Amazing!" + "" + "" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "current page URL", getHostPath() + "/Target.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "current page", "You made it!", wc.getCurrentPage().getText() ); assertEquals( "returned page URL", getHostPath() + "/Target.html", response.getURL().toExternalForm() ); assertEquals( "returned page", "You made it!", response.getText() ); } public void testLocationReadableSubproperties() throws Exception { defineResource( "Target.html", "You made it!" ); defineResource( "location.js", "function show() {" + "alert('host is ' + window.location.host);" + "alert('hostname is ' + document.location.hostname);" + "alert('port is ' + window.location.port);" + "alert('pathname is ' + window.location.pathname);" + "alert('protocol is ' + document.location.protocol);" + "alert('search is ' + window.location.search);" + "}" ); defineResource( "simple/OnCommand.html?point=center", "Amazing!" + "" + "" + "" + "" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/simple/OnCommand.html?point=center" ); assertEquals( "Alert message 1", "host is " + getHostPath().substring( 7 ), wc.popNextAlert() ); assertEquals( "Alert message 2", "hostname is localhost", wc.popNextAlert() ); assertEquals( "Alert message 3", "port is " + getHostPort(), wc.popNextAlert() ); assertEquals( "Alert message 4", "pathname is /simple/OnCommand.html", wc.popNextAlert() ); assertEquals( "Alert message 5", "protocol is http:", wc.popNextAlert() ); assertEquals( "Alert message 6", "search is ?point=center", wc.popNextAlert() ); } public void testLocationWriteableSubproperties() throws Exception { defineResource( "Target.html", "You made it!" ); defineResource( "OnCommand.html?where=here", "You found it!" ); defineResource( "OnCommand.html", "Amazing!" + "" + "" + "go" + "go" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[0].mouseOver(); assertEquals( "2nd page URL", getHostPath() + "/Target.html", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "2nd page", "You made it!", wc.getCurrentPage().getText() ); response = wc.getResponse( getHostPath() + "/OnCommand.html" ); response.getLinks()[1].mouseOver(); assertEquals( "3rd page URL", getHostPath() + "/OnCommand.html?where=here", wc.getCurrentPage().getURL().toExternalForm() ); assertEquals( "3rd page", "You found it!", wc.getCurrentPage().getText() ); } public void testScriptDisabled() throws Exception { HttpUnitOptions.setScriptingEnabled( false ); defineResource( "nothing.html", "Should get here" ); defineResource( "OnCommand.html", "" + "" + "
" + "green" + "" ); WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse( getHostPath() + "/OnCommand.html" ); WebForm form = response.getFormWithName( "realform" ); WebLink link = response.getLinks()[0]; assertEquals( "initial parameter value", "blue", form.getParameterValue( "color" ) ); link.click(); assertEquals( "unchanged parameter value", "blue", form.getParameterValue( "color" ) ); assertEquals( "Expected result", "Should get here", wc.getCurrentPage().getText() ); } public void testNavigatorObject() throws Exception { defineResource( "OnCommand.html", "\n" + "\n" + "" ); HttpUnitOptions.setExceptionsThrownOnScriptError( true ); WebConversation wc = new WebConversation(); wc.getClientProperties().setApplicationID( "Internet Explorer", "Mozilla", "4.0" ); wc.getClientProperties().setPlatform( "JVM" ); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message 1", "appName=Internet Explorer", wc.popNextAlert() ); assertEquals( "Alert message 2", "appCodeName=Mozilla", wc.popNextAlert() ); assertEquals( "Alert message 3", "appVersion=4.0", wc.popNextAlert() ); assertEquals( "Alert message 4", "userAgent=Mozilla/4.0", wc.popNextAlert() ); assertEquals( "Alert message 5", "platform=JVM", wc.popNextAlert() ); assertEquals( "Alert message 6", "javaEnabled=false", wc.popNextAlert() ); assertEquals( "Alert message 7", "# plugins=0", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } public void testScreenObject() throws Exception { defineResource( "OnCommand.html", "\n" + "\n" + "" ); HttpUnitOptions.setExceptionsThrownOnScriptError( true ); WebConversation wc = new WebConversation(); wc.getClientProperties().setAvailableScreenSize( 1024, 752 ); wc.getResponse( getHostPath() + "/OnCommand.html" ); assertEquals( "Alert message 1", "dimensions=1024x752", wc.popNextAlert() ); assertNull( "Alert should have been removed", wc.getNextAlert() ); } public void testStyleProperty() throws Exception { defineResource( "start.html", "" + "" + "
foo
" ); WebConversation wc = new WebConversation(); wc.getResponse( getHostPath() + "/start.html" ); assertEquals( "element with id test has style.display inline", wc.popNextAlert() ); assertEquals( "element with id test has style.display block", wc.popNextAlert() ); assertEquals( "element with id test has style.visibility hidden", wc.popNextAlert() ); assertEquals( "element with id test has style.visibility visible", wc.popNextAlert() ); } /** * test for Patch proposal 1653410 * Date: 2008-01-08 15:49 * @author Mattias Jiderhamn (mattias78) */ public void testSetAttribute() throws Exception { /* * A minimal snippet: ... var field = document.getElementById("foo"); var attributeValue = field.getAttribute("myattr"); alert("The attribute value is " + attributeValue); field.setAttribute("myattr", "new_attribute_value"); */ // will only work with Dom based scripting engine before patch // needs addCustomAttribute for old scriptin engine if (HttpUnitOptions.DEFAULT_SCRIPT_ENGINE_FACTORY.equals(HttpUnitOptions.ORIGINAL_SCRIPTING_ENGINE_FACTORY)) { HttpUnitOptions.addCustomAttribute("myattr"); } defineResource( "start.html", "\n"+ "\n" + "\n" + ""+ "
"+ "\n"+ "\n" + "\n" + ""+ "
"+ "\n"+ "\n" + "\n" + "
\n"+ "\n" + "\n" + "
" ); defineWebPage( "Contents", "This is another page with one link" ); defineWebPage( "Form", "This is a page with a simple form: " + "
"); WebResponse response = _wc.getResponse( getHostPath() + "/Frame.html" ); WebRequest[] requests = response.getFrameRequests(); assertEquals( "Number of links in main frame", 1, response.getLinks().length ); assertEquals( "Number of forms in main frame", 0, response.getForms().length ); assertEquals( "Number of frame requests", 1, requests.length ); assertEquals( "Target for iframe request", "center", requests[0].getTarget() ); WebResponse contents = getFrameWithURL( _wc, "Contents" ); assertNotNull( "Contents not found", contents ); assertEquals( "Number of links in iframe", 1, _wc.getFrameContents( "center" ).getLinks().length ); } /** * test I Frame with a Form according to mail to mailinglist of 2008-03-25 * Problems with IFrames by Allwyn D'souza * TODO activate test when it's clear how it should work * @throws Exception */ public void xtestIFrameForm() throws Exception { String login="//Login.html (main page that is loaded - this page embed the IFrame).\n"+ "\n"+ "\n"+ "\n"+ "\n"+ "\n"+ "\n"+ "
\n"+ "\n"+ "\n"+ "
\n"+ "
\n"+ "" ); defineWebPage( "Contents", "This is another page with one link" ); _wc.getClientProperties().setIframeSupported( false ); WebResponse response = _wc.getResponse( getHostPath() + "/Frame.html" ); WebRequest[] requests = response.getFrameRequests(); assertEquals( "Number of links in main frame", 1, response.getLinks().length ); assertEquals( "Number of forms in main frame", 1, response.getForms().length ); assertEquals( "Number of frame requests", 0, requests.length ); } /** * Verifies that an open call from a subframe can specify another frame name. */ public void testOpenIntoSubframe() throws Exception { defineResource( "Frames.html", "" + " " + " " + "" ); defineResource( "target.txt", "You made it!" ); defineWebPage( "main", "