| /* |
| * Copyright (C) 2010, 2015-2016 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef TestController_h |
| #define TestController_h |
| |
| #include "GeolocationProviderMock.h" |
| #include "WebNotificationProvider.h" |
| #include "WorkQueueManager.h" |
| #include <WebKit/WKRetainPtr.h> |
| #include <string> |
| #include <vector> |
| #include <wtf/HashMap.h> |
| #include <wtf/Vector.h> |
| #include <wtf/text/StringHash.h> |
| |
| OBJC_CLASS WKWebViewConfiguration; |
| |
| namespace WTR { |
| |
| class TestInvocation; |
| class OriginSettings; |
| class PlatformWebView; |
| class EventSenderProxy; |
| struct TestCommand; |
| struct TestOptions; |
| |
| // FIXME: Rename this TestRunner? |
| class TestController { |
| public: |
| static TestController& singleton(); |
| |
| static const unsigned viewWidth; |
| static const unsigned viewHeight; |
| |
| static const unsigned w3cSVGViewWidth; |
| static const unsigned w3cSVGViewHeight; |
| |
| static const double defaultShortTimeout; |
| static const double noTimeout; |
| |
| TestController(int argc, const char* argv[]); |
| ~TestController(); |
| |
| bool verbose() const { return m_verbose; } |
| |
| WKStringRef injectedBundlePath() const { return m_injectedBundlePath.get(); } |
| WKStringRef testPluginDirectory() const { return m_testPluginDirectory.get(); } |
| |
| PlatformWebView* mainWebView() { return m_mainWebView.get(); } |
| WKContextRef context() { return m_context.get(); } |
| |
| EventSenderProxy* eventSenderProxy() { return m_eventSenderProxy.get(); } |
| |
| bool shouldUseRemoteLayerTree() const { return m_shouldUseRemoteLayerTree; } |
| |
| // Runs the run loop until `done` is true or the timeout elapses. |
| bool useWaitToDumpWatchdogTimer() { return m_useWaitToDumpWatchdogTimer; } |
| void runUntil(bool& done, double timeoutSeconds); |
| void notifyDone(); |
| |
| bool shouldShowWebView() const { return m_shouldShowWebView; } |
| bool usingServerMode() const { return m_usingServerMode; } |
| void configureViewForTest(const TestInvocation&); |
| |
| bool beforeUnloadReturnValue() const { return m_beforeUnloadReturnValue; } |
| void setBeforeUnloadReturnValue(bool value) { m_beforeUnloadReturnValue = value; } |
| |
| void simulateWebNotificationClick(uint64_t notificationID); |
| |
| // Geolocation. |
| void setGeolocationPermission(bool); |
| void setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed); |
| void setMockGeolocationPositionUnavailableError(WKStringRef errorMessage); |
| void handleGeolocationPermissionRequest(WKGeolocationPermissionRequestRef); |
| bool isGeolocationProviderActive() const; |
| |
| // MediaStream. |
| String saltForOrigin(WKFrameRef, String); |
| void getUserMediaInfoForOrigin(WKFrameRef, WKStringRef originKey, bool&, WKRetainPtr<WKStringRef>&); |
| WKStringRef getUserMediaSaltForOrigin(WKFrameRef, WKStringRef originKey); |
| void setUserMediaPermission(bool); |
| void setUserMediaPersistentPermissionForOrigin(bool, WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString); |
| void handleUserMediaPermissionRequest(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef); |
| void handleCheckOfUserMediaPermissionForOrigin(WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, const WKUserMediaPermissionCheckRef&); |
| OriginSettings& settingsForOrigin(const String&); |
| unsigned userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString); |
| void resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString); |
| |
| // Policy delegate. |
| void setCustomPolicyDelegate(bool enabled, bool permissive); |
| |
| // Page Visibility. |
| void setHidden(bool); |
| |
| unsigned imageCountInGeneralPasteboard() const; |
| |
| bool resetStateToConsistentValues(const TestOptions&); |
| void resetPreferencesToConsistentValues(const TestOptions&); |
| |
| void terminateWebContentProcess(); |
| void reattachPageToWebProcess(); |
| |
| static const char* webProcessName(); |
| static const char* networkProcessName(); |
| static const char* databaseProcessName(); |
| |
| WorkQueueManager& workQueueManager() { return m_workQueueManager; } |
| |
| void setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool value) { m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges = value; } |
| void setHandlesAuthenticationChallenges(bool value) { m_handlesAuthenticationChallenges = value; } |
| void setAuthenticationUsername(String username) { m_authenticationUsername = username; } |
| void setAuthenticationPassword(String password) { m_authenticationPassword = password; } |
| |
| void setBlockAllPlugins(bool shouldBlock) { m_shouldBlockAllPlugins = shouldBlock; } |
| |
| void setShouldLogHistoryClientCallbacks(bool shouldLog) { m_shouldLogHistoryClientCallbacks = shouldLog; } |
| void setShouldLogCanAuthenticateAgainstProtectionSpace(bool shouldLog) { m_shouldLogCanAuthenticateAgainstProtectionSpace = shouldLog; } |
| |
| bool isCurrentInvocation(TestInvocation* invocation) const { return invocation == m_currentInvocation.get(); } |
| |
| void setShouldDecideNavigationPolicyAfterDelay(bool value) { m_shouldDecideNavigationPolicyAfterDelay = value; } |
| |
| void setNavigationGesturesEnabled(bool value); |
| void setIgnoresViewportScaleLimits(bool); |
| |
| void setShouldDownloadUndisplayableMIMETypes(bool value) { m_shouldDownloadUndisplayableMIMETypes = value; } |
| |
| private: |
| WKRetainPtr<WKPageConfigurationRef> generatePageConfiguration(WKContextConfigurationRef); |
| WKRetainPtr<WKContextConfigurationRef> generateContextConfiguration() const; |
| void initialize(int argc, const char* argv[]); |
| void createWebViewWithOptions(const TestOptions&); |
| void run(); |
| |
| void runTestingServerLoop(); |
| bool runTest(const char* pathOrURL); |
| |
| void platformInitialize(); |
| void platformDestroy(); |
| WKContextRef platformAdjustContext(WKContextRef, WKContextConfigurationRef); |
| void platformInitializeContext(); |
| void platformCreateWebView(WKPageConfigurationRef, const TestOptions&); |
| static PlatformWebView* platformCreateOtherPage(PlatformWebView* parentView, WKPageConfigurationRef, const TestOptions&); |
| void platformResetPreferencesToConsistentValues(); |
| void platformResetStateToConsistentValues(); |
| #if PLATFORM(COCOA) |
| void cocoaResetStateToConsistentValues(); |
| #endif |
| void platformConfigureViewForTest(const TestInvocation&); |
| void platformWillRunTest(const TestInvocation&); |
| void platformRunUntil(bool& done, double timeout); |
| void platformDidCommitLoadForFrame(WKPageRef, WKFrameRef); |
| WKPreferencesRef platformPreferences(); |
| void initializeInjectedBundlePath(); |
| void initializeTestPluginDirectory(); |
| |
| void ensureViewSupportsOptionsForTest(const TestInvocation&); |
| TestOptions testOptionsForTest(const TestCommand&) const; |
| void updatePlatformSpecificTestOptionsForTest(TestOptions&, const std::string& pathOrURL) const; |
| |
| void updateWebViewSizeForTest(const TestInvocation&); |
| void updateWindowScaleForTest(PlatformWebView*, const TestInvocation&); |
| |
| void decidePolicyForGeolocationPermissionRequestIfPossible(); |
| void decidePolicyForUserMediaPermissionRequestIfPossible(); |
| |
| // WKContextInjectedBundleClient |
| static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*); |
| static void didReceiveSynchronousMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*); |
| static WKTypeRef getInjectedBundleInitializationUserData(WKContextRef, const void *clientInfo); |
| |
| // WKPageInjectedBundleClient |
| static void didReceivePageMessageFromInjectedBundle(WKPageRef, WKStringRef messageName, WKTypeRef messageBody, const void*); |
| static void didReceiveSynchronousPageMessageFromInjectedBundle(WKPageRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*); |
| void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody); |
| WKRetainPtr<WKTypeRef> didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody); |
| WKRetainPtr<WKTypeRef> getInjectedBundleInitializationUserData(); |
| |
| void didReceiveKeyDownMessageFromInjectedBundle(WKDictionaryRef messageBodyDictionary, bool synchronous); |
| |
| // WKContextClient |
| static void networkProcessDidCrash(WKContextRef, const void*); |
| void networkProcessDidCrash(); |
| static void databaseProcessDidCrash(WKContextRef, const void*); |
| void databaseProcessDidCrash(); |
| |
| // WKPageNavigationClient |
| static void didCommitNavigation(WKPageRef, WKNavigationRef, WKTypeRef userData, const void*); |
| void didCommitNavigation(WKPageRef, WKNavigationRef); |
| |
| static void didFinishNavigation(WKPageRef, WKNavigationRef, WKTypeRef userData, const void*); |
| void didFinishNavigation(WKPageRef, WKNavigationRef); |
| |
| |
| // WKContextDownloadClient |
| static void downloadDidStart(WKContextRef, WKDownloadRef, const void*); |
| void downloadDidStart(WKContextRef, WKDownloadRef); |
| static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool* allowOverwrite, const void *clientInfo); |
| WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef, WKStringRef filename, bool*& allowOverwrite); |
| static void downloadDidFinish(WKContextRef, WKDownloadRef, const void*); |
| void downloadDidFinish(WKContextRef, WKDownloadRef); |
| static void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef, const void*); |
| void downloadDidFail(WKContextRef, WKDownloadRef, WKErrorRef); |
| static void downloadDidCancel(WKContextRef, WKDownloadRef, const void*); |
| void downloadDidCancel(WKContextRef, WKDownloadRef); |
| |
| static void processDidCrash(WKPageRef, const void* clientInfo); |
| void processDidCrash(); |
| |
| static void didBeginNavigationGesture(WKPageRef, const void*); |
| static void willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef, const void*); |
| static void didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef, const void*); |
| static void didRemoveNavigationGestureSnapshot(WKPageRef, const void*); |
| void didBeginNavigationGesture(WKPageRef); |
| void willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef); |
| void didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef); |
| void didRemoveNavigationGestureSnapshot(WKPageRef); |
| |
| static WKPluginLoadPolicy decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo); |
| WKPluginLoadPolicy decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription); |
| |
| |
| static void decidePolicyForNotificationPermissionRequest(WKPageRef, WKSecurityOriginRef, WKNotificationPermissionRequestRef, const void*); |
| void decidePolicyForNotificationPermissionRequest(WKPageRef, WKSecurityOriginRef, WKNotificationPermissionRequestRef); |
| |
| static void unavailablePluginButtonClicked(WKPageRef, WKPluginUnavailabilityReason, WKDictionaryRef, const void*); |
| |
| static bool canAuthenticateAgainstProtectionSpace(WKPageRef, WKProtectionSpaceRef, const void*); |
| bool canAuthenticateAgainstProtectionSpace(WKPageRef, WKProtectionSpaceRef); |
| |
| static void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef, const void*); |
| void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef); |
| |
| static void decidePolicyForNavigationAction(WKPageRef, WKNavigationActionRef, WKFramePolicyListenerRef, WKTypeRef, const void*); |
| void decidePolicyForNavigationAction(WKFramePolicyListenerRef); |
| |
| static void decidePolicyForNavigationResponse(WKPageRef, WKNavigationResponseRef, WKFramePolicyListenerRef, WKTypeRef, const void*); |
| void decidePolicyForNavigationResponse(WKNavigationResponseRef, WKFramePolicyListenerRef); |
| |
| // WKContextHistoryClient |
| static void didNavigateWithNavigationData(WKContextRef, WKPageRef, WKNavigationDataRef, WKFrameRef, const void*); |
| void didNavigateWithNavigationData(WKNavigationDataRef, WKFrameRef); |
| |
| static void didPerformClientRedirect(WKContextRef, WKPageRef, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef, const void*); |
| void didPerformClientRedirect(WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef); |
| |
| static void didPerformServerRedirect(WKContextRef, WKPageRef, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef, const void*); |
| void didPerformServerRedirect(WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef); |
| |
| static void didUpdateHistoryTitle(WKContextRef, WKPageRef, WKStringRef title, WKURLRef, WKFrameRef, const void*); |
| void didUpdateHistoryTitle(WKStringRef title, WKURLRef, WKFrameRef); |
| |
| static WKPageRef createOtherPage(WKPageRef, WKPageConfigurationRef, WKNavigationActionRef, WKWindowFeaturesRef, const void*); |
| |
| static void runModal(WKPageRef, const void* clientInfo); |
| static void runModal(PlatformWebView*); |
| |
| static const char* libraryPathForTesting(); |
| static const char* platformLibraryPathForTesting(); |
| |
| std::unique_ptr<TestInvocation> m_currentInvocation; |
| |
| bool m_verbose { false }; |
| bool m_printSeparators { false }; |
| bool m_usingServerMode { false }; |
| bool m_gcBetweenTests { false }; |
| bool m_shouldDumpPixelsForAllTests { false }; |
| std::vector<std::string> m_paths; |
| std::vector<std::string> m_allowedHosts; |
| WKRetainPtr<WKStringRef> m_injectedBundlePath; |
| WKRetainPtr<WKStringRef> m_testPluginDirectory; |
| |
| WebNotificationProvider m_webNotificationProvider; |
| |
| std::unique_ptr<PlatformWebView> m_mainWebView; |
| WKRetainPtr<WKContextRef> m_context; |
| WKRetainPtr<WKPageGroupRef> m_pageGroup; |
| |
| enum State { |
| Initial, |
| Resetting, |
| RunningTest |
| }; |
| State m_state { Initial }; |
| bool m_doneResetting { false }; |
| |
| bool m_useWaitToDumpWatchdogTimer { true }; |
| bool m_forceNoTimeout { false }; |
| |
| bool m_didPrintWebProcessCrashedMessage { false }; |
| bool m_shouldExitWhenWebProcessCrashes { true }; |
| |
| bool m_beforeUnloadReturnValue { true }; |
| |
| std::unique_ptr<GeolocationProviderMock> m_geolocationProvider; |
| Vector<WKRetainPtr<WKGeolocationPermissionRequestRef> > m_geolocationPermissionRequests; |
| bool m_isGeolocationPermissionSet { false }; |
| bool m_isGeolocationPermissionAllowed { false }; |
| |
| HashMap<String, RefPtr<OriginSettings>> m_cachedUserMediaPermissions; |
| |
| typedef Vector<std::pair<String, WKRetainPtr<WKUserMediaPermissionRequestRef>>> PermissionRequestList; |
| PermissionRequestList m_userMediaPermissionRequests; |
| |
| bool m_isUserMediaPermissionSet { false }; |
| bool m_isUserMediaPermissionAllowed { false }; |
| |
| bool m_policyDelegateEnabled { false }; |
| bool m_policyDelegatePermissive { false }; |
| bool m_shouldDownloadUndisplayableMIMETypes { false }; |
| |
| bool m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges { false }; |
| bool m_handlesAuthenticationChallenges { false }; |
| String m_authenticationUsername; |
| String m_authenticationPassword; |
| |
| bool m_shouldBlockAllPlugins { false }; |
| |
| bool m_forceComplexText { false }; |
| bool m_shouldUseAcceleratedDrawing { false }; |
| bool m_shouldUseRemoteLayerTree { false }; |
| |
| bool m_shouldLogCanAuthenticateAgainstProtectionSpace { false }; |
| bool m_shouldLogHistoryClientCallbacks { false }; |
| bool m_shouldShowWebView { false }; |
| |
| bool m_shouldDecideNavigationPolicyAfterDelay { false }; |
| |
| std::unique_ptr<EventSenderProxy> m_eventSenderProxy; |
| |
| WorkQueueManager m_workQueueManager; |
| }; |
| |
| struct TestCommand { |
| std::string pathOrURL; |
| std::string absolutePath; |
| bool shouldDumpPixels { false }; |
| std::string expectedPixelHash; |
| int timeout { 0 }; |
| bool dumpJSConsoleLogInStdErr { false }; |
| }; |
| |
| } // namespace WTR |
| |
| #endif // TestController_h |