"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const execution_1 = require("../execution");
const errorUtil_1 = require("../util/errorUtil");
const Observer_1 = require("./Observer");
const ObservationDispatcher_1 = require("./ObservationDispatcher");
const syntheticActionCodes_1 = require("./syntheticActionCodes");
const mablApi_1 = require("../mablApi");
const loggingProvider_1 = require("../providers/logging/loggingProvider");
const BROWSER_OBSERVATION_ARTIFACT_NAME = 'dom_snapshot.html';
const MOBILE_OBSERVATION_ARTIFACT_NAME = 'mobile_page_source.xml';
const DOM_EXTRACTION_SCRIPT = function () {
    const originalPdfDetectorNode = document.querySelector('#__mabl-pdf-detector');
    let pdfParent;
    if (originalPdfDetectorNode) {
        pdfParent = originalPdfDetectorNode.parentNode;
        pdfParent?.removeChild(originalPdfDetectorNode);
    }
    const cleanDom = document?.doctype
        ? '<!doctype ' +
            document.doctype.name +
            '>' +
            document.documentElement.outerHTML
        : document.documentElement.outerHTML;
    if (originalPdfDetectorNode) {
        pdfParent?.appendChild(originalPdfDetectorNode);
    }
    return cleanDom;
};
const DOM_EXTRACTION_STRING = `(${DOM_EXTRACTION_SCRIPT.toString()})()`;
class DomObserver extends Observer_1.DeferredObserver {
    constructor(dispatcher) {
        super(Observer_1.ObservationType.DOM_SNAPSHOT, dispatcher);
        this.observeDeferredFunction = async (context) => {
            const executionContext = context.executionContext;
            let domSnapshot = '';
            let observationArtifactName = BROWSER_OBSERVATION_ARTIFACT_NAME;
            if ((0, execution_1.isMobileExecutionContext)(executionContext)) {
                const isCaptureFinalStateAction = context.executionIndex.actionName ===
                    syntheticActionCodes_1.CAPTURE_APPLICATION_STATE_ACTION_CODE;
                if (isCaptureFinalStateAction) {
                    observationArtifactName = MOBILE_OBSERVATION_ARTIFACT_NAME;
                    loggingProvider_1.logger.info('Capturing mobile page source at the end of the test run');
                    try {
                        const platform = executionContext.mobileTestEnvironment.getConfig().app.platformName;
                        switch (platform) {
                            case mablApi_1.MobilePlatformEnum.Android:
                                domSnapshot = await executionContext.mobileTestEnvironment
                                    .getDriver()
                                    .getPageSource();
                                break;
                            case mablApi_1.MobilePlatformEnum.Ios:
                                domSnapshot = (await executionContext.mobileTestEnvironment
                                    .getDriver()
                                    .execute('mobile: source', {
                                    format: 'xml',
                                    excludedAttributes: 'visible',
                                }));
                                break;
                        }
                    }
                    catch (error) {
                        loggingProvider_1.logger.error(`Getting mobile end state page source failed with error ${error}`);
                    }
                }
            }
            else {
                const frame = executionContext.pageFrameContext.getCurrentFrame();
                domSnapshot = await (0, execution_1.runWithRetries)(() => frame.evaluateCodeInSecondaryWorld(({ domExtractionScript }) => eval(domExtractionScript), {
                    domExtractionScript: DOM_EXTRACTION_STRING,
                }), ObservationDispatcher_1.MAX_RETRIES, errorUtil_1.STRINGS_TO_RETRY_ON, executionContext, ObservationDispatcher_1.MIN_TIMEOUT_MS, ObservationDispatcher_1.MAX_TIMEOUT_MS, ObservationDispatcher_1.OBSERVATION_MAX_WAIT_TIME_MS);
            }
            if (!domSnapshot) {
                return {};
            }
            const tmpFile = await this.writeTempFile(observationArtifactName, domSnapshot);
            const filesByObservationType = {};
            if (tmpFile) {
                filesByObservationType[this.observationType] = { uri: tmpFile };
            }
            return { filesByObservationType };
        };
    }
}
exports.default = DomObserver;
