How to extract all the input elements from an HTML form?

1,095 views
Skip to first unread message

John Arrowwood

unread,
Jan 27, 2020, 5:37:06 PM1/27/20
to REST assured
I know this is probably easy to do, but nothing I've tried has worked.  And I'm having trouble finding documentation that explains my exact use case.

I'm trying to find all the <input> tags in an HTML page, extract the field @name and @value, and store them in a map, to aid in form submission.

What's the right way to do this?

Thanks!

Johan Haleby

unread,
Jan 28, 2020, 5:44:23 AM1/28/20
to rest-a...@googlegroups.com
You should be able to use something like this:

List<Map> nameAndValue = xmlPath.getList("**.findAll { it.name() == 'input' }.collect { [name: it.@name, value: it.'@value'] }", Map.class);

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rest-assured/b1f2fd10-cb3a-406a-9113-b1aa84d11f7c%40googlegroups.com.

Johan Haleby

unread,
Jan 28, 2020, 5:45:29 AM1/28/20
to rest-a...@googlegroups.com
You should instruct XmlPath to use HTML as compatibility mode:

XmlPath xmlPath = new XmlPath(HTML, html);

John Arrowwood

unread,
Jan 28, 2020, 10:34:33 AM1/28/20
to REST assured
My code looks like this:

XmlPath xp = response.xmlPath(XmlPath.CompatibilityMode.HTML);

String target = xp.getString( "html.body.form.@action");
System.out.println( target );

List<Map> fields = xp.getList("html.body.form.**.findAll { it.name == 'input' }.collect { [name: it.@name, value: it.@value] }", Map.class);
System.out.println( fields );
System.out.println( fields.size() );

The output looks like this:

/auth/logon
[]
0

So, I can confirm that I can find the form tag, but I can't find and collect any of the input tags from within it.  

The HTML looks like this:

    <form enctype="application/x-www-form-urlencoded" method="POST" class="form" name="authForm" action="/auth/logon" accept-charset="UTF-8">
      <input type="hidden" name="_csrf" value="1967212d-c0cd-484a-8f2a-a61358d1f969"/>
      <div class="formarea">
        <h1>Welcome to User Account Management</h1>
        <span>
          <script>/* throw up warning if using old browser */</script>
        </span>
        <div class="oldBrwr"/>
        <span>
          <input type="hidden" id="view" name="view" value="username"/>
          <input type="hidden" id="authId" name="authId" value="{value}"/>
          <input type="hidden" id="goToUrl" name="goToUrl" value="http%3A%2F%2Fwww.example.com%2F"/>
          <script src="js/deviceprint.js" type="text/javascript" language="javascript"/>
          <input type="hidden" id="deviceId" name="deviceId" value=""/>
          <script>decorateWithDeviceId(document.getElementById('deviceId'));</script>
        </span>
        <label for="user">User ID</label>
        <input tabindex="1" type="text" class="usernameicon" id="user" autofocus="" name="username" autocomplete="off" onkeyup="document.forms[0].user.value!=''?document.forms[0].user.value=document.forms[0].user.value.trim().toLowerCase():'';" value=""/>
        <div id="forgotPassword">
          <a shape="rect" tabindex="2" class="forgotPasswordLink" style="float:right; margin-top:-43px" href="/auth/forgot">
                        Forgot User ID or Password?
                    </a>
        </div>
        <div style="clear:both"/>
        <div class="XD-CLASS-EULA">/* EULA */</div>
        <div style="clear:both"/>
        <button tabindex="3" type="submit" class="submitbutton"> Accept </button>
        <button tabindex="4" type="button" class="cancelbutton" cancel="" onclick="alert('You will not be able to access the application without accepting the Terms and Conditions of Use.')"> Decline </button>
        <div style="clear:both"/>
      </div>
    </form>

The only thing that I can see that might be throwing it off is that for some reason the HTML element contains two heads and two bodies.  But since I can find the form tag, I wouldn't think that would be the problem.

Any thoughts?

On Tuesday, January 28, 2020 at 5:45:29 AM UTC-5, Johan Haleby wrote:
You should instruct XmlPath to use HTML as compatibility mode:

XmlPath xmlPath = new XmlPath(HTML, html);

On Tue, Jan 28, 2020 at 11:44 AM Johan Haleby <johan...@gmail.com> wrote:
You should be able to use something like this:

List<Map> nameAndValue = xmlPath.getList("**.findAll { it.name() == 'input' }.collect { [name: it.@name, value: it.'@value'] }", Map.class);

On Mon, Jan 27, 2020 at 11:37 PM John Arrowwood <jarr...@gmail.com> wrote:
I know this is probably easy to do, but nothing I've tried has worked.  And I'm having trouble finding documentation that explains my exact use case.

I'm trying to find all the <input> tags in an HTML page, extract the field @name and @value, and store them in a map, to aid in form submission.

What's the right way to do this?

Thanks!

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-a...@googlegroups.com.

John Arrowwood

unread,
Jan 28, 2020, 11:28:54 AM1/28/20
to REST assured
Nevermind, I see it.  it's `it.name()` with the parenthesis.  I somehow missed that.

John Arrowwood

unread,
Jan 28, 2020, 11:45:13 AM1/28/20
to REST assured
Now it's iterating over the tags, but it's not returning name and value, just "name" and the value.  I don't think that's the right syntax for the `.collect` part of the expression to give me what I want.

private static Map<String,String> formInputs ( Response response ) {
Map<String, String> data = new HashMap<String, String>();
XmlPath xp = response.xmlPath(XmlPath.CompatibilityMode.HTML);
List<Map> fields = xp.getList("**.findAll { it.name() == 'input' }.collect { [name: it.@name, value: it.@value] }", Map.class);
System.out.println( fields.size() );
for ( Map f : fields ) {
System.out.println( f );
// data.put( f.get("name").toString(), f.get("value").toString() );
}
return data;
}

Output:
6
{name=b030bea4-9062-4d3a-8a88-d80fa1fe6b61}
{name=username}
{name=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvdGsiOiJoNDlrbzdsdmplMXVzOGhkb3NycXE0anA3YiIsInJlYWxtIjoibz1ld3Msb3U9c2VydmljZXMsZGM9ZmlucmEsZGM9b3JnIiwic2Vzc2lvbklkIjoiQVFJQzV3TTJMWTRTZmN5dHM5cllPZjBzaEU5N0tCR0ZIWjV3Z2ktVjJVcHhtS1UuKkFBSlRTUUFDTURJQUFsTkxBQk0yTmpVNE16QXdORFU0T1Rrek16YzRNelUyQUFKVE1RQUNNRFUuKiJ9.YhkWtvbuOn_lsA2vkzMbSmZTv9S9uoweJnCLj8L-g6A}
{name=https%3A%2F%2Fews.stress.finra.org%3A443%2Fewsadmin2}
{name=}
{name=}
Reply all
Reply to author
Forward
0 new messages