这个 ClassCastException 是一个 HtmlUnit 错误吗?

Is this ClassCastException a HtmlUnit bug?

我是 htmlunit (2.23) 的新手,我无法让这个测试工作: 我正在从 HtmlUnit 中抛出这个 ClassCastException,我不知道这是一个错误,还是我做错了什么。

java.lang.ClassCastException: com.gargoylesoftware.htmlunit.TextPage cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlPage at com.gargoylesoftware.htmlunit.WebClient.makeWebResponseForJavaScriptUrl(WebClient.java:1241) at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:375) at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:304) at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:451) at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:436) at org.wyttenbach.dale.mlec.OutageTest.test(OutageTest.java:46) ...

代码

import java.awt.Desktop;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Test;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.JavaScriptPage;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.TextPage;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class OutageTest {

  private static final String SITE_URL = "https://ebill.mlecmn.net/woViewer/";

  private static final String OUTAGE_MAP_URL = SITE_URL + "mapviewer.html?config=Outage+Web+Map";

  @Test
  public void test() throws FailingHttpStatusCodeException, MalformedURLException, IOException {
    try (final WebClient webClient = new WebClient()) {
      webClient.waitForBackgroundJavaScript(20000);
      webClient.setAjaxController(new NicelyResynchronizingAjaxController());
      webClient.getOptions().setUseInsecureSSL(true);
      Map<String, Page> urls = new HashMap<String, Page>();
      LinkedList<String> urlsToVisit = new LinkedList<String>();
      urlsToVisit.add(OUTAGE_MAP_URL);
      while (!urlsToVisit.isEmpty()) {
        String url = urlsToVisit.remove();
        if (urls.containsKey(url)) {
          continue;
        }
        Page page = webClient.getPage(url);
        urls.put(url, page);
        if (page instanceof HtmlPage) {
          HtmlPage page2 = (HtmlPage) page;
          System.err.println("================================================================");
          System.err.println(page2.asXml());
          System.err.println("================================================================");
          Assert.assertFalse("Outage in Nordland township: " + url, page2.asText().contains("Nordland"));
          urlsToVisit.addAll(extractLinks(page2));
        } else if (page instanceof JavaScriptPage) {
          JavaScriptPage page2 = (JavaScriptPage) page;  
          Assert.assertFalse("Outage in Nordland township: " + url, page2.getContent().contains("Nordland"));
        } else if (page instanceof TextPage) {
          TextPage page2 = (TextPage) page;  
          Assert.assertFalse("Outage in Nordland township: " + url, page2.getContent().contains("Nordland"));
        } else {
          System.err.println(String.format("%s => %s", url, page.getClass().getName()));
        }
      }
    } catch (AssertionError e) {
      reportOutage();
      throw e;
    }
  }

  private Collection<String> extractLinks(HtmlPage page) {
    List<String> links = new ArrayList<String>();
    for (DomElement x : page.getElementsByTagName("script")) {
      String src = x.getAttribute("src");
      if (!src.contains(":")) {
        src = SITE_URL + src;
        System.err.println("script src="+src);
      }
      links.add(src);
    }
    for (DomElement x : page.getElementsByTagName("link")) {
      String href = x.getAttribute("href");
      if (!href.contains(":")) {
        href = SITE_URL + href;
        System.err.println("link href="+href);
      }
      links.add(href);
    }
    // Causes ClassCastException com.gargoylesoftware.htmlunit.TextPage cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlPage
    //at com.gargoylesoftware.htmlunit.WebClient.makeWebResponseForJavaScriptUrl(WebClient.java:1241)
    for (DomElement x : page.getElementsByTagName("iframe")) {
      String src = x.getAttribute("src");
      if (!src.contains(":")) {
        src = SITE_URL + src;
        System.err.println("iframe src="+src);
      }
      links.add(src);
    }
    return links;
  }

  private void reportOutage()  {
    try {
      Desktop.getDesktop().browse(new URI(OUTAGE_MAP_URL));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

或多或少是的 - 但我必须做更深入的分析。 但你还是有希望的 ;-)

您的代码尝试从给定网页中提取 urls。在此过程中,您将 url 'javascript:""' 添加到要处理的 url 列表中。此 url 导致此 class 转换异常。如果您不将此 url 添加到列表中,则测试有效(至少对我而言)。