/*
 * Copyright (C) 2005-2020 Apple Inc. All rights reserved.
 *           (C) 2007 Graham Dennis (graham.dennis@gmail.com)
 *
 * 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
 */

#import "config.h"
#import "DumpRenderTree.h"

#import "AccessibilityController.h"
#import "DefaultPolicyDelegate.h"
#import "DumpRenderTreeDraggingInfo.h"
#import "DumpRenderTreePasteboard.h"
#import "DumpRenderTreeWindow.h"
#import "EditingDelegate.h"
#import "EventSendingController.h"
#import "FrameLoadDelegate.h"
#import "HistoryDelegate.h"
#import "JavaScriptThreading.h"
#import "LayoutTestSpellChecker.h"
#import "MockGeolocationProvider.h"
#import "MockWebNotificationProvider.h"
#import "NavigationController.h"
#import "ObjCPlugin.h"
#import "ObjCPluginFunction.h"
#import "PixelDumpSupport.h"
#import "PolicyDelegate.h"
#import "PoseAsClass.h"
#import "ResourceLoadDelegate.h"
#import "TestCommand.h"
#import "TestFeatures.h"
#import "TestOptions.h"
#import "TestRunner.h"
#import "UIDelegate.h"
#import "WebArchiveDumpSupport.h"
#import "WebCoreTestSupport.h"
#import "WorkQueue.h"
#import "WorkQueueItem.h"
#import <CoreFoundation/CoreFoundation.h>
#import <JavaScriptCore/InitializeThreading.h>
#import <JavaScriptCore/JSCConfig.h>
#import <JavaScriptCore/Options.h>
#import <JavaScriptCore/TestRunnerUtils.h>
#import <WebCore/LogInitialization.h>
#import <WebCore/NetworkStorageSession.h>
#import <WebKit/DOMElement.h>
#import <WebKit/DOMExtensions.h>
#import <WebKit/DOMRange.h>
#import <WebKit/WebArchive.h>
#import <WebKit/WebBackForwardList.h>
#import <WebKit/WebCache.h>
#import <WebKit/WebCoreStatistics.h>
#import <WebKit/WebDataSourcePrivate.h>
#import <WebKit/WebDatabaseManagerPrivate.h>
#import <WebKit/WebDeviceOrientationProviderMock.h>
#import <WebKit/WebDocumentPrivate.h>
#import <WebKit/WebEditingDelegate.h>
#import <WebKit/WebFeature.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/WebHistory.h>
#import <WebKit/WebHistoryItemPrivate.h>
#import <WebKit/WebInspector.h>
#import <WebKit/WebKitNSStringExtras.h>
#import <WebKit/WebPluginDatabase.h>
#import <WebKit/WebPreferenceKeysPrivate.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <WebKit/WebResourceLoadDelegate.h>
#import <WebKit/WebStorageManagerPrivate.h>
#import <WebKit/WebView.h>
#import <WebKit/WebViewPrivate.h>
#import <getopt.h>
#import <objc/runtime.h>
#import <wtf/Assertions.h>
#import <wtf/FastMalloc.h>
#import <wtf/NeverDestroyed.h>
#import <wtf/OSObjectPtr.h>
#import <wtf/ProcessPrivilege.h>
#import <wtf/RetainPtr.h>
#import <wtf/Threading.h>
#import <wtf/UniqueArray.h>
#import <wtf/WorkQueue.h>
#import <wtf/cocoa/CrashReporter.h>
#import <wtf/cocoa/TypeCastsCocoa.h>
#import <wtf/cocoa/VectorCocoa.h>
#import <wtf/text/StringBuilder.h>
#import <wtf/text/WTFString.h>

#if !PLATFORM(IOS_FAMILY)
#import <Carbon/Carbon.h>
#import <WebKit/WebDynamicScrollBarsView.h>
#endif

#if PLATFORM(IOS_FAMILY)
#import "DumpRenderTreeBrowserView.h"
#import "IOSLayoutTestCommunication.h"
#import "UIKitSPI.h"
#import <QuartzCore/QuartzCore.h>
#import <WebKit/WAKWindow.h>
#import <WebKit/WebCoreThread.h>
#import <WebKit/WebCoreThreadRun.h>
#import <WebKit/WebDOMOperations.h>
#import <fcntl.h>
#import <pal/spi/cg/CoreGraphicsSPI.h>
#endif

extern "C" {
#import <mach-o/getsect.h>
}

static RetainPtr<NSString> toNS(const std::string& string)
{
    return adoptNS([[NSString alloc] initWithUTF8String:string.c_str()]);
}

#if !PLATFORM(IOS_FAMILY)
@interface DumpRenderTreeApplication : NSApplication
@end

@interface DumpRenderTreeEvent : NSEvent
@end
#else
@interface ScrollViewResizerDelegate : NSObject
@end

@implementation ScrollViewResizerDelegate
- (void)view:(UIWebDocumentView *)view didSetFrame:(CGRect)newFrame oldFrame:(CGRect)oldFrame asResultOfZoom:(BOOL)wasResultOfZoom
{
    UIView *scrollView = [view superview];
    while (![scrollView isKindOfClass:[UIWebScrollView class]])
        scrollView = [scrollView superview];

    ASSERT(scrollView && [scrollView isKindOfClass:[UIWebScrollView class]]);
    const CGSize scrollViewSize = [scrollView bounds].size;
    CGSize contentSize = newFrame.size;
    contentSize.height = CGRound(std::max(CGRectGetMaxY(newFrame), scrollViewSize.height));
    [(UIWebScrollView *)scrollView setContentSize:contentSize];
}
@end
#endif

@interface NSURLRequest (PrivateThingsWeShouldntReallyUse)
+(void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString *)host;
@end

#if USE(APPKIT)
@interface NSSound ()
+ (void)_setAlertType:(NSUInteger)alertType;
@end
#endif

@interface WebView ()
- (BOOL)_flushCompositingChanges;
@end

#if !PLATFORM(IOS_FAMILY)
@interface WebView (WebViewInternalForTesting)
- (WebCore::Frame*)_mainCoreFrame;
@end
#endif

static void runTest(const std::string& testURL);

// Deciding when it's OK to dump out the state is a bit tricky.  All these must be true:
// - There is no load in progress
// - There is no work queued up (see workQueue var, below)
// - waitToDump==NO.  This means either waitUntilDone was never called, or it was called
//       and notifyDone was called subsequently.
// Note that the call to notifyDone and the end of the load can happen in either order.

volatile bool done;

RetainPtr<NavigationController> gNavigationController;
RefPtr<TestRunner> gTestRunner;

std::optional<WTR::TestOptions> mainFrameTestOptions;
WebFrame *mainFrame = nil;
// This is the topmost frame that is loading, during a given load, or nil when no load is 
// in progress.  Usually this is the same as the main frame, but not always.  In the case
// where a frameset is loaded, and then new content is loaded into one of the child frames,
// that child frame is the "topmost frame that is loading".
WebFrame *topLoadingFrame = nil; // !nil iff a load is in progress

#if PLATFORM(MAC)
RetainPtr<NSWindow> mainWindow;
#endif

RetainPtr<CFMutableSetRef> disallowedURLs = nullptr;
static RetainPtr<CFRunLoopTimerRef> waitToDumpWatchdog;

static RetainPtr<WebView>& globalWebView()
{
    static NeverDestroyed<RetainPtr<WebView>> globalWebView;
    return globalWebView;
}

// Delegates
static RetainPtr<FrameLoadDelegate>& frameLoadDelegate()
{
    static NeverDestroyed<RetainPtr<FrameLoadDelegate>> frameLoadDelegate;
    return frameLoadDelegate;
}

static RetainPtr<UIDelegate>& uiDelegate()
{
    static NeverDestroyed<RetainPtr<UIDelegate>> uiDelegate;
    return uiDelegate;
}

static RetainPtr<EditingDelegate>& editingDelegate()
{
    static NeverDestroyed<RetainPtr<EditingDelegate>> editingDelegate;
    return editingDelegate;
}

static RetainPtr<ResourceLoadDelegate>& resourceLoadDelegate()
{
    static NeverDestroyed<RetainPtr<ResourceLoadDelegate>> resourceLoadDelegate;
    return resourceLoadDelegate;
}

static RetainPtr<HistoryDelegate>& historyDelegate()
{
    static NeverDestroyed<RetainPtr<HistoryDelegate>> historyDelegate;
    return historyDelegate;
}

RetainPtr<PolicyDelegate> policyDelegate;
RetainPtr<DefaultPolicyDelegate> defaultPolicyDelegate;

#if PLATFORM(IOS_FAMILY)
static RetainPtr<ScrollViewResizerDelegate>& scrollViewResizerDelegate()
{
    static NeverDestroyed<RetainPtr<ScrollViewResizerDelegate>> scrollViewResizerDelegate;
    return scrollViewResizerDelegate;
}
#endif

static int dumpPixelsForAllTests;
static bool dumpPixelsForCurrentTest;
static int threaded;
static int dumpTree = YES;
static int useTimeoutWatchdog = YES;
static int forceComplexText;
static int useAcceleratedDrawing;
static int gcBetweenTests;
static int allowAnyHTTPSCertificateForAllowedHosts;
static int enableAllExperimentalFeatures = YES;
static int showWebView;
static int printTestCount;
static int checkForWorldLeaks;
static BOOL printSeparators;
static std::set<std::string> allowedHosts;
static std::string webCoreLogging;

static RetainPtr<CFStringRef>& persistentUserStyleSheetLocation()
{
    static NeverDestroyed<RetainPtr<CFStringRef>> persistentUserStyleSheetLocation;
    return persistentUserStyleSheetLocation;
}

static RetainPtr<WebHistoryItem>& prevTestBFItem()
{
    static NeverDestroyed<RetainPtr<WebHistoryItem>> _prevTestBFItem; // current b/f item at the end of the previous test.
    return _prevTestBFItem;
}

