TestRunnerWin.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /*
  2. * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. 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 Apple Computer, 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.
  16. *
  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.
  27. */
  28. #include "config.h"
  29. #include "TestRunner.h"
  30. #include "DumpRenderTree.h"
  31. #include "EditingDelegate.h"
  32. #include "PolicyDelegate.h"
  33. #include "WorkQueue.h"
  34. #include "WorkQueueItem.h"
  35. #include <CoreFoundation/CoreFoundation.h>
  36. #include <JavaScriptCore/JSRetainPtr.h>
  37. #include <JavaScriptCore/JSStringRefBSTR.h>
  38. #include <JavaScriptCore/JavaScriptCore.h>
  39. #include <WebCore/COMPtr.h>
  40. #include <WebKit/WebKit.h>
  41. #include <WebKit/WebKitCOMAPI.h>
  42. #include <comutil.h>
  43. #include <shlguid.h>
  44. #include <shlwapi.h>
  45. #include <shobjidl.h>
  46. #include <string>
  47. #include <wtf/Assertions.h>
  48. #include <wtf/Platform.h>
  49. #include <wtf/RetainPtr.h>
  50. #include <wtf/Vector.h>
  51. using std::string;
  52. using std::wstring;
  53. static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath);
  54. TestRunner::~TestRunner()
  55. {
  56. COMPtr<IWebView> webView;
  57. if (FAILED(frame->webView(&webView)))
  58. return;
  59. // reset webview-related states back to default values in preparation for next test
  60. COMPtr<IWebViewPrivate> viewPrivate;
  61. if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
  62. viewPrivate->setTabKeyCyclesThroughElements(TRUE);
  63. COMPtr<IWebViewEditing> viewEditing;
  64. if (FAILED(webView->QueryInterface(&viewEditing)))
  65. return;
  66. COMPtr<IWebEditingDelegate> delegate;
  67. if (FAILED(viewEditing->editingDelegate(&delegate)))
  68. return;
  69. COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
  70. if (editingDelegate)
  71. editingDelegate->setAcceptsEditing(TRUE);
  72. }
  73. void TestRunner::addDisallowedURL(JSStringRef url)
  74. {
  75. // FIXME: Implement!
  76. }
  77. void TestRunner::clearBackForwardList()
  78. {
  79. COMPtr<IWebView> webView;
  80. if (FAILED(frame->webView(&webView)))
  81. return;
  82. COMPtr<IWebBackForwardList> backForwardList;
  83. if (FAILED(webView->backForwardList(&backForwardList)))
  84. return;
  85. COMPtr<IWebHistoryItem> item;
  86. if (FAILED(backForwardList->currentItem(&item)))
  87. return;
  88. // We clear the history by setting the back/forward list's capacity to 0
  89. // then restoring it back and adding back the current item.
  90. int capacity;
  91. if (FAILED(backForwardList->capacity(&capacity)))
  92. return;
  93. backForwardList->setCapacity(0);
  94. backForwardList->setCapacity(capacity);
  95. backForwardList->addItem(item.get());
  96. backForwardList->goToItem(item.get());
  97. }
  98. bool TestRunner::callShouldCloseOnWebView()
  99. {
  100. COMPtr<IWebView> webView;
  101. if (FAILED(frame->webView(&webView)))
  102. return false;
  103. COMPtr<IWebViewPrivate> viewPrivate;
  104. if (FAILED(webView->QueryInterface(&viewPrivate)))
  105. return false;
  106. BOOL result;
  107. viewPrivate->shouldClose(&result);
  108. return result;
  109. }
  110. JSStringRef TestRunner::copyDecodedHostName(JSStringRef name)
  111. {
  112. // FIXME: Implement!
  113. return 0;
  114. }
  115. JSStringRef TestRunner::copyEncodedHostName(JSStringRef name)
  116. {
  117. // FIXME: Implement!
  118. return 0;
  119. }
  120. void TestRunner::dispatchPendingLoadRequests()
  121. {
  122. // FIXME: Implement for testing fix for 6727495
  123. }
  124. void TestRunner::display()
  125. {
  126. displayWebView();
  127. }
  128. void TestRunner::keepWebHistory()
  129. {
  130. COMPtr<IWebHistory> history;
  131. if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
  132. return;
  133. COMPtr<IWebHistory> sharedHistory;
  134. if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(sharedHistory), reinterpret_cast<void**>(&sharedHistory))))
  135. return;
  136. history->setOptionalSharedHistory(sharedHistory.get());
  137. }
  138. void TestRunner::waitForPolicyDelegate()
  139. {
  140. COMPtr<IWebView> webView;
  141. if (FAILED(frame->webView(&webView)))
  142. return;
  143. setWaitToDump(true);
  144. policyDelegate->setControllerToNotifyDone(this);
  145. webView->setPolicyDelegate(policyDelegate);
  146. }
  147. size_t TestRunner::webHistoryItemCount()
  148. {
  149. COMPtr<IWebHistory> history;
  150. if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
  151. return 0;
  152. COMPtr<IWebHistory> sharedHistory;
  153. if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory)
  154. return 0;
  155. COMPtr<IWebHistoryPrivate> sharedHistoryPrivate;
  156. if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate)))
  157. return 0;
  158. int count;
  159. if (FAILED(sharedHistoryPrivate->allItems(&count, 0)))
  160. return 0;
  161. return count;
  162. }
  163. JSRetainPtr<JSStringRef> TestRunner::platformName() const
  164. {
  165. JSRetainPtr<JSStringRef> platformName(Adopt, JSStringCreateWithUTF8CString("win"));
  166. return platformName;
  167. }
  168. void TestRunner::notifyDone()
  169. {
  170. // Same as on mac. This can be shared.
  171. if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
  172. dump();
  173. m_waitToDump = false;
  174. }
  175. JSStringRef TestRunner::pathToLocalResource(JSContextRef context, JSStringRef url)
  176. {
  177. wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url));
  178. wstring localPath;
  179. if (!resolveCygwinPath(input, localPath)) {
  180. printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str());
  181. return 0;
  182. }
  183. return JSStringCreateWithCharacters(localPath.c_str(), localPath.length());
  184. }
  185. static wstring jsStringRefToWString(JSStringRef jsStr)
  186. {
  187. size_t length = JSStringGetLength(jsStr);
  188. Vector<WCHAR> buffer(length + 1);
  189. memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
  190. buffer[length] = '\0';
  191. return buffer.data();
  192. }
  193. void TestRunner::queueLoad(JSStringRef url, JSStringRef target)
  194. {
  195. COMPtr<IWebDataSource> dataSource;
  196. if (FAILED(frame->dataSource(&dataSource)))
  197. return;
  198. COMPtr<IWebURLResponse> response;
  199. if (FAILED(dataSource->response(&response)) || !response)
  200. return;
  201. BSTR responseURLBSTR;
  202. if (FAILED(response->URL(&responseURLBSTR)))
  203. return;
  204. wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
  205. SysFreeString(responseURLBSTR);
  206. // FIXME: We should do real relative URL resolution here.
  207. int lastSlash = responseURL.rfind('/');
  208. if (lastSlash != -1)
  209. responseURL = responseURL.substr(0, lastSlash);
  210. wstring wURL = jsStringRefToWString(url);
  211. wstring wAbsoluteURL = responseURL + TEXT("/") + wURL;
  212. JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length()));
  213. WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
  214. }
  215. void TestRunner::setAcceptsEditing(bool acceptsEditing)
  216. {
  217. COMPtr<IWebView> webView;
  218. if (FAILED(frame->webView(&webView)))
  219. return;
  220. COMPtr<IWebViewEditing> viewEditing;
  221. if (FAILED(webView->QueryInterface(&viewEditing)))
  222. return;
  223. COMPtr<IWebEditingDelegate> delegate;
  224. if (FAILED(viewEditing->editingDelegate(&delegate)))
  225. return;
  226. EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
  227. editingDelegate->setAcceptsEditing(acceptsEditing);
  228. }
  229. void TestRunner::setAlwaysAcceptCookies(bool alwaysAcceptCookies)
  230. {
  231. if (alwaysAcceptCookies == m_alwaysAcceptCookies)
  232. return;
  233. if (!::setAlwaysAcceptCookies(alwaysAcceptCookies))
  234. return;
  235. m_alwaysAcceptCookies = alwaysAcceptCookies;
  236. }
  237. void TestRunner::setAuthorAndUserStylesEnabled(bool flag)
  238. {
  239. COMPtr<IWebView> webView;
  240. if (FAILED(frame->webView(&webView)))
  241. return;
  242. COMPtr<IWebPreferences> preferences;
  243. if (FAILED(webView->preferences(&preferences)))
  244. return;
  245. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  246. if (!prefsPrivate)
  247. return;
  248. prefsPrivate->setAuthorAndUserStylesEnabled(flag);
  249. }
  250. void TestRunner::setCustomPolicyDelegate(bool setDelegate, bool permissive)
  251. {
  252. COMPtr<IWebView> webView;
  253. if (FAILED(frame->webView(&webView)))
  254. return;
  255. if (setDelegate) {
  256. policyDelegate->setPermissive(permissive);
  257. webView->setPolicyDelegate(policyDelegate);
  258. } else
  259. webView->setPolicyDelegate(0);
  260. }
  261. void TestRunner::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
  262. {
  263. // FIXME: Implement for DeviceOrientation layout tests.
  264. // See https://bugs.webkit.org/show_bug.cgi?id=30335.
  265. }
  266. void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed)
  267. {
  268. // FIXME: Implement for Geolocation layout tests.
  269. // See https://bugs.webkit.org/show_bug.cgi?id=28264.
  270. }
  271. void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message)
  272. {
  273. // FIXME: Implement for Geolocation layout tests.
  274. // See https://bugs.webkit.org/show_bug.cgi?id=28264.
  275. }
  276. void TestRunner::setGeolocationPermission(bool allow)
  277. {
  278. // FIXME: Implement for Geolocation layout tests.
  279. setGeolocationPermissionCommon(allow);
  280. }
  281. int TestRunner::numberOfPendingGeolocationPermissionRequests()
  282. {
  283. // FIXME: Implement for Geolocation layout tests.
  284. return -1;
  285. }
  286. void TestRunner::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language)
  287. {
  288. // FIXME: Implement for speech input layout tests.
  289. // See https://bugs.webkit.org/show_bug.cgi?id=39485.
  290. }
  291. void TestRunner::setMockSpeechInputDumpRect(bool flag)
  292. {
  293. // FIXME: Implement for speech input layout tests.
  294. // See https://bugs.webkit.org/show_bug.cgi?id=39485.
  295. }
  296. void TestRunner::startSpeechInput(JSContextRef inputElement)
  297. {
  298. // FIXME: Implement for speech input layout tests.
  299. // See https://bugs.webkit.org/show_bug.cgi?id=39485.
  300. }
  301. void TestRunner::setIconDatabaseEnabled(bool iconDatabaseEnabled)
  302. {
  303. // See also <rdar://problem/6480108>
  304. COMPtr<IWebIconDatabase> iconDatabase;
  305. COMPtr<IWebIconDatabase> tmpIconDatabase;
  306. if (FAILED(WebKitCreateInstance(CLSID_WebIconDatabase, 0, IID_IWebIconDatabase, (void**)&tmpIconDatabase)))
  307. return;
  308. if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase)))
  309. return;
  310. iconDatabase->setEnabled(iconDatabaseEnabled);
  311. }
  312. void TestRunner::setMainFrameIsFirstResponder(bool flag)
  313. {
  314. // FIXME: Implement!
  315. }
  316. void TestRunner::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
  317. {
  318. COMPtr<IWebView> webView;
  319. if (FAILED(frame->webView(&webView)))
  320. return;
  321. COMPtr<IWebPreferences> preferences;
  322. if (FAILED(webView->preferences(&preferences)))
  323. return;
  324. preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
  325. }
  326. void TestRunner::setXSSAuditorEnabled(bool enabled)
  327. {
  328. COMPtr<IWebView> webView;
  329. if (FAILED(frame->webView(&webView)))
  330. return;
  331. COMPtr<IWebPreferences> preferences;
  332. if (FAILED(webView->preferences(&preferences)))
  333. return;
  334. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  335. if (!prefsPrivate)
  336. return;
  337. prefsPrivate->setXSSAuditorEnabled(enabled);
  338. }
  339. void TestRunner::setSpatialNavigationEnabled(bool enabled)
  340. {
  341. // FIXME: Implement for SpatialNavigation layout tests.
  342. }
  343. void TestRunner::setAllowUniversalAccessFromFileURLs(bool enabled)
  344. {
  345. COMPtr<IWebView> webView;
  346. if (FAILED(frame->webView(&webView)))
  347. return;
  348. COMPtr<IWebPreferences> preferences;
  349. if (FAILED(webView->preferences(&preferences)))
  350. return;
  351. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  352. if (!prefsPrivate)
  353. return;
  354. prefsPrivate->setAllowUniversalAccessFromFileURLs(enabled);
  355. }
  356. void TestRunner::setAllowFileAccessFromFileURLs(bool enabled)
  357. {
  358. COMPtr<IWebView> webView;
  359. if (FAILED(frame->webView(&webView)))
  360. return;
  361. COMPtr<IWebPreferences> preferences;
  362. if (FAILED(webView->preferences(&preferences)))
  363. return;
  364. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  365. if (!prefsPrivate)
  366. return;
  367. prefsPrivate->setAllowFileAccessFromFileURLs(enabled);
  368. }
  369. void TestRunner::setPopupBlockingEnabled(bool enabled)
  370. {
  371. COMPtr<IWebView> webView;
  372. if (FAILED(frame->webView(&webView)))
  373. return;
  374. COMPtr<IWebPreferences> preferences;
  375. if (FAILED(webView->preferences(&preferences)))
  376. return;
  377. preferences->setJavaScriptCanOpenWindowsAutomatically(!enabled);
  378. }
  379. void TestRunner::setPluginsEnabled(bool flag)
  380. {
  381. // FIXME: Implement
  382. }
  383. void TestRunner::setJavaScriptCanAccessClipboard(bool enabled)
  384. {
  385. COMPtr<IWebView> webView;
  386. if (FAILED(frame->webView(&webView)))
  387. return;
  388. COMPtr<IWebPreferences> preferences;
  389. if (FAILED(webView->preferences(&preferences)))
  390. return;
  391. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  392. if (!prefsPrivate)
  393. return;
  394. prefsPrivate->setJavaScriptCanAccessClipboard(enabled);
  395. }
  396. void TestRunner::setTabKeyCyclesThroughElements(bool shouldCycle)
  397. {
  398. COMPtr<IWebView> webView;
  399. if (FAILED(frame->webView(&webView)))
  400. return;
  401. COMPtr<IWebViewPrivate> viewPrivate;
  402. if (FAILED(webView->QueryInterface(&viewPrivate)))
  403. return;
  404. viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
  405. }
  406. void TestRunner::setUseDashboardCompatibilityMode(bool flag)
  407. {
  408. // FIXME: Implement!
  409. }
  410. void TestRunner::setUserStyleSheetEnabled(bool flag)
  411. {
  412. COMPtr<IWebView> webView;
  413. if (FAILED(frame->webView(&webView)))
  414. return;
  415. COMPtr<IWebPreferences> preferences;
  416. if (FAILED(webView->preferences(&preferences)))
  417. return;
  418. preferences->setUserStyleSheetEnabled(flag);
  419. }
  420. bool appendComponentToPath(wstring& path, const wstring& component)
  421. {
  422. WCHAR buffer[MAX_PATH];
  423. if (path.size() + 1 > MAX_PATH)
  424. return false;
  425. memcpy(buffer, path.data(), path.size() * sizeof(WCHAR));
  426. buffer[path.size()] = '\0';
  427. if (!PathAppendW(buffer, component.c_str()))
  428. return false;
  429. path = wstring(buffer);
  430. return true;
  431. }
  432. static bool followShortcuts(wstring& path)
  433. {
  434. if (PathFileExists(path.c_str()))
  435. return true;
  436. // Do we have a shortcut?
  437. wstring linkPath = path;
  438. linkPath.append(TEXT(".lnk"));
  439. if (!PathFileExists(linkPath.c_str()))
  440. return true;
  441. // We have a shortcut, find its target.
  442. COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink);
  443. if (!shortcut)
  444. return false;
  445. COMPtr<IPersistFile> persistFile(Query, shortcut);
  446. if (!shortcut)
  447. return false;
  448. if (FAILED(persistFile->Load(linkPath.c_str(), STGM_READ)))
  449. return false;
  450. if (FAILED(shortcut->Resolve(0, 0)))
  451. return false;
  452. WCHAR targetPath[MAX_PATH];
  453. DWORD targetPathLen = _countof(targetPath);
  454. if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0)))
  455. return false;
  456. if (!PathFileExists(targetPath))
  457. return false;
  458. // Use the target path as the result path instead.
  459. path = wstring(targetPath);
  460. return true;
  461. }
  462. static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath)
  463. {
  464. wstring fileProtocol = L"file://";
  465. bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos;
  466. if (cygwinPath[isFileProtocol ? 7 : 0] != '/') // ensure path is absolute
  467. return false;
  468. // Get the Root path.
  469. WCHAR rootPath[MAX_PATH];
  470. DWORD rootPathSize = _countof(rootPath);
  471. DWORD keyType;
  472. DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize);
  473. if (result != ERROR_SUCCESS || keyType != REG_SZ) {
  474. // Cygwin 1.7 doesn't store Cygwin's root as a mount point anymore, because mount points are now stored in /etc/fstab.
  475. // However, /etc/fstab doesn't contain any information about where / is located as a Windows path, so we need to use Cygwin's
  476. // new registry key that has the root.
  477. result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygwin\\setup"), TEXT("rootdir"), &keyType, &rootPath, &rootPathSize);
  478. if (result != ERROR_SUCCESS || keyType != REG_SZ)
  479. return false;
  480. }
  481. windowsPath = wstring(rootPath, rootPathSize);
  482. int oldPos = isFileProtocol ? 8 : 1;
  483. while (1) {
  484. int newPos = cygwinPath.find('/', oldPos);
  485. if (newPos == -1) {
  486. wstring pathComponent = cygwinPath.substr(oldPos);
  487. if (!appendComponentToPath(windowsPath, pathComponent))
  488. return false;
  489. if (!followShortcuts(windowsPath))
  490. return false;
  491. break;
  492. }
  493. wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos);
  494. if (!appendComponentToPath(windowsPath, pathComponent))
  495. return false;
  496. if (!followShortcuts(windowsPath))
  497. return false;
  498. oldPos = newPos + 1;
  499. }
  500. if (isFileProtocol)
  501. windowsPath = fileProtocol + windowsPath;
  502. return true;
  503. }
  504. void TestRunner::setUserStyleSheetLocation(JSStringRef jsURL)
  505. {
  506. COMPtr<IWebView> webView;
  507. if (FAILED(frame->webView(&webView)))
  508. return;
  509. COMPtr<IWebPreferences> preferences;
  510. if (FAILED(webView->preferences(&preferences)))
  511. return;
  512. RetainPtr<CFStringRef> urlString = adoptCF(JSStringCopyCFString(0, jsURL));
  513. RetainPtr<CFURLRef> url = adoptCF(CFURLCreateWithString(0, urlString.get(), 0));
  514. if (!url)
  515. return;
  516. // Now copy the file system path, POSIX style.
  517. RetainPtr<CFStringRef> pathCF = adoptCF(CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle));
  518. if (!pathCF)
  519. return;
  520. wstring path = cfStringRefToWString(pathCF.get());
  521. wstring resultPath;
  522. if (!resolveCygwinPath(path, resultPath))
  523. return;
  524. // The path has been resolved, now convert it back to a CFURL.
  525. int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0);
  526. Vector<char> utf8Vector(result);
  527. result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0);
  528. if (!result)
  529. return;
  530. url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false);
  531. if (!url)
  532. return;
  533. resultPath = cfStringRefToWString(CFURLGetString(url.get()));
  534. BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size());
  535. preferences->setUserStyleSheetLocation(resultPathBSTR);
  536. SysFreeString(resultPathBSTR);
  537. }
  538. void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value)
  539. {
  540. COMPtr<IWebView> webView;
  541. if (FAILED(frame->webView(&webView)))
  542. return;
  543. COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
  544. if (!webViewPrivate)
  545. return;
  546. COMPtr<IDOMElement> domElement;
  547. if (FAILED(webViewPrivate->elementFromJS(context, element, &domElement)))
  548. return;
  549. COMPtr<IDOMHTMLInputElement> domInputElement;
  550. if (FAILED(domElement->QueryInterface(IID_IDOMHTMLInputElement, reinterpret_cast<void**>(&domInputElement))))
  551. return;
  552. _bstr_t valueBSTR(JSStringCopyBSTR(value), false);
  553. domInputElement->setValueForUser(valueBSTR);
  554. }
  555. void TestRunner::setViewModeMediaFeature(JSStringRef mode)
  556. {
  557. // FIXME: implement
  558. }
  559. void TestRunner::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
  560. {
  561. RetainPtr<CFStringRef> urlString = adoptCF(JSStringCopyCFString(0, jsURL));
  562. ::setPersistentUserStyleSheetLocation(urlString.get());
  563. }
  564. void TestRunner::clearPersistentUserStyleSheet()
  565. {
  566. ::setPersistentUserStyleSheetLocation(0);
  567. }
  568. void TestRunner::setWindowIsKey(bool flag)
  569. {
  570. COMPtr<IWebView> webView;
  571. if (FAILED(frame->webView(&webView)))
  572. return;
  573. COMPtr<IWebViewPrivate> viewPrivate;
  574. if (FAILED(webView->QueryInterface(&viewPrivate)))
  575. return;
  576. HWND webViewWindow;
  577. if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow)))
  578. return;
  579. ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0);
  580. }
  581. static const CFTimeInterval waitToDumpWatchdogInterval = 30.0;
  582. static void CALLBACK waitUntilDoneWatchdogFired(HWND, UINT, UINT_PTR, DWORD)
  583. {
  584. gTestRunner->waitToDumpWatchdogTimerFired();
  585. }
  586. void TestRunner::setWaitToDump(bool waitUntilDone)
  587. {
  588. m_waitToDump = waitUntilDone;
  589. if (m_waitToDump && !waitToDumpWatchdog)
  590. waitToDumpWatchdog = SetTimer(0, 0, waitToDumpWatchdogInterval * 1000, waitUntilDoneWatchdogFired);
  591. }
  592. int TestRunner::windowCount()
  593. {
  594. return openWindows().size();
  595. }
  596. void TestRunner::execCommand(JSStringRef name, JSStringRef value)
  597. {
  598. wstring wName = jsStringRefToWString(name);
  599. wstring wValue = jsStringRefToWString(value);
  600. COMPtr<IWebView> webView;
  601. if (FAILED(frame->webView(&webView)))
  602. return;
  603. COMPtr<IWebViewPrivate> viewPrivate;
  604. if (FAILED(webView->QueryInterface(&viewPrivate)))
  605. return;
  606. BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length());
  607. BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length());
  608. viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR);
  609. SysFreeString(nameBSTR);
  610. SysFreeString(valueBSTR);
  611. }
  612. bool TestRunner::findString(JSContextRef /* context */, JSStringRef /* target */, JSObjectRef /* optionsArray */)
  613. {
  614. // FIXME: Implement
  615. return false;
  616. }
  617. void TestRunner::setCacheModel(int)
  618. {
  619. // FIXME: Implement
  620. }
  621. bool TestRunner::isCommandEnabled(JSStringRef /*name*/)
  622. {
  623. printf("ERROR: TestRunner::isCommandEnabled() not implemented\n");
  624. return false;
  625. }
  626. void TestRunner::clearAllApplicationCaches()
  627. {
  628. // FIXME: Implement to support application cache quotas.
  629. }
  630. void TestRunner::clearApplicationCacheForOrigin(JSStringRef origin)
  631. {
  632. // FIXME: Implement to support deleting all application cache for an origin.
  633. }
  634. void TestRunner::setApplicationCacheOriginQuota(unsigned long long quota)
  635. {
  636. // FIXME: Implement to support application cache quotas.
  637. }
  638. JSValueRef TestRunner::originsWithApplicationCache(JSContextRef context)
  639. {
  640. // FIXME: Implement to get origins that have application caches.
  641. return JSValueMakeUndefined(context);
  642. }
  643. long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef name)
  644. {
  645. // FIXME: Implement to get disk usage by all application caches for an origin.
  646. return 0;
  647. }
  648. void TestRunner::clearAllDatabases()
  649. {
  650. COMPtr<IWebDatabaseManager> databaseManager;
  651. COMPtr<IWebDatabaseManager> tmpDatabaseManager;
  652. if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager)))
  653. return;
  654. if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager)))
  655. return;
  656. databaseManager->deleteAllDatabases();
  657. }
  658. void TestRunner::overridePreference(JSStringRef key, JSStringRef value)
  659. {
  660. COMPtr<IWebView> webView;
  661. if (FAILED(frame->webView(&webView)))
  662. return;
  663. COMPtr<IWebPreferences> preferences;
  664. if (FAILED(webView->preferences(&preferences)))
  665. return;
  666. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  667. if (!prefsPrivate)
  668. return;
  669. BSTR keyBSTR = JSStringCopyBSTR(key);
  670. BSTR valueBSTR = JSStringCopyBSTR(value);
  671. prefsPrivate->setPreferenceForTest(keyBSTR, valueBSTR);
  672. SysFreeString(keyBSTR);
  673. SysFreeString(valueBSTR);
  674. }
  675. void TestRunner::setDatabaseQuota(unsigned long long quota)
  676. {
  677. COMPtr<IWebDatabaseManager> databaseManager;
  678. COMPtr<IWebDatabaseManager> tmpDatabaseManager;
  679. if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager)))
  680. return;
  681. if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager)))
  682. return;
  683. databaseManager->setQuota(TEXT("file:///"), quota);
  684. }
  685. void TestRunner::goBack()
  686. {
  687. // FIXME: implement to enable loader/navigation-while-deferring-loads.html
  688. }
  689. void TestRunner::setDefersLoading(bool)
  690. {
  691. // FIXME: implement to enable loader/navigation-while-deferring-loads.html
  692. }
  693. void TestRunner::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
  694. {
  695. COMPtr<IWebViewPrivate> webView;
  696. if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
  697. return;
  698. BSTR schemeBSTR = JSStringCopyBSTR(scheme);
  699. webView->setDomainRelaxationForbiddenForURLScheme(forbidden, schemeBSTR);
  700. SysFreeString(schemeBSTR);
  701. }
  702. void TestRunner::setAppCacheMaximumSize(unsigned long long size)
  703. {
  704. printf("ERROR: TestRunner::setAppCacheMaximumSize() not implemented\n");
  705. }
  706. static _bstr_t bstrT(JSStringRef jsString)
  707. {
  708. // The false parameter tells the _bstr_t constructor to adopt the BSTR we pass it.
  709. return _bstr_t(JSStringCopyBSTR(jsString), false);
  710. }
  711. void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
  712. {
  713. COMPtr<IWebViewPrivate> webView;
  714. if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
  715. return;
  716. webView->addOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains);
  717. }
  718. void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
  719. {
  720. COMPtr<IWebViewPrivate> webView;
  721. if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
  722. return;
  723. webView->removeOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains);
  724. }
  725. void TestRunner::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy)
  726. {
  727. // FIXME: implement
  728. }
  729. void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
  730. {
  731. COMPtr<IWebViewPrivate> webView;
  732. if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
  733. return;
  734. COMPtr<IWebScriptWorld> world;
  735. if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
  736. return;
  737. webView->addUserScriptToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0, runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd);
  738. }
  739. void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames)
  740. {
  741. COMPtr<IWebViewPrivate> webView;
  742. if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
  743. return;
  744. COMPtr<IWebScriptWorld> world;
  745. if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
  746. return;
  747. webView->addUserStyleSheetToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0);
  748. }
  749. void TestRunner::setDeveloperExtrasEnabled(bool enabled)
  750. {
  751. COMPtr<IWebView> webView;
  752. if (FAILED(frame->webView(&webView)))
  753. return;
  754. COMPtr<IWebPreferences> preferences;
  755. if (FAILED(webView->preferences(&preferences)))
  756. return;
  757. COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
  758. if (!prefsPrivate)
  759. return;
  760. prefsPrivate->setDeveloperExtrasEnabled(enabled);
  761. }
  762. void TestRunner::showWebInspector()
  763. {
  764. COMPtr<IWebView> webView;
  765. if (FAILED(frame->webView(&webView)))
  766. return;
  767. COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
  768. if (!viewPrivate)
  769. return;
  770. COMPtr<IWebInspector> inspector;
  771. if (SUCCEEDED(viewPrivate->inspector(&inspector)))
  772. inspector->show();
  773. }
  774. void TestRunner::closeWebInspector()
  775. {
  776. COMPtr<IWebView> webView;
  777. if (FAILED(frame->webView(&webView)))
  778. return;
  779. COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
  780. if (!viewPrivate)
  781. return;
  782. COMPtr<IWebInspector> inspector;
  783. if (FAILED(viewPrivate->inspector(&inspector)))
  784. return;
  785. inspector->close();
  786. }
  787. void TestRunner::evaluateInWebInspector(long callId, JSStringRef script)
  788. {
  789. COMPtr<IWebView> webView;
  790. if (FAILED(frame->webView(&webView)))
  791. return;
  792. COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
  793. if (!viewPrivate)
  794. return;
  795. COMPtr<IWebInspector> inspector;
  796. if (FAILED(viewPrivate->inspector(&inspector)))
  797. return;
  798. COMPtr<IWebInspectorPrivate> inspectorPrivate(Query, inspector);
  799. if (!inspectorPrivate)
  800. return;
  801. inspectorPrivate->evaluateInFrontend(callId, bstrT(script).GetBSTR());
  802. }
  803. typedef HashMap<unsigned, COMPtr<IWebScriptWorld> > WorldMap;
  804. static WorldMap& worldMap()
  805. {
  806. static WorldMap& map = *new WorldMap;
  807. return map;
  808. }
  809. unsigned worldIDForWorld(IWebScriptWorld* world)
  810. {
  811. WorldMap::const_iterator end = worldMap().end();
  812. for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) {
  813. if (it->value == world)
  814. return it->key;
  815. }
  816. return 0;
  817. }
  818. void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
  819. {
  820. // FIXME: Implement this.
  821. }
  822. void TestRunner::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
  823. {
  824. COMPtr<IWebFramePrivate> framePrivate(Query, frame);
  825. if (!framePrivate)
  826. return;
  827. // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world
  828. // that is created once and cached forever.
  829. COMPtr<IWebScriptWorld> world;
  830. if (!worldID) {
  831. if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
  832. return;
  833. } else {
  834. COMPtr<IWebScriptWorld>& worldSlot = worldMap().add(worldID, 0).iterator->value;
  835. if (!worldSlot && FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(worldSlot), reinterpret_cast<void**>(&worldSlot))))
  836. return;
  837. world = worldSlot;
  838. }
  839. BSTR result;
  840. if (FAILED(framePrivate->stringByEvaluatingJavaScriptInScriptWorld(world.get(), globalObject, bstrT(script).GetBSTR(), &result)))
  841. return;
  842. SysFreeString(result);
  843. }
  844. void TestRunner::removeAllVisitedLinks()
  845. {
  846. COMPtr<IWebHistory> history;
  847. if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
  848. return;
  849. COMPtr<IWebHistory> sharedHistory;
  850. if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory)
  851. return;
  852. COMPtr<IWebHistoryPrivate> sharedHistoryPrivate;
  853. if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate)))
  854. return;
  855. sharedHistoryPrivate->removeAllVisitedLinks();
  856. }
  857. void TestRunner::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL)
  858. {
  859. }
  860. void TestRunner::apiTestGoToCurrentBackForwardItem()
  861. {
  862. COMPtr<IWebView> webView;
  863. if (FAILED(frame->webView(&webView)))
  864. return;
  865. COMPtr<IWebBackForwardList> backForwardList;
  866. if (FAILED(webView->backForwardList(&backForwardList)))
  867. return;
  868. COMPtr<IWebHistoryItem> item;
  869. if (FAILED(backForwardList->currentItem(&item)))
  870. return;
  871. BOOL success;
  872. webView->goToBackForwardItem(item.get(), &success);
  873. }
  874. void TestRunner::setWebViewEditable(bool)
  875. {
  876. }
  877. void TestRunner::authenticateSession(JSStringRef, JSStringRef, JSStringRef)
  878. {
  879. }
  880. void TestRunner::abortModal()
  881. {
  882. }
  883. void TestRunner::setSerializeHTTPLoads(bool)
  884. {
  885. // FIXME: Implement.
  886. }
  887. void TestRunner::syncLocalStorage()
  888. {
  889. // FIXME: Implement.
  890. }
  891. void TestRunner::observeStorageTrackerNotifications(unsigned number)
  892. {
  893. // FIXME: Implement.
  894. }
  895. void TestRunner::deleteAllLocalStorage()
  896. {
  897. // FIXME: Implement.
  898. }
  899. JSValueRef TestRunner::originsWithLocalStorage(JSContextRef context)
  900. {
  901. // FIXME: Implement.
  902. return JSValueMakeUndefined(context);
  903. }
  904. long long TestRunner::localStorageDiskUsageForOrigin(JSStringRef originIdentifier)
  905. {
  906. // FIXME: Implement to support getting local storage disk usage for an origin.
  907. return 0;
  908. }
  909. void TestRunner::deleteLocalStorageForOrigin(JSStringRef URL)
  910. {
  911. // FIXME: Implement.
  912. }
  913. void TestRunner::setTextDirection(JSStringRef direction)
  914. {
  915. COMPtr<IWebFramePrivate> framePrivate(Query, frame);
  916. if (!framePrivate)
  917. return;
  918. framePrivate->setTextDirection(bstrT(direction).GetBSTR());
  919. }
  920. void TestRunner::addChromeInputField()
  921. {
  922. }
  923. void TestRunner::removeChromeInputField()
  924. {
  925. }
  926. void TestRunner::focusWebView()
  927. {
  928. }
  929. void TestRunner::setBackingScaleFactor(double)
  930. {
  931. }
  932. void TestRunner::grantWebNotificationPermission(JSStringRef origin)
  933. {
  934. }
  935. void TestRunner::denyWebNotificationPermission(JSStringRef jsOrigin)
  936. {
  937. }
  938. void TestRunner::removeAllWebNotificationPermissions()
  939. {
  940. }
  941. void TestRunner::simulateWebNotificationClick(JSValueRef jsNotification)
  942. {
  943. }
  944. void TestRunner::simulateLegacyWebNotificationClick(JSStringRef title)
  945. {
  946. // FIXME: Implement.
  947. }
  948. void TestRunner::resetPageVisibility()
  949. {
  950. // FIXME: Implement this.
  951. }
  952. void TestRunner::setPageVisibility(const char*)
  953. {
  954. // FIXME: Implement this.
  955. }
  956. void TestRunner::setAutomaticLinkDetectionEnabled(bool)
  957. {
  958. // FIXME: Implement this.
  959. }
  960. void TestRunner::setStorageDatabaseIdleInterval(double)
  961. {
  962. // FIXME: Implement this.
  963. }
  964. void TestRunner::closeIdleLocalStorageDatabases()
  965. {
  966. // FIXME: Implement this.
  967. }