/*
 * Copyright (C) 2010-2017 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.
 */

interface TestRunner {
    readonly attribute boolean isWebKit2;

    // The basics.
    void dumpAsText(boolean dumpPixels);
    void dumpChildFramesAsText();
    void waitForPolicyDelegate();
    void waitUntilDone();
    void notifyDone();
    double preciseTime();
    readonly attribute double timeout;

    // Downloads.
    void waitUntilDownloadFinished();
    void setShouldLogDownloadCallbacks(boolean value);

    // Other dumping.
    void dumpBackForwardList();
    void dumpChildFrameScrollPositions();
    void dumpEditingCallbacks();
    void dumpSelectionRect();
    void dumpStatusCallbacks();
    void dumpTitleChanges();
    void dumpFullScreenCallbacks();
    void dumpFrameLoadCallbacks();
    void dumpProgressFinishedCallback();
    void dumpResourceLoadCallbacks();
    void dumpResourceResponseMIMETypes();
    void dumpWillCacheResponse();
    void dumpApplicationCacheDelegateCallbacks();
    void dumpDatabaseCallbacks();
    void dumpDOMAsWebArchive();
    void dumpPolicyDelegateCallbacks();

    void clearDOMCaches();
    void clearDOMCache(DOMString origin);
    boolean hasDOMCache(DOMString origin);
    unsigned long domCacheSize(DOMString origin);

    // Special options.
    void keepWebHistory();
    void setAcceptsEditing(boolean value);
    void setCanOpenWindows(boolean value);
    void setCloseRemainingWindowsWhenComplete(boolean value);
    void setXSSAuditorEnabled(boolean value);
    void setAllowUniversalAccessFromFileURLs(boolean value);
    void setAllowFileAccessFromFileURLs(boolean value);
    void setNeedsStorageAccessFromFileURLsQuirk(boolean value);
    void setPluginsEnabled(boolean value);
    void setJavaScriptCanAccessClipboard(boolean value);
    void setPrivateBrowsingEnabled(boolean value);
    void setUseDashboardCompatibilityMode(boolean value);
    void setPopupBlockingEnabled(boolean value);
    void setAuthorAndUserStylesEnabled(boolean value);
    void setCustomPolicyDelegate(boolean enabled, boolean permissive);
    void addOriginAccessWhitelistEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
    void removeOriginAccessWhitelistEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
    void setUserStyleSheetEnabled(boolean value);
    void setUserStyleSheetLocation(DOMString location);
    void setSpatialNavigationEnabled(boolean value);
    void setTabKeyCyclesThroughElements(boolean enabled);
    void setSerializeHTTPLoads();
    void dispatchPendingLoadRequests();
    void setCacheModel(long model);
    void setAsynchronousSpellCheckingEnabled(boolean value);
    void setPrinting();
    void setShouldDecideNavigationPolicyAfterDelay(boolean value);
    void setShouldDecideResponsePolicyAfterDelay(boolean value);
    void setNavigationGesturesEnabled(boolean value);
    void setIgnoresViewportScaleLimits(boolean value);
    void setShouldDownloadUndisplayableMIMETypes(boolean value);

    // Special DOM functions.
    void clearBackForwardList();
    void execCommand(DOMString name, DOMString argument);
    boolean isCommandEnabled(DOMString name);
    unsigned long windowCount();

    // Special DOM variables.
    attribute boolean globalFlag;

    // Repaint testing.
    void testRepaint();
    void repaintSweepHorizontally();
    void display();
    void displayAndTrackRepaints();

    // Failed load condition testing
    void forceImmediateCompletion();

    // Printing
    boolean isPageBoxVisible(long pageIndex);

    [PassContext] void setValueForUser(object element, DOMString value);

    // UserContent testing.
    void addUserScript(DOMString source, boolean runAtStart, boolean allFrames);
    void addUserStyleSheet(DOMString source, boolean allFrames);

    // Local storage API
    void clearAllDatabases();
    void setDatabaseQuota(unsigned long long quota);
    DOMString pathToLocalResource(DOMString url);

    attribute double databaseDefaultQuota;
    attribute double databaseMaxQuota;

    // Application Cache API
    void clearAllApplicationCaches();
    void setAppCacheMaximumSize(unsigned long long size);
    long long applicationCacheDiskUsageForOrigin(DOMString origin);
    void clearApplicationCacheForOrigin(DOMString name);
    void disallowIncreaseForApplicationCacheQuota();
    object originsWithApplicationCache();