#if PLATFORM(IOS_FAMILY)
const CGRect layoutTestViewportRect = { {0, 0}, {static_cast<CGFloat>(TestRunner::viewWidth), static_cast<CGFloat>(TestRunner::viewHeight)} };
RetainPtr<DumpRenderTreeBrowserView> gWebBrowserView;
RetainPtr<DumpRenderTreeWebScrollView> gWebScrollView;
RetainPtr<DumpRenderTreeWindow> gDrtWindow;
#endif

void setPersistentUserStyleSheetLocation(CFStringRef url)
{
    persistentUserStyleSheetLocation() = url;
}

static bool shouldIgnoreWebCoreNodeLeaks(const std::string& urlString)
{
    static char* const ignoreSet[] = {
        // Keeping this infrastructure around in case we ever need it again.
    };
    static const int ignoreSetCount = sizeof(ignoreSet) / sizeof(char*);

    for (int i = 0; i < ignoreSetCount; i++) {
        // FIXME: ignore case
        std::string curIgnore(ignoreSet[i]);
        // Match at the end of the urlString.
        if (!urlString.compare(urlString.length() - curIgnore.length(), curIgnore.length(), curIgnore))
            return true;
    }
    return false;
}

#if !PLATFORM(IOS_FAMILY)
static NSSet *allowedFontFamilySet()
{
    static NeverDestroyed<RetainPtr<NSSet>> fontFamilySet = [NSSet setWithObjects:
        @"Ahem",
        @"Al Bayan",
        @"American Typewriter",
        @"Andale Mono",
        @"Apple Braille",
        @"Apple Color Emoji",
        @"Apple Chancery",
        @"Apple Garamond BT",
        @"Apple LiGothic",
        @"Apple LiSung",
        @"Apple Symbols",
        @"AppleGothic",
        @"AppleMyungjo",
        @"Arial Black",
        @"Arial Hebrew",
        @"Arial Narrow",
        @"Arial Rounded MT Bold",
        @"Arial Unicode MS",
        @"Arial",
        @"Avenir Next",
        @"Ayuthaya",
        @"Baghdad",
        @"Baskerville",
        @"BiauKai",
        @"Big Caslon",
        @"Brush Script MT",
        @"Chalkboard",
        @"Chalkduster",
        @"Charcoal CY",
        @"Cochin",
        @"Comic Sans MS",
        @"Copperplate",
        @"Corsiva Hebrew",
        @"Courier New",
        @"Courier",
        @"DecoType Naskh",
        @"Devanagari MT",
        @"Didot",
        @"Euphemia UCAS",
        @"Futura",
        @"GB18030 Bitmap",
        @"Geeza Pro",
        @"Geneva CY",
        @"Geneva",
        @"Georgia",
        @"Gill Sans",
        @"Gujarati MT",
        @"GungSeo",
        @"Gurmukhi MT",
        @"HeadLineA",
        @"Hei",
        @"Heiti SC",
        @"Heiti TC",
        @"Helvetica CY",
        @"Helvetica Neue",
        @"Helvetica",
        @"Herculanum",
        @"Hiragino Kaku Gothic Pro",
        @"Hiragino Kaku Gothic ProN",
        @"Hiragino Kaku Gothic Std",
        @"Hiragino Kaku Gothic StdN",
        @"Hiragino Maru Gothic Pro",
        @"Hiragino Maru Gothic ProN",
        @"Hiragino Mincho Pro",
        @"Hiragino Mincho ProN",
        @"Hiragino Sans",
        @"Hiragino Sans GB",
        @"Hoefler Text",
        @"Impact",
        @"InaiMathi",
        @"Kai",
        @"Kailasa",
        @"Kokonor",
        @"Krungthep",
        @"KufiStandardGK",
        @"Lao Sangam MN",
        @"LastResort",
        @"LiHei Pro",
        @"LiSong Pro",
        @"Lucida Grande",
        @"Marker Felt",
        @"Menlo",
        @"Microsoft Sans Serif",
        @"Monaco",
        @"Mshtakan",
        @"Nadeem",
        @"New Peninim MT",
        @"Optima",
        @"Osaka",
        @"Palatino",
        @"Papyrus",
        @"PCMyungjo",
        @"PilGi",
        @"PingFang HK",
        @"PingFang SC",
        @"PingFang TC",
        @"Plantagenet Cherokee",
        @"Raanana",
        @"Sathu",
        @"Silom",
        @"Skia",
        @"Snell Roundhand",
        @"Songti SC",
        @"Songti TC",
        @"STFangsong",
        @"STHeiti",
        @"STIX Two Math",
        @"STIX Two Text",
        @"STIXGeneral",
        @"STIXSizeOneSym",
        @"STKaiti",
        @"STSong",
        @"Symbol",
        @"Tahoma",
        @"Thonburi",
        @"Times New Roman",
        @"Times",
        @"Trebuchet MS",
        @"Verdana",
        @"Webdings",
        @"WebKit WeightWatcher",
        @"FontWithFeaturesOTF",
        @"FontWithFeaturesTTF",
        @"Wingdings 2",
        @"Wingdings 3",
        @"Wingdings",
        @"Zapf Dingbats",
        @"Zapfino",
        nil];

    return fontFamilySet.get().get();
}

static NSArray *fontAllowList()
{
    static NeverDestroyed availableFonts = [] {
        auto availableFonts = adoptNS([[NSMutableArray alloc] init]);
        for (NSString *fontFamily in allowedFontFamilySet()) {
            NSArray* fontsForFamily = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
            [availableFonts addObject:fontFamily];
            for (NSArray* fontInfo in fontsForFamily) {
                // Font name is the first entry in the array.
                [availableFonts addObject:[fontInfo objectAtIndex:0]];
            }
        }
        return availableFonts;
    }();
    return availableFonts.get().get();
}

// Activating system copies of these fonts overrides any others that could be preferred, such as ones
// in /Library/Fonts/Microsoft, and which don't always have the same metrics.
// FIXME: Switch to a solution from <rdar://problem/19553550> once it's available.
static void activateSystemCoreWebFonts()
{
    NSArray *coreWebFontNames = @[
        @"Andale Mono",
        @"Arial",
        @"Arial Black",
        @"Comic Sans MS",
        @"Courier New",
        @"Georgia",
        @"Impact",
        @"Times New Roman",
        @"Trebuchet MS",
        @"Verdana",
        @"Webdings"
    ];

    NSArray *fontFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:@"/Library/Fonts" isDirectory:YES]
        includingPropertiesForKeys:@[NSURLFileResourceTypeKey, NSURLNameKey] options:0 error:0];

    for (NSURL *fontURL in fontFiles) {
        NSString *resourceType;
        NSString *fileName;
        if (![fontURL getResourceValue:&resourceType forKey:NSURLFileResourceTypeKey error:0]
            || ![fontURL getResourceValue:&fileName forKey:NSURLNameKey error:0])
            continue;
        if (![resourceType isEqualToString:NSURLFileResourceTypeRegular])
            continue;

        // Activate all font variations, such as Arial Bold Italic.ttf. This algorithm is not 100% precise, as it
        // also activates e.g. Arial Unicode, which is not a variation of Arial.
        for (NSString *coreWebFontName in coreWebFontNames) {
            if ([fileName hasPrefix:coreWebFontName]) {
                CTFontManagerRegisterFontsForURL((CFURLRef)fontURL, kCTFontManagerScopeProcess, 0);
                break;
            }
        }
    }
}

static void activateTestingFonts()
{
    constexpr NSString *fontFileNames[] = {
        @"AHEM____.TTF",
        @"WebKitWeightWatcher100.ttf",
        @"WebKitWeightWatcher200.ttf",
        @"WebKitWeightWatcher300.ttf",
        @"WebKitWeightWatcher400.ttf",
        @"WebKitWeightWatcher500.ttf",
        @"WebKitWeightWatcher600.ttf",
        @"WebKitWeightWatcher700.ttf",
        @"WebKitWeightWatcher800.ttf",
        @"WebKitWeightWatcher900.ttf",
        @"FontWithFeatures.ttf",
        @"FontWithFeatures.otf",
    };

    NSURL *resourcesDirectory = [NSURL URLWithString:@"DumpRenderTree.resources" relativeToURL:[[NSBundle mainBundle] executableURL]];
    auto fontURLs = createNSArray(fontFileNames, [&] (NSString *name) {
        return [resourcesDirectory URLByAppendingPathComponent:name isDirectory:NO].absoluteURL;
    });

    CFArrayRef errors = nullptr;
    if (!CTFontManagerRegisterFontsForURLs((CFArrayRef)fontURLs.get(), kCTFontManagerScopeProcess, &errors)) {
        NSLog(@"Failed to activate fonts: %@", errors);
        CFRelease(errors);
        exit(1);
    }
}

static void adjustFonts()
{
    activateSystemCoreWebFonts();
    activateTestingFonts();
}

#else

static void activateFontIOS(const uint8_t* fontData, unsigned long length, std::string sectionName)
{
    auto data = adoptCF(CGDataProviderCreateWithData(nullptr, fontData, length, nullptr));
    if (!data) {
        fprintf(stderr, "Failed to create CGDataProviderRef for the %s font.\n", sectionName.c_str());
        exit(1);
    }

    auto cgFont = adoptCF(CGFontCreateWithDataProvider(data.get()));
    if (!cgFont) {
        fprintf(stderr, "Failed to create CGFontRef for the %s font.\n", sectionName.c_str());
        exit(1);
    }

    CFErrorRef error = nullptr;
    CTFontManagerRegisterGraphicsFont(cgFont.get(), &error);
    if (error) {
        fprintf(stderr, "Failed to add CGFont to CoreText for the %s font: %s.\n", sectionName.c_str(), CFStringGetCStringPtr(CFErrorCopyDescription(error), kCFStringEncodingUTF8));
        exit(1);
    }
}

