Java tutorial
/* * Copyright (c) 2002-2016 Gargoyle Software Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gargoylesoftware.htmlunit.html; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; import com.gargoylesoftware.htmlunit.CollectingAlertHandler; import com.gargoylesoftware.htmlunit.MockWebConnection; import com.gargoylesoftware.htmlunit.SimpleWebTestCase; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.util.NameValuePair; /** * Tests for {@link HtmlPage}. * * @author Ahmed Ashour * @author Marc Guillemot */ @RunWith(BrowserRunner.class) public class HtmlPage2Test extends SimpleWebTestCase { /** * Utility for temporary folders. * Has to be public due to JUnit's constraints for @Rule. */ @Rule public final TemporaryFolder tmpFolderProvider_ = new TemporaryFolder(); /** * Different versions of IE behave differently here. * Distinction is made with * {@link com.gargoylesoftware.htmlunit.BrowserVersionFeatures#JS_FRAME_RESOLVE_URL_WITH_PARENT_WINDOW}. * @throws Exception if the test fails */ @Test @Alerts("25") public void loadExternalJavaScript() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function makeIframe() {\n" + " var iframesrc = '<html><head>';\n" + " iframesrc += '<script src=\"" + "js.js" + "\"></' + 'script>';\n" + " iframesrc += '<script>';\n" + " iframesrc += 'function doSquared(){';\n" + " iframesrc += ' try {';\n" + " iframesrc += ' var y = squared(5);';\n" + " iframesrc += ' alert(y);';\n" + " iframesrc += ' } catch (e) {';\n" + " iframesrc += ' alert(\"error\");';\n" + " iframesrc += ' }'\n" + " iframesrc += '};';\n" + " iframesrc += '</' + 'script>';\n" + " iframesrc += '</head>';\n" + " iframesrc += '<body onLoad=\"doSquared()\" >';\n" + " iframesrc += '</body>';\n" + " iframesrc += '</html>';\n" + " var iframe = document.createElement('IFRAME');\n" + " iframe.id = 'iMessage';\n" + " iframe.name = 'iMessage';\n" + " iframe.src = \"javascript:'\" + iframesrc + \"'\";\n" + " document.body.appendChild(iframe);\n" + "}\n" + "</script></head>\n" + "<body onload='makeIframe()'>\n" + "</body></html>"; final String js = "function squared(n) {return n * n}"; final WebClient webClient = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); webConnection.setResponse(URL_FIRST, html); webConnection.setResponse(new URL(URL_FIRST, "js.js"), js); webClient.setWebConnection(webConnection); final List<String> collectedAlerts = new ArrayList<>(); webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); webClient.getPage(URL_FIRST); assertEquals(getExpectedAlerts(), collectedAlerts); } /** * Differs from {@link #loadExternalJavaScript()} by the absolute reference of the javascript source. * @throws Exception if the test fails */ @Test @Alerts("25") public void loadExternalJavaScript_absolute() throws Exception { final String html = "<html><head>\n" + "<script>\n" + "function makeIframe() {\n" + " var iframesrc = '<html><head>';\n" + " iframesrc += '<script src=\"" + URL_SECOND + "\"></' + 'script>';\n" + " iframesrc += '<script>';\n" + " iframesrc += 'function doSquared(){';\n" + " iframesrc += ' try {';\n" + " iframesrc += ' var y = squared(5);';\n" + " iframesrc += ' alert(y);';\n" + " iframesrc += ' } catch (e) {';\n" + " iframesrc += ' alert(\"error\");';\n" + " iframesrc += ' }'\n" + " iframesrc += '};';\n" + " iframesrc += '</' + 'script>';\n" + " iframesrc += '</head>';\n" + " iframesrc += '<body onLoad=\"doSquared()\" >';\n" + " iframesrc += '</body>';\n" + " iframesrc += '</html>';\n" + " var iframe = document.createElement('IFRAME');\n" + " iframe.id = 'iMessage';\n" + " iframe.name = 'iMessage';\n" + " iframe.src = \"javascript:'\" + iframesrc + \"'\";\n" + " document.body.appendChild(iframe);\n" + "}\n" + "</script></head>\n" + "<body onload='makeIframe()'>\n" + "</body></html>"; final String js = "function squared(n) {return n * n}"; final WebClient webClient = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); webConnection.setResponse(URL_FIRST, html); webConnection.setResponse(URL_SECOND, js); webClient.setWebConnection(webConnection); final List<String> collectedAlerts = new ArrayList<>(); webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); webClient.getPage(URL_FIRST); assertEquals(getExpectedAlerts(), collectedAlerts); } /** * @throws Exception if the test fails */ @Test public void getFullQualifiedUrl_topWindow() throws Exception { final String firstHtml = "<html><head><title>first</title>\n" + "<script>\n" + " function init() {\n" + " var iframe = window.frames['f'];\n" + " iframe.document.write(\"<form name='form' action='" + URL_SECOND + "'>" + "<input name='submit' type='submit'></form>\");\n" + " iframe.document.close();\n" + " }\n" + "</script></head>\n" + "<body onload='init()'>\n" + " <iframe name='f'></iframe>\n" + "</body></html>"; final String secondHtml = "<html><head><title>second</title></head>" + "<body><p>Form submitted successfully.</p></body></html>"; final WebClient client = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); webConnection.setResponse(URL_FIRST, firstHtml); webConnection.setDefaultResponse(secondHtml); client.setWebConnection(webConnection); final HtmlPage page = client.getPage(URL_FIRST); HtmlPage framePage = (HtmlPage) page.getFrameByName("f").getEnclosedPage(); final HtmlForm form = framePage.getFormByName("form"); final HtmlInput submit = form.getInputByName("submit"); framePage = submit.click(); assertEquals("Form submitted successfully.", framePage.getBody().asText()); } /** * @throws Exception if the test fails */ @Test @Alerts("Hello there") public void save() throws Exception { final String html = "<html><head><script src='" + URL_SECOND + "'>\n</script></head></html>"; final String js = "alert('Hello there')"; final WebClient webClient = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); webConnection.setResponse(URL_FIRST, html); webConnection.setResponse(URL_SECOND, js); webClient.setWebConnection(webConnection); final List<String> collectedAlerts = new ArrayList<>(); webClient.setAlertHandler(new CollectingAlertHandler(collectedAlerts)); final HtmlPage page = webClient.getPage(URL_FIRST); assertEquals(getExpectedAlerts(), collectedAlerts); final HtmlScript sript = page.getFirstByXPath("//script"); assertEquals(URL_SECOND.toString(), sript.getSrcAttribute()); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final String content = FileUtils.readFileToString(file); assertFalse(content.contains("<script")); assertEquals(URL_SECOND.toString(), sript.getSrcAttribute()); } /** * @throws Exception if the test fails */ @Test public void save_image() throws Exception { final String html = "<html><body><img src='" + URL_SECOND + "'></body></html>"; final URL url = getClass().getClassLoader().getResource("testfiles/tiny-jpg.img"); final FileInputStream fis = new FileInputStream(new File(url.toURI())); final byte[] directBytes = IOUtils.toByteArray(fis); fis.close(); final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, html); final List<NameValuePair> emptyList = Collections.emptyList(); webConnection.setResponse(URL_SECOND, directBytes, 200, "ok", "image/jpg", emptyList); final HtmlPage page = webClient.getPage(URL_FIRST); final HtmlImage img = page.getFirstByXPath("//img"); assertEquals(URL_SECOND.toString(), img.getSrcAttribute()); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save2.html"); final File imgFile = new File(tmpFolder, "hu_HtmlPageTest_save2/second.jpeg"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final byte[] loadedBytes = FileUtils.readFileToByteArray(imgFile); assertTrue(loadedBytes.length > 0); assertEquals(URL_SECOND.toString(), img.getSrcAttribute()); } /** * As of 24.05.2011 an IOException was occurring when saving a page where * the response to the request for an image was not an image. * @throws Exception if the test fails */ @Test public void save_imageNotImage() throws Exception { final String html = "<html><body><img src='foo.txt'></body></html>"; final MockWebConnection webConnection = getMockWebConnection(); webConnection.setDefaultResponse("hello", "text/plain"); final HtmlPage page = loadPageWithAlerts(html); final File folder = tmpFolderProvider_.newFolder("hu"); final File file = new File(folder, "hu_save.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final File imgFile = new File(folder, "hu_save/foo.txt"); assertEquals("hello", FileUtils.readFileToString(imgFile, "UTF-8")); } /** * @throws Exception if the test fails */ @Test public void save_image_without_src() throws Exception { final String html = "<html><body><img></body></html>"; final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, html); final HtmlPage page = webClient.getPage(URL_FIRST); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save3.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final HtmlImage img = page.getFirstByXPath("//img"); assertEquals(DomElement.ATTRIBUTE_NOT_DEFINED, img.getSrcAttribute()); } /** * @throws Exception if the test fails */ @Test public void save_image_empty_src() throws Exception { final String html = "<html><body><img src=''></body></html>"; final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, html); final HtmlPage page = webClient.getPage(URL_FIRST); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save3.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final HtmlImage img = page.getFirstByXPath("//img"); assertEquals(DomElement.ATTRIBUTE_NOT_DEFINED, img.getSrcAttribute()); } /** * @throws Exception if the test fails */ @Test public void save_frames() throws Exception { final String mainContent = "<html><head><title>First</title></head>\n" + "<frameset cols='50%,*'>\n" + " <frame name='left' src='" + URL_SECOND + "' frameborder='1' />\n" + " <frame name='right' src='" + URL_THIRD + "' frameborder='1' />\n" + " <frame name='withoutsrc' />\n" + "</frameset>\n" + "</html>"; final String frameLeftContent = "<html><head><title>Second</title></head><body>\n" + "<iframe src='iframe.html'></iframe>\n" + "<img src='img.jpg'>\n" + "</body></html>"; final String frameRightContent = "<html><head><title>Third</title></head><body>frame right</body></html>"; final String iframeContent = "<html><head><title>Iframe</title></head><body>iframe</body></html>"; final InputStream is = getClass().getClassLoader().getResourceAsStream("testfiles/tiny-jpg.img"); final byte[] directBytes = IOUtils.toByteArray(is); is.close(); final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, mainContent); webConnection.setResponse(URL_SECOND, frameLeftContent); webConnection.setResponse(URL_THIRD, frameRightContent); final URL urlIframe = new URL(URL_SECOND, "iframe.html"); webConnection.setResponse(urlIframe, iframeContent); final List<NameValuePair> emptyList = Collections.emptyList(); final URL urlImage = new URL(URL_SECOND, "img.jpg"); webConnection.setResponse(urlImage, directBytes, 200, "ok", "image/jpg", emptyList); final HtmlPage page = webClient.getPage(URL_FIRST); final HtmlFrame leftFrame = page.getElementByName("left"); assertEquals(URL_SECOND.toString(), leftFrame.getSrcAttribute()); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_saveFrame.html"); final File expectedLeftFrameFile = new File(tmpFolder, "hu_HtmlPageTest_saveFrame/second.html"); final File expectedRightFrameFile = new File(tmpFolder, "hu_HtmlPageTest_saveFrame/third.html"); final File expectedIFrameFile = new File(tmpFolder, "hu_HtmlPageTest_saveFrame/second/iframe.html"); final File expectedImgFile = new File(tmpFolder, "hu_HtmlPageTest_saveFrame/second/img.jpg"); final File[] allFiles = { file, expectedLeftFrameFile, expectedImgFile, expectedIFrameFile, expectedRightFrameFile }; page.save(file); for (final File f : allFiles) { assertTrue(f.toString(), f.exists()); assertTrue(f.toString(), f.isFile()); } final byte[] loadedBytes = FileUtils.readFileToByteArray(expectedImgFile); assertTrue(loadedBytes.length > 0); // ensure that saving the page hasn't changed the DOM assertEquals(URL_SECOND.toString(), leftFrame.getSrcAttribute()); } /** * @throws Exception if the test fails */ @Test public void save_css() throws Exception { final String html = "<html><head>" + "<link rel='stylesheet' type='text/css' href='" + URL_SECOND + "'/></head></html>"; final String css = "body {color: blue}"; final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, html); webConnection.setResponse(URL_SECOND, css); final HtmlPage page = webClient.getPage(URL_FIRST); final HtmlLink cssLink = page.getFirstByXPath("//link"); assertEquals(URL_SECOND.toString(), cssLink.getHrefAttribute()); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save4.html"); final File cssFile = new File(tmpFolder, "hu_HtmlPageTest_save4/second.css"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); assertEquals(css, FileUtils.readFileToString(cssFile)); assertEquals(URL_SECOND.toString(), cssLink.getHrefAttribute()); } /** * @throws Exception if the test fails */ @Test public void save_css_without_href() throws Exception { final String html = "<html><head>" + "<link rel='stylesheet' type='text/css' /></head></html>"; final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, html); final HtmlPage page = webClient.getPage(URL_FIRST); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save5.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final HtmlLink cssLink = page.getFirstByXPath("//link"); assertEquals(DomElement.ATTRIBUTE_NOT_DEFINED, cssLink.getHrefAttribute()); } /** * @throws Exception if the test fails */ @Test public void save_css_empty_href() throws Exception { final String html = "<html><head>" + "<link rel='stylesheet' type='text/css' href='' /></head></html>"; final WebClient webClient = getWebClientWithMockWebConnection(); final MockWebConnection webConnection = getMockWebConnection(); webConnection.setResponse(URL_FIRST, html); final HtmlPage page = webClient.getPage(URL_FIRST); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save5.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); final HtmlLink cssLink = page.getFirstByXPath("//link"); assertEquals(DomElement.ATTRIBUTE_NOT_DEFINED, cssLink.getHrefAttribute()); } /** * This was producing java.io.IOException: File name too long as of HtmlUnit-2.9. * Many file systems have a limit 255 byte for file names. * @throws Exception if the test fails */ @Test public void saveShouldStripLongFileNames() throws Exception { final String longName = RandomStringUtils.randomAlphabetic(500) + ".html"; final String html = "<html><body><iframe src='" + longName + "'></iframe></body></html>"; final WebClient webClient = getWebClient(); final MockWebConnection webConnection = new MockWebConnection(); webConnection.setDefaultResponse("<html/>"); webConnection.setResponse(URL_FIRST, html); webClient.setWebConnection(webConnection); final HtmlPage page = webClient.getPage(URL_FIRST); final File tmpFolder = tmpFolderProvider_.newFolder("hu"); final File file = new File(tmpFolder, "hu_HtmlPageTest_save.html"); page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); } /** * @throws Exception if the test fails */ @Test public void serialization_attributeListenerLock() throws Exception { final String html = "<html><head><script>" + "function foo() {" + " document.getElementById('aframe').src = '" + URL_FIRST + "';" + " return false;" + "}</script>" + "<body><iframe src='about:blank' id='aframe'></iframe>" + "<a href='#' onclick='foo()' id='link'>load iframe</a></body></html>"; final HtmlPage page = loadPageWithAlerts(html); final WebClient copy = clone(page.getWebClient()); final HtmlPage copyPage = (HtmlPage) copy.getCurrentWindow().getTopWindow().getEnclosedPage(); copyPage.getHtmlElementById("link").click(); assertEquals(URL_FIRST.toExternalForm(), copyPage.getElementById("aframe").getAttribute("src")); } /** * @throws Exception if the test fails */ @Test public void save_emptyTextArea() throws Exception { final String html = "<html>\n" + "<head/>\n" + "<body>\n" + "<textarea></textarea>\n" + "</body>\n" + "</html>"; final HtmlPage page = loadPage(html); final File tmpFolder = new File(System.getProperty("java.io.tmpdir")); final File file = new File(tmpFolder, "hu_HtmlPage2Test_save_emptyTextArea.html"); try { page.save(file); assertTrue(file.exists()); assertTrue(file.isFile()); assertTrue(page.asXml().contains("</textarea>")); assertTrue(FileUtils.readFileToString(file).contains("</textarea>")); } finally { file.delete(); } } }