"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorMessageStringToErrorWithStack = exports.logsAfterEachHook = exports.logsBeforeEachHook = exports.logsAfterAllHook = exports.logsBeforeAllHook = void 0;
const utils_1 = require("./utils");
const hooksHandlersDisposersHelper_1 = require("./hooksHandlersDisposersHelper");
const DISPOSERS_TOPIC = 'console-logs';
async function logsBeforeAllHook(testContext, proxyContext, rootPage) {
    async function onConsole(message) {
        testContext.consoleEntries.push(await puppeteerOrPlaywrightConsoleMessageToOurRepresentation(message, testContext.dateConstructor.now()));
    }
    function onPageError(error) {
        testContext.unhandledExceptions.push(puppeteerPageErrorToOurRepresentation(error, testContext.dateConstructor.now()));
    }
    async function onConsolePlaywright(message) {
        testContext.consoleEntries.push(await puppeteerOrPlaywrightConsoleMessageToOurRepresentation(message, testContext.dateConstructor.now()));
    }
    function onPageErrorPlaywright(error) {
        testContext.unhandledExceptions.push(playwrightPageErrorToOurRepresentation(error, testContext.dateConstructor.now()));
    }
    if (utils_1.isNotPlaywrightPage(rootPage)) {
        rootPage.on('console', onConsole);
        rootPage.on('pageerror', onPageError);
        hooksHandlersDisposersHelper_1.addDisposer(testContext, DISPOSERS_TOPIC, () => {
            rootPage.off('console', onConsole);
            rootPage.off('pageerror', onPageError);
        });
    }
    else {
        rootPage.on('console', onConsolePlaywright);
        rootPage.on('pageerror', onPageErrorPlaywright);
        hooksHandlersDisposersHelper_1.addDisposer(testContext, DISPOSERS_TOPIC, () => {
            rootPage.off('console', onConsolePlaywright);
            rootPage.off('pageerror', onPageErrorPlaywright);
        });
    }
}
exports.logsBeforeAllHook = logsBeforeAllHook;
async function logsAfterAllHook(testContext) {
    hooksHandlersDisposersHelper_1.runAllDisposers(testContext, DISPOSERS_TOPIC);
}
exports.logsAfterAllHook = logsAfterAllHook;
async function logsBeforeEachHook(testContext, proxyContext, rootPage) { }
exports.logsBeforeEachHook = logsBeforeEachHook;
async function logsAfterEachHook(testContext, proxyContext, rootPage) {
    const stepContext = testContext.currentStep;
    if (!stepContext) {
        return;
    }
    const consoleEntries = testContext.consoleEntries.filter((e) => e.timestamp > stepContext.startTimestamp);
    const unhandledExceptions = testContext.unhandledExceptions.filter((e) => e.timestamp > stepContext.startTimestamp);
    testContext.addStepMetadata({ consoleEntries, unhandledExceptions });
}
exports.logsAfterEachHook = logsAfterEachHook;
async function puppeteerOrPlaywrightConsoleMessageToOurRepresentation(message, timestamp) {
    const args = await Promise.all(message.args().map((arg) => arg.jsonValue().then((value) => JSON.stringify(value), () => 'failed getting arg from page')));
    const location = message.location();
    return {
        level: message.type(),
        text: message.text(),
        line: location.lineNumber,
        column: location.columnNumber,
        url: location.url,
        timestamp,
        args,
    };
}
function playwrightPageErrorToOurRepresentation(error, timestamp) {
    return {
        message: error.message,
        timestamp,
        stack: error.stack,
    };
}
function puppeteerPageErrorToOurRepresentation(error, timestamp) {
    const resolvedError = errorMessageStringToErrorWithStack(error.message);
    return {
        message: resolvedError.message,
        timestamp,
        stack: resolvedError.stack,
    };
}
function errorMessageStringToErrorWithStack(messageWithStack) {
    const lines = messageWithStack.split('\n');
    const firstStackTraceLine = lines.findIndex((line) => line.startsWith('    at'));
    let message = '';
    let stack = '';
    if (firstStackTraceLine === -1) {
        message = messageWithStack;
    }
    else {
        message = lines.slice(0, firstStackTraceLine).join('\n');
        stack = messageWithStack;
    }
    const match = message.match(/^[a-zA-Z0-0_]*Error: (.*)$/);
    if (match) {
        message = match[1];
    }
    const err = new Error(message);
    err.stack = stack;
    return err;
}
exports.errorMessageStringToErrorWithStack = errorMessageStringToErrorWithStack;