static void activateFontsIOS()
{
    // __asm() requires a string literal, so we can't do this as either local variables or template parameters.
#define fontData(sectionName) \
{ \
    extern const uint8_t start##sectionName __asm("section$start$__DATA$" # sectionName); \
    extern const uint8_t end##sectionName __asm("section$end$__DATA$" # sectionName); \
    activateFontIOS(&start##sectionName, &end##sectionName - &start##sectionName, #sectionName); \
}
    fontData(Ahem);
    fontData(WeightWatcher100);
    fontData(WeightWatcher200);
    fontData(WeightWatcher300);
    fontData(WeightWatcher400);
    fontData(WeightWatcher500);
    fontData(WeightWatcher600);
    fontData(WeightWatcher700);
    fontData(WeightWatcher800);
    fontData(WeightWatcher900);
    fontData(FWFTTF);
    fontData(FWFOTF);
}
#endif // !PLATFORM(IOS_FAMILY)


#if PLATFORM(IOS_FAMILY)
static void adjustWebDocumentForFlexibleViewport(UIWebBrowserView *webBrowserView, UIWebScrollView *scrollView)
{
    // These values match MobileSafari's, see -[TabDocument _createDocumentView].
    [webBrowserView setMinimumScale:0.25f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setMaximumScale:5.0f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setViewportSize:CGSizeMake(UIWebViewStandardViewportWidth, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:UIEveryDocumentMask];

    // Adjust the viewport view and viewport to have similar behavior
    // as the browser.
    [(DumpRenderTreeBrowserView *)webBrowserView setScrollingUsesUIWebScrollView:YES];
    [webBrowserView setDelegate:scrollViewResizerDelegate().get()];

    CGRect screenBounds = [UIScreen mainScreen].bounds;
    CGRect viewportRect = CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height);

    [scrollView setBounds:viewportRect];
    [scrollView setFrame:viewportRect];

    [webBrowserView setMinimumSize:viewportRect.size];
    [webBrowserView setAutoresizes:YES];
    [webBrowserView setFrame:screenBounds];

    // This just affects text autosizing.
    [mainFrame _setVisibleSize:CGSizeMake(screenBounds.size.width, screenBounds.size.height)];
}

static void adjustWebDocumentForStandardViewport(UIWebBrowserView *webBrowserView, UIWebScrollView *scrollView)
{
    [webBrowserView setMinimumScale:1.0f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setMaximumScale:5.0f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setInitialScale:1.0f forDocumentTypes:UIEveryDocumentMask];

    [(DumpRenderTreeBrowserView *)webBrowserView setScrollingUsesUIWebScrollView:NO];
    [webBrowserView setDelegate: nil];

    [scrollView setBounds:layoutTestViewportRect];
    [scrollView setFrame:layoutTestViewportRect];

    [webBrowserView setMinimumSize:layoutTestViewportRect.size];
    [webBrowserView setAutoresizes:NO];
    [webBrowserView setFrame:layoutTestViewportRect];

    // This just affects text autosizing.
    [mainFrame _setVisibleSize:CGSizeMake(layoutTestViewportRect.size.width, layoutTestViewportRect.size.height)];

}
#endif

#if !PLATFORM(IOS_FAMILY)
@interface DRTMockScroller : NSScroller
@end

@implementation DRTMockScroller

- (NSRect)rectForPart:(NSScrollerPart)partCode
{
    if (partCode != NSScrollerKnob)
        return [super rectForPart:partCode];

    NSRect frameRect = [self frame];
    NSRect bounds = [self bounds];
    BOOL isHorizontal = frameRect.size.width > frameRect.size.height;
    CGFloat trackLength = isHorizontal ? bounds.size.width : bounds.size.height;
    CGFloat minKnobSize = isHorizontal ? bounds.size.height : bounds.size.width;
    CGFloat knobLength = std::max(minKnobSize, static_cast<CGFloat>(std::round(trackLength * [self knobProportion])));
    CGFloat knobPosition = static_cast<CGFloat>((std::round([self doubleValue] * (trackLength - knobLength))));

    if (isHorizontal)
        return NSMakeRect(bounds.origin.x + knobPosition, bounds.origin.y, knobLength, bounds.size.height);

    return NSMakeRect(bounds.origin.x, bounds.origin.y +  + knobPosition, bounds.size.width, knobLength);
}

- (void)drawKnob
{
    if (![self isEnabled])
        return;

    NSRect knobRect = [self rectForPart:NSScrollerKnob];

    static NeverDestroyed<RetainPtr<NSColor>> knobColor = [NSColor colorWithDeviceRed:0x80 / 255.0 green:0x80 / 255.0 blue:0x80 / 255.0 alpha:1];
    [knobColor.get() set];

    NSRectFill(knobRect);
}

- (void)drawRect:(NSRect)dirtyRect
{
    static NeverDestroyed<RetainPtr<NSColor>> trackColor = [NSColor colorWithDeviceRed:0xC0 / 255.0 green:0xC0 / 255.0 blue:0xC0 / 255.0 alpha:1];
    static NeverDestroyed<RetainPtr<NSColor>> disabledTrackColor = [NSColor colorWithDeviceRed:0xE0 / 255.0 green:0xE0 / 255.0 blue:0xE0 / 255.0 alpha:1];

    if ([self isEnabled])
        [trackColor.get() set];
    else
        [disabledTrackColor.get() set];

    NSRectFill(dirtyRect);

    [self drawKnob];
}

@end

static void registerMockScrollbars()
{
    [WebDynamicScrollBarsView setCustomScrollerClass:[DRTMockScroller class]];
}
#endif

RetainPtr<WebView> createWebViewAndOffscreenWindow()
{
#if !PLATFORM(IOS_FAMILY)
    NSRect rect = NSMakeRect(0, 0, TestRunner::viewWidth, TestRunner::viewHeight);
    auto webView = adoptNS([[WebView alloc] initWithFrame:rect frameName:nil groupName:@"org.webkit.DumpRenderTree"]);
#else
    auto webBrowserView = adoptNS([[DumpRenderTreeBrowserView alloc] initWithFrame:layoutTestViewportRect]);
    [webBrowserView setInputViewObeysDOMFocus:YES];
    auto webView = retainPtr([webBrowserView webView]);
    [webView setGroupName:@"org.webkit.DumpRenderTree"];
#endif

    [webView setUIDelegate:uiDelegate().get()];
    [webView setFrameLoadDelegate:frameLoadDelegate().get()];
    [webView setEditingDelegate:editingDelegate().get()];
    [webView setResourceLoadDelegate:resourceLoadDelegate().get()];
    [webView _setGeolocationProvider:[MockGeolocationProvider shared]];
    [webView _setDeviceOrientationProvider:[WebDeviceOrientationProviderMock shared]];
    [webView _setNotificationProvider:[MockWebNotificationProvider shared]];

    // Register the same schemes that Safari does
    [WebView registerURLSchemeAsLocal:@"feed"];
    [WebView registerURLSchemeAsLocal:@"feeds"];
    [WebView registerURLSchemeAsLocal:@"feedsearch"];

#if PLATFORM(MAC)
    [webView setWindowOcclusionDetectionEnabled:NO];
    [WebView _setFontAllowList:fontAllowList()];
#endif

#if !PLATFORM(IOS_FAMILY)
    [webView setContinuousSpellCheckingEnabled:YES];
    [webView setAutomaticQuoteSubstitutionEnabled:NO];
    [webView setAutomaticLinkDetectionEnabled:NO];
    [webView setAutomaticDashSubstitutionEnabled:NO];
    [webView setAutomaticTextReplacementEnabled:NO];
    [webView setAutomaticSpellingCorrectionEnabled:YES];
    [webView setGrammarCheckingEnabled:YES];

    [webView setDefersCallbacks:NO];
    [webView setInteractiveFormValidationEnabled:YES];
    [webView setValidationMessageTimerMagnification:-1];

    // To make things like certain NSViews, dragging, and plug-ins work, put the WebView a window, but put it off-screen so you don't see it.
    // Put it at -10000, -10000 in "flipped coordinates", since WebCore and the DOM use flipped coordinates.
    NSScreen *firstScreen = [[NSScreen screens] firstObject];
    NSRect windowRect = (showWebView) ? NSOffsetRect(rect, 100, 100) : NSOffsetRect(rect, -10000, [firstScreen frame].size.height - rect.size.height + 10000);
    mainWindow = adoptNS([[DumpRenderTreeWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]);
    [mainWindow setReleasedWhenClosed:NO];
    [mainWindow setColorSpace:[firstScreen colorSpace]];
    [mainWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary];
    [[mainWindow contentView] addSubview:webView.get()];
    if (showWebView)
        [mainWindow orderFront:nil];
    else
        [mainWindow orderBack:nil];
    [mainWindow setAutodisplay:NO];

    [(DumpRenderTreeWindow *)mainWindow.get() startListeningForAcceleratedCompositingChanges];
#else
    auto drtWindow = adoptNS([[DumpRenderTreeWindow alloc] initWithLayer:[webBrowserView layer]]);
    [drtWindow setContentView:webView.get()];
    [webBrowserView setWAKWindow:drtWindow.get()];

    [[webView window] makeFirstResponder:[[[webView mainFrame] frameView] documentView]];

    CGRect uiWindowRect = layoutTestViewportRect;
    uiWindowRect.origin.y += [UIApp statusBarHeight];
    auto uiWindow = adoptNS([[UIWindow alloc] initWithFrame:uiWindowRect]);

    auto viewController = adoptNS([[UIViewController alloc] init]);
    [uiWindow setRootViewController:viewController.get()];

    // The UIWindow and UIWebBrowserView are released when the DumpRenderTreeWindow is closed.
    drtWindow.get().uiWindow = uiWindow.get();
    drtWindow.get().browserView = webBrowserView.get();

    auto scrollView = adoptNS([[DumpRenderTreeWebScrollView alloc] initWithFrame:layoutTestViewportRect]);
    [scrollView addSubview:webBrowserView.get()];

    [[viewController view] addSubview:scrollView.get()];

    adjustWebDocumentForStandardViewport(webBrowserView.get(), scrollView.get());
#endif

#if !PLATFORM(IOS_FAMILY)
    // For reasons that are not entirely clear, the following pair of calls makes WebView handle its
    // dynamic scrollbars properly. Without it, every frame will always have scrollbars.
    NSBitmapImageRep *imageRep = [webView bitmapImageRepForCachingDisplayInRect:[webView bounds]];
    [webView cacheDisplayInRect:[webView bounds] toBitmapImageRep:imageRep];
#else
    // Initialize the global UIViews, and set the key UIWindow to be painted.
    if (!gWebBrowserView) {
        gWebBrowserView = WTFMove(webBrowserView);
        gWebScrollView = WTFMove(scrollView);
        gDrtWindow = WTFMove(drtWindow);
        [uiWindow makeKeyAndVisible];
        [uiWindow retain];
    }
#endif

    [webView setMediaVolume:0];
    return webView;
}

static void destroyGlobalWebViewAndOffscreenWindow()
{
    if (!mainFrame && !globalWebView())
        return;

    ASSERT(globalWebView() == [mainFrame webView]);

#if !PLATFORM(IOS_FAMILY)
    NSWindow *window = [globalWebView() window];
#endif
    [globalWebView() close];
    mainFrame = nil;
    globalWebView() = nil;

#if !PLATFORM(IOS_FAMILY)
    // Work around problem where registering drag types leaves an outstanding
    // "perform selector" on the window, which retains the window. It's a bit
    // inelegant and perhaps dangerous to just blow them all away, but in practice
    // it probably won't cause any trouble (and this is just a test tool, after all).
    [NSObject cancelPreviousPerformRequestsWithTarget:window];

    [window close];
    mainWindow = nil;
#else
    auto uiWindow = adoptNS([gWebBrowserView window]);
    [uiWindow removeFromSuperview];
#endif
}

static void createGlobalWebViewAndOffscreenWindow()
{
    destroyGlobalWebViewAndOffscreenWindow();
    globalWebView() = createWebViewAndOffscreenWindow();
    mainFrame = [globalWebView() mainFrame];
}

static NSString *libraryPathForDumpRenderTree()
{
    char* dumpRenderTreeTemp = getenv("DUMPRENDERTREE_TEMP");
    if (dumpRenderTreeTemp)
        return [[NSFileManager defaultManager] stringWithFileSystemRepresentation:dumpRenderTreeTemp length:strlen(dumpRenderTreeTemp)];
    else
        return [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
}

static void setWebPreferencesForTestOptions(WebPreferences *preferences, const WTR::TestOptions& options)
{
    [preferences _batchUpdatePreferencesInBlock:^(WebPreferences *preferences) {
        [preferences _resetForTesting];

        if (enableAllExperimentalFeatures) {
            for (WebFeature *feature in [WebPreferences _experimentalFeatures])
                [preferences _setEnabled:YES forFeature:feature];
        }

        if (persistentUserStyleSheetLocation()) {
            preferences.userStyleSheetLocation = [NSURL URLWithString:(__bridge NSString *)persistentUserStyleSheetLocation().get()];
            preferences.userStyleSheetEnabled = YES;
        } else
            preferences.userStyleSheetEnabled = NO;

        preferences.acceleratedDrawingEnabled = useAcceleratedDrawing;
        preferences.editableLinkBehavior = WebKitEditableLinkOnlyLiveWithShiftKey;
        preferences.frameFlattening = WebKitFrameFlatteningDisabled;
        preferences.cacheModel = WebCacheModelDocumentBrowser;

        preferences.privateBrowsingEnabled = options.useEphemeralSession();

        for (const auto& [key, value] : options.boolWebPreferenceFeatures())
            [preferences _setBoolPreferenceForTestingWithValue:value forKey:toNS(WTR::TestOptions::toWebKitLegacyPreferenceKey(key)).get()];

        for (const auto& [key, value] : options.doubleWebPreferenceFeatures())
            [preferences _setDoublePreferenceForTestingWithValue:value forKey:toNS(WTR::TestOptions::toWebKitLegacyPreferenceKey(key)).get()];

        for (const auto& [key, value] : options.uint32WebPreferenceFeatures())
            [preferences _setUInt32PreferenceForTestingWithValue:value forKey:toNS(WTR::TestOptions::toWebKitLegacyPreferenceKey(key)).get()];

        for (const auto& [key, value] : options.stringWebPreferenceFeatures())
            [preferences _setStringPreferenceForTestingWithValue:toNS(value).get() forKey:toNS(WTR::TestOptions::toWebKitLegacyPreferenceKey(key)).get()];

        // FIXME: Tests currently expect this to always be false in WebKitLegacy testing - https://bugs.webkit.org/show_bug.cgi?id=222864.
        [preferences _setBoolPreferenceForTestingWithValue:NO forKey:@"WebKitLayoutFormattingContextEnabled"];
    }];

    [WebPreferences _clearNetworkLoaderSession];
    [WebPreferences _setCurrentNetworkLoaderSessionCookieAcceptPolicy:NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain];
}

// Called once on DumpRenderTree startup.
static void setDefaultsToConsistentValuesForTesting()
{
#if PLATFORM(IOS_FAMILY)
    WebThreadLock();
#endif

    static const int NoFontSmoothing = 0;
    static const int BlueTintedAppearance = 1;

    NSString *libraryPath = libraryPathForDumpRenderTree();

    NSDictionary *dict = @{
        @"AppleKeyboardUIMode": @1,
        @"AppleAntiAliasingThreshold": @4,
        @"AppleFontSmoothing": @(NoFontSmoothing),
        @"AppleAquaColorVariant": @(BlueTintedAppearance),
        @"AppleHighlightColor": @"0.709800 0.835300 1.000000",
        @"AppleOtherHighlightColor":@"0.500000 0.500000 0.500000",
        @"AppleLanguages": @[ @"en" ],
        WebKitEnableFullDocumentTeardownPreferenceKey: @YES,
        @"UseWebKitWebInspector": @YES,
#if !PLATFORM(IOS_FAMILY)
        @"NSPreferredSpellServerLanguage": @"en_US",
        @"NSUserDictionaryReplacementItems": @[],
        @"NSTestCorrectionDictionary": @{
            @"notationl": @"notational",
            @"mesage": @"message",
            @"wouldn": @"would",
            @"wellcome": @"welcome",
            @"hellolfworld": @"hello\nworld"
        },
#endif
        @"AppleScrollBarVariant": @"DoubleMax",
#if !PLATFORM(IOS_FAMILY)
        @"NSScrollAnimationEnabled": @NO,
#endif
        @"NSOverlayScrollersEnabled": @NO,
        @"AppleShowScrollBars": @"Always",
        @"NSButtonAnimationsEnabled": @NO, // Ideally, we should find a way to test animations, but for now, make sure that the dumped snapshot matches actual state.
        @"NSWindowDisplayWithRunLoopObserver": @YES, // Temporary workaround, see <rdar://problem/20351297>.
        @"AppleEnableSwipeNavigateWithScrolls": @YES,
        @"com.apple.swipescrolldirection": @1,
    };

    [[NSUserDefaults standardUserDefaults] setValuesForKeysWithDictionary:dict];

    NSDictionary *processInstanceDefaults = @{
        WebDatabaseDirectoryDefaultsKey: [libraryPath stringByAppendingPathComponent:@"Databases"],
        WebStorageDirectoryDefaultsKey: [libraryPath stringByAppendingPathComponent:@"LocalStorage"],
        WebKitLocalCacheDefaultsKey: [libraryPath stringByAppendingPathComponent:@"LocalCache"],
        WebKitResourceLoadStatisticsDirectoryDefaultsKey: [libraryPath stringByAppendingPathComponent:@"LocalStorage"],
    };

    [[NSUserDefaults standardUserDefaults] setVolatileDomain:processInstanceDefaults forName:NSArgumentDomain];
}

static void allocateGlobalControllers()
{
    // FIXME: We should remove these and move to the ObjC standard [Foo sharedInstance] model
    gNavigationController = adoptNS([[NavigationController alloc] init]);
    frameLoadDelegate() = adoptNS([[FrameLoadDelegate alloc] init]);
    uiDelegate() = adoptNS([[UIDelegate alloc] init]);
    editingDelegate() = adoptNS([[EditingDelegate alloc] init]);
    resourceLoadDelegate() = adoptNS([[ResourceLoadDelegate alloc] init]);
    policyDelegate = adoptNS([[PolicyDelegate alloc] init]);
    historyDelegate() = adoptNS([[HistoryDelegate alloc] init]);
    defaultPolicyDelegate = adoptNS([[DefaultPolicyDelegate alloc] init]);
#if PLATFORM(IOS_FAMILY)
    scrollViewResizerDelegate() = adoptNS([[ScrollViewResizerDelegate alloc] init]);
#endif
}

static void releaseGlobalControllers()
{
    gNavigationController = nil;
    frameLoadDelegate() = nil;
    editingDelegate() = nil;
    resourceLoadDelegate() = nil;
    uiDelegate() = nil;
    historyDelegate() = nil;
    policyDelegate = nil;
    defaultPolicyDelegate = nil;
#if PLATFORM(IOS_FAMILY)
    scrollViewResizerDelegate() = nil;
#endif
}

static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[])
{
    struct option options[] = {
        {"notree", no_argument, &dumpTree, NO},
        {"pixel-tests", no_argument, &dumpPixelsForAllTests, YES},
        {"tree", no_argument, &dumpTree, YES},
        {"threaded", no_argument, &threaded, YES},
        {"complex-text", no_argument, &forceComplexText, YES},
        {"accelerated-drawing", no_argument, &useAcceleratedDrawing, YES},
        {"gc-between-tests", no_argument, &gcBetweenTests, YES},
        {"no-timeout", no_argument, &useTimeoutWatchdog, NO},
        {"allowed-host", required_argument, nullptr, 'a'},
        {"allow-any-certificate-for-allowed-hosts", no_argument, &allowAnyHTTPSCertificateForAllowedHosts, YES},
        {"no-enable-all-experimental-features", no_argument, &enableAllExperimentalFeatures, NO},
        {"show-webview", no_argument, &showWebView, YES},
        {"print-test-count", no_argument, &printTestCount, YES},
        {"world-leaks", no_argument, &checkForWorldLeaks, NO},
        {"webcore-logging", required_argument, nullptr, 'w'},
        {nullptr, 0, nullptr, 0}
    };

    int option;
    while ((option = getopt_long(argc, (char * const *)argv, "", options, nullptr)) != -1) {
        switch (option) {
            case '?':   // unknown or ambiguous option
            case ':':   // missing argument
                exit(1);
                break;
            case 'a': // "allowed-host"
                allowedHosts.insert(optarg);
                break;
            case 'w': // "webcore-logging"
                webCoreLogging = optarg;
        }
    }
}

static void addTestPluginsToPluginSearchPath(const char* executablePath)
{
#if !PLATFORM(IOS_FAMILY)
    NSString *pwd = [[NSString stringWithUTF8String:executablePath] stringByDeletingLastPathComponent];
    [WebPluginDatabase setAdditionalWebPlugInPaths:@[pwd]];
    [[WebPluginDatabase sharedDatabase] refresh];
#endif
}

static bool useLongRunningServerMode(int argc, const char *argv[])
{
    // This assumes you've already called getopt_long
    return (argc == optind+1 && strcmp(argv[optind], "-") == 0);
}

static bool handleControlCommand(const char* command)
{
    if (!strncmp("#CHECK FOR WORLD LEAKS", command, 22) || !strncmp("#LIST CHILD PROCESSES", command, 21)) {
        // DumpRenderTree does not support checking for world leaks or listing child processes.
        WTF::String result("\n"_s);
        unsigned resultLength = result.length();
        printf("Content-Type: text/plain\n");
        printf("Content-Length: %u\n", resultLength);
        fwrite(result.utf8().data(), 1, resultLength, stdout);
        printf("#EOF\n");
        fprintf(stderr, "#EOF\n");
        fflush(stdout);
        fflush(stderr);
        return true;
    }
    return false;
}

static void runTestingServerLoop()
{
    // When DumpRenderTree run in server mode, we just wait around for file names
    // to be passed to us and read each in turn, passing the results back to the client
    char filenameBuffer[2048];
    unsigned testCount = 0;
    while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
        char *newLineCharacter = strchr(filenameBuffer, '\n');
        if (newLineCharacter)
            *newLineCharacter = '\0';

        if (strlen(filenameBuffer) == 0)
            continue;

        if (handleControlCommand(filenameBuffer))
            continue;

        runTest(filenameBuffer);

        if (printTestCount) {
            ++testCount;
            printf("\nServer mode has completed %u tests.\n\n", testCount);
        }
    }
}

#if PLATFORM(IOS_FAMILY)
static BOOL overrideIsInHardwareKeyboardMode()
{
    return NO;
}
#endif

static void prepareConsistentTestingEnvironment()
{
#if PLATFORM(MAC)
    poseAsClass("DumpRenderTreePasteboard", "NSPasteboard");
    poseAsClass("DumpRenderTreeEvent", "NSEvent");
#else
    poseAsClass("DumpRenderTreeEvent", "GSEvent");

    // Override the implementation of +[UIKeyboard isInHardwareKeyboardMode] to ensure that test runs are deterministic
    // regardless of whether a hardware keyboard is attached. We intentionally never restore the original implementation.
    method_setImplementation(class_getClassMethod([UIKeyboard class], @selector(isInHardwareKeyboardMode)), reinterpret_cast<IMP>(overrideIsInHardwareKeyboardMode));
#endif

    [[WebPreferences standardPreferences] setAutosaves:NO];

    [WebPreferences _switchNetworkLoaderToNewTestingSession];

#if PLATFORM(MAC)
    adjustFonts();
    registerMockScrollbars();

    // The mock scrollbars setting cannot be modified after creating a view, so we have to do it now.
    [[WebPreferences standardPreferences] setMockScrollbarsEnabled:YES];
#else
    activateFontsIOS();

    // Enable the tracker before creating the first WebView will cause initialization to use the correct database paths.
    [[WebPreferences standardPreferences] setStorageTrackerEnabled:YES];
#endif

    allocateGlobalControllers();

#if PLATFORM(MAC)
    NSActivityOptions options = (NSActivityUserInitiatedAllowingIdleSystemSleep | NSActivityLatencyCritical) & ~(NSActivitySuddenTerminationDisabled | NSActivityAutomaticTerminationDisabled);
    static NeverDestroyed<RetainPtr<id>> assertion = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:@"DumpRenderTree should not be subject to process suppression"];
    ASSERT_UNUSED(assertion, assertion.get());
#endif

    if (webCoreLogging.length())
        [[NSUserDefaults standardUserDefaults] setValue:[NSString stringWithUTF8String:webCoreLogging.c_str()] forKey:@"WebCoreLogging"];
}

