import { JestEnvironmentConfig, EnvironmentContext } from '@jest/environment';
import NodeEnvironment from 'jest-environment-node';
import { ConnectOptions, PuppeteerLaunchOptions, Browser, Page, BrowserContext } from 'puppeteer';
import { Config } from 'jest-dev-server';

interface JestPuppeteerConfig {
    /**
     * Puppeteer connect options.
     * @see https://pptr.dev/api/puppeteer.connectoptions
     */
    connect?: ConnectOptions;
    /**
     * Puppeteer launch options.
     * @see https://pptr.dev/api/puppeteer.launchoptions
     */
    launch?: PuppeteerLaunchOptions;
    /**
     * Server config for `jest-dev-server`.
     * @see https://www.npmjs.com/package/jest-dev-server
     */
    server?: Config | Config[];
    /**
     * Allow to run one browser per worker.
     * @default false
     */
    browserPerWorker?: boolean;
    /**
     * Browser context to use.
     * @default "default"
     */
    browserContext?: "default" | "incognito";
    /**
     * Exit on page error.
     * @default true
     */
    exitOnPageError?: boolean;
    /**
     * Use `runBeforeUnload` in `page.close`.
     * @see https://pptr.dev/api/puppeteer.page.close
     * @default false
     */
    runBeforeUnloadOnClose?: boolean;
}

type JestPuppeteer = {
    debug: () => Promise<void>;
    resetPage: () => Promise<void>;
    resetBrowser: () => Promise<void>;
};
type StrictGlobal = {
    browser?: Browser | undefined;
    page?: Page | undefined;
    context?: BrowserContext | undefined;
    puppeteerConfig: JestPuppeteerConfig;
    jestPuppeteer: JestPuppeteer;
};
type JestPuppeteerGlobal = Required<StrictGlobal>;
declare class PuppeteerEnvironment extends NodeEnvironment {
    global: StrictGlobal & NodeEnvironment["global"];
    constructor(config: JestEnvironmentConfig, _context: EnvironmentContext);
    setTimeout(timeout: number): void;
    setup(): Promise<void>;
    teardown(): Promise<void>;
}

export { type JestPuppeteerConfig, type JestPuppeteerGlobal, PuppeteerEnvironment as TestEnvironment, PuppeteerEnvironment as default };