    // Text search testing.
    boolean findString(DOMString target, object optionsArray);

    // Evaluating script in a special context.
    [PassContext] void evaluateScriptInIsolatedWorld(unsigned long worldID, DOMString script);

    // For Web Inspector tests
    void showWebInspector();
    void closeWebInspector();
    void evaluateInWebInspector(DOMString script);
    readonly attribute DOMString inspectorTestStubURL;

    void setPOSIXLocale(DOMString locale);

    void setTextDirection(DOMString direction);

    void setWillSendRequestReturnsNull(boolean flag);
    void setWillSendRequestReturnsNullOnRedirect(boolean flag);
    void setWillSendRequestAddsHTTPBody(DOMString body);
    
    void setShouldStayOnPageAfterHandlingBeforeUnload(boolean flag);

    void setDefersLoading(boolean flag);
    void setStopProvisionalFrameLoads();

    readonly attribute boolean didReceiveServerRedirectForProvisionalNavigation;
    void clearDidReceiveServerRedirectForProvisionalNavigation();

    // Focus testing.
    void addChromeInputField(object callback);
    void removeChromeInputField(object callback);
    void focusWebView(object callback);

    // Window/view state
    void setBackingScaleFactor(double backingScaleFactor, object callback);

    void setWindowIsKey(boolean isKey);
    void setViewSize(double width, double height);

    // Cookies testing
    void setAlwaysAcceptCookies(boolean accept);
    void setCookieStoragePartitioningEnabled(boolean enabled);

    void overridePreference(DOMString preference, DOMString value);

    // Page Visibility API
    void setPageVisibility(DOMString state);
    void resetPageVisibility();

    // Control full screen behavior.
    void setHasCustomFullScreenBehavior(boolean value);

    // Web notifications support
    void grantWebNotificationPermission(DOMString origin);
    void denyWebNotificationPermission(DOMString origin);
    void removeAllWebNotificationPermissions();
    void simulateWebNotificationClick(object notification);

    // Geolocation
    void setGeolocationPermission(boolean value);
    void setMockGeolocationPosition(double latitude, double longitude, double accuracy, optional object altitude, optional object altitudeAccuracy, optional object heading, optional object speed, optional object floorLevel);
    void setMockGeolocationPositionUnavailableError(DOMString errorMessage);
    boolean isGeolocationProviderActive();