const char crashedMessage[] = "#CRASHED\n";

void writeCrashedMessageOnFatalError(int signalCode)
{
    // Reset the default action for the signal so that we run ReportCrash(8) on pending and
    // subsequent instances of the signal.
    signal(signalCode, SIG_DFL);

    // WRITE(2) and FSYNC(2) are considered safe to call from a signal handler by SIGACTION(2).
    write(STDERR_FILENO, &crashedMessage[0], sizeof(crashedMessage) - 1);
    fsync(STDERR_FILENO);
}

void dumpRenderTree(int argc, const char *argv[])
{
    JSC::Config::configureForTesting();

#if PLATFORM(IOS_FAMILY)
    setUpIOSLayoutTestCommunication();
    [UIApplication sharedApplication].idleTimerDisabled = YES;
    [[UIScreen mainScreen] _setScale:2.0];
#endif

    signal(SIGILL, &writeCrashedMessageOnFatalError);
    signal(SIGFPE, &writeCrashedMessageOnFatalError);
    signal(SIGBUS, &writeCrashedMessageOnFatalError);
    signal(SIGSEGV, &writeCrashedMessageOnFatalError);

    initializeGlobalsFromCommandLineOptions(argc, argv);
    prepareConsistentTestingEnvironment();
    addTestPluginsToPluginSearchPath(argv[0]);

    JSC::initialize();
    WTF::initializeMainThread();
    WebCoreTestSupport::populateJITOperations();

    if (forceComplexText)
        [WebView _setAlwaysUsesComplexTextCodePath:YES];

#if USE(APPKIT)
    [NSSound _setAlertType:0];
#endif

    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    [WebCache empty];

    [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:@"localhost"];
    [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:@"127.0.0.1"];
    if (allowAnyHTTPSCertificateForAllowedHosts) {
        for (auto& host : allowedHosts)
            [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[NSString stringWithUTF8String:host.c_str()]];
    }

    if (threaded)
        startJavaScriptThreads();

    if (useLongRunningServerMode(argc, argv)) {
        printSeparators = YES;
        runTestingServerLoop();
    } else {
        printSeparators = optind < argc - 1;
        for (int i = optind; i != argc; ++i)
            runTest(argv[i]);
    }

    if (threaded)
        stopJavaScriptThreads();

    destroyGlobalWebViewAndOffscreenWindow();

    releaseGlobalControllers();

#if !PLATFORM(IOS_FAMILY)
    [DumpRenderTreePasteboard releaseLocalPasteboards];
#endif

    // FIXME: This should be moved onto TestRunner and made into a HashSet
    disallowedURLs = nullptr;

#if PLATFORM(IOS_FAMILY)
    tearDownIOSLayoutTestCommunication();
#endif
}

