1 /* 2 * Copyright (c) 2013, Opera Software ASA. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Opera Software ASA nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 * OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 33 #include "FrameTestHelpers.h" 34 #include "URLTestHelpers.h" 35 #include "WebFrameClient.h" 36 #include "WebFrameImpl.h" 37 #include "WebSettings.h" 38 #include "WebViewImpl.h" 39 #include <gtest/gtest.h> 40 #include "core/page/Page.h" 41 #include "core/page/PageSerializer.h" 42 #include "platform/SerializedResource.h" 43 #include "public/platform/Platform.h" 44 #include "public/platform/WebString.h" 45 #include "public/platform/WebThread.h" 46 #include "public/platform/WebURL.h" 47 #include "public/platform/WebURLRequest.h" 48 #include "public/platform/WebURLResponse.h" 49 #include "public/platform/WebUnitTestSupport.h" 50 #include "wtf/Vector.h" 51 52 using namespace WebCore; 53 using namespace blink; 54 using blink::FrameTestHelpers::runPendingTasks; 55 using blink::URLTestHelpers::toKURL; 56 using blink::URLTestHelpers::registerMockedURLLoad; 57 58 namespace { 59 60 class TestWebFrameClient : public WebFrameClient { 61 public: 62 virtual ~TestWebFrameClient() { } 63 }; 64 65 class PageSerializerTest : public testing::Test { 66 public: 67 PageSerializerTest() 68 : m_folder(WebString::fromUTF8("pageserializer/")) 69 , m_baseUrl(toKURL("http://www.test.com")) 70 { 71 } 72 73 protected: 74 virtual void SetUp() 75 { 76 // Create and initialize the WebView. 77 m_webViewImpl = toWebViewImpl(WebView::create(0)); 78 79 // We want the images to load and JavaScript to be on. 80 WebSettings* settings = m_webViewImpl->settings(); 81 settings->setImagesEnabled(true); 82 settings->setLoadsImagesAutomatically(true); 83 settings->setJavaScriptEnabled(true); 84 85 m_mainFrame = WebFrame::create(&m_webFrameClient); 86 m_webViewImpl->setMainFrame(m_mainFrame); 87 } 88 89 virtual void TearDown() 90 { 91 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); 92 m_webViewImpl->close(); 93 m_webViewImpl = 0; 94 m_mainFrame->close(); 95 m_mainFrame = 0; 96 } 97 98 void setBaseUrl(const char* url) 99 { 100 m_baseUrl = toKURL(url); 101 } 102 103 void setBaseFolder(const char* folder) 104 { 105 m_folder = WebString::fromUTF8(folder); 106 } 107 108 void registerURL(const char* file, const char* mimeType) 109 { 110 registerMockedURLLoad(KURL(m_baseUrl, file), WebString::fromUTF8(file), m_folder, WebString::fromUTF8(mimeType)); 111 } 112 113 void registerErrorURL(const char* file, int statusCode) 114 { 115 WebURLError error; 116 error.reason = 0xdead + statusCode; 117 error.domain = "PageSerializerTest"; 118 119 WebURLResponse response; 120 response.initialize(); 121 response.setMIMEType("text/html"); 122 response.setHTTPStatusCode(statusCode); 123 124 Platform::current()->unitTestSupport()->registerMockedErrorURL(KURL(m_baseUrl, file), response, error); 125 } 126 127 void serialize(const char* url) 128 { 129 WebURLRequest urlRequest; 130 urlRequest.initialize(); 131 urlRequest.setURL(KURL(m_baseUrl, url)); 132 m_webViewImpl->mainFrame()->loadRequest(urlRequest); 133 // Make sure any pending request get served. 134 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(); 135 // Some requests get delayed, run the timer. 136 runPendingTasks(); 137 // Server the delayed resources. 138 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests(); 139 140 PageSerializer serializer(&m_resources); 141 serializer.serialize(m_webViewImpl->mainFrameImpl()->frame()->page()); 142 } 143 144 Vector<SerializedResource>& getResources() 145 { 146 return m_resources; 147 } 148 149 150 const SerializedResource* getResource(const char* url, const char* mimeType) 151 { 152 KURL kURL = KURL(m_baseUrl, url); 153 String mime(mimeType); 154 for (size_t i = 0; i < m_resources.size(); ++i) { 155 const SerializedResource& resource = m_resources[i]; 156 if (resource.url == kURL && !resource.data->isEmpty() 157 && (mime.isNull() || equalIgnoringCase(resource.mimeType, mime))) 158 return &resource; 159 } 160 return 0; 161 } 162 163 bool isSerialized(const char* url, const char* mimeType = 0) 164 { 165 return getResource(url, mimeType); 166 } 167 168 String getSerializedData(const char* url, const char* mimeType = 0) 169 { 170 const SerializedResource* resource = getResource(url, mimeType); 171 if (resource) 172 return String(resource->data->data(), resource->data->size()); 173 return String(); 174 } 175 176 WebViewImpl* m_webViewImpl; 177 178 private: 179 TestWebFrameClient m_webFrameClient; 180 WebFrame* m_mainFrame; 181 WebString m_folder; 182 KURL m_baseUrl; 183 Vector<SerializedResource> m_resources; 184 }; 185 186 187 TEST_F(PageSerializerTest, InputImage) 188 { 189 setBaseFolder("pageserializer/input-image/"); 190 191 registerURL("input-image.html", "text/html"); 192 registerURL("button.png", "image/png"); 193 registerErrorURL("non-existing-button.png", 404); 194 195 serialize("input-image.html"); 196 197 EXPECT_TRUE(isSerialized("button.png", "image/png")); 198 EXPECT_FALSE(isSerialized("non-existing-button.png", "image/png")); 199 } 200 201 TEST_F(PageSerializerTest, XMLDeclaration) 202 { 203 setBaseFolder("pageserializer/xmldecl/"); 204 205 registerURL("xmldecl.xml", "text/xml"); 206 serialize("xmldecl.xml"); 207 208 String expectedStart("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 209 EXPECT_TRUE(getSerializedData("xmldecl.xml").startsWith(expectedStart)); 210 } 211 212 TEST_F(PageSerializerTest, DTD) 213 { 214 setBaseFolder("pageserializer/dtd/"); 215 216 registerURL("dtd.html", "text/html"); 217 serialize("dtd.html"); 218 219 String expectedStart("<!DOCTYPE html>"); 220 EXPECT_TRUE(getSerializedData("dtd.html").startsWith(expectedStart)); 221 } 222 223 TEST_F(PageSerializerTest, Font) 224 { 225 setBaseFolder("pageserializer/font/"); 226 227 registerURL("font.html", "text/html"); 228 registerURL("font.ttf", "application/octet-stream"); 229 230 serialize("font.html"); 231 232 EXPECT_TRUE(isSerialized("font.ttf", "application/octet-stream")); 233 } 234 235 } 236