/*
 * 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;
    readonly attribute boolean isIOSFamily;

    // The basics.
    undefined dumpAsText(boolean dumpPixels);
    undefined dumpChildFramesAsText();
    undefined waitForPolicyDelegate();
    undefined waitUntilDone();
    undefined notifyDone();
    double preciseTime(); // seconds since the epoch
    readonly attribute double timeout; // milliseconds

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

    const unsigned short RENDER_TREE_SHOW_ALL_LAYERS            = 1;
    const unsigned short RENDER_TREE_SHOW_LAYER_NESTING         = 2;
    const unsigned short RENDER_TREE_SHOW_COMPOSITED_LAYERS     = 4;
    const unsigned short RENDER_TREE_SHOW_OVERFLOW              = 8;
    const unsigned short RENDER_TREE_SHOW_SVG_GEOMETRY          = 16;
    const unsigned short RENDER_TREE_SHOW_LAYER_FRAGMENTS       = 32;
    undefined setRenderTreeDumpOptions(unsigned short options);

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

    undefined clearDOMCaches();
    undefined clearDOMCache(DOMString origin);
    boolean hasDOMCache(DOMString origin);
    unsigned long domCacheSize(DOMString origin);
    undefined setAllowStorageQuotaIncrease(boolean value);

    // Special options.
    undefined keepWebHistory();
    undefined setAcceptsEditing(boolean value);
    undefined preventPopupWindows();
    undefined setCustomPolicyDelegate(boolean enabled, boolean permissive);
    undefined addOriginAccessAllowListEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
    undefined removeOriginAccessAllowListEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
    undefined setUserStyleSheetEnabled(boolean value);
    undefined setUserStyleSheetLocation(DOMString location);
    undefined setTabKeyCyclesThroughElements(boolean enabled);
    undefined setSerializeHTTPLoads();
    undefined dispatchPendingLoadRequests();
    undefined setCacheModel(long model);
    undefined setAsynchronousSpellCheckingEnabled(boolean value);
    undefined setPrinting();
    undefined setShouldDecideNavigationPolicyAfterDelay(boolean value);
    undefined setShouldDecideResponsePolicyAfterDelay(boolean value);
    undefined setNavigationGesturesEnabled(boolean value);
    undefined setIgnoresViewportScaleLimits(boolean value);
    undefined setShouldDownloadUndisplayableMIMETypes(boolean value);

    // Special DOM functions.
    undefined clearBackForwardList();
    undefined execCommand(DOMString name, DOMString showUI, DOMString value);
    boolean isCommandEnabled(DOMString name);
    unsigned long windowCount();

    // Device Orientation Motion.
    undefined setShouldAllowDeviceOrientationAndMotionAccess(boolean value);

    // Special DOM variables.
    attribute boolean globalFlag;

    // Repaint testing.
    undefined testRepaint();
    undefined repaintSweepHorizontally();
    undefined display();
    undefined displayAndTrackRepaints();
    undefined displayOnLoadFinish();

    // Failed load condition testing
    undefined forceImmediateCompletion();

    // Printing
    boolean isPageBoxVisible(long pageIndex);

    undefined dumpAllHTTPRedirectedResponseHeaders();

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

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

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

    attribute double databaseDefaultQuota;
    attribute double databaseMaxQuota;

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

    // Text search testing.
    boolean findString(DOMString target, object optionsArray);
    undefined findStringMatchesInPage(DOMString target, object optionsArray);
    undefined replaceFindMatchesAtIndices(object matchIndicesArray, DOMString replacementText, boolean selectionOnly);

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

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

    undefined setPOSIXLocale(DOMString locale);

    undefined setTextDirection(DOMString direction);

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

    undefined setStopProvisionalFrameLoads();

    readonly attribute boolean didReceiveServerRedirectForProvisionalNavigation;
    undefined clearDidReceiveServerRedirectForProvisionalNavigation();

    // Focus testing.
    undefined addChromeInputField(object callback);
    undefined removeChromeInputField(object callback);
    undefined focusWebView(object callback);
    undefined setTextInChromeInputField(DOMString text, object callback);
    undefined getSelectedTextInChromeInputField(object callback);
    undefined selectChromeInputField(object callback);

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

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

    // Cookies testing
    undefined setAlwaysAcceptCookies(boolean accept);
    undefined setOnlyAcceptFirstPartyCookies(boolean accept);

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

    // Control full screen behavior.
    undefined setHasCustomFullScreenBehavior(boolean value);
    undefined setEnterFullscreenForElementCallback(object callback);
    undefined setExitFullscreenForElementCallback(object callback);

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

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

    // MediaStream
    undefined setUserMediaPermission(boolean value);
    undefined resetUserMediaPermission();
    undefined setUserMediaPersistentPermissionForOrigin(boolean permission, DOMString origin, DOMString parentOrigin);
    unsigned long userMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
    undefined resetUserMediaPermissionRequestCountForOrigin(DOMString origin, DOMString parentOrigin);
    readonly attribute boolean isDoingMediaCapture;

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

    boolean callShouldCloseOnWebView();

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

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

    undefined setAllowsAnySSLCertificate(boolean value);

    undefined setShouldSwapToEphemeralSessionOnNextNavigation(boolean value);
    undefined setShouldSwapToDefaultSessionOnNextNavigation(boolean value);

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

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

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

    unsigned long imageCountInGeneralPasteboard();

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

    undefined clearTestRunnerCallbacks();

    undefined accummulateLogsForChannel(DOMString channel);

    // Contextual menu actions
    undefined setAllowedMenuActions(object actions);
    undefined installCustomMenuAction(DOMString name, boolean dismissesAutomatically, object callback);

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

    // Resource Load Statistics
    undefined clearStatisticsDataForDomain(DOMString domain);
    boolean doesStatisticsDomainIDExistInDatabase(unsigned long domainID);
    undefined setStatisticsEnabled(boolean value);
    boolean isStatisticsEphemeral();
    undefined installStatisticsDidModifyDataRecordsCallback(object callback);
    undefined installStatisticsDidScanDataRecordsCallback(object callback);
    undefined setStatisticsDebugMode(boolean value, object completionHandler);
    undefined setStatisticsPrevalentResourceForDebugMode(DOMString hostName, object completionHandler);
    undefined setStatisticsLastSeen(DOMString hostName, double seconds, object completionHandler);
    undefined setStatisticsMergeStatistic(DOMString hostName, DOMString topFrameDomain1, DOMString topFrameDomain2, double lastSeen, boolean hadUserInteraction, double mostRecentUserInteraction, boolean isGrandfathered, boolean isPrevalent, boolean isVeryPrevalent, unsigned long dataRecordsRemoved, object completionHandler);
    undefined setStatisticsExpiredStatistic(DOMString hostName, unsigned long numberOfOperatingDaysPassed, boolean hadUserInteraction, boolean isScheduledForAllButCookieDataRemoval, boolean isPrevalent, object completionHandler);
    undefined setStatisticsPrevalentResource(DOMString hostName, boolean value, object completionHandler);
    undefined setStatisticsVeryPrevalentResource(DOMString hostName, boolean value, object completionHandler);
    boolean isStatisticsPrevalentResource(DOMString hostName);
    boolean isStatisticsVeryPrevalentResource(DOMString hostName);
    boolean isStatisticsRegisteredAsSubresourceUnder(DOMString subresourceHost, DOMString topFrameHost);
    boolean isStatisticsRegisteredAsSubFrameUnder(DOMString subFrameHost, DOMString topFrameHost);
    boolean isStatisticsRegisteredAsRedirectingTo(DOMString hostRedirectedFrom, DOMString hostRedirectedTo);
    undefined setStatisticsHasHadUserInteraction(DOMString hostName, boolean value, object completionHandler);
    boolean isStatisticsHasHadUserInteraction(DOMString hostName);
    boolean isStatisticsOnlyInDatabaseOnce(DOMString subHost, DOMString topHost);
    undefined setStatisticsGrandfathered(DOMString hostName, boolean value);
    boolean isStatisticsGrandfathered(DOMString hostName);
    undefined setStatisticsSubframeUnderTopFrameOrigin(DOMString hostName, DOMString topFrameHostName);
    undefined setStatisticsSubresourceUnderTopFrameOrigin(DOMString hostName, DOMString topFrameHostName);
    undefined setStatisticsSubresourceUniqueRedirectTo(DOMString hostName, DOMString hostNameRedirectedTo);
    undefined setStatisticsSubresourceUniqueRedirectFrom(DOMString hostName, DOMString hostNameRedirectedTo);
    undefined setStatisticsTopFrameUniqueRedirectTo(DOMString hostName, DOMString hostNameRedirectedTo);
    undefined setStatisticsTopFrameUniqueRedirectFrom(DOMString hostName, DOMString hostNameRedirectedTo);
    undefined setStatisticsCrossSiteLoadWithLinkDecoration(DOMString fromHost, DOMString toHost);
    undefined setStatisticsTimeToLiveUserInteraction(double seconds);
    boolean statisticsNotifyObserver();
    undefined statisticsProcessStatisticsAndDataRecords();
    undefined statisticsUpdateCookieBlocking(object completionHandler);
    undefined setStatisticsIsRunningTest(boolean value);
    undefined setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(boolean value);
    undefined setStatisticsMinimumTimeBetweenDataRecordsRemoval(double seconds);
    undefined setStatisticsGrandfatheringTime(double seconds);
    undefined setStatisticsMaxStatisticsEntries(unsigned long entries);
    undefined setStatisticsPruneEntriesDownTo(unsigned long entries);
    undefined statisticsClearInMemoryAndPersistentStore(object callback);
    undefined statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(unsigned long hours, object callback);
    undefined statisticsClearThroughWebsiteDataRemoval(object callback);
    undefined statisticsDeleteCookiesForHost(DOMString hostName, boolean includeHttpOnlyCookies);
    boolean isStatisticsHasLocalStorage(DOMString hostName);
    undefined setStatisticsCacheMaxAgeCap(double seconds);
    undefined statisticsResetToConsistentState(object completionHandler);
    boolean hasStatisticsIsolatedSession(DOMString hostName);
    undefined setStatisticsShouldDowngradeReferrer(boolean value, object callback);
    undefined setStatisticsShouldBlockThirdPartyCookies(boolean value, object callback, optional boolean onlyOnSitesWithoutUserInteraction);
    undefined setStatisticsFirstPartyWebsiteDataRemovalMode(boolean value, object callback);
    undefined statisticsSetToSameSiteStrictCookies(DOMString hostName, object callback);
    undefined statisticsSetFirstPartyHostCNAMEDomain(DOMString firstPartyURLString, DOMString cnameURLString, object callback);
    undefined statisticsSetThirdPartyCNAMEDomain(DOMString cnameURLString, object callback);
    undefined loadedSubresourceDomains(object callback);

    // Injected bundle form client.
    undefined installTextDidChangeInTextFieldCallback(object callback);
    undefined installTextFieldDidBeginEditingCallback(object callback);
    undefined installTextFieldDidEndEditingCallback(object callback);

    // Storage Access API
    undefined getAllStorageAccessEntries(object callback);

    // Open panel
    undefined setOpenPanelFiles(object filesArray);
    undefined setOpenPanelFilesMediaIcon(object mediaIcon);

    // Modal alerts
    undefined setShouldDismissJavaScriptAlertsAsynchronously(boolean value);
    undefined abortModal();

    undefined setCustomUserAgent(DOMString userAgent);

    undefined terminateGPUProcess();
    undefined terminateNetworkProcess();
    undefined terminateServiceWorkers();
    undefined setUseSeparateServiceWorkerProcess(boolean value);

    readonly attribute unsigned long serverTrustEvaluationCallbackCallsCount;

    readonly attribute boolean didCancelClientRedirect;

    undefined removeAllSessionCredentials(object callback);

    undefined getApplicationManifestThen(object callback);

    undefined installFakeHelvetica(DOMString configuration);

    undefined addMockCameraDevice(DOMString persistentId, DOMString label);
    undefined addMockMicrophoneDevice(DOMString persistentId, DOMString label);
    undefined addMockScreenDevice(DOMString persistentId, DOMString label);
    undefined clearMockMediaDevices();
    undefined removeMockMediaDevice(DOMString persistentId);
    undefined resetMockMediaDevices();
    undefined setMockCameraOrientation(unsigned long orientation);
    boolean isMockRealtimeMediaSourceCenterEnabled();
    undefined setMockCameraIsInterrupted(boolean isInterrupted);

    boolean hasAppBoundSession();
    undefined clearAppBoundSession();
    undefined setAppBoundDomains(object originsArray, object callback);
    boolean didLoadAppInitiatedRequest();
    boolean didLoadNonAppInitiatedRequest();

    undefined injectUserScript(DOMString string);
    readonly attribute unsigned long userScriptInjectedCount;

    undefined sendDisplayConfigurationChangedMessageForTesting();

    undefined setServiceWorkerFetchTimeout(double seconds);

    // WebAuthn
    undefined addTestKeyToKeychain(DOMString privateKeyBase64, DOMString attrLabel, DOMString applicationTagBase64);
    undefined cleanUpKeychain(DOMString attrLabel, optional DOMString applicationLabelBase64);
    boolean keyExistsInKeychain(DOMString attrLabel, DOMString applicationLabelBase64);

    // Private Click Measurement
    undefined clearPrivateClickMeasurement();
    undefined clearPrivateClickMeasurementsThroughWebsiteDataRemoval();
    undefined setPrivateClickMeasurementOverrideTimerForTesting(boolean value);
    undefined markAttributedPrivateClickMeasurementsAsExpiredForTesting();
    undefined setPrivateClickMeasurementEphemeralMeasurementForTesting(boolean value);
    undefined simulateResourceLoadStatisticsSessionRestart();
    undefined setPrivateClickMeasurementTokenPublicKeyURLForTesting(DOMString url);
    undefined setPrivateClickMeasurementTokenSignatureURLForTesting(DOMString url);
    undefined setPrivateClickMeasurementAttributionReportURLsForTesting(DOMString sourceURLString, DOMString destinationURLString);
    undefined markPrivateClickMeasurementsAsExpiredForTesting();
    undefined setPrivateClickMeasurementFraudPreventionValuesForTesting(DOMString unlinkableToken, DOMString secretToken, DOMString signature, DOMString keyID);
    undefined setPrivateClickMeasurementAppBundleIDForTesting(DOMString appBundleID);

    // SpeechRecognition
    undefined setIsSpeechRecognitionPermissionGranted(boolean value);

    // MediaKeySystem
    undefined setIsMediaKeySystemPermissionGranted(boolean value);

    undefined takeViewPortSnapshot(object callback);
};