#if PLATFORM(IOS_FAMILY)
static int _argc;
static const char **_argv;

@implementation DumpRenderTree

- (void)_runDumpRenderTree
{
    dumpRenderTree(_argc, _argv);
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    [self performSelectorOnMainThread:@selector(_runDumpRenderTree) withObject:nil waitUntilDone:NO];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    RELEASE_ASSERT_NOT_REACHED();
}

- (void)_webThreadEventLoopHasRun
{
    ASSERT(!WebThreadIsCurrent());
    _hasFlushedWebThreadRunQueue = YES;
}

- (void)_webThreadInvoked
{
    ASSERT(WebThreadIsCurrent());
    WorkQueue::main().dispatch([self, retainedSelf = retainPtr(self)] {
        [self _webThreadEventLoopHasRun];
    });
}

// The test can end in response to a delegate callback while there are still methods queued on the Web Thread.
// If we do not ensure the Web Thread has been run, the callback can be done on a WebView that no longer exists.
// To avoid this, _waitForWebThread dispatches a call to the WebThread event loop, actively processing the delegate
// callbacks in the main thread while waiting for the call to be invoked on the Web Thread.
- (void)_waitForWebThread
{
    ASSERT(!WebThreadIsCurrent());
    _hasFlushedWebThreadRunQueue = NO;
    WebThreadRun(^{
        [self _webThreadInvoked];
    });
    while (!_hasFlushedWebThreadRunQueue) {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
        }
    }
}

@end
#endif

static bool returningFromMain = false;

void atexitFunction()
{
    if (returningFromMain)
        return;

    NSLog(@"DumpRenderTree is exiting unexpectedly. Generating a crash log.");
    __builtin_trap();
}

int DumpRenderTreeMain(int argc, const char *argv[])
{
    atexit(atexitFunction);

    WTF::setProcessPrivileges(allPrivileges());
    WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);
    WebCoreTestSupport::setLinkedOnOrAfterEverythingForTesting();

