• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / httpunit / 656

06 Dec 2025 09:11PM UTC coverage: 80.452% (+0.02%) from 80.435%
656

push

github

hazendaz
[maven-release-plugin] prepare for next development iteration

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8245 of 10137 relevant lines covered (81.34%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.16
/src/main/java/com/meterware/httpunit/HTMLPage.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2025 Russell Gold
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
9
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
12
 * of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
 * DEALINGS IN THE SOFTWARE.
19
 */
20
package com.meterware.httpunit;
21

22
import com.meterware.httpunit.parsing.DocumentAdapter;
23
import com.meterware.httpunit.parsing.HTMLParserFactory;
24
import com.meterware.httpunit.scripting.NamedDelegate;
25
import com.meterware.httpunit.scripting.ScriptableDelegate;
26
import com.meterware.httpunit.scripting.ScriptingHandler;
27

28
import java.io.IOException;
29
import java.net.URL;
30
import java.util.ArrayList;
31
import java.util.List;
32

33
import org.w3c.dom.Document;
34
import org.w3c.dom.Element;
35
import org.w3c.dom.NodeList;
36
import org.w3c.dom.html.HTMLDocument;
37
import org.xml.sax.SAXException;
38

39
/**
40
 * This class represents an HTML page returned from a request.
41
 **/
42
public class HTMLPage extends ParsedHTML {
43

44
    /** The scriptable. */
45
    private Scriptable _scriptable;
46

47
    /**
48
     * Instantiates a new HTML page.
49
     *
50
     * @param response
51
     *            the response
52
     * @param frame
53
     *            the frame
54
     * @param baseURL
55
     *            the base URL
56
     * @param baseTarget
57
     *            the base target
58
     * @param characterSet
59
     *            the character set
60
     */
61
    HTMLPage(WebResponse response, FrameSelector frame, URL baseURL, String baseTarget, String characterSet) {
62
        super(response, frame, baseURL, baseTarget, null, characterSet);
1✔
63
    }
1✔
64

65
    /**
66
     * Returns the title of the page.
67
     *
68
     * @return the title
69
     *
70
     * @throws SAXException
71
     *             the SAX exception
72
     */
73
    public String getTitle() throws SAXException {
74
        NodeList nl = ((Document) getOriginalDOM()).getElementsByTagName("title");
1✔
75
        if (nl.getLength() == 0 || !nl.item(0).hasChildNodes()) {
1!
76
            return "";
×
77
        }
78
        return nl.item(0).getFirstChild().getNodeValue();
1✔
79
    }
80

81
    /**
82
     * Returns the onLoad event script.
83
     *
84
     * @return the on load event
85
     *
86
     * @throws SAXException
87
     *             the SAX exception
88
     */
89
    public String getOnLoadEvent() throws SAXException {
90
        Element mainElement = getMainElement((Document) getOriginalDOM());
1✔
91
        return mainElement == null ? "" : mainElement.getAttribute("onload");
1!
92
    }
93

94
    /**
95
     * Gets the main element.
96
     *
97
     * @param document
98
     *            the document
99
     *
100
     * @return the main element
101
     */
102
    private Element getMainElement(Document document) {
103
        NodeList nl = document.getElementsByTagName("frameset");
1✔
104
        if (nl.getLength() == 0) {
1✔
105
            nl = document.getElementsByTagName("body");
1✔
106
        }
107
        return nl.getLength() == 0 ? null : (Element) nl.item(0);
1!
108
    }
109

110
    /**
111
     * Returns the location of the linked stylesheet in the head <code> <link type="text/css" rel="stylesheet"
112
     * href="/mystyle.css" /> </code>
113
     *
114
     * @return the external style sheet
115
     *
116
     * @throws SAXException
117
     *             the SAX exception
118
     */
119
    public String getExternalStyleSheet() throws SAXException {
120
        NodeList nl = ((Document) getOriginalDOM()).getElementsByTagName("link");
1✔
121
        int length = nl.getLength();
1✔
122
        if (length == 0) {
1!
123
            return "";
×
124
        }
125

126
        for (int i = 0; i < length; i++) {
1!
127
            if ("stylesheet".equalsIgnoreCase(NodeUtils.getNodeAttribute(nl.item(i), "rel"))) {
1✔
128
                return NodeUtils.getNodeAttribute(nl.item(i), "href");
1✔
129
            }
130
        }
131
        return "";
×
132
    }
133

134
    /**
135
     * Retrieves the "content" of the meta tags for a key pair attribute-attributeValue. &lt;code&gt; &lt;meta
136
     * name="robots" content="index" /&gt; &lt;meta name="robots" content="follow" /&gt; &lt;meta http-equiv="Expires"
137
     * content="now" /&gt; &lt;/code&gt; this can be used like this &lt;code&gt; getMetaTagContent("name","robots") will
138
     * return { "index","follow" } getMetaTagContent("http-equiv","Expires") will return { "now" } &lt;/code&gt;
139
     *
140
     * @param attribute
141
     *            the attribute
142
     * @param attributeValue
143
     *            the attribute value
144
     *
145
     * @return the meta tag content
146
     */
147
    public String[] getMetaTagContent(String attribute, String attributeValue) {
148
        List<String> matches = new ArrayList<>();
1✔
149
        NodeList nl = ((Document) getOriginalDOM()).getElementsByTagName("meta");
1✔
150
        int length = nl.getLength();
1✔
151

152
        for (int i = 0; i < length; i++) {
1✔
153
            if (attributeValue.equalsIgnoreCase(NodeUtils.getNodeAttribute(nl.item(i), attribute))) {
1✔
154
                matches.add(NodeUtils.getNodeAttribute(nl.item(i), "content"));
1✔
155
            }
156
        }
157
        return matches.toArray(new String[0]);
1✔
158
    }
159

160
    /**
161
     * scriptable for HTML Page.
162
     */
163

164
    public class Scriptable extends ScriptableDelegate {
165

166
        /**
167
         * get the Object with the given propertyName
168
         *
169
         * @param propertyName
170
         *            - the name of the property
171
         */
172
        @Override
173
        public Object get(String propertyName) {
174
            NamedDelegate delegate = getNamedItem(getForms(), propertyName);
1✔
175
            if (delegate != null) {
1✔
176
                return delegate;
1✔
177
            }
178

179
            delegate = getNamedItem(getLinks(), propertyName);
1✔
180
            if (delegate != null) {
1✔
181
                return delegate;
1✔
182
            }
183

184
            return getNamedItem(getImages(), propertyName);
1✔
185
        }
186

187
        /**
188
         * Gets the named item.
189
         *
190
         * @param items
191
         *            the items
192
         * @param name
193
         *            the name
194
         *
195
         * @return the named item
196
         */
197
        private NamedDelegate getNamedItem(ScriptingHandler[] items, String name) {
198
            if (name == null) {
1!
199
                return null;
×
200
            }
201
            for (ScriptingHandler item : items) {
1✔
202
                if (item instanceof NamedDelegate && name.equals(((NamedDelegate) item).getName())) {
1!
203
                    return (NamedDelegate) item;
1✔
204
                }
205
            }
206
            return null;
1✔
207
        }
208

209
        /**
210
         * Sets the value of the named property. Will throw a runtime exception if the property does not exist or cannot
211
         * accept the specified value.
212
         **/
213
        @Override
214
        public void set(String propertyName, Object value) {
215
            if (propertyName.equalsIgnoreCase("location")) {
×
216
                getResponse().getScriptableObject().set("location", value);
×
217
            } else {
218
                super.set(propertyName, value);
×
219
            }
220
        }
×
221

222
        /**
223
         * Gets the parent.
224
         *
225
         * @return the parent
226
         */
227
        public WebResponse.Scriptable getParent() {
228
            return getResponse().getScriptableObject();
×
229
        }
230

231
        /**
232
         * Gets the title.
233
         *
234
         * @return the title
235
         *
236
         * @throws SAXException
237
         *             the SAX exception
238
         */
239
        public String getTitle() throws SAXException {
240
            return HTMLPage.this.getTitle();
1✔
241
        }
242

243
        /**
244
         * Gets the links.
245
         *
246
         * @return the links
247
         */
248
        public ScriptingHandler[] getLinks() {
249
            WebLink[] links = HTMLPage.this.getLinks();
1✔
250
            ScriptingHandler[] result = new WebLink.Scriptable[links.length];
1✔
251
            for (int i = 0; i < links.length; i++) {
1✔
252
                result[i] = links[i].getScriptingHandler();
1✔
253
            }
254
            return result;
1✔
255
        }
256

257
        /**
258
         * Gets the forms.
259
         *
260
         * @return the forms
261
         */
262
        public ScriptingHandler[] getForms() {
263
            WebForm[] forms = HTMLPage.this.getForms();
1✔
264
            ScriptingHandler[] result = new ScriptingHandler[forms.length];
1✔
265
            for (int i = 0; i < forms.length; i++) {
1✔
266
                result[i] = forms[i].getScriptingHandler();
1✔
267
            }
268
            return result;
1✔
269
        }
270

271
        /**
272
         * Gets the images.
273
         *
274
         * @return the images
275
         */
276
        public ScriptingHandler[] getImages() {
277
            WebImage[] images = HTMLPage.this.getImages();
1✔
278
            ScriptingHandler[] result = new WebImage.Scriptable[images.length];
1✔
279
            for (int i = 0; i < images.length; i++) {
1✔
280
                result[i] = images[i].getScriptingHandler();
1✔
281
            }
282
            return result;
1✔
283
        }
284

285
        /**
286
         * Instantiates a new scriptable.
287
         */
288
        Scriptable() {
1✔
289
        }
1✔
290

291
        /**
292
         * Replace text.
293
         *
294
         * @param text
295
         *            the text
296
         * @param contentType
297
         *            the content type
298
         *
299
         * @return true, if successful
300
         */
301
        public boolean replaceText(String text, String contentType) {
302
            return getResponse().replaceText(text, contentType);
1✔
303
        }
304

305
        /**
306
         * Sets the cookie.
307
         *
308
         * @param name
309
         *            the name
310
         * @param value
311
         *            the value
312
         */
313
        public void setCookie(String name, String value) {
314
            getResponse().setCookie(name, value);
1✔
315
        }
1✔
316

317
        /**
318
         * Gets the cookie.
319
         *
320
         * @return the cookie
321
         */
322
        public String getCookie() {
323
            return emptyIfNull(getResponse().getCookieHeader());
1✔
324
        }
325

326
        /**
327
         * Empty if null.
328
         *
329
         * @param string
330
         *            the string
331
         *
332
         * @return the string
333
         */
334
        private String emptyIfNull(String string) {
335
            return string == null ? "" : string;
1✔
336
        }
337

338
        /**
339
         * Gets the element with ID.
340
         *
341
         * @param id
342
         *            the id
343
         *
344
         * @return the element with ID
345
         */
346
        public ScriptableDelegate getElementWithID(String id) {
347
            final HTMLElement elementWithID = HTMLPage.this.getElementWithID(id);
1✔
348
            return elementWithID == null ? null : (ScriptableDelegate) elementWithID.getScriptingHandler();
1✔
349
        }
350

351
        /**
352
         * Gets the elements by name.
353
         *
354
         * @param name
355
         *            the name
356
         *
357
         * @return the elements by name
358
         */
359
        public ScriptableDelegate[] getElementsByName(String name) {
360
            return getDelegates(HTMLPage.this.getElementsWithName(name));
1✔
361
        }
362

363
        /**
364
         * Gets the elements by tag name.
365
         *
366
         * @param name
367
         *            the name
368
         *
369
         * @return the elements by tag name
370
         */
371
        public ScriptableDelegate[] getElementsByTagName(String name) {
372
            return getDelegates(HTMLPage.this.getElementsByTagName(HTMLPage.this.getRootNode(), name));
1✔
373
        }
374
    }
375

376
    /**
377
     * Gets the scriptable object.
378
     *
379
     * @return the scriptable object
380
     */
381
    Scriptable getScriptableObject() {
382
        if (_scriptable == null) {
1✔
383
            _scriptable = new Scriptable();
1✔
384
            _scriptable.setScriptEngine(getResponse().getScriptableObject().getScriptEngine(_scriptable));
1✔
385
        }
386
        return _scriptable;
1✔
387
    }
388

389
    /**
390
     * parse the given test with the given URL.
391
     *
392
     * @param text
393
     *            the text
394
     * @param pageURL
395
     *            the page URL
396
     *
397
     * @throws SAXException
398
     *             the SAX exception
399
     * @throws IOException
400
     *             Signals that an I/O exception has occurred.
401
     */
402
    public void parse(String text, URL pageURL) throws SAXException, IOException {
403
        HTMLParserFactory.getHTMLParser().parse(pageURL, text, new DocumentAdapter() {
1✔
404
            @Override
405
            public void setDocument(HTMLDocument document) {
406
                HTMLPage.this.setRootNode(document);
1✔
407
            }
1✔
408

409
            @Override
410
            public String getIncludedScript(String srcAttribute) throws IOException {
411
                return HTMLPage.this.getIncludedScript(srcAttribute);
1✔
412
            }
413

414
            @Override
415
            public ScriptingHandler getScriptingHandler() {
416
                return getResponse().getScriptingHandler();
1✔
417
            }
418
        });
419
    }
1✔
420

421
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc