一、前言
关于htmlunit源码包中的com.gargoylesoftware.htmlunit.util.UrlUtils资源工具类,进行字符串转为URL对象toUrlSafe、对url地址解密处理encodeUrl、解密处理decode、根据协议及主机/端口等获取URL对象地址getUrlWithNewHost/getUrlWithNewPort/getUrlWithNewPath/getUrlWithNewRef等操作。
二、源码说明
1.UrlUtils类(其中StringUtils参见其他文章)
package com.gargoylesoftware.htmlunit.util;@b@@b@import com.gargoylesoftware.htmlunit.WebAssert;@b@import java.io.UnsupportedEncodingException;@b@import java.net.MalformedURLException;@b@import java.net.URL;@b@import java.util.BitSet;@b@import org.apache.commons.codec.DecoderException;@b@import org.apache.commons.codec.net.URLCodec;@b@@b@public final class UrlUtils@b@{@b@ private static final BitSet PATH_ALLOWED_CHARS = new BitSet(256);@b@ private static final BitSet QUERY_ALLOWED_CHARS = new BitSet(256);@b@ private static final BitSet ANCHOR_ALLOWED_CHARS = new BitSet(256);@b@ private static final URLCreator URL_CREATOR = URLCreator.getCreator();@b@@b@ public static URL toUrlSafe(String url)@b@ {@b@ try@b@ {@b@ return toUrlUnsafe(url);@b@ }@b@ catch (MalformedURLException e)@b@ {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ public static URL toUrlUnsafe(String url)@b@ throws MalformedURLException@b@ {@b@ WebAssert.notNull("url", url);@b@ return URL_CREATOR.toUrlUnsafeClassic(url);@b@ }@b@@b@ public static URL encodeUrl(URL url, boolean minimalQueryEncoding)@b@ {@b@ String p = url.getProtocol();@b@ if (("javascript".equalsIgnoreCase(p)) || ("about".equalsIgnoreCase(p)) || ("data".equalsIgnoreCase(p)))@b@ {@b@ return url;@b@ }@b@ try {@b@ String path = url.getPath();@b@ if (path != null)@b@ path = encode(path, PATH_ALLOWED_CHARS, "utf-8");@b@@b@ String query = url.getQuery();@b@ if (query != null)@b@ if (minimalQueryEncoding) {@b@ query = org.apache.commons.lang.StringUtils.replace(query, " ", "%20");@b@ }@b@ else@b@ query = encode(query, QUERY_ALLOWED_CHARS, "windows-1252");@b@@b@@b@ String anchor = url.getRef();@b@ if (anchor != null)@b@ anchor = encode(anchor, ANCHOR_ALLOWED_CHARS, "utf-8");@b@@b@ return createNewUrl(url.getProtocol(), url.getHost(), url.getPort(), path, anchor, query);@b@ }@b@ catch (MalformedURLException e)@b@ {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ public static String encodeAnchor(String anchor)@b@ {@b@ if (anchor != null)@b@ anchor = encode(anchor, ANCHOR_ALLOWED_CHARS, "utf-8");@b@@b@ return anchor;@b@ }@b@@b@ public static String decode(String escaped)@b@ {@b@ byte[] bytes;@b@ try@b@ {@b@ bytes = escaped.getBytes("US-ASCII");@b@ byte[] bytes2 = URLCodec.decodeUrl(bytes);@b@ return new String(bytes2, "UTF-8");@b@ }@b@ catch (UnsupportedEncodingException e)@b@ {@b@ throw new RuntimeException(e);@b@ }@b@ catch (DecoderException e)@b@ {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ private static String encode(String unescaped, BitSet allowed, String charset)@b@ {@b@ byte[] bytes;@b@ try@b@ {@b@ bytes = unescaped.getBytes(charset);@b@ byte[] bytes2 = URLCodec.encodeUrl(allowed, bytes);@b@ return new String(bytes2, "US-ASCII");@b@ }@b@ catch (UnsupportedEncodingException e)@b@ {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ public static URL getUrlWithNewProtocol(URL u, String newProtocol)@b@ throws MalformedURLException@b@ {@b@ return createNewUrl(newProtocol, u.getHost(), u.getPort(), u.getPath(), u.getRef(), u.getQuery());@b@ }@b@@b@ public static URL getUrlWithNewHost(URL u, String newHost)@b@ throws MalformedURLException@b@ {@b@ return createNewUrl(u.getProtocol(), newHost, u.getPort(), u.getPath(), u.getRef(), u.getQuery());@b@ }@b@@b@ public static URL getUrlWithNewPort(URL u, int newPort)@b@ throws MalformedURLException@b@ {@b@ return createNewUrl(u.getProtocol(), u.getHost(), newPort, u.getPath(), u.getRef(), u.getQuery());@b@ }@b@@b@ public static URL getUrlWithNewPath(URL u, String newPath)@b@ throws MalformedURLException@b@ {@b@ return createNewUrl(u.getProtocol(), u.getHost(), u.getPort(), newPath, u.getRef(), u.getQuery());@b@ }@b@@b@ public static URL getUrlWithNewRef(URL u, String newRef)@b@ throws MalformedURLException@b@ {@b@ return createNewUrl(u.getProtocol(), u.getHost(), u.getPort(), u.getPath(), newRef, u.getQuery());@b@ }@b@@b@ public static URL getUrlWithNewQuery(URL u, String newQuery)@b@ throws MalformedURLException@b@ {@b@ return createNewUrl(u.getProtocol(), u.getHost(), u.getPort(), u.getPath(), u.getRef(), newQuery);@b@ }@b@@b@ private static URL createNewUrl(String protocol, String host, int port, String path, String ref, String query)@b@ throws MalformedURLException@b@ {@b@ StringBuilder s = new StringBuilder();@b@ s.append(protocol);@b@ s.append("://");@b@ s.append(host);@b@ if (port != -1)@b@ s.append(":").append(port);@b@@b@ if ((path != null) && (path.length() > 0)) {@b@ if ('/' != path.charAt(0))@b@ s.append("/");@b@@b@ s.append(path);@b@ }@b@ if (query != null)@b@ s.append("?").append(query);@b@@b@ if (ref != null) {@b@ if ((ref.length() <= 0) || ('#' != ref.charAt(0)))@b@ s.append("#");@b@@b@ s.append(ref);@b@ }@b@ URL url = new URL(s.toString());@b@ return url;@b@ }@b@@b@ public static String resolveUrl(String baseUrl, String relativeUrl)@b@ {@b@ if (baseUrl == null)@b@ throw new IllegalArgumentException("Base URL must not be null");@b@@b@ if (relativeUrl == null)@b@ throw new IllegalArgumentException("Relative URL must not be null");@b@@b@ Url url = resolveUrl(parseUrl(baseUrl.trim()), relativeUrl.trim());@b@@b@ return url.toString();@b@ }@b@@b@ public static String resolveUrl(URL baseUrl, String relativeUrl)@b@ {@b@ if (baseUrl == null)@b@ throw new IllegalArgumentException("Base URL must not be null");@b@@b@ return resolveUrl(baseUrl.toExternalForm(), relativeUrl);@b@ }@b@@b@ private static Url parseUrl(String spec)@b@ {@b@ int locationStartIndex;@b@ int locationEndIndex;@b@ Url url = new Url();@b@ int startIndex = 0;@b@ int endIndex = spec.length();@b@@b@ int crosshatchIndex = StringUtils.indexOf(spec, '#', startIndex, endIndex);@b@@b@ if (crosshatchIndex >= 0) {@b@ Url.access$002(url, spec.substring(crosshatchIndex + 1, endIndex));@b@ endIndex = crosshatchIndex;@b@ }@b@@b@ int colonIndex = StringUtils.indexOf(spec, ':', startIndex, endIndex);@b@@b@ if (colonIndex > 0) {@b@ String scheme = spec.substring(startIndex, colonIndex);@b@ if (isValidScheme(scheme)) {@b@ Url.access$102(url, scheme);@b@ startIndex = colonIndex + 1;@b@ }@b@@b@ }@b@@b@ if (spec.startsWith("//", startIndex)) {@b@ locationStartIndex = startIndex + 2;@b@ locationEndIndex = StringUtils.indexOf(spec, '/', locationStartIndex, endIndex);@b@ if (locationEndIndex >= 0)@b@ startIndex = locationEndIndex;@b@ }@b@ else@b@ {@b@ locationStartIndex = -1;@b@ locationEndIndex = -1;@b@ }@b@@b@ int questionMarkIndex = StringUtils.indexOf(spec, '?', startIndex, endIndex);@b@@b@ if (questionMarkIndex >= 0) {@b@ if ((locationStartIndex >= 0) && (locationEndIndex < 0))@b@ {@b@ locationEndIndex = questionMarkIndex;@b@ startIndex = questionMarkIndex;@b@ }@b@ Url.access$202(url, spec.substring(questionMarkIndex + 1, endIndex));@b@ endIndex = questionMarkIndex;@b@ }@b@@b@ int semicolonIndex = StringUtils.indexOf(spec, ';', startIndex, endIndex);@b@@b@ if (semicolonIndex >= 0) {@b@ if ((locationStartIndex >= 0) && (locationEndIndex < 0))@b@ {@b@ locationEndIndex = semicolonIndex;@b@ startIndex = semicolonIndex;@b@ }@b@ Url.access$302(url, spec.substring(semicolonIndex + 1, endIndex));@b@ endIndex = semicolonIndex;@b@ }@b@@b@ if ((locationStartIndex >= 0) && (locationEndIndex < 0))@b@ {@b@ locationEndIndex = endIndex;@b@ }@b@ else if (startIndex < endIndex) {@b@ Url.access$402(url, spec.substring(startIndex, endIndex));@b@ }@b@@b@ if ((locationStartIndex >= 0) && (locationEndIndex >= 0))@b@ Url.access$502(url, spec.substring(locationStartIndex, locationEndIndex));@b@@b@ return url;@b@ }@b@@b@ private static boolean isValidScheme(String scheme)@b@ {@b@ int length = scheme.length();@b@ if (length < 1)@b@ return false;@b@@b@ char c = scheme.charAt(0);@b@ if (!(Character.isLetter(c)))@b@ return false;@b@@b@ for (int i = 1; i < length; ++i) {@b@ c = scheme.charAt(i);@b@ if ((!(Character.isLetterOrDigit(c))) && (c != '.') && (c != '+') && (c != '-'))@b@ return false;@b@ }@b@@b@ return true;@b@ }@b@@b@ private static Url resolveUrl(Url baseUrl, String relativeUrl)@b@ {@b@ int pathSegmentIndex;@b@ String pathSegment;@b@ int slashIndex;@b@ Url url = parseUrl(relativeUrl);@b@@b@ if (baseUrl == null) {@b@ return url;@b@ }@b@@b@ if (relativeUrl.length() == 0) {@b@ return new Url(baseUrl);@b@ }@b@@b@ if (Url.access$100(url) != null) {@b@ return url;@b@ }@b@@b@ Url.access$102(url, Url.access$100(baseUrl));@b@@b@ if (Url.access$500(url) != null)@b@ return url;@b@@b@ Url.access$502(url, Url.access$500(baseUrl));@b@@b@ if ((Url.access$400(url) != null) && (Url.access$400(url).length() > 0) && ('/' == Url.access$400(url).charAt(0))) {@b@ Url.access$402(url, removeLeadingSlashPoints(Url.access$400(url)));@b@ return url;@b@ }@b@@b@ if (Url.access$400(url) == null) {@b@ Url.access$402(url, Url.access$400(baseUrl));@b@@b@ if (Url.access$300(url) != null)@b@ return url;@b@@b@ Url.access$302(url, Url.access$300(baseUrl));@b@@b@ if (Url.access$200(url) != null)@b@ return url;@b@@b@ Url.access$202(url, Url.access$200(baseUrl));@b@ return url;@b@ }@b@@b@ String basePath = Url.access$400(baseUrl);@b@ String path = "";@b@@b@ if (basePath != null) {@b@ int lastSlashIndex = basePath.lastIndexOf(47);@b@@b@ if (lastSlashIndex >= 0)@b@ path = basePath.substring(0, lastSlashIndex + 1);@b@ }@b@ else@b@ {@b@ path = "/";@b@ }@b@ path = path.concat(Url.access$400(url));@b@@b@ while ((pathSegmentIndex = path.indexOf("/./")) >= 0) {@b@ path = path.substring(0, pathSegmentIndex + 1).concat(path.substring(pathSegmentIndex + 3));@b@ }@b@@b@ if (path.endsWith("/.")) {@b@ path = path.substring(0, path.length() - 1);@b@ }@b@@b@ while (true)@b@ {@b@ while (true)@b@ {@b@ if ((pathSegmentIndex = path.indexOf("/../")) <= 0) break label363;@b@ pathSegment = path.substring(0, pathSegmentIndex);@b@ slashIndex = pathSegment.lastIndexOf(47);@b@@b@ if (slashIndex >= 0)@b@ break;@b@ }@b@ if (!("..".equals(pathSegment.substring(slashIndex)))) {@b@ path = path.substring(0, slashIndex + 1).concat(path.substring(pathSegmentIndex + 4));@b@ }@b@@b@ }@b@@b@ if (path.endsWith("/..")) {@b@ label363: pathSegment = path.substring(0, path.length() - 3);@b@ slashIndex = pathSegment.lastIndexOf(47);@b@@b@ if (slashIndex >= 0)@b@ path = path.substring(0, slashIndex + 1);@b@@b@ }@b@@b@ path = removeLeadingSlashPoints(path);@b@@b@ Url.access$402(url, path);@b@@b@ return url;@b@ }@b@@b@ private static String removeLeadingSlashPoints(String path)@b@ {@b@ while (path.startsWith("/..")) {@b@ path = path.substring(3);@b@ }@b@@b@ return path;@b@ }@b@@b@ static@b@ {@b@ BitSet reserved = new BitSet(256);@b@ reserved.set(59);@b@ reserved.set(47);@b@ reserved.set(63);@b@ reserved.set(58);@b@ reserved.set(64);@b@ reserved.set(38);@b@ reserved.set(61);@b@ reserved.set(43);@b@ reserved.set(36);@b@ reserved.set(44);@b@@b@ BitSet mark = new BitSet(256);@b@ mark.set(45);@b@ mark.set(95);@b@ mark.set(46);@b@ mark.set(33);@b@ mark.set(126);@b@ mark.set(42);@b@ mark.set(39);@b@ mark.set(40);@b@ mark.set(41);@b@@b@ BitSet alpha = new BitSet(256);@b@ for (int i = 97; i <= 122; ++i)@b@ alpha.set(i);@b@@b@ for (i = 65; i <= 90; ++i) {@b@ alpha.set(i);@b@ }@b@@b@ BitSet digit = new BitSet(256);@b@ for (int i = 48; i <= 57; ++i) {@b@ digit.set(i);@b@ }@b@@b@ BitSet alphanumeric = new BitSet(256);@b@ alphanumeric.or(alpha);@b@ alphanumeric.or(digit);@b@@b@ BitSet unreserved = new BitSet(256);@b@ unreserved.or(alphanumeric);@b@ unreserved.or(mark);@b@@b@ BitSet hex = new BitSet(256);@b@ hex.or(digit);@b@ for (int i = 97; i <= 102; ++i)@b@ hex.set(i);@b@@b@ for (i = 65; i <= 70; ++i) {@b@ hex.set(i);@b@ }@b@@b@ BitSet escaped = new BitSet(256);@b@ escaped.set(37);@b@ escaped.or(hex);@b@@b@ BitSet uric = new BitSet(256);@b@ uric.or(reserved);@b@ uric.or(unreserved);@b@ uric.or(escaped);@b@@b@ BitSet pchar = new BitSet(256);@b@ pchar.or(unreserved);@b@ pchar.or(escaped);@b@ pchar.set(58);@b@ pchar.set(64);@b@ pchar.set(38);@b@ pchar.set(61);@b@ pchar.set(43);@b@ pchar.set(36);@b@ pchar.set(44);@b@@b@ BitSet param = pchar;@b@@b@ BitSet segment = new BitSet(256);@b@ segment.or(pchar);@b@ segment.set(59);@b@ segment.or(param);@b@@b@ BitSet pathSegments = new BitSet(256);@b@ pathSegments.set(47);@b@ pathSegments.or(segment);@b@@b@ BitSet absPath = new BitSet(256);@b@ absPath.set(47);@b@ absPath.or(pathSegments);@b@@b@ BitSet allowedAbsPath = new BitSet(256);@b@ allowedAbsPath.or(absPath);@b@@b@ BitSet allowedFragment = new BitSet(256);@b@ allowedFragment.or(uric);@b@@b@ BitSet allowedQuery = new BitSet(256);@b@ allowedQuery.or(uric);@b@@b@ PATH_ALLOWED_CHARS.or(allowedAbsPath);@b@ QUERY_ALLOWED_CHARS.or(allowedQuery);@b@ ANCHOR_ALLOWED_CHARS.or(allowedFragment);@b@ }@b@@b@ private static class Url@b@ {@b@ private String scheme_;@b@ private String location_;@b@ private String path_;@b@ private String parameters_;@b@ private String query_;@b@ private String fragment_;@b@@b@ public Url()@b@ {@b@ }@b@@b@ public Url(Url url)@b@ {@b@ this.scheme_ = url.scheme_;@b@ this.location_ = url.location_;@b@ this.path_ = url.path_;@b@ this.parameters_ = url.parameters_;@b@ this.query_ = url.query_;@b@ this.fragment_ = url.fragment_;@b@ }@b@@b@ public String toString()@b@ {@b@ StringBuilder sb = new StringBuilder();@b@@b@ if (this.scheme_ != null) {@b@ sb.append(this.scheme_);@b@ sb.append(':');@b@ }@b@ if (this.location_ != null) {@b@ sb.append("//");@b@ sb.append(this.location_);@b@ }@b@ if (this.path_ != null)@b@ sb.append(this.path_);@b@@b@ if (this.parameters_ != null) {@b@ sb.append(';');@b@ sb.append(this.parameters_);@b@ }@b@ if (this.query_ != null) {@b@ sb.append('?');@b@ sb.append(this.query_);@b@ }@b@ if (this.fragment_ != null) {@b@ sb.append('#');@b@ sb.append(this.fragment_);@b@ }@b@ return sb.toString();@b@ }@b@ }@b@}
2.WebAssert类
package com.gargoylesoftware.htmlunit;@b@@b@import com.gargoylesoftware.htmlunit.html.HtmlAnchor;@b@import com.gargoylesoftware.htmlunit.html.HtmlElement;@b@import com.gargoylesoftware.htmlunit.html.HtmlInput;@b@import com.gargoylesoftware.htmlunit.html.HtmlPage;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.List;@b@@b@public final class WebAssert@b@{@b@ public static void assertTitleEquals(HtmlPage page, String title)@b@ {@b@ String s = page.getTitleText();@b@ if (!(s.equals(title))) {@b@ String msg = "Actual page title '" + s + "' does not match expected page title '" + title + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertTitleContains(HtmlPage page, String titlePortion)@b@ {@b@ String s = page.getTitleText();@b@ if (s.indexOf(titlePortion) == -1) {@b@ String msg = "Page title '" + s + "' does not contain the substring '" + titlePortion + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertTitleMatches(HtmlPage page, String regex)@b@ {@b@ String s = page.getTitleText();@b@ if (!(s.matches(regex))) {@b@ String msg = "Page title '" + s + "' does not match the regular expression '" + regex + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertElementPresent(HtmlPage page, String id)@b@ {@b@ try@b@ {@b@ page.getHtmlElementById(id);@b@ }@b@ catch (ElementNotFoundException e) {@b@ String msg = "The page does not contain an element with ID '" + id + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertElementPresentByXPath(HtmlPage page, String xpath)@b@ {@b@ List elements = page.getByXPath(xpath);@b@ if (elements.isEmpty()) {@b@ String msg = "The page does not contain any elements matching the XPath expression '" + xpath + "'.";@b@@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertElementNotPresent(HtmlPage page, String id)@b@ {@b@ try@b@ {@b@ page.getHtmlElementById(id);@b@ }@b@ catch (ElementNotFoundException e) {@b@ return;@b@ }@b@ String msg = "The page contains an element with ID '" + id + "'.";@b@ throw new AssertionError(msg);@b@ }@b@@b@ public static void assertElementNotPresentByXPath(HtmlPage page, String xpath)@b@ {@b@ List elements = page.getByXPath(xpath);@b@ if (!(elements.isEmpty())) {@b@ String msg = "The page does not contain any elements matching the XPath expression '" + xpath + "'.";@b@@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertTextPresent(HtmlPage page, String text)@b@ {@b@ if (page.asText().indexOf(text) == -1) {@b@ String msg = "The page does not contain the text '" + text + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertTextPresentInElement(HtmlPage page, String text, String id)@b@ {@b@ HtmlElement element;@b@ String msg;@b@ try@b@ {@b@ element = page.getHtmlElementById(id);@b@ if (element.asText().indexOf(text) == -1) {@b@ msg = "The element with ID '" + id + "' does not contain the text '" + text + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@ catch (ElementNotFoundException e) {@b@ msg = "Unable to verify that the element with ID '" + id + "' contains the text '" + text + "' because the specified element does not exist.";@b@@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertTextNotPresent(HtmlPage page, String text)@b@ {@b@ if (page.asText().contains(text)) {@b@ String msg = "The page contains the text '" + text + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertTextNotPresentInElement(HtmlPage page, String text, String id)@b@ {@b@ HtmlElement element;@b@ String msg;@b@ try@b@ {@b@ element = page.getHtmlElementById(id);@b@ if (element.asText().contains(text)) {@b@ msg = "The element with ID '" + id + "' contains the text '" + text + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@ catch (ElementNotFoundException e) {@b@ msg = "Unable to verify that the element with ID '" + id + "' does not contain the text '" + text + "' because the specified element does not exist.";@b@@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertLinkPresent(HtmlPage page, String id)@b@ {@b@ try@b@ {@b@ page.getDocumentElement().getOneHtmlElementByAttribute("a", "id", id);@b@ }@b@ catch (ElementNotFoundException e) {@b@ String msg = "The page does not contain a link with ID '" + id + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertLinkNotPresent(HtmlPage page, String id)@b@ {@b@ try@b@ {@b@ page.getDocumentElement().getOneHtmlElementByAttribute("a", "id", id);@b@@b@ String msg = "The page contains a link with ID '" + id + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ catch (ElementNotFoundException e)@b@ {@b@ }@b@ }@b@@b@ public static void assertLinkPresentWithText(HtmlPage page, String text)@b@ {@b@ boolean found = false;@b@ for (HtmlAnchor a : page.getAnchors())@b@ if (a.asText().contains(text)) {@b@ found = true;@b@ break;@b@ }@b@@b@ if (!(found)) {@b@ String msg = "The page does not contain a link with text '" + text + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertLinkNotPresentWithText(HtmlPage page, String text)@b@ {@b@ boolean found = false;@b@ for (HtmlAnchor a : page.getAnchors())@b@ if (a.asText().contains(text)) {@b@ found = true;@b@ break;@b@ }@b@@b@ if (found) {@b@ String msg = "The page contains a link with text '" + text + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertFormPresent(HtmlPage page, String name)@b@ {@b@ try@b@ {@b@ page.getFormByName(name);@b@ }@b@ catch (ElementNotFoundException e) {@b@ String msg = "The page does not contain a form named '" + name + "'.";@b@ throw new AssertionError(msg);@b@ }@b@ }@b@@b@ public static void assertFormNotPresent(HtmlPage page, String name)@b@ {@b@ try@b@ {@b@ page.getFormByName(name);@b@ }@b@ catch (ElementNotFoundException e) {@b@ return;@b@ }@b@ String msg = "The page contains a form named '" + name + "'.";@b@ throw new AssertionError(msg);@b@ }@b@@b@ public static void assertInputPresent(HtmlPage page, String name)@b@ {@b@ String xpath = "//input[@name='" + name + "']";@b@ List list = page.getByXPath(xpath);@b@ if (list.isEmpty())@b@ throw new AssertionError("Unable to find an input element named '" + name + "'.");@b@ }@b@@b@ public static void assertInputNotPresent(HtmlPage page, String name)@b@ {@b@ String xpath = "//input[@name='" + name + "']";@b@ List list = page.getByXPath(xpath);@b@ if (!(list.isEmpty()))@b@ throw new AssertionError("Unable to find an input element named '" + name + "'.");@b@ }@b@@b@ public static void assertInputContainsValue(HtmlPage page, String name, String value)@b@ {@b@ String xpath = "//input[@name='" + name + "']";@b@ List list = page.getByXPath(xpath);@b@ if (list.isEmpty())@b@ throw new AssertionError("Unable to find an input element named '" + name + "'.");@b@@b@ HtmlInput input = (HtmlInput)list.get(0);@b@ String s = input.getValueAttribute();@b@ if (!(s.equals(value)))@b@ throw new AssertionError("The input element named '" + name + "' contains the value '" + s + "', not the expected value '" + value + "'.");@b@ }@b@@b@ public static void assertInputDoesNotContainValue(HtmlPage page, String name, String value)@b@ {@b@ String xpath = "//input[@name='" + name + "']";@b@ List list = page.getByXPath(xpath);@b@ if (list.isEmpty())@b@ throw new AssertionError("Unable to find an input element named '" + name + "'.");@b@@b@ HtmlInput input = (HtmlInput)list.get(0);@b@ String s = input.getValueAttribute();@b@ if (s.equals(value))@b@ throw new AssertionError("The input element named '" + name + "' contains the value '" + s + "', not the expected value '" + value + "'.");@b@ }@b@@b@ public static void assertAllTabIndexAttributesSet(HtmlPage page)@b@ {@b@ List tags = Arrays.asList(new String[] { "a", "area", "button", "input", "object", "select", "textarea" });@b@@b@ for (HtmlElement element : page.getDocumentElement().getHtmlElementsByTagNames(tags)) {@b@ Short tabIndex = element.getTabIndex();@b@ if ((tabIndex == null) || (tabIndex == HtmlElement.TAB_INDEX_OUT_OF_BOUNDS)) {@b@ String s = element.getAttribute("tabindex");@b@ throw new AssertionError("Illegal value for tab index: '" + s + "'.");@b@ }@b@ }@b@ }@b@@b@ public static void assertAllAccessKeyAttributesUnique(HtmlPage page)@b@ {@b@ List list = new ArrayList();@b@ for (HtmlElement element : page.getHtmlElementDescendants()) {@b@ String key = element.getAttribute("accesskey");@b@ if ((key != null) && (key.length() != 0)) {@b@ if (list.contains(key))@b@ throw new AssertionError("The access key '" + key + "' is not unique.");@b@@b@ list.add(key);@b@ }@b@ }@b@ }@b@@b@ public static void assertAllIdAttributesUnique(HtmlPage page)@b@ {@b@ List list = new ArrayList();@b@ for (HtmlElement element : page.getHtmlElementDescendants()) {@b@ String id = element.getAttribute("id");@b@ if ((id != null) && (id.length() != 0)) {@b@ if (list.contains(id))@b@ throw new AssertionError("The element ID '" + id + "' is not unique.");@b@@b@ list.add(id);@b@ }@b@ }@b@ }@b@@b@ public static void notNull(String description, Object object)@b@ {@b@ if (object == null)@b@ throw new NullPointerException(description);@b@ }@b@}