    // MediaStream
    void setUserMediaPermission(boolean value);
    void resetUserMediaPermission();
    void setUserMediaPersistentPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin);
    unsigned long userMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
    void resetUserMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);

    // Audio testing.
    [PassContext] void setAudioResult(object data);

    boolean callShouldCloseOnWebView();

    // Work queue.
    void queueBackNavigation(unsigned long howFarBackward);
    void queueForwardNavigation(unsigned long howFarForward);
    void queueLoad(DOMString url, DOMString target, optional boolean shouldOpenExternalURLs);
    void queueLoadHTMLString(DOMString content, optional DOMString baseURL, optional DOMString unreachableURL);
    void queueReload();
    void queueLoadingScript(DOMString script);
    void queueNonLoadingScript(DOMString script);

    // Authentication
    void setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(boolean value);
    void setHandlesAuthenticationChallenges(boolean value);
    void setShouldLogCanAuthenticateAgainstProtectionSpace(boolean value);
    void setAuthenticationUsername(DOMString username);
    void setAuthenticationPassword(DOMString password);

    void setAllowsAnySSLCertificate(boolean value);

    // Secure text input mode (Mac only)
    readonly attribute boolean secureEventInputIsEnabled;
    
    // Override plugin load policy.
    void setBlockAllPlugins(boolean shouldBlock);
    void setPluginSupportedMode(DOMString mode);

    // Hooks to the JSC compiler.
    object failNextNewCodeBlock();
    object numberOfDFGCompiles(object function);
    object neverInlineFunction(object function);

    // Swipe gestures
    void installDidBeginSwipeCallback(object callback);
    void installWillEndSwipeCallback(object callback);
    void installDidEndSwipeCallback(object callback);
    void installDidRemoveSwipeSnapshotCallback(object callback);

    unsigned long imageCountInGeneralPasteboard();

    // UI Process Testing
    void runUIScript(DOMString script, object callback);

    void clearTestRunnerCallbacks();

    void accummulateLogsForChannel(DOMString channel);

    // Gamepad
    void setMockGamepadDetails(unsigned long index, DOMString id, unsigned long axisCount, unsigned long buttonCount);
    void setMockGamepadAxisValue(unsigned long index, unsigned long axisIndex, double value);
    void setMockGamepadButtonValue(unsigned long index, unsigned long buttonIndex, double value);
    void connectMockGamepad(unsigned long index);
    void disconnectMockGamepad(unsigned long index);

    // Resource Load Statistics
    void installStatisticsDidModifyDataRecordsCallback(object callback);
    void installStatisticsDidScanDataRecordsCallback(object callback);
    void installStatisticsDidRunTelemetryCallback(object callback);
    void setStatisticsLastSeen(DOMString hostName, double seconds);
    void setStatisticsPrevalentResource(DOMString hostName, boolean value);
    void setStatisticsVeryPrevalentResource(DOMString hostName, boolean value);
    boolean isStatisticsPrevalentResource(DOMString hostName);
    boolean isStatisticsVeryPrevalentResource(DOMString hostName);
    boolean isStatisticsRegisteredAsSubFrameUnder(DOMString subFrameHost, DOMString topFrameHost);
    boolean isStatisticsRegisteredAsRedirectingTo(DOMString hostRedirectedFrom, DOMString hostRedirectedTo);
    void setStatisticsHasHadUserInteraction(DOMString hostName, boolean value);
    void setStatisticsHasHadNonRecentUserInteraction(DOMString hostName);
    boolean isStatisticsHasHadUserInteraction(DOMString hostName);
    void setStatisticsGrandfathered(DOMString hostName, boolean value);
    boolean isStatisticsGrandfathered(DOMString hostName);
    void setStatisticsSubframeUnderTopFrameOrigin(DOMString hostName, DOMString topFrameHostName);
    void setStatisticsSubresourceUnderTopFrameOrigin(DOMString hostName, DOMString topFrameHostName);
    void setStatisticsSubresourceUniqueRedirectTo(DOMString hostName, DOMString hostNameRedirectedTo);
    void setStatisticsSubresourceUniqueRedirectFrom(DOMString hostName, DOMString hostNameRedirectedTo);
    void setStatisticsTopFrameUniqueRedirectTo(DOMString hostName, DOMString hostNameRedirectedTo);
    void setStatisticsTopFrameUniqueRedirectFrom(DOMString hostName, DOMString hostNameRedirectedTo);
    void setStatisticsTimeToLiveUserInteraction(double seconds);
    void setStatisticsTimeToLiveCookiePartitionFree(double seconds);
    void statisticsNotifyObserver();
    void statisticsProcessStatisticsAndDataRecords();
    void statisticsUpdateCookiePartitioning(object callback);
    void statisticsSetShouldPartitionCookiesForHost(DOMString hostName, boolean value, object callback);
    void statisticsSubmitTelemetry();
    void setStatisticsNotifyPagesWhenDataRecordsWereScanned(boolean value);
    void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(boolean value);
    void setStatisticsNotifyPagesWhenTelemetryWasCaptured(boolean value);
    void setStatisticsMinimumTimeBetweenDataRecordsRemoval(double seconds);
    void setStatisticsGrandfatheringTime(double seconds);
    void setStatisticsMaxStatisticsEntries(unsigned long entries);
    void setStatisticsPruneEntriesDownTo(unsigned long entries);
    void statisticsClearInMemoryAndPersistentStore(object callback);
    void statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(unsigned long hours, object callback);
    void statisticsClearThroughWebsiteDataRemoval(object callback);
    void statisticsResetToConsistentState();

    // Storage Access API
    void setStorageAccessAPIEnabled(boolean enabled);
    void getAllStorageAccessEntries(object callback);

    // Open panel
    void setOpenPanelFiles(object filesArray);

    void setWebRTCLegacyAPIEnabled(boolean value);

    void terminateNetworkProcess();
    void terminateServiceWorkerProcess();

    readonly attribute boolean didCancelClientRedirect;

    void removeAllSessionCredentials(object callback);

    void getApplicationManifestThen(object callback);

    void installFakeHelvetica(DOMString configuration);
};