#if PLATFORM(IOS_FAMILY)
    _UIApplicationLoadWebKit();
#endif

    @autoreleasepool {
        setDefaultsToConsistentValuesForTesting(); // Must be called before NSApplication initialization.

#if !PLATFORM(IOS_FAMILY)
        [DumpRenderTreeApplication sharedApplication]; // Force AppKit to init itself

        dumpRenderTree(argc, argv);
#else
        _argc = argc;
        _argv = argv;
        UIApplicationMain(argc, (char**)argv, @"DumpRenderTree", @"DumpRenderTree");
#endif

        [WebCoreStatistics garbageCollectJavaScriptObjects];
        [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
        JSC::finalizeStatsAtEndOfTesting();
    }

    returningFromMain = true;
    return 0;
}

static NSInteger compareHistoryItems(id item1, id item2, void *context)
{
    return [[item1 target] caseInsensitiveCompare:[item2 target]];
}

static NSData *dumpAudio()
{
    const auto& dataVector = gTestRunner->audioResult();

    NSData *data = [NSData dataWithBytes:dataVector.data() length:dataVector.size()];
    return data;
}

static void dumpHistoryItem(WebHistoryItem *item, int indent, BOOL current)
{
    int start = 0;
    if (current) {
        printf("curr->");
        start = 6;
    }
    for (int i = start; i < indent; i++)
        putchar(' ');

    NSString *urlString = [item URLString];
    if ([[NSURL URLWithString:urlString] isFileURL]) {
        NSRange range = [urlString rangeOfString:@"/LayoutTests/"];
        urlString = [@"(file test):" stringByAppendingString:[urlString substringFromIndex:(range.length + range.location)]];
    }

    printf("%s", [urlString UTF8String]);
    NSString *target = [item target];
    if (target && [target length] > 0)
        printf(" (in frame \"%s\")", [target UTF8String]);
    if ([item isTargetItem])
        printf("  **nav target**");
    putchar('\n');
    NSArray *kids = [item children];
    if (kids) {
        // must sort to eliminate arbitrary result ordering which defeats reproducible testing
        kids = [kids sortedArrayUsingFunction:&compareHistoryItems context:nil];
        for (unsigned i = 0; i < [kids count]; i++)
            dumpHistoryItem([kids objectAtIndex:i], indent+4, NO);
    }
}

static void dumpFrameScrollPosition(WebFrame *f)
{
    WebScriptObject* scriptObject = [f windowObject];
    NSPoint scrollPosition = NSMakePoint(
        [[scriptObject valueForKey:@"pageXOffset"] floatValue],
        [[scriptObject valueForKey:@"pageYOffset"] floatValue]);
    if (ABS(scrollPosition.x) > 0.00000001 || ABS(scrollPosition.y) > 0.00000001) {
        if ([f parentFrame] != nil)
            printf("frame '%s' ", [[f name] UTF8String]);
        printf("scrolled to %.f,%.f\n", scrollPosition.x, scrollPosition.y);
    }

    if (gTestRunner->dumpChildFrameScrollPositions()) {
        NSArray *kids = [f childFrames];
        if (kids)
            for (unsigned i = 0; i < [kids count]; i++)
                dumpFrameScrollPosition([kids objectAtIndex:i]);
    }
}

static RetainPtr<NSString> dumpFramesAsText(WebFrame *frame)
{
    DOMDocument *document = [frame DOMDocument];
    DOMElement *documentElement = [document documentElement];

    if (!documentElement)
        return @"";

    RetainPtr<NSMutableString> result;

    // Add header for all but the main frame.
    if ([frame parentFrame])
        result = adoptNS([[NSMutableString alloc] initWithFormat:@"\n--------\nFrame: '%@'\n--------\n", [frame name]]);
    else
        result = adoptNS([[NSMutableString alloc] init]);

    NSString *innerText = [documentElement innerText];

    // We use WTF::String::tryGetUtf8 to convert innerText to a UTF8 buffer since
    // it can handle dangling surrogates and the NSString
    // conversion methods cannot. After the conversion to a buffer, we turn that buffer into
    // a CFString via fromUTF8WithLatin1Fallback().createCFString() which can be appended to
    // the result without any conversion.
    if (auto utf8Result = WTF::String(innerText).tryGetUtf8()) {
        auto string = WTFMove(utf8Result.value());
        [result appendFormat:@"%@\n", String::fromUTF8WithLatin1Fallback(string.data(), string.length()).createCFString().get()];
    } else
        [result appendString:@"\n"];

    if (gTestRunner->dumpChildFramesAsText()) {
        NSArray *kids = [frame childFrames];
        if (kids) {
            for (unsigned i = 0; i < [kids count]; i++)
                [result appendString:dumpFramesAsText([kids objectAtIndex:i]).get()];
        }
    }

    // To keep things tidy, strip all trailing spaces: they are not a meaningful part of dumpAsText test output.
    [result replaceOccurrencesOfString:@" +\n" withString:@"\n" options:NSRegularExpressionSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@" +$" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [result length])];

    return result;
}

static NSData *dumpFrameAsPDF(WebFrame *frame)
{
#if !PLATFORM(IOS_FAMILY)
    if (!frame)
        return nil;

    // Sadly we have to dump to a file and then read from that file again
    // +[NSPrintOperation PDFOperationWithView:insideRect:] requires a rect and prints to a single page
    // likewise +[NSView dataWithPDFInsideRect:] also prints to a single continuous page
    // The goal of this function is to test "real" printing across multiple pages.
    // FIXME: It's possible there might be printing SPI to let us print a multi-page PDF to an NSData object
    NSString *path = [libraryPathForDumpRenderTree() stringByAppendingPathComponent:@"test.pdf"];

    NSMutableDictionary *printInfoDict = [NSMutableDictionary dictionaryWithDictionary:[[NSPrintInfo sharedPrintInfo] dictionary]];
    [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
    [printInfoDict setObject:path forKey:NSPrintSavePath];

    auto printInfo = adoptNS([[NSPrintInfo alloc] initWithDictionary:printInfoDict]);
    [printInfo setHorizontalPagination:NSAutoPagination];
    [printInfo setVerticalPagination:NSAutoPagination];
    [printInfo setVerticallyCentered:NO];

    NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:[frame frameView] printInfo:printInfo.get()];
    [printOperation setShowPanels:NO];
    [printOperation runOperation];

    NSData *pdfData = [NSData dataWithContentsOfFile:path];
    [[NSFileManager defaultManager] removeFileAtPath:path handler:nil];

    return pdfData;
#else
    return nil;
#endif
}

static void dumpBackForwardListForWebView(WebView *view)
{
    printf("\n============== Back Forward List ==============\n");
    WebBackForwardList *bfList = [view backForwardList];

    // Print out all items in the list after prevTestBFItem, which was from the previous test
    // Gather items from the end of the list, the print them out from oldest to newest
    auto itemsToPrint = adoptNS([[NSMutableArray alloc] init]);
    for (int i = [bfList forwardListCount]; i > 0; i--) {
        WebHistoryItem *item = [bfList itemAtIndex:i];
        // something is wrong if the item from the last test is in the forward part of the b/f list
        assert(item != prevTestBFItem());
        [itemsToPrint addObject:item];
    }

    assert([bfList currentItem] != prevTestBFItem());
    [itemsToPrint addObject:[bfList currentItem]];
    int currentItemIndex = [itemsToPrint count] - 1;

    for (int i = -1; i >= -[bfList backListCount]; i--) {
        WebHistoryItem *item = [bfList itemAtIndex:i];
        if (item == prevTestBFItem())
            break;
        [itemsToPrint addObject:item];
    }

    for (int i = [itemsToPrint count]-1; i >= 0; i--)
        dumpHistoryItem([itemsToPrint objectAtIndex:i], 8, i == currentItemIndex);

    printf("===============================================\n");
}

#if !PLATFORM(IOS_FAMILY)
static void changeWindowScaleIfNeeded(const char* testPathOrURL)
{
    auto localPathOrURL = String::fromUTF8(testPathOrURL);
    float currentScaleFactor = [[[mainFrame webView] window] backingScaleFactor];
    float requiredScaleFactor = 1;
    if (localPathOrURL.containsIgnoringASCIICase("/hidpi-3x-"_s))
        requiredScaleFactor = 3;
    else if (localPathOrURL.containsIgnoringASCIICase("/hidpi-"_s))
        requiredScaleFactor = 2;
    if (currentScaleFactor == requiredScaleFactor)
        return;
    // When the new scale factor is set on the window first, WebView doesn't see it as a new scale and stops propagating the behavior change to WebCore::Page.
    gTestRunner->setBackingScaleFactor(requiredScaleFactor);
    NSWindow *window = [[mainFrame webView] window];
    if ([window respondsToSelector:@selector(_setWindowResolution:)])
        [window _setWindowResolution:requiredScaleFactor];
    else
        [window _setWindowResolution:requiredScaleFactor displayIfChanged:YES];
}
#endif

static void sizeWebViewForCurrentTest()
{
    [uiDelegate() resetWindowOrigin];

    // W3C SVG tests expect to be 480x360
    bool isSVGW3CTest = (gTestRunner->testURL().find("svg/W3C-SVG-1.1") != std::string::npos);
    NSSize frameSize = isSVGW3CTest ? NSMakeSize(TestRunner::w3cSVGViewWidth, TestRunner::w3cSVGViewHeight) : NSMakeSize(TestRunner::viewWidth, TestRunner::viewHeight);
    [[mainFrame webView] setFrameSize:frameSize];
    [[mainFrame frameView] setFrame:NSMakeRect(0, 0, frameSize.width, frameSize.height)];
}

static const char *methodNameStringForFailedTest()
{
    const char *errorMessage;
    if (gTestRunner->dumpAsText())
        errorMessage = "[documentElement innerText]";
    else if (gTestRunner->dumpDOMAsWebArchive())
        errorMessage = "[[mainFrame DOMDocument] webArchive]";
    else if (gTestRunner->dumpSourceAsWebArchive())
        errorMessage = "[[mainFrame dataSource] webArchive]";
    else
        errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";

    return errorMessage;
}

static void dumpBackForwardListForAllWindows()
{
    for (NSWindow *window in [DumpRenderTreeWindow openWindows]) {
#if !PLATFORM(IOS_FAMILY)
        WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
#else
        ASSERT([[window contentView] isKindOfClass:[WebView class]]);
        WebView *webView = (WebView *)[window contentView];
#endif
        dumpBackForwardListForWebView(webView);
    }
}

static void invalidateAnyPreviousWaitToDumpWatchdog()
{
    if (waitToDumpWatchdog) {
        CFRunLoopTimerInvalidate(waitToDumpWatchdog.get());
        waitToDumpWatchdog = nullptr;
    }
}

void setWaitToDumpWatchdog(RetainPtr<CFRunLoopTimerRef>&& timer)
{
    ASSERT(timer);
    ASSERT(shouldSetWaitToDumpWatchdog());
    waitToDumpWatchdog = WTFMove(timer);
    CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog.get(), kCFRunLoopCommonModes);
}

bool shouldSetWaitToDumpWatchdog()
{
    return !waitToDumpWatchdog && useTimeoutWatchdog;
}

static void updateDisplay()
{
    WebView *webView = [mainFrame webView];
#if PLATFORM(IOS_FAMILY)
    [gWebBrowserView layoutIfNeeded]; // Re-enables tile painting, which was disabled when committing the frame load.
    [gDrtWindow layoutTilesNow];
    [webView _flushCompositingChanges];
#else
    [webView _forceRepaintForTesting];
    if ([webView _isUsingAcceleratedCompositing])
        [webView display];
    else
        [webView displayIfNeeded];
#endif
}

void dump()
{
#if PLATFORM(IOS_FAMILY)
    WebThreadLock();
#endif

    if (done)
        return;

    updateDisplay();

    invalidateAnyPreviousWaitToDumpWatchdog();
    ASSERT(!gTestRunner->hasPendingWebNotificationClick());

    if (dumpTree) {
        RetainPtr<NSString> resultString;
        NSData *resultData = nil;
        NSString *resultMimeType = @"text/plain";

        if ([[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"]) {
            gTestRunner->setDumpAsText(true);
            gTestRunner->setGeneratePixelResults(false);
        }
        if (gTestRunner->dumpAsAudio()) {
            resultData = dumpAudio();
            resultMimeType = @"audio/wav";
        } else if (gTestRunner->dumpAsText()) {
            resultString = dumpFramesAsText(mainFrame);
        } else if (gTestRunner->dumpAsPDF()) {
            resultData = dumpFrameAsPDF(mainFrame);
            resultMimeType = @"application/pdf";
        } else if (gTestRunner->dumpDOMAsWebArchive()) {
            WebArchive *webArchive = [[mainFrame DOMDocument] webArchive];
            resultString = bridge_cast(WebCoreTestSupport::createXMLStringFromWebArchiveData(bridge_cast([webArchive data])));
            resultMimeType = @"application/x-webarchive";
        } else if (gTestRunner->dumpSourceAsWebArchive()) {
            WebArchive *webArchive = [[mainFrame dataSource] webArchive];
            resultString = bridge_cast(WebCoreTestSupport::createXMLStringFromWebArchiveData(bridge_cast([webArchive data])));
            resultMimeType = @"application/x-webarchive";
        } else if (gTestRunner->isPrinting())
            resultString = [mainFrame renderTreeAsExternalRepresentationForPrinting];
        else
            resultString = [mainFrame renderTreeAsExternalRepresentationWithOptions:gTestRunner->renderTreeDumpOptions()];

        if (resultString && !resultData)
            resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];

        printf("Content-Type: %s\n", [resultMimeType UTF8String]);

        WTF::FastMallocStatistics mallocStats = WTF::fastMallocStatistics();
        printf("DumpMalloc: %li\n", mallocStats.committedVMBytes);

        if (gTestRunner->dumpAsAudio())
            printf("Content-Length: %lu\n", static_cast<unsigned long>([resultData length]));

        if (resultData) {
            fwrite([resultData bytes], 1, [resultData length], stdout);

            if (!gTestRunner->dumpAsText() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive() && !gTestRunner->dumpAsAudio())
                dumpFrameScrollPosition(mainFrame);

            if (gTestRunner->dumpBackForwardList())
                dumpBackForwardListForAllWindows();
        } else
            printf("ERROR: nil result from %s", methodNameStringForFailedTest());

        // Stop the watchdog thread before we leave this test to make sure it doesn't
        // fire in between tests causing the next test to fail.
        // This is a speculative fix for: https://bugs.webkit.org/show_bug.cgi?id=32339
        invalidateAnyPreviousWaitToDumpWatchdog();

        if (printSeparators)
            puts("#EOF");       // terminate the content block
    }

    if (dumpPixelsForCurrentTest && gTestRunner->generatePixelResults())
        // FIXME: when isPrinting is set, dump the image with page separators.
        dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash());

    puts("#EOF");   // terminate the (possibly empty) pixels block
    fflush(stdout);

    done = YES;
    CFRunLoopStop(CFRunLoopGetMain());
}

static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
{
    return strstr(pathOrURL, "loading/") && !strstr(pathOrURL, "://localhost");
}

static bool shouldLogHistoryDelegates(const char* pathOrURL)
{
    return strstr(pathOrURL, "globalhistory/");
}

static bool shouldDumpAsText(const char* pathOrURL)
{
    return strstr(pathOrURL, "dumpAsText/");
}

#if PLATFORM(IOS_FAMILY)
static bool shouldMakeViewportFlexible(const char* pathOrURL)
{
    return strstr(pathOrURL, "viewport/") && !strstr(pathOrURL, "visual-viewport/");
}
#endif

static bool shouldUseEphemeralSession(const char* pathOrURL)
{
    return strstr(pathOrURL, "w3c/IndexedDB-private-browsing");
}

static void setJSCOptions(const WTR::TestOptions& options)
{
    static WTF::StringBuilder savedOptions;

    if (!savedOptions.isEmpty()) {
        JSC::Options::setOptions(savedOptions.toString().ascii().data());
        savedOptions.clear();
    }

    if (options.jscOptions().length()) {
        JSC::Options::dumpAllOptionsInALine(savedOptions);
        JSC::Options::setOptions(options.jscOptions().c_str());
    }
}

enum class ResetTime { BeforeTest, AfterTest };
static void resetWebViewToConsistentState(const WTR::TestOptions& options, ResetTime resetTime)
{
    setJSCOptions(options);

    WebView *webView = [mainFrame webView];

#if PLATFORM(IOS_FAMILY)
    adjustWebDocumentForStandardViewport(gWebBrowserView.get(), gWebScrollView.get());
    [webView _setAllowsMessaging:YES];
    [[UIScreen mainScreen] _setScale:2.0];
#endif
    [webView setEditable:NO];
    [(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES];
    [webView makeTextStandardSize:nil];
    [webView resetPageZoom:nil];
    [webView _scaleWebView:1.0 atOrigin:NSZeroPoint];
#if !PLATFORM(IOS_FAMILY)
    [webView _setCustomBackingScaleFactor:0];
#endif
    [webView setTabKeyCyclesThroughElements:YES];
    [webView setPolicyDelegate:defaultPolicyDelegate.get()];
    [policyDelegate setPermissive:NO];
    [policyDelegate setControllerToNotifyDone:0];
    [uiDelegate() resetToConsistentStateBeforeTesting:options];
    [frameLoadDelegate() resetToConsistentState];
    [webView _clearMainFrameName];
    [[webView undoManager] removeAllActions];
    [WebView _removeAllUserContentFromGroup:[webView groupName]];
#if !PLATFORM(IOS_FAMILY)
    [[webView window] setAutodisplay:NO];
#endif
    [webView setTracksRepaints:NO];

    [WebCache clearCachedCredentials];

    setWebPreferencesForTestOptions(webView.preferences, options);
#if PLATFORM(MAC)
    [webView setWantsLayer:options.layerBackedWebView()];
#endif

    TestRunner::setSerializeHTTPLoads(false);
    TestRunner::setAllowsAnySSLCertificate(true);

    setlocale(LC_ALL, "");

    ASSERT(gTestRunner);
    gTestRunner->resetPageVisibility();
    // In the case that a test using the chrome input field failed, be sure to clean up for the next test.
    gTestRunner->removeChromeInputField();

    // We do not do this before running the test since it may eagerly create the global JS context
    // if we have not loaded anything yet.
    if (resetTime == ResetTime::AfterTest)
        WebCoreTestSupport::resetInternalsObject([mainFrame globalContext]);

#if !PLATFORM(IOS_FAMILY)
    if (WebCore::Frame* frame = [webView _mainCoreFrame])
        WebCoreTestSupport::clearWheelEventTestMonitor(*frame);
#endif

#if !PLATFORM(IOS_FAMILY)
    [webView setContinuousSpellCheckingEnabled:YES];
    [webView setAutomaticQuoteSubstitutionEnabled:NO];
    [webView setAutomaticLinkDetectionEnabled:NO];
    [webView setAutomaticDashSubstitutionEnabled:NO];
    [webView setAutomaticTextReplacementEnabled:NO];
    [webView setAutomaticSpellingCorrectionEnabled:YES];
    [webView setGrammarCheckingEnabled:YES];

    [WebView _setUsesTestModeFocusRingColor:YES];
#endif
    [WebView _resetOriginAccessAllowLists];

    [[MockGeolocationProvider shared] stopTimer];
    [[MockWebNotificationProvider shared] reset];

#if !PLATFORM(IOS_FAMILY)
    // Clear the contents of the general pasteboard
    [[NSPasteboard generalPasteboard] declareTypes:@[NSStringPboardType] owner:nil];
#endif

    WebCoreTestSupport::setAdditionalSupportedImageTypesForTesting(String::fromLatin1(options.additionalSupportedImageTypes().c_str()));

    [mainFrame _clearOpener];

#if PLATFORM(MAC)
    [LayoutTestSpellChecker uninstallAndReset];
#endif

    WebCoreTestSupport::clearAllLogChannelsToAccumulate();
    WebCoreTestSupport::initializeLogChannelsIfNecessary();
}

#if PLATFORM(IOS_FAMILY)
// Work around <rdar://problem/9909073> WebKit's method of calling delegates on
// the main thread is not thread safe. If the web thread is attempting to call
// out to a delegate method on the main thread, we want to spin the main thread
// run loop until the delegate method completes before taking the web thread
// lock to prevent potentially re-entering WebCore.
static void WebThreadLockAfterDelegateCallbacksHaveCompleted()
{
    auto delegateSemaphore = adoptOSObject(dispatch_semaphore_create(0));
    WebThreadRun(^{
        dispatch_semaphore_signal(delegateSemaphore.get());
    });

    while (dispatch_semaphore_wait(delegateSemaphore.get(), DISPATCH_TIME_NOW)) {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
        }
    }

    WebThreadLock();
}
#endif

