2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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 Apple Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "DumpRenderTree.h"
32 #include "EditingDelegate.h"
33 #include "FrameLoadDelegate.h"
34 #include "HistoryDelegate.h"
35 #include "JavaScriptThreading.h"
36 #include "PixelDumpSupport.h"
37 #include "PolicyDelegate.h"
38 #include "ResourceLoadDelegate.h"
39 #include "TestRunner.h"
40 #include "UIDelegate.h"
41 #include "WebCoreTestSupport.h"
42 #include "WorkQueueItem.h"
43 #include "WorkQueue.h"
53 #include <wtf/RetainPtr.h>
54 #include <wtf/Vector.h>
56 #include <CoreFoundation/CoreFoundation.h>
57 #include <WebCore/FileSystem.h>
58 #include <WebKit/WebKit.h>
59 #include <WebKit/WebKitCOMAPI.h>
62 #include <CFNetwork/CFHTTPCookiesPriv.h>
63 #include <CFNetwork/CFURLCachePriv.h>
69 const LPWSTR TestPluginDir = L"TestNetscapePlugin_Debug";
71 const LPWSTR TestPluginDir = L"TestNetscapePlugin";
74 static LPCWSTR fontsEnvironmentVariable = L"WEBKIT_TESTFONTS";
75 static LPCWSTR dumpRenderTreeTemp = L"DUMPRENDERTREE_TEMP";
78 static CFStringRef WebDatabaseDirectoryDefaultsKey = CFSTR("WebDatabaseDirectory");
79 static CFStringRef WebKitLocalCacheDefaultsKey = CFSTR("WebKitLocalCache");
80 static CFStringRef WebStorageDirectoryDefaultsKey = CFSTR("WebKitLocalStorageDatabasePathPreferenceKey");
82 const LPCWSTR kDumpRenderTreeClassName = L"DumpRenderTreeWindow";
84 static bool dumpTree = true;
85 static bool dumpPixelsForAllTests = false;
86 static bool dumpPixelsForCurrentTest;
87 static bool dumpAllPixels;
88 static bool printSeparators;
89 static bool leakChecking = false;
90 static bool threaded = false;
91 static bool forceComplexText = false;
92 static bool printSupportedFeatures = false;
93 static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
96 // This is the topmost frame that is loading, during a given load, or nil when no load is
97 // in progress. Usually this is the same as the main frame, but not always. In the case
98 // where a frameset is loaded, and then new content is loaded into one of the child frames,
99 // that child frame is the "topmost frame that is loading".
100 IWebFrame* topLoadingFrame; // !nil iff a load is in progress
101 static COMPtr<IWebHistoryItem> prevTestBFItem; // current b/f item at the end of the previous test
102 PolicyDelegate* policyDelegate;
103 COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate;
104 COMPtr<UIDelegate> sharedUIDelegate;
105 COMPtr<EditingDelegate> sharedEditingDelegate;
106 COMPtr<HistoryDelegate> sharedHistoryDelegate;
111 RefPtr<TestRunner> gTestRunner;
113 UINT_PTR waitToDumpWatchdog = 0;
115 void setPersistentUserStyleSheetLocation(CFStringRef url)
117 persistentUserStyleSheetLocation = url;
120 bool setAlwaysAcceptCookies(bool alwaysAcceptCookies)
123 COMPtr<IWebCookieManager> cookieManager;
124 if (FAILED(WebKitCreateInstance(CLSID_WebCookieManager, 0, IID_IWebCookieManager, reinterpret_cast<void**>(&cookieManager))))
126 CFHTTPCookieStorageRef cookieStorage = 0;
127 if (FAILED(cookieManager->cookieStorage(&cookieStorage)) || !cookieStorage)
130 WebKitCookieStorageAcceptPolicy cookieAcceptPolicy = alwaysAcceptCookies ? WebKitCookieStorageAcceptPolicyAlways : WebKitCookieStorageAcceptPolicyOnlyFromMainDocumentDomain;
131 CFHTTPCookieStorageSetCookieAcceptPolicy(cookieStorage, cookieAcceptPolicy);
139 static RetainPtr<CFStringRef> substringFromIndex(CFStringRef string, CFIndex index)
141 return adoptCF(CFStringCreateWithSubstring(kCFAllocatorDefault, string, CFRangeMake(index, CFStringGetLength(string) - index)));
144 static wstring lastPathComponentAsWString(CFURLRef url)
146 RetainPtr<CFStringRef> lastPathComponent = adoptCF(CFURLCopyLastPathComponent(url));
147 return cfStringRefToWString(lastPathComponent.get());
150 wstring urlSuitableForTestResult(const wstring& urlString)
152 RetainPtr<CFURLRef> url = adoptCF(CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(urlString.c_str()), urlString.length() * sizeof(wstring::value_type), kCFStringEncodingUTF16, 0));
154 RetainPtr<CFStringRef> scheme = adoptCF(CFURLCopyScheme(url.get()));
155 if (scheme && CFStringCompare(scheme.get(), CFSTR("file"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)
158 COMPtr<IWebDataSource> dataSource;
159 if (FAILED(frame->dataSource(&dataSource))) {
160 if (FAILED(frame->provisionalDataSource(&dataSource)))
161 return lastPathComponentAsWString(url.get());
164 COMPtr<IWebMutableURLRequest> request;
165 if (FAILED(dataSource->request(&request)))
166 return lastPathComponentAsWString(url.get());
168 _bstr_t requestURLString;
169 if (FAILED(request->URL(requestURLString.GetAddress())))
170 return lastPathComponentAsWString(url.get());
172 RetainPtr<CFURLRef> requestURL = adoptCF(CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(requestURLString.GetBSTR()), requestURLString.length() * sizeof(OLECHAR), kCFStringEncodingUTF16, 0));
173 RetainPtr<CFURLRef> baseURL = adoptCF(CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, requestURL.get()));
175 RetainPtr<CFStringRef> basePath = adoptCF(CFURLCopyPath(baseURL.get()));
176 RetainPtr<CFStringRef> path = adoptCF(CFURLCopyPath(url.get()));
178 if (basePath.get() && CFStringHasPrefix(path.get(), basePath.get()))
179 return cfStringRefToWString(substringFromIndex(path.get(), CFStringGetLength(basePath.get())).get());
181 return lastPathComponentAsWString(url.get());
184 wstring lastPathComponent(const wstring& urlString)
186 if (urlString.empty())
189 RetainPtr<CFURLRef> url = adoptCF(CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(urlString.c_str()), urlString.length() * sizeof(wstring::value_type), kCFStringEncodingUTF16, 0));
190 RetainPtr<CFStringRef> lastPathComponent = adoptCF(CFURLCopyLastPathComponent(url.get()));
192 return cfStringRefToWString(lastPathComponent.get());
195 static string toUTF8(const wchar_t* wideString, size_t length)
197 int result = WideCharToMultiByte(CP_UTF8, 0, wideString, length + 1, 0, 0, 0, 0);
198 Vector<char> utf8Vector(result);
199 result = WideCharToMultiByte(CP_UTF8, 0, wideString, length + 1, utf8Vector.data(), result, 0, 0);
203 return string(utf8Vector.data(), utf8Vector.size() - 1);
207 static String libraryPathForDumpRenderTree()
209 DWORD size = ::GetEnvironmentVariable(dumpRenderTreeTemp, 0, 0);
210 Vector<TCHAR> buffer(size);
211 if (::GetEnvironmentVariable(dumpRenderTreeTemp, buffer.data(), buffer.size())) {
212 wstring path = buffer.data();
213 if (!path.empty() && (path[path.length() - 1] != L'\\'))
215 return String (path.data(), path.length());
218 return WebCore::localUserSpecificStorageDirectory();
222 string toUTF8(BSTR bstr)
224 return toUTF8(bstr, SysStringLen(bstr));
227 string toUTF8(const wstring& wideString)
229 return toUTF8(wideString.c_str(), wideString.length());
232 wstring cfStringRefToWString(CFStringRef cfStr)
234 Vector<wchar_t> v(CFStringGetLength(cfStr));
235 CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), (UniChar *)v.data());
237 return wstring(v.data(), v.size());
240 static LRESULT CALLBACK DumpRenderTreeWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
244 for (unsigned i = openWindows().size() - 1; i >= 0; --i) {
245 if (openWindows()[i] == hWnd) {
246 openWindows().remove(i);
247 windowToWebViewMap().remove(hWnd);
254 return DefWindowProc(hWnd, msg, wParam, lParam);
258 static const wstring& exePath()
261 static bool initialized;
267 TCHAR buffer[MAX_PATH];
268 GetModuleFileName(GetModuleHandle(0), buffer, ARRAYSIZE(buffer));
270 int lastSlash = path.rfind('\\');
271 if (lastSlash != -1 && lastSlash + 1 < path.length())
272 path = path.substr(0, lastSlash + 1);
277 static const wstring& fontsPath()
280 static bool initialized;
286 DWORD size = GetEnvironmentVariable(fontsEnvironmentVariable, 0, 0);
287 Vector<TCHAR> buffer(size);
288 if (GetEnvironmentVariable(fontsEnvironmentVariable, buffer.data(), buffer.size())) {
289 path = buffer.data();
290 if (path[path.length() - 1] != '\\')
295 path = exePath() + TEXT("DumpRenderTree.resources\\");
300 #define WEBKITDLL TEXT("WebKit_debug.dll")
302 #define WEBKITDLL TEXT("WebKit.dll")
305 static void initialize()
307 if (HMODULE webKitModule = LoadLibrary(WEBKITDLL))
308 if (FARPROC dllRegisterServer = GetProcAddress(webKitModule, "DllRegisterServer"))
314 static LPCTSTR fontsToInstall[] = {
315 TEXT("AHEM____.ttf"),
316 TEXT("Apple Chancery.ttf"),
317 TEXT("Courier Bold.ttf"),
319 TEXT("Helvetica Bold Oblique.ttf"),
320 TEXT("Helvetica Bold.ttf"),
321 TEXT("Helvetica Oblique.ttf"),
322 TEXT("Helvetica.ttf"),
323 TEXT("Helvetica Neue Bold Italic.ttf"),
324 TEXT("Helvetica Neue Bold.ttf"),
325 TEXT("Helvetica Neue Condensed Black.ttf"),
326 TEXT("Helvetica Neue Condensed Bold.ttf"),
327 TEXT("Helvetica Neue Italic.ttf"),
328 TEXT("Helvetica Neue Light Italic.ttf"),
329 TEXT("Helvetica Neue Light.ttf"),
330 TEXT("Helvetica Neue UltraLight Italic.ttf"),
331 TEXT("Helvetica Neue UltraLight.ttf"),
332 TEXT("Helvetica Neue.ttf"),
333 TEXT("Lucida Grande.ttf"),
334 TEXT("Lucida Grande Bold.ttf"),
337 TEXT("Times Bold Italic.ttf"),
338 TEXT("Times Bold.ttf"),
339 TEXT("Times Italic.ttf"),
340 TEXT("Times Roman.ttf"),
341 TEXT("WebKit Layout Tests 2.ttf"),
342 TEXT("WebKit Layout Tests.ttf"),
343 TEXT("WebKitWeightWatcher100.ttf"),
344 TEXT("WebKitWeightWatcher200.ttf"),
345 TEXT("WebKitWeightWatcher300.ttf"),
346 TEXT("WebKitWeightWatcher400.ttf"),
347 TEXT("WebKitWeightWatcher500.ttf"),
348 TEXT("WebKitWeightWatcher600.ttf"),
349 TEXT("WebKitWeightWatcher700.ttf"),
350 TEXT("WebKitWeightWatcher800.ttf"),
351 TEXT("WebKitWeightWatcher900.ttf")
354 wstring resourcesPath = fontsPath();
356 COMPtr<IWebTextRenderer> textRenderer;
357 if (SUCCEEDED(WebKitCreateInstance(CLSID_WebTextRenderer, 0, IID_IWebTextRenderer, (void**)&textRenderer)))
358 for (int i = 0; i < ARRAYSIZE(fontsToInstall); ++i)
359 textRenderer->registerPrivateFont(wstring(resourcesPath + fontsToInstall[i]).c_str());
361 // Register a host window
364 wcex.cbSize = sizeof(WNDCLASSEX);
366 wcex.style = CS_HREDRAW | CS_VREDRAW;
367 wcex.lpfnWndProc = DumpRenderTreeWndProc;
370 wcex.hInstance = GetModuleHandle(0);
372 wcex.hCursor = LoadCursor(0, IDC_ARROW);
373 wcex.hbrBackground = 0;
374 wcex.lpszMenuName = 0;
375 wcex.lpszClassName = kDumpRenderTreeClassName;
378 RegisterClassEx(&wcex);
381 void displayWebView()
383 ::InvalidateRect(webViewWindow, 0, TRUE);
384 ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
387 void dumpFrameScrollPosition(IWebFrame* frame)
392 COMPtr<IWebFramePrivate> framePrivate;
393 if (FAILED(frame->QueryInterface(&framePrivate)))
397 if (FAILED(framePrivate->scrollOffset(&scrollPosition)))
400 if (abs(scrollPosition.cx) > 0.00000001 || abs(scrollPosition.cy) > 0.00000001) {
401 COMPtr<IWebFrame> parent;
402 if (FAILED(frame->parentFrame(&parent)))
406 if (FAILED(frame->name(&name.GetBSTR())))
408 printf("frame '%S' ", static_cast<wchar_t*>(name));
410 printf("scrolled to %.f,%.f\n", (double)scrollPosition.cx, (double)scrollPosition.cy);
413 if (::gTestRunner->dumpChildFrameScrollPositions()) {
414 COMPtr<IEnumVARIANT> enumKids;
415 if (FAILED(frame->childFrames(&enumKids)))
419 while (enumKids->Next(1, &var, 0) == S_OK) {
420 ASSERT(V_VT(&var) == VT_UNKNOWN);
421 COMPtr<IWebFrame> framePtr;
422 V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
423 dumpFrameScrollPosition(framePtr.get());
429 static wstring dumpFramesAsText(IWebFrame* frame)
434 COMPtr<IDOMDocument> document;
435 if (FAILED(frame->DOMDocument(&document)))
438 COMPtr<IDOMElement> documentElement;
439 if (FAILED(document->documentElement(&documentElement)))
444 // Add header for all but the main frame.
445 COMPtr<IWebFrame> parent;
446 if (FAILED(frame->parentFrame(&parent)))
450 if (FAILED(frame->name(&name.GetBSTR())))
453 result.append(L"\n--------\nFrame: '");
454 result.append(static_cast<wchar_t*>(name), name.length());
455 result.append(L"'\n--------\n");
459 COMPtr<IDOMElementPrivate> docPrivate;
460 if (SUCCEEDED(documentElement->QueryInterface(&docPrivate)))
461 docPrivate->innerText(&innerText.GetBSTR());
463 result.append(static_cast<wchar_t*>(innerText), innerText.length());
464 result.append(L"\n");
466 if (::gTestRunner->dumpChildFramesAsText()) {
467 COMPtr<IEnumVARIANT> enumKids;
468 if (FAILED(frame->childFrames(&enumKids)))
472 while (enumKids->Next(1, &var, 0) == S_OK) {
473 ASSERT(V_VT(&var) == VT_UNKNOWN);
474 COMPtr<IWebFrame> framePtr;
475 V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
476 result.append(dumpFramesAsText(framePtr.get()));
484 static int compareHistoryItems(const void* item1, const void* item2)
486 COMPtr<IWebHistoryItemPrivate> itemA;
487 if (FAILED((*(COMPtr<IUnknown>*)item1)->QueryInterface(&itemA)))
490 COMPtr<IWebHistoryItemPrivate> itemB;
491 if (FAILED((*(COMPtr<IUnknown>*)item2)->QueryInterface(&itemB)))
495 if (FAILED(itemA->target(&targetA.GetBSTR())))
499 if (FAILED(itemB->target(&targetB.GetBSTR())))
502 return wcsicmp(static_cast<wchar_t*>(targetA), static_cast<wchar_t*>(targetB));
505 static void dumpHistoryItem(IWebHistoryItem* item, int indent, bool current)
514 for (int i = start; i < indent; i++)
518 if (FAILED(item->URLString(&url.GetBSTR())))
521 if (wcsstr(static_cast<wchar_t*>(url), L"file:/") == static_cast<wchar_t*>(url)) {
522 static wchar_t* layoutTestsString = L"/LayoutTests/";
523 static wchar_t* fileTestString = L"(file test):";
525 wchar_t* result = wcsstr(static_cast<wchar_t*>(url), layoutTestsString);
528 wchar_t* start = result + wcslen(layoutTestsString);
530 _bstr_t newURL(SysAllocStringLen(0, SysStringLen(url)), false);
531 wcscpy(static_cast<wchar_t*>(newURL), fileTestString);
532 wcscpy(static_cast<wchar_t*>(newURL) + wcslen(fileTestString), start);
537 printf("%S", static_cast<wchar_t*>(url));
539 COMPtr<IWebHistoryItemPrivate> itemPrivate;
540 if (FAILED(item->QueryInterface(&itemPrivate)))
544 if (FAILED(itemPrivate->target(&target.GetBSTR())))
547 printf(" (in frame \"%S\")", static_cast<wchar_t*>(target));
548 BOOL isTargetItem = FALSE;
549 if (FAILED(itemPrivate->isTargetItem(&isTargetItem)))
552 printf(" **nav target**");
557 if (FAILED(itemPrivate->children(&kidsCount, &arrPtr)) || !kidsCount)
560 Vector<COMPtr<IUnknown> > kidsVector;
563 if (FAILED(::SafeArrayGetLBound(arrPtr, 1, &lowerBound)))
567 if (FAILED(::SafeArrayGetUBound(arrPtr, 1, &upperBound)))
570 LONG length = upperBound - lowerBound + 1;
573 ASSERT(length == kidsCount);
575 IUnknown** safeArrayData;
576 if (FAILED(::SafeArrayAccessData(arrPtr, (void**)&safeArrayData)))
579 for (int i = 0; i < length; ++i)
580 kidsVector.append(safeArrayData[i]);
581 ::SafeArrayUnaccessData(arrPtr);
583 // must sort to eliminate arbitrary result ordering which defeats reproducible testing
584 qsort(kidsVector.data(), kidsCount, sizeof(kidsVector[0]), compareHistoryItems);
586 for (unsigned i = 0; i < kidsCount; ++i) {
587 COMPtr<IWebHistoryItem> item;
588 kidsVector[i]->QueryInterface(&item);
589 dumpHistoryItem(item.get(), indent + 4, false);
593 if (arrPtr && SUCCEEDED(::SafeArrayUnlock(arrPtr)))
594 ::SafeArrayDestroy(arrPtr);
597 static void dumpBackForwardList(IWebView* webView)
601 printf("\n============== Back Forward List ==============\n");
603 COMPtr<IWebBackForwardList> bfList;
604 if (FAILED(webView->backForwardList(&bfList)))
607 // Print out all items in the list after prevTestBFItem, which was from the previous test
608 // Gather items from the end of the list, the print them out from oldest to newest
610 Vector<COMPtr<IUnknown> > itemsToPrint;
612 int forwardListCount;
613 if (FAILED(bfList->forwardListCount(&forwardListCount)))
616 for (int i = forwardListCount; i > 0; --i) {
617 COMPtr<IWebHistoryItem> item;
618 if (FAILED(bfList->itemAtIndex(i, &item)))
620 // something is wrong if the item from the last test is in the forward part of the b/f list
621 ASSERT(item != prevTestBFItem);
622 COMPtr<IUnknown> itemUnknown;
623 item->QueryInterface(&itemUnknown);
624 itemsToPrint.append(itemUnknown);
627 COMPtr<IWebHistoryItem> currentItem;
628 if (FAILED(bfList->currentItem(¤tItem)))
631 ASSERT(currentItem != prevTestBFItem);
632 COMPtr<IUnknown> currentItemUnknown;
633 currentItem->QueryInterface(¤tItemUnknown);
634 itemsToPrint.append(currentItemUnknown);
635 int currentItemIndex = itemsToPrint.size() - 1;
638 if (FAILED(bfList->backListCount(&backListCount)))
641 for (int i = -1; i >= -backListCount; --i) {
642 COMPtr<IWebHistoryItem> item;
643 if (FAILED(bfList->itemAtIndex(i, &item)))
645 if (item == prevTestBFItem)
647 COMPtr<IUnknown> itemUnknown;
648 item->QueryInterface(&itemUnknown);
649 itemsToPrint.append(itemUnknown);
652 for (int i = itemsToPrint.size() - 1; i >= 0; --i) {
653 COMPtr<IWebHistoryItem> historyItemToPrint;
654 itemsToPrint[i]->QueryInterface(&historyItemToPrint);
655 dumpHistoryItem(historyItemToPrint.get(), 8, i == currentItemIndex);
658 printf("===============================================\n");
661 static void dumpBackForwardListForAllWindows()
663 unsigned count = openWindows().size();
664 for (unsigned i = 0; i < count; i++) {
665 HWND window = openWindows()[i];
666 IWebView* webView = windowToWebViewMap().get(window).get();
667 dumpBackForwardList(webView);
671 static void invalidateAnyPreviousWaitToDumpWatchdog()
673 if (!waitToDumpWatchdog)
676 KillTimer(0, waitToDumpWatchdog);
677 waitToDumpWatchdog = 0;
682 invalidateAnyPreviousWaitToDumpWatchdog();
684 COMPtr<IWebDataSource> dataSource;
685 if (SUCCEEDED(frame->dataSource(&dataSource))) {
686 COMPtr<IWebURLResponse> response;
687 if (SUCCEEDED(dataSource->response(&response)) && response) {
689 if (SUCCEEDED(response->MIMEType(&mimeType.GetBSTR())) && !_tcscmp(static_cast<TCHAR*>(mimeType), TEXT("text/plain"))) {
690 ::gTestRunner->setDumpAsText(true);
691 ::gTestRunner->setGeneratePixelResults(false);
696 _bstr_t resultString;
699 ::InvalidateRect(webViewWindow, 0, TRUE);
700 ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
702 if (::gTestRunner->dumpAsText()) {
703 resultString = dumpFramesAsText(frame).data();
705 COMPtr<IWebFramePrivate> framePrivate;
706 if (FAILED(frame->QueryInterface(&framePrivate)))
708 framePrivate->renderTreeAsExternalRepresentation(gTestRunner->isPrinting(), &resultString.GetBSTR());
711 if (resultString.length()) {
712 unsigned stringLength = resultString.length();
713 int bufferSize = ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, 0, 0, 0, 0);
714 char* buffer = (char*)malloc(bufferSize + 1);
715 ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, buffer, bufferSize + 1, 0, 0);
716 fwrite(buffer, 1, bufferSize, stdout);
719 if (!::gTestRunner->dumpAsText() && !::gTestRunner->dumpDOMAsWebArchive() && !::gTestRunner->dumpSourceAsWebArchive() && !::gTestRunner->dumpAsAudio())
720 dumpFrameScrollPosition(frame);
722 if (::gTestRunner->dumpBackForwardList())
723 dumpBackForwardListForAllWindows();
725 printf("ERROR: nil result from %s", ::gTestRunner->dumpAsText() ? "IDOMElement::innerText" : "IFrameViewPrivate::renderTreeAsExternalRepresentation");
727 if (printSeparators) {
728 puts("#EOF"); // terminate the content block
729 fputs("#EOF\n", stderr);
733 if (dumpPixelsForCurrentTest
734 && gTestRunner->generatePixelResults()
735 && !gTestRunner->dumpDOMAsWebArchive()
736 && !gTestRunner->dumpSourceAsWebArchive())
737 dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash());
739 printf("#EOF\n"); // terminate the (possibly empty) pixels block
744 SysFreeString(resultString);
745 // This will exit from our message loop.
750 static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
752 return strstr(pathOrURL, "/loading/") || strstr(pathOrURL, "\\loading\\");
755 static bool shouldLogHistoryDelegates(const char* pathOrURL)
757 return strstr(pathOrURL, "/globalhistory/") || strstr(pathOrURL, "\\globalhistory\\");
760 static bool shouldDumpAsText(const char* pathOrURL)
762 return strstr(pathOrURL, "/dumpAsText/") || strstr(pathOrURL, "\\dumpAsText\\");
765 static bool shouldEnableDeveloperExtras(const char* pathOrURL)
770 static void resetDefaultsToConsistentValues(IWebPreferences* preferences)
773 static _bstr_t standardFamily(TEXT("Times"));
774 static _bstr_t fixedFamily(TEXT("Courier"));
775 static _bstr_t sansSerifFamily(TEXT("Helvetica"));
776 static _bstr_t cursiveFamily(TEXT("Apple Chancery"));
777 static _bstr_t fantasyFamily(TEXT("Papyrus"));
778 static _bstr_t pictographFamily(TEXT("Apple Color Emoji"));
780 static _bstr_t standardFamily(TEXT("Times New Roman"));
781 static _bstr_t fixedFamily(TEXT("Courier New"));
782 static _bstr_t sansSerifFamily(TEXT("Arial"));
783 static _bstr_t cursiveFamily(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use.
784 static _bstr_t fantasyFamily(TEXT("Times New Roman"));
785 static _bstr_t pictographFamily(TEXT("Times New Roman"));
788 preferences->setStandardFontFamily(standardFamily);
789 preferences->setFixedFontFamily(fixedFamily);
790 preferences->setSerifFontFamily(standardFamily);
791 preferences->setSansSerifFontFamily(sansSerifFamily);
792 preferences->setCursiveFontFamily(cursiveFamily);
793 preferences->setFantasyFontFamily(fantasyFamily);
794 preferences->setPictographFontFamily(pictographFamily);
796 preferences->setAutosaves(FALSE);
797 preferences->setDefaultFontSize(16);
798 preferences->setDefaultFixedFontSize(13);
799 preferences->setMinimumFontSize(0);
800 preferences->setDefaultTextEncodingName(L"ISO-8859-1");
801 preferences->setJavaEnabled(FALSE);
802 preferences->setPlugInsEnabled(TRUE);
803 preferences->setDOMPasteAllowed(TRUE);
804 preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey);
805 preferences->setFontSmoothing(FontSmoothingTypeStandard);
806 preferences->setUsesPageCache(FALSE);
807 preferences->setPrivateBrowsingEnabled(FALSE);
808 preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE);
809 preferences->setJavaScriptEnabled(TRUE);
810 preferences->setTabsToLinks(FALSE);
811 preferences->setShouldPrintBackgrounds(TRUE);
812 preferences->setCacheModel(WebCacheModelDocumentBrowser);
813 preferences->setLoadsImagesAutomatically(TRUE);
814 preferences->setTextAreasAreResizable(TRUE);
815 preferences->setCSSRegionsEnabled(TRUE);
817 if (persistentUserStyleSheetLocation) {
818 Vector<wchar_t> urlCharacters(CFStringGetLength(persistentUserStyleSheetLocation.get()));
819 CFStringGetCharacters(persistentUserStyleSheetLocation.get(), CFRangeMake(0, CFStringGetLength(persistentUserStyleSheetLocation.get())), (UniChar *)urlCharacters.data());
820 _bstr_t url(urlCharacters.data());
821 preferences->setUserStyleSheetLocation(url);
822 preferences->setUserStyleSheetEnabled(TRUE);
824 preferences->setUserStyleSheetEnabled(FALSE);
826 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
828 prefsPrivate->setAllowUniversalAccessFromFileURLs(TRUE);
829 prefsPrivate->setAllowFileAccessFromFileURLs(TRUE);
830 prefsPrivate->setAuthorAndUserStylesEnabled(TRUE);
831 prefsPrivate->setDeveloperExtrasEnabled(FALSE);
832 prefsPrivate->setExperimentalNotificationsEnabled(TRUE);
833 prefsPrivate->setShouldPaintNativeControls(FALSE); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592>
834 prefsPrivate->setJavaScriptCanAccessClipboard(TRUE);
835 prefsPrivate->setXSSAuditorEnabled(FALSE);
836 prefsPrivate->setOfflineWebApplicationCacheEnabled(TRUE);
837 prefsPrivate->setLoadsSiteIconsIgnoringImageLoadingPreference(FALSE);
838 prefsPrivate->setFrameFlatteningEnabled(FALSE);
839 prefsPrivate->setFullScreenEnabled(TRUE);
841 prefsPrivate->setAcceleratedCompositingEnabled(TRUE);
843 prefsPrivate->setMockScrollbarsEnabled(TRUE);
844 prefsPrivate->setScreenFontSubstitutionEnabled(TRUE);
846 setAlwaysAcceptCookies(false);
848 setlocale(LC_ALL, "");
851 static void resetWebViewToConsistentStateBeforeTesting()
853 COMPtr<IWebView> webView;
854 if (FAILED(frame->webView(&webView)))
857 webView->setPolicyDelegate(0);
858 policyDelegate->setPermissive(false);
859 policyDelegate->setControllerToNotifyDone(0);
861 COMPtr<IWebIBActions> webIBActions(Query, webView);
863 webIBActions->makeTextStandardSize(0);
864 webIBActions->resetPageZoom(0);
868 COMPtr<IWebPreferences> preferences;
869 if (SUCCEEDED(webView->preferences(&preferences)))
870 resetDefaultsToConsistentValues(preferences.get());
873 JSGlobalContextRef context = frame->globalContext();
874 WebCoreTestSupport::resetInternalsObject(context);
877 COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
882 if (SUCCEEDED(webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))) && viewWindow)
883 SetFocus(viewWindow);
885 webViewPrivate->clearMainFrameName();
886 webViewPrivate->resetOriginAccessWhitelists();
889 if (SUCCEEDED(webView->groupName(&groupName.GetBSTR())))
890 webViewPrivate->removeAllUserContentFromGroup(groupName);
892 sharedUIDelegate->resetUndoManager();
894 sharedFrameLoadDelegate->resetToConsistentState();
896 COMPtr<IWebFramePrivate> framePrivate;
897 if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
898 framePrivate->clearOpener();
901 static void sizeWebViewForCurrentTest()
903 bool isSVGW3CTest = (gTestRunner->testPathOrURL().find("svg\\W3C-SVG-1.1") != string::npos);
907 width = TestRunner::w3cSVGViewWidth;
908 height = TestRunner::w3cSVGViewHeight;
910 width = TestRunner::viewWidth;
911 height = TestRunner::viewHeight;
914 ::SetWindowPos(webViewWindow, 0, 0, 0, width, height, SWP_NOMOVE);
917 static String findFontFallback(const char* pathOrUrl)
919 String pathToFontFallback = WebCore::directoryName(pathOrUrl);
921 wchar_t fullPath[_MAX_PATH];
922 if (!_wfullpath(fullPath, pathToFontFallback.charactersWithNullTermination().data(), _MAX_PATH))
923 return emptyString();
925 if (!::PathIsDirectoryW(fullPath))
926 return emptyString();
928 String pathToCheck = fullPath;
930 static const String layoutTests = "LayoutTests";
932 // Find the layout test root on the current path:
933 size_t location = pathToCheck.find(layoutTests);
934 if (WTF::notFound == location)
935 return emptyString();
937 String pathToTest = pathToCheck.substring(location + layoutTests.length() + 1);
938 String possiblePathToLogue = WebCore::pathByAppendingComponent(pathToCheck.substring(0, location + layoutTests.length() + 1), "platform\\win");
940 Vector<String> possiblePaths;
941 possiblePaths.append(WebCore::pathByAppendingComponent(possiblePathToLogue, pathToTest));
943 size_t nextCandidateEnd = pathToTest.reverseFind('\\');
944 while (nextCandidateEnd && nextCandidateEnd != WTF::notFound) {
945 pathToTest = pathToTest.substring(0, nextCandidateEnd);
946 possiblePaths.append(WebCore::pathByAppendingComponent(possiblePathToLogue, pathToTest));
947 nextCandidateEnd = pathToTest.reverseFind('\\');
950 for (Vector<String>::iterator pos = possiblePaths.begin(); pos != possiblePaths.end(); ++pos) {
951 pathToFontFallback = WebCore::pathByAppendingComponent(*pos, "resources\\");
953 if (::PathIsDirectoryW(pathToFontFallback.charactersWithNullTermination().data()))
954 return pathToFontFallback;
957 return emptyString();
960 static void addFontFallbackIfPresent(const String& fontFallbackPath)
962 if (fontFallbackPath.isEmpty())
965 String fontFallback = WebCore::pathByAppendingComponent(fontFallbackPath, "Mac-compatible-font-fallback.css");
967 if (!::PathFileExistsW(fontFallback.charactersWithNullTermination().data()))
970 ::setPersistentUserStyleSheetLocation(fontFallback.createCFString().get());
973 static void removeFontFallbackIfPresent(const String& fontFallbackPath)
975 if (fontFallbackPath.isEmpty())
978 String fontFallback = WebCore::pathByAppendingComponent(fontFallbackPath, "Mac-compatible-font-fallback.css");
980 if (!::PathFileExistsW(fontFallback.charactersWithNullTermination().data()))
983 ::setPersistentUserStyleSheetLocation(0);
987 static void runTest(const string& inputLine)
989 ASSERT(!inputLine.empty());
991 TestCommand command = parseInputLine(inputLine);
992 const string& pathOrURL = command.pathOrURL;
993 dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests;
995 static _bstr_t methodBStr(TEXT("GET"));
997 CFStringRef str = CFStringCreateWithCString(0, pathOrURL.c_str(), kCFStringEncodingWindowsLatin1);
998 CFURLRef url = CFURLCreateWithString(0, str, 0);
1001 url = CFURLCreateWithFileSystemPath(0, str, kCFURLWindowsPathStyle, false);
1005 String fallbackPath = findFontFallback(pathOrURL.c_str());
1007 str = CFURLGetString(url);
1009 CFIndex length = CFStringGetLength(str);
1010 UniChar* buffer = new UniChar[length + 1];
1012 CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
1015 _bstr_t urlBStr((OLECHAR*)buffer);
1016 ASSERT(urlBStr.length() == length);
1021 ::gTestRunner = TestRunner::create(pathOrURL, command.expectedPixelHash);
1022 topLoadingFrame = 0;
1025 addFontFallbackIfPresent(fallbackPath);
1027 sizeWebViewForCurrentTest();
1028 gTestRunner->setIconDatabaseEnabled(false);
1030 if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
1031 gTestRunner->setDumpFrameLoadCallbacks(true);
1033 COMPtr<IWebView> webView;
1034 if (SUCCEEDED(frame->webView(&webView))) {
1035 COMPtr<IWebViewPrivate> viewPrivate;
1036 if (SUCCEEDED(webView->QueryInterface(&viewPrivate))) {
1037 if (shouldLogHistoryDelegates(pathOrURL.c_str())) {
1038 gTestRunner->setDumpHistoryDelegateCallbacks(true);
1039 viewPrivate->setHistoryDelegate(sharedHistoryDelegate.get());
1041 viewPrivate->setHistoryDelegate(0);
1044 COMPtr<IWebHistory> history;
1045 if (SUCCEEDED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
1046 history->setOptionalSharedHistory(0);
1048 resetWebViewToConsistentStateBeforeTesting();
1050 if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
1051 gTestRunner->setDeveloperExtrasEnabled(true);
1052 if (shouldDumpAsText(pathOrURL.c_str())) {
1053 gTestRunner->setDumpAsText(true);
1054 gTestRunner->setGeneratePixelResults(false);
1060 COMPtr<IWebBackForwardList> bfList;
1061 if (SUCCEEDED(webView->backForwardList(&bfList)))
1062 bfList->currentItem(&prevTestBFItem);
1065 WorkQueue::shared()->clear();
1066 WorkQueue::shared()->setFrozen(false);
1069 webView->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
1071 COMPtr<IWebMutableURLRequest> request;
1072 HRESULT hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request);
1076 request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
1078 request->setHTTPMethod(methodBStr);
1079 frame->loadRequest(request.get());
1084 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
1086 if (!GetMessage(&msg, 0, 0, 0))
1089 // We get spurious WM_MOUSELEAVE events which make event handling machinery think that mouse button
1090 // is released during dragging (see e.g. fast\dynamic\layer-hit-test-crash.html).
1091 // Mouse can never leave WebView during normal DumpRenderTree operation, so we just ignore all such events.
1092 if (msg.message == WM_MOUSELEAVE)
1094 TranslateMessage(&msg);
1095 DispatchMessage(&msg);
1098 if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
1099 gTestRunner->closeWebInspector();
1100 gTestRunner->setDeveloperExtrasEnabled(false);
1103 resetWebViewToConsistentStateBeforeTesting();
1105 frame->stopLoading();
1107 if (::gTestRunner->closeRemainingWindowsWhenComplete()) {
1108 Vector<HWND> windows = openWindows();
1109 unsigned size = windows.size();
1110 for (unsigned i = 0; i < size; i++) {
1111 HWND window = windows[i];
1113 // Don't try to close the main window
1114 if (window == hostWindow)
1117 DestroyWindow(window);
1122 removeFontFallbackIfPresent(fallbackPath);
1123 ::gTestRunner.clear();
1128 Vector<HWND>& openWindows()
1130 static Vector<HWND> vector;
1134 WindowToWebViewMap& windowToWebViewMap()
1136 static WindowToWebViewMap map;
1140 IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow)
1142 int maxViewWidth = TestRunner::viewWidth;
1143 int maxViewHeight = TestRunner::viewHeight;
1144 HWND hostWindow = CreateWindowEx(WS_EX_TOOLWINDOW, kDumpRenderTreeClassName, TEXT("DumpRenderTree"), WS_POPUP,
1145 -maxViewWidth, -maxViewHeight, maxViewWidth, maxViewHeight, 0, 0, GetModuleHandle(0), 0);
1149 HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, (void**)&webView);
1151 fprintf(stderr, "Failed to create CLSID_WebView instance, error 0x%x\n", hr);
1155 if (FAILED(webView->setHostWindow((OLE_HANDLE)(ULONG64)hostWindow)))
1159 clientRect.bottom = clientRect.left = clientRect.top = clientRect.right = 0;
1160 _bstr_t groupName(L"org.webkit.DumpRenderTree");
1161 if (FAILED(webView->initWithFrame(clientRect, 0, groupName)))
1164 COMPtr<IWebViewPrivate> viewPrivate;
1165 if (FAILED(webView->QueryInterface(&viewPrivate)))
1168 viewPrivate->setShouldApplyMacFontAscentHack(TRUE);
1169 viewPrivate->setAlwaysUsesComplexTextCodePath(forceComplexText);
1171 _bstr_t pluginPath(SysAllocStringLen(0, exePath().length() + _tcslen(TestPluginDir)), false);
1172 _tcscpy(static_cast<TCHAR*>(pluginPath), exePath().c_str());
1173 _tcscat(static_cast<TCHAR*>(pluginPath), TestPluginDir);
1174 if (FAILED(viewPrivate->addAdditionalPluginDirectory(pluginPath)))
1178 if (FAILED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
1181 *webViewWindow = viewWindow;
1183 SetWindowPos(viewWindow, 0, 0, 0, maxViewWidth, maxViewHeight, 0);
1184 ShowWindow(hostWindow, SW_SHOW);
1186 if (FAILED(webView->setFrameLoadDelegate(sharedFrameLoadDelegate.get())))
1189 if (FAILED(viewPrivate->setFrameLoadDelegatePrivate(sharedFrameLoadDelegate.get())))
1192 if (FAILED(webView->setUIDelegate(sharedUIDelegate.get())))
1195 COMPtr<IWebViewEditing> viewEditing;
1196 if (FAILED(webView->QueryInterface(&viewEditing)))
1199 if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get())))
1202 ResourceLoadDelegate* resourceLoadDelegate = new ResourceLoadDelegate();
1203 HRESULT result = webView->setResourceLoadDelegate(resourceLoadDelegate);
1204 resourceLoadDelegate->Release(); // The delegate is owned by the WebView, so release our reference to it.
1208 openWindows().append(hostWindow);
1209 windowToWebViewMap().set(hostWindow, webView);
1214 RetainPtr<CFURLCacheRef> sharedCFURLCache()
1217 HMODULE module = GetModuleHandle(TEXT("CFNetwork.dll"));
1219 HMODULE module = GetModuleHandle(TEXT("CFNetwork_debug.dll"));
1224 typedef CFURLCacheRef (*CFURLCacheCopySharedURLCacheProcPtr)(void);
1225 if (CFURLCacheCopySharedURLCacheProcPtr copyCache = reinterpret_cast<CFURLCacheCopySharedURLCacheProcPtr>(GetProcAddress(module, "CFURLCacheCopySharedURLCache")))
1226 return adoptCF(copyCache());
1228 typedef CFURLCacheRef (*CFURLCacheSharedURLCacheProcPtr)(void);
1229 if (CFURLCacheSharedURLCacheProcPtr sharedCache = reinterpret_cast<CFURLCacheSharedURLCacheProcPtr>(GetProcAddress(module, "CFURLCacheSharedURLCache")))
1230 return sharedCache();
1236 static LONG WINAPI exceptionFilter(EXCEPTION_POINTERS*)
1238 fputs("#CRASHED\n", stderr);
1240 return EXCEPTION_CONTINUE_SEARCH;
1243 int main(int argc, const char* argv[])
1245 // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
1246 // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
1247 // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
1250 ::SetUnhandledExceptionFilter(exceptionFilter);
1252 leakChecking = false;
1254 _setmode(1, _O_BINARY);
1255 _setmode(2, _O_BINARY);
1259 Vector<const char*> tests;
1261 for (int i = 1; i < argc; ++i) {
1262 if (!stricmp(argv[i], "--threaded")) {
1267 if (!stricmp(argv[i], "--dump-all-pixels")) {
1268 dumpAllPixels = true;
1272 if (!stricmp(argv[i], "--complex-text")) {
1273 forceComplexText = true;
1277 if (!stricmp(argv[i], "--print-supported-features")) {
1278 printSupportedFeatures = true;
1282 if (!stricmp(argv[i], "--pixel-tests")) {
1283 dumpPixelsForAllTests = true;
1287 tests.append(argv[i]);
1290 policyDelegate = new PolicyDelegate();
1291 sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate);
1292 sharedUIDelegate.adoptRef(new UIDelegate);
1293 sharedEditingDelegate.adoptRef(new EditingDelegate);
1294 sharedHistoryDelegate.adoptRef(new HistoryDelegate);
1296 // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592>
1297 COMPtr<IWebPreferences> tmpPreferences;
1298 if (FAILED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, reinterpret_cast<void**>(&tmpPreferences))))
1300 COMPtr<IWebPreferences> standardPreferences;
1301 if (FAILED(tmpPreferences->standardPreferences(&standardPreferences)))
1303 COMPtr<IWebPreferencesPrivate> standardPreferencesPrivate;
1304 if (FAILED(standardPreferences->QueryInterface(&standardPreferencesPrivate)))
1306 standardPreferencesPrivate->setShouldPaintNativeControls(FALSE);
1307 standardPreferences->setJavaScriptEnabled(TRUE);
1308 standardPreferences->setDefaultFontSize(16);
1310 standardPreferences->setAcceleratedCompositingEnabled(TRUE);
1311 standardPreferences->setAVFoundationEnabled(TRUE);
1313 standardPreferences->setContinuousSpellCheckingEnabled(TRUE);
1315 if (printSupportedFeatures) {
1316 BOOL acceleratedCompositingAvailable;
1317 standardPreferences->acceleratedCompositingEnabled(&acceleratedCompositingAvailable);
1319 #if ENABLE(3D_RENDERING)
1320 // In theory, we could have a software-based 3D rendering implementation that we use when
1321 // hardware-acceleration is not available. But we don't have any such software
1322 // implementation, so 3D rendering is only available when hardware-acceleration is.
1323 BOOL threeDRenderingAvailable = acceleratedCompositingAvailable;
1325 BOOL threeDRenderingAvailable = FALSE;
1328 printf("SupportedFeatures:%s %s\n", acceleratedCompositingAvailable ? "AcceleratedCompositing" : "", threeDRenderingAvailable ? "3DRendering" : "");
1333 // Set up these values before creating the WebView so that the various initializations will see these preferred values.
1334 String path = libraryPathForDumpRenderTree();
1335 CFPreferencesSetAppValue(WebDatabaseDirectoryDefaultsKey, WebCore::pathByAppendingComponent(path, "Databases").createCFString().get(), kCFPreferencesCurrentApplication);
1336 CFPreferencesSetAppValue(WebStorageDirectoryDefaultsKey, WebCore::pathByAppendingComponent(path, "LocalStorage").createCFString().get(), kCFPreferencesCurrentApplication);
1337 CFPreferencesSetAppValue(WebKitLocalCacheDefaultsKey, WebCore::pathByAppendingComponent(path, "LocalCache").createCFString().get(), kCFPreferencesCurrentApplication);
1340 COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow));
1344 COMPtr<IWebIconDatabase> iconDatabase;
1345 COMPtr<IWebIconDatabase> tmpIconDatabase;
1346 if (FAILED(WebKitCreateInstance(CLSID_WebIconDatabase, 0, IID_IWebIconDatabase, (void**)&tmpIconDatabase)))
1348 if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase)))
1351 if (FAILED(webView->mainFrame(&frame)))
1355 RetainPtr<CFURLCacheRef> urlCache = sharedCFURLCache();
1356 CFURLCacheRemoveAllCachedResponses(urlCache.get());
1360 _CrtMemState entryToMainMemCheckpoint;
1362 _CrtMemCheckpoint(&entryToMainMemCheckpoint);
1366 startJavaScriptThreads();
1368 if (tests.size() == 1 && !strcmp(tests[0], "-")) {
1369 char filenameBuffer[2048];
1370 printSeparators = true;
1371 while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
1372 char* newLineCharacter = strchr(filenameBuffer, '\n');
1373 if (newLineCharacter)
1374 *newLineCharacter = '\0';
1376 if (strlen(filenameBuffer) == 0)
1379 runTest(filenameBuffer);
1382 printSeparators = tests.size() > 1;
1383 for (int i = 0; i < tests.size(); i++)
1388 stopJavaScriptThreads();
1390 delete policyDelegate;
1395 // dump leaks to stderr
1396 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
1397 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
1398 _CrtMemDumpAllObjectsSince(&entryToMainMemCheckpoint);
1407 extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
1409 return main(argc, argv);