Menu

Option constructor throws an exception

Help
Anonymous
2003-09-22
2003-09-24
  • Anonymous

    Anonymous - 2003-09-22

    According to the documentation, I should be able to construct a new Option object and add it to a Select objects list of options.  However it throws an exception:

    TypeError: "options" is not defined. (httpunit; line 174)
        at org.mozilla.javascript.NativeGlobal.constructError(NativeGlobal.java:590)
        at org.mozilla.javascript.NativeGlobal.constructError(NativeGlobal.java:550)
        at org.mozilla.javascript.NativeGlobal.typeError1(NativeGlobal.java:560)
        at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2042)

    Here is a sample to invoke the exception:

    <html><head><title>Test Javascript</title>
    <script language="javascript">
    <!--
    function doLoad()
    {
      document.testform.testselect.options[3] = new Option("4", "4");
    }
    // -->
    </script>
    </head>
    <body onLoad="doLoad()">
    <form name="testform">
    <b>Select One: </b>
    <select name="testselect">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    </select><br>
    <input type="submit" name="submitButton" value="Submit">
    </form>
    </body>
    </html>

     
    • Anonymous

      Anonymous - 2003-09-23

      Actually it appears as though HttpUnit does not support the Select.options DOM attribute at all as demonstrated by this simpler example:

      <html><head><title>Test Javascript</title>
      </head>
      <body onLoad="alert('numoptions='+document.testform.testselect.options.length)">
      <form name="testform">
      <b>Select One: </b>
      <select name="testselect">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      </select><br>
      <input type="submit" name="submitButton" value="Submit">
      </form>
      </body>
      </html>

       
    • Anonymous

      Anonymous - 2003-09-23

      I checked out the unit test case for this scenario to see why it works and my test does not.  Apparently, the Select.options attribute is only available when it is not passed in to the page as a get parameter.  So if the file "testJavascript.html" contains the code in my previous post, then testing "testJavascript.html" works but "testJavascript.html?testselect=1" fails.  Here is the code I'm using:

      import junit.framework.TestCase;

      import com.meterware.httpunit.GetMethodWebRequest;
      import com.meterware.httpunit.WebConversation;
      import com.meterware.httpunit.WebRequest;
      import com.meterware.httpunit.WebResponse;

      public class TestJavascriptCompatibility extends TestCase
      {
          public TestJavascriptCompatibility(String name)
          {
              super(name);
          }
         
          public void testPage() throws Exception
          {
              WebConversation wc = new WebConversation();
              WebRequest req =
                  new GetMethodWebRequest(
                      "http://localhost/testJavascript.html?testselect=123");
              WebResponse response = wc.getResponse(req);
              boolean failed = false;

              if (!goodResponse(response.getResponseCode()))
              {
                  fail(
                      "Test javascript page returned an error: "
                          + response.getResponseCode());
                  failed = true;
              }
             
              if (!failed)
              {
                  String msg = wc.popNextAlert();
                  if (msg != null)
                    System.out.println("alert: " + msg);
              }
          }

          private boolean goodResponse(int responseCode)
          {
              return (responseCode >= 200 && responseCode < 300);
          }
      }

       
    • Anonymous

      Anonymous - 2003-09-23

      It looks like ScriptRuntime.getProp() is returning an array instead of the single form property for testform.testselect.  The first element is some kind of PresetFormParameter (the request parameter?) and the second element is the SelectionFormControl.  I'm not sure what the point is of returning the preset value and select form control as two separate objects.  In any event, this is contrary to the ECMA 262 spec section 10.1.4.

       
    • Anonymous

      Anonymous - 2003-09-24

      I was able to hack together a fix and it appears to work.  I ran the HTTPUnitSuite test and only two things failed.

      PseudoServerTest.testNoSuchServer fails with jdk1.4.2 because HttpURLConnection.getResponseCode() throws an IOException and not a NoSuchHostException.

      JUnitServletTest.testScriptedServletAccess() fails for some reason but it failed before I changed anything.

      I changed two lines in WebForm.Scriptable.get(String) and added a new method WebForm.getFormControl(String).

              public Object get( String propertyName ) {
                  if (propertyName.equals( "target" )) {
                      return getTarget();
                  } else {
                      Object parameter = getFormControl(propertyName);
                      if (parameter != null) return parameter;
                      FormControl control = getControlWithID( propertyName );
                      return control == null ? super.get( propertyName ) : control.getScriptableDelegate();
                  }
              }

          private Object getFormControl(String name) {
              Vector vec = new Vector();
              ScriptableDelegate retArray[] = null;
              Object ret = null;
              FormControl controls[] = getFormControls();
              int controlIter, numControls = controls == null ? 0 : controls.length;
              int retLength;
              for (controlIter = 0; controlIter < numControls; ++controlIter)
              {
                  if (controls[controlIter].getName().equals(name))
                  {
                      vec.addElement(controls[controlIter].getDelegate());
                  }
              }
              retLength = vec.size();
             
              if (retLength == 1)
              {
                  ret = vec.elementAt(0);
              }
              else if (retLength > 1)
              {
                  retArray = new ScriptableDelegate[retLength];
                  vec.copyInto(retArray);
                  ret = retArray;
              }
              return ret;
          }

       

Log in to post a comment.

MongoDB Logo MongoDB