/// <reference types="istanbul-lib-coverage" />
/// <reference types="istanbul-lib-instrument" />
/// <reference types="istanbul-lib-source-maps" />
import Executor, { Config as BaseConfig, Events as BaseEvents, Plugins } from './Executor';
import Task from '@dojo/core/async/Task';
import Environment from '../Environment';
import Command from '@theintern/leadfoot/Command';
import Tunnel, { TunnelOptions, DownloadProgressEvent } from '@theintern/digdug/Tunnel';
import Server from '../Server';
import Suite from '../Suite';
import { RuntimeEnvironment } from '../types';
import { CoverageMap } from 'istanbul-lib-coverage';
import { Instrumenter } from 'istanbul-lib-instrument';
import { MapStore } from 'istanbul-lib-source-maps';
import { BrowserStackOptions } from '@theintern/digdug/BrowserStackTunnel';
import { SeleniumOptions } from '@theintern/digdug/SeleniumTunnel';
export default class Node extends Executor<Events, Config, NodePlugins> {
    server: Server;
    tunnel: Tunnel;
    protected _coverageMap: CoverageMap;
    protected _loadingFunctionalSuites: boolean;
    protected _instrumentBasePath: string;
    protected _instrumenter: Instrumenter;
    protected _sourceMaps: MapStore;
    protected _instrumentedMaps: MapStore;
    protected _unhookRequire: null | (() => void);
    protected _sessionSuites: Suite[];
    constructor(options?: {
        [key in keyof Config]?: any;
    });
    readonly coverageMap: CoverageMap;
    readonly environment: RuntimeEnvironment;
    readonly instrumentedMapStore: MapStore;
    readonly sourceMapStore: MapStore;
    /**
     * The root suites managed by this executor
     */
    readonly suites: Suite[];
    /**
     * Override Executor#addSuite to handle functional suites
     */
    addSuite(factory: (parentSuite: Suite) => void): void;
    /**
     * Retrieve a registered tunnel constructor
     */
    getTunnel(name: string): typeof Tunnel;
    /**
     * Insert coverage instrumentation into a given code string
     */
    instrumentCode(code: string, filename: string): string;
    /**
     * Load scripts using Node's require
     */
    loadScript(script: string | string[]): Task<void>;
    /**
     * Register a tunnel constructor with the plugin system. It can be retrieved later with getTunnel or getPlugin.
     */
    registerTunnel(name: string, Ctor: typeof Tunnel): void;
    /**
     * Return true if a given file should be instrumented based on the current config
     */
    shouldInstrumentFile(filename: string): boolean;
    protected _afterRun(): Task<void>;
    protected _beforeRun(): Task<boolean>;
    /**
     * Creates suites for each environment in which tests will be executed. This method will only be called if there are
     * both environments and suites to run.
     */
    protected _createSessionSuites(): Task<void>;
    /**
     * Load functional test suites
     */
    protected _loadFunctionalSuites(): Task<void>;
    protected _processOption(name: keyof Config, value: any, addToExisting: boolean): void;
    protected _resolveConfig(): Task<void>;
    protected _runTests(): Task<void>;
    protected _runRemoteTests(): Task<void>;
    /**
     * Adds hooks for code coverage instrumentation in the Node.js loader.
     */
    protected _setInstrumentationHooks(): void;
    /**
     * Removes instrumentation hooks
     */
    protected _removeInstrumentationHooks(): void;
}
export interface NodePlugins extends Plugins {
    tunnel: typeof Tunnel;
}
export interface Config extends BaseConfig {
    capabilities: {
        name?: string;
        build?: string;
        [key: string]: any;
    };
    /** Time to wait for contact from a remote server */
    connectTimeout: number;
    /**
     * If set, coverage will be collected for all files. This allows uncovered files to be noticed more easily.
     */
    coverageSources: string[];
    /** A list of remote environments */
    environments: EnvironmentSpec[];
    /** If true, collect coverage data from functional tests */
    functionalCoverage: boolean;
    functionalSuites: string[];
    instrumenterOptions: {
        [key: string]: any;
    };
    leaveRemoteOpen: boolean | 'fail';
    maxConcurrency: number;
    serveOnly: boolean;
    serverPort: number;
    serverUrl: string;
    runInSync: boolean;
    socketPort?: number;
    tunnel: string;
    tunnelOptions?: TunnelOptions | BrowserStackOptions | SeleniumOptions;
}
export interface Remote extends Command<any> {
    environmentType?: Environment;
    setHeartbeatInterval(delay: number): Command<any>;
}
export interface EnvironmentSpec {
    browserName: string;
    [key: string]: any;
}
export interface TunnelMessage {
    tunnel: Tunnel;
    progress?: DownloadProgressEvent;
    status?: string;
}
export interface Events extends BaseEvents {
    /** A test server has stopped */
    serverEnd: Server;
    /** A test server was started */
    serverStart: Server;
    /** Emitted as a Tunnel executable download is in process */
    tunnelDownloadProgress: TunnelMessage;
    /** A WebDriver tunnel has been opened */
    tunnelStart: TunnelMessage;
    /** A status update from a WebDriver tunnel */
    tunnelStatus: TunnelMessage;
    /** A WebDriver tunnel has been stopped */
    tunnelStop: TunnelMessage;
}