static NSURL *computeTestURL(NSString *pathOrURLString, NSString **relativeTestPath)
{
    *relativeTestPath = nil;

    if ([pathOrURLString hasPrefix:@"http://"] || [pathOrURLString hasPrefix:@"https://"] || [pathOrURLString hasPrefix:@"file://"])
        return [NSURL URLWithString:pathOrURLString];

    NSString *absolutePath = [[[NSURL fileURLWithPath:pathOrURLString] absoluteURL] path];

    NSRange layoutTestsRange = [absolutePath rangeOfString:@"/LayoutTests/"];
    if (layoutTestsRange.location == NSNotFound)
        return [NSURL fileURLWithPath:absolutePath];

    *relativeTestPath = [absolutePath substringFromIndex:NSMaxRange(layoutTestsRange)];
    return [NSURL fileURLWithPath:absolutePath];
}

static WTR::TestOptions testOptionsForTest(const WTR::TestCommand& command)
{
    WTR::TestFeatures features = WTR::TestOptions::defaults();
    WTR::merge(features, WTR::hardcodedFeaturesBasedOnPathForTest(command));
    WTR::merge(features, WTR::featureDefaultsFromTestHeaderForTest(command, WTR::TestOptions::keyTypeMapping()));

    return WTR::TestOptions { WTFMove(features) };
}

static void runTest(const std::string& inputLine)
{
    ASSERT(!inputLine.empty());

    auto command = WTR::parseInputLine(inputLine);
    auto pathOrURL = command.pathOrURL;
    dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests;

    NSString *pathOrURLString = [NSString stringWithUTF8String:pathOrURL.c_str()];
    if (!pathOrURLString) {
        fprintf(stderr, "Failed to parse \"%s\" as UTF-8\n", pathOrURL.c_str());
        return;
    }

    NSString *testPath;
    NSURL *url = computeTestURL(pathOrURLString, &testPath);
    if (!url) {
        fprintf(stderr, "Failed to parse \"%s\" as a URL\n", pathOrURL.c_str());
        return;
    }
    if (!testPath)
        testPath = [url absoluteString];

    auto message = makeString("CRASHING TEST: ", testPath.UTF8String);
    WTF::setCrashLogMessage(message.utf8().data());

    auto options = testOptionsForTest(command);

    if (!mainFrameTestOptions || !options.webViewIsCompatibleWithOptions(mainFrameTestOptions.value()))
        createGlobalWebViewAndOffscreenWindow();

    mainFrameTestOptions = options;

    const char* testURL([[url absoluteString] UTF8String]);
    gTestRunner = TestRunner::create(testURL, command.expectedPixelHash);
    gTestRunner->setAllowedHosts(allowedHosts);
    gTestRunner->setCustomTimeout(command.timeout.milliseconds());
    gTestRunner->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr || options.dumpJSConsoleLogInStdErr());

    resetWebViewToConsistentState(options, ResetTime::BeforeTest);

#if !PLATFORM(IOS_FAMILY)
    changeWindowScaleIfNeeded(testURL);
#endif

    topLoadingFrame = nil;
#if !PLATFORM(IOS_FAMILY)
    ASSERT(!draggingInfo); // the previous test should have called eventSender.mouseUp to drop!
    draggingInfo = nil;
#endif
    done = NO;

    sizeWebViewForCurrentTest();
    gTestRunner->setIconDatabaseEnabled(false);
    gTestRunner->clearAllApplicationCaches();

    gTestRunner->clearAllDatabases();

    if (disallowedURLs)
        CFSetRemoveAllValues(disallowedURLs.get());
    if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
        gTestRunner->setDumpFrameLoadCallbacks(true);

    if (shouldLogHistoryDelegates(pathOrURL.c_str()))
        [[mainFrame webView] setHistoryDelegate:historyDelegate().get()];
    else
        [[mainFrame webView] setHistoryDelegate:nil];

    if (shouldDumpAsText(pathOrURL.c_str())) {
        gTestRunner->setDumpAsText(true);
        gTestRunner->setGeneratePixelResults(false);
    }

#if PLATFORM(IOS_FAMILY)
    if (shouldMakeViewportFlexible(pathOrURL.c_str()))
        adjustWebDocumentForFlexibleViewport(gWebBrowserView.get(), gWebScrollView.get());
#endif

    if (shouldUseEphemeralSession(pathOrURL.c_str()))
        [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:YES];

    if ([WebHistory optionalSharedHistory])
        [WebHistory setOptionalSharedHistory:nil];

    lastMousePosition = NSZeroPoint;
    lastClickPosition = NSZeroPoint;

    prevTestBFItem() = [[[mainFrame webView] backForwardList] currentItem];

    auto& workQueue = DRT::WorkQueue::singleton();
    workQueue.clear();
    workQueue.setFrozen(false);

    bool ignoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(testURL);
    if (ignoreWebCoreNodeLeaks)
        [WebCoreStatistics startIgnoringWebCoreNodeLeaks];

    @autoreleasepool {
        [mainFrame loadRequest:[NSURLRequest requestWithURL:url]];
    }

    while (!done) {
        @autoreleasepool {
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false);
        }
    }

#if PLATFORM(IOS_FAMILY)
    [(DumpRenderTree *)UIApp _waitForWebThread];
    WebThreadLockAfterDelegateCallbacksHaveCompleted();
#endif

    @autoreleasepool {
        [EventSendingController clearSavedEvents];
        [[mainFrame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream];

        workQueue.clear();

        // If the test page could have possibly opened the Web Inspector frontend,
        // then try to close it in case it was accidentally left open.
        gTestRunner->closeWebInspector();

#if PLATFORM(MAC)
        // Make sure the WebView is parented, since the test may have unparented it.
        WebView *webView = [mainFrame webView];
        if (![webView superview])
            [[mainWindow contentView] addSubview:webView];
#endif

        for (NSWindow *window in DumpRenderTreeWindow.openWindows) {
            // Don't try to close the main window
            if (window == mainFrame.webView.window)
                continue;

#if !PLATFORM(IOS_FAMILY)
            WebView *webView = [window.contentView.subviews objectAtIndex:0];
#else
            ASSERT([window.contentView isKindOfClass:WebView.class]);
            WebView *webView = (WebView *)window.contentView;
#endif

            [webView close];
            [window close];
        }

        resetWebViewToConsistentState(options, ResetTime::AfterTest);

        // Loading an empty request synchronously replaces the document with a blank one, which is necessary
        // to stop timers, WebSockets and other activity that could otherwise spill output into next test's results.
        [mainFrame loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
    }

    // We should only have our main window left open when we're done
    ASSERT(CFArrayGetCount(openWindowsRef) == 1);
    ASSERT(CFArrayGetValueAtIndex(openWindowsRef, 0) == (__bridge CFTypeRef)[[mainFrame webView] window]);

    gTestRunner->cleanup();
    gTestRunner = nullptr;

#if PLATFORM(MAC)
    [DumpRenderTreeDraggingInfo clearAllFilePromiseReceivers];
#endif

    if (ignoreWebCoreNodeLeaks)
        [WebCoreStatistics stopIgnoringWebCoreNodeLeaks];

    if (gcBetweenTests)
        [WebCoreStatistics garbageCollectJavaScriptObjects];
    
    JSC::waitForVMDestruction();

    fputs("#EOF\n", stderr);
    fflush(stderr);
}

void displayWebView()
{
#if !PLATFORM(IOS_FAMILY)
    WebView *webView = [mainFrame webView];
    [webView display];
#else
    [gDrtWindow layoutTilesNow];
    [gDrtWindow setNeedsDisplayInRect:[gDrtWindow frame]];
    [CATransaction flush];
#endif
}

void displayAndTrackRepaintsWebView()
{
    displayWebView();
#if !PLATFORM(IOS_FAMILY)
    // FIXME: Tracking repaints is not specific to Mac. We should enable such support on iOS.
    WebView *webView = [mainFrame webView];
    [webView setTracksRepaints:YES];
    [webView resetTrackedRepaints];
#endif
}

#if !PLATFORM(IOS_FAMILY)
@implementation DumpRenderTreeEvent

+ (NSPoint)mouseLocation
{
    return [[[mainFrame webView] window] convertBaseToScreen:lastMousePosition];
}

@end

@implementation DumpRenderTreeApplication

- (BOOL)isRunning
{
    // <rdar://problem/7686123> Java plug-in freezes unless NSApplication is running
    return YES;
}

@end
#endif
