"use strict";
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TOTAL_TIME_SELECTOR = exports.ACTIVITY_COLUMN_SELECTOR = exports.CALL_TREE_SELECTOR = exports.BOTTOM_UP_SELECTOR = exports.SUMMARY_TAB_SELECTOR = exports.STOP_BUTTON_SELECTOR = exports.RELOAD_AND_RECORD_BUTTON_SELECTOR = exports.RECORD_BUTTON_SELECTOR = exports.CLEAR_BUTTON_SELECTOR = exports.FILTER_TEXTBOX_SELECTOR = void 0;
exports.navigateToPerformanceTab = navigateToPerformanceTab;
exports.openCaptureSettings = openCaptureSettings;
exports.searchForComponent = searchForComponent;
exports.navigateToBottomUpTab = navigateToBottomUpTab;
exports.navigateToCallTreeTab = navigateToCallTreeTab;
exports.setFilter = setFilter;
exports.toggleCaseSensitive = toggleCaseSensitive;
exports.toggleRegExButtonBottomUp = toggleRegExButtonBottomUp;
exports.toggleMatchWholeWordButtonBottomUp = toggleMatchWholeWordButtonBottomUp;
exports.startRecording = startRecording;
exports.increaseTimeoutForPerfPanel = increaseTimeoutForPerfPanel;
exports.loadTraceAndWaitToFullyRender = loadTraceAndWaitToFullyRender;
exports.reloadAndRecord = reloadAndRecord;
exports.stopRecording = stopRecording;
exports.getTotalTimeFromSummary = getTotalTimeFromSummary;
exports.getTotalTimeFromPie = getTotalTimeFromPie;
exports.retrieveSelectedAndExpandedActivityItems = retrieveSelectedAndExpandedActivityItems;
exports.navigateToSelectorStatsTab = navigateToSelectorStatsTab;
exports.selectRecalculateStylesEvent = selectRecalculateStylesEvent;
exports.enableCSSSelectorStats = enableCSSSelectorStats;
exports.veImpressionForPerformancePanel = veImpressionForPerformancePanel;
exports.uploadTraceFile = uploadTraceFile;
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const paths_js_1 = require("../../conductor/paths.js");
const quick_open_helpers_js_1 = require("./quick_open-helpers.js");
const visual_logging_helpers_js_1 = require("./visual-logging-helpers.js");
exports.FILTER_TEXTBOX_SELECTOR = '[aria-label="Filter"]';
exports.CLEAR_BUTTON_SELECTOR = '[aria-label="Clear"]';
exports.RECORD_BUTTON_SELECTOR = '[aria-label="Record"]';
exports.RELOAD_AND_RECORD_BUTTON_SELECTOR = '[aria-label="Record and reload"]';
exports.STOP_BUTTON_SELECTOR = '[aria-label="Stop"]';
exports.SUMMARY_TAB_SELECTOR = '[aria-label="Summary"]';
exports.BOTTOM_UP_SELECTOR = '[aria-label="Bottom-up"]';
exports.CALL_TREE_SELECTOR = '[aria-label="Call tree"]';
exports.ACTIVITY_COLUMN_SELECTOR = '.activity-column.disclosure';
exports.TOTAL_TIME_SELECTOR = 'div:nth-child(1) > div.vbox.timeline-details-chip-body > div:nth-child(1) > div.timeline-details-view-row-value';
const RECALCULATE_STYLE_TITLE = 'Recalculate style';
const SELECTOR_STATS_SELECTOR = '[aria-label="Selector stats"]';
const CSS_SELECTOR_STATS_TITLE = 'Enable CSS selector stats (slow)';
const TIMELINE_SETTINGS_PANE = '.timeline-settings-pane';
async function navigateToPerformanceTab(testResource, devToolsPage, inspectedPage) {
    await devToolsPage.evaluate(() => {
        // Prevent the Performance panel shortcuts dialog, that is automatically shown the first
        // time the performance panel is opened, from opening in tests.
        localStorage.setItem('hide-shortcuts-dialog-for-test', 'true');
        // Disable the auto showing of the RPP sidebar. This only
        // happens on the first time the user should see the
        // sidebar, so it makes tests have to check if it's open or
        // not. Instead, let's just disable any auto-show in tests.
        localStorage.setItem('disable-auto-show-rpp-sidebar-for-test', 'true');
    });
    if (testResource) {
        await inspectedPage.goToResource(`performance/${testResource}.html`);
    }
    // Open the tab.
    await (0, quick_open_helpers_js_1.openCommandMenu)(devToolsPage);
    await devToolsPage.typeText('Performance');
    await devToolsPage.pressKey('Enter');
    // Make sure the landing page is shown.
    await devToolsPage.waitFor('.timeline-landing-page');
}
async function openCaptureSettings(sectionClassName, devToolsPage) {
    const captureSettingsButton = await devToolsPage.waitForAria('Capture settings');
    await captureSettingsButton.click();
    await devToolsPage.waitFor(sectionClassName);
    await (0, visual_logging_helpers_js_1.expectVeEvents)([
        (0, visual_logging_helpers_js_1.veClick)('Toolbar > Toggle: timeline-settings-toggle'),
        (0, visual_logging_helpers_js_1.veImpression)('Pane', 'timeline-settings-pane', [
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline-capture-layers-and-pictures'),
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline-capture-selector-stats'),
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline-disable-js-sampling'),
            (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'cpu-throttling'),
            (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'active-network-condition-key'),
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline-show-extension-data'),
        ]),
    ], 'Panel: timeline', devToolsPage);
}
async function searchForComponent(searchEntry, devToolsPage) {
    await devToolsPage.waitFor('div.timeline-summary');
    await devToolsPage.summonSearchBox();
    const inputEl = await devToolsPage.waitFor('input#search-input-field');
    await inputEl.focus();
    await inputEl.evaluate((el, searchEntry) => {
        el.value = searchEntry;
        el.blur();
        el.dispatchEvent(new Event('input'));
    }, searchEntry);
    await devToolsPage.raf();
    await devToolsPage.timeout(300);
}
async function navigateToBottomUpTab(devToolsPage, veLinkContext) {
    await devToolsPage.click(exports.BOTTOM_UP_SELECTOR);
    await (0, visual_logging_helpers_js_1.expectVeEvents)([
        (0, visual_logging_helpers_js_1.veClick)('Section: timeline.flame-chart-view > Toolbar: sidebar > PanelTabHeader: bottom-up'),
        (0, visual_logging_helpers_js_1.veImpressionsUnder)('Section: timeline.flame-chart-view', [
            (0, visual_logging_helpers_js_1.veImpression)('Pane', 'bottom-up', [
                (0, visual_logging_helpers_js_1.veImpression)('Toolbar', undefined, [
                    (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'match-case'),
                    (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'regular-expression'),
                    (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'match-whole-word'),
                    (0, visual_logging_helpers_js_1.veImpression)('TextField', 'filter'),
                    (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'timeline-tree-group-by'),
                ]),
                (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'self'),
                (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'total'),
                (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'activity'),
                (0, visual_logging_helpers_js_1.veImpression)('TableRow', undefined, [
                    (0, visual_logging_helpers_js_1.veImpression)('TableCell', 'self'),
                    (0, visual_logging_helpers_js_1.veImpression)('TableCell', 'total'),
                    (0, visual_logging_helpers_js_1.veImpression)('TableCell', 'activity', [(0, visual_logging_helpers_js_1.veImpression)('Link', veLinkContext)]),
                ]),
            ]),
        ]),
    ], 'Panel: timeline', devToolsPage);
}
async function navigateToCallTreeTab(devToolsPage) {
    await devToolsPage.click(exports.CALL_TREE_SELECTOR);
    await (0, visual_logging_helpers_js_1.expectVeEvents)([
        (0, visual_logging_helpers_js_1.veClick)('Section: timeline.flame-chart-view > Toolbar: sidebar > PanelTabHeader: call-tree'),
        (0, visual_logging_helpers_js_1.veImpressionsUnder)('Section: timeline.flame-chart-view', [
            (0, visual_logging_helpers_js_1.veImpression)('Pane', 'call-tree', [
                (0, visual_logging_helpers_js_1.veImpression)('Toolbar', undefined, [
                    (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'match-case'),
                    (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'regular-expression'),
                    (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'match-whole-word'),
                    (0, visual_logging_helpers_js_1.veImpression)('TextField', 'filter'),
                    (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'timeline-tree-group-by'),
                ]),
                (0, visual_logging_helpers_js_1.veImpression)('TableHeader: self'),
                (0, visual_logging_helpers_js_1.veImpression)('TableHeader: total'),
                (0, visual_logging_helpers_js_1.veImpression)('TableHeader: activity'),
                (0, visual_logging_helpers_js_1.veImpression)('TableRow', undefined, [
                    (0, visual_logging_helpers_js_1.veImpression)('TableCell: self'),
                    (0, visual_logging_helpers_js_1.veImpression)('TableCell: total'),
                    (0, visual_logging_helpers_js_1.veImpression)('TableCell: activity'),
                ]),
            ]),
        ]),
    ], 'Panel: timeline', devToolsPage);
}
async function setFilter(filter, devToolsPage) {
    const filterBoxElement = await devToolsPage.click(exports.FILTER_TEXTBOX_SELECTOR);
    await filterBoxElement.type(filter);
    await (0, visual_logging_helpers_js_1.expectVeEvents)([(0, visual_logging_helpers_js_1.veChange)(''), (0, visual_logging_helpers_js_1.veImpression)('Action', 'clear')], 'Panel: timeline > Section: timeline.flame-chart-view > Pane: bottom-up > Toolbar > TextField: filter', devToolsPage);
}
async function toggleCaseSensitive(devToolsPage) {
    const matchCaseButton = await devToolsPage.waitForAria('Match case');
    await matchCaseButton.click();
    await (0, visual_logging_helpers_js_1.expectVeEvents)([(0, visual_logging_helpers_js_1.veClick)('Panel: timeline > Section: timeline.flame-chart-view > Pane: bottom-up > Toolbar > Toggle: match-case')], undefined, devToolsPage);
}
async function toggleRegExButtonBottomUp(devToolsPage) {
    const regexButton = await devToolsPage.waitFor('.timeline-tree-view [aria-label="Use regular expression"]');
    await regexButton.click();
    await (0, visual_logging_helpers_js_1.expectVeEvents)([
        (0, visual_logging_helpers_js_1.veClick)('Panel: timeline > Section: timeline.flame-chart-view > Pane: bottom-up > Toolbar > Toggle: regular-expression'),
    ], undefined, devToolsPage);
}
async function toggleMatchWholeWordButtonBottomUp(devToolsPage) {
    const wholeWordButton = await devToolsPage.waitForAria('Match whole word');
    await wholeWordButton.click();
    await (0, visual_logging_helpers_js_1.expectVeEvents)([(0, visual_logging_helpers_js_1.veClick)('Panel: timeline > Section: timeline.flame-chart-view > Pane: bottom-up > Toolbar > Toggle: match-whole-word')], undefined, devToolsPage);
}
async function startRecording(devToolsPage) {
    await devToolsPage.click(exports.CLEAR_BUTTON_SELECTOR);
    await devToolsPage.click(exports.RECORD_BUTTON_SELECTOR);
    // Wait for the button to turn to its stop state.
    await devToolsPage.waitFor(exports.STOP_BUTTON_SELECTOR);
    await (0, visual_logging_helpers_js_1.expectVeEvents)([(0, visual_logging_helpers_js_1.veClick)('Toolbar > Toggle: timeline.toggle-recording'), veImpressionForStatusDialog()], 'Panel: timeline', devToolsPage);
}
/**
 * Increases the timeout for the tests in the given context.
 * Useful for performance as tests that import or record a trace often get over the default timeout on slower bots.
 * Note that in e2e this can only be used on a `describe`, not an
 * `it`, hence why the type of the argument is `Mocha.Suite`
 */
function increaseTimeoutForPerfPanel(context) {
    // If the timeout is 0, then we are in debug mode, and don't want to override
    // that.
    if (context.timeout()) {
        context.timeout(30_000);
    }
}
/**
 * @param checkHasActiveTrace Usually this only required for enhanced traces
 */
async function loadTraceAndWaitToFullyRender(devToolsPage, initiateTraceLoadCb, checkHasActiveTrace = false) {
    const panelElement = await devToolsPage.waitFor('.widget.panel.timeline');
    const [, traceLoadedData] = await Promise.all([
        initiateTraceLoadCb(),
        panelElement.evaluate((el, checkPanelState) => {
            return new Promise(async (res) => {
                // Set-up the event listener first to prevent further
                // race conditions.
                el.addEventListener('traceload', e => {
                    const ev = e;
                    res(ev.duration);
                }, { once: true });
                if (checkPanelState) {
                    // @ts-expect-error This is loaded inside the new DevTools page.
                    const TimelineModule = await import('./panels/timeline/timeline.js');
                    if (TimelineModule.TimelinePanel.TimelinePanel.instance().hasActiveTrace()) {
                        res(-1);
                    }
                }
            });
        }, checkHasActiveTrace),
    ]);
    // There's a lot of scheduling/waiting in the Timeline panel's rendering stack
    // currently. Some events are fired, some things are debounced, some things wait
    // for the RenderCoordinator to update. So let's give all that plenty of time to
    // happen.
    await devToolsPage.timeout(200);
    await devToolsPage.raf();
    await devToolsPage.raf();
    return traceLoadedData;
}
async function reloadAndRecord(devToolsPage) {
    await loadTraceAndWaitToFullyRender(devToolsPage, () => devToolsPage.click(exports.RELOAD_AND_RECORD_BUTTON_SELECTOR));
    await (0, visual_logging_helpers_js_1.expectVeEvents)([(0, visual_logging_helpers_js_1.veClick)('Toolbar > Action: timeline.record-reload'), veImpressionForStatusDialog()], 'Panel: timeline', devToolsPage);
}
async function stopRecording(devToolsPage) {
    await loadTraceAndWaitToFullyRender(devToolsPage, () => devToolsPage.click(exports.STOP_BUTTON_SELECTOR));
    await (0, visual_logging_helpers_js_1.expectVeEvents)([
        (0, visual_logging_helpers_js_1.veClick)('Toolbar > Toggle: timeline.toggle-recording'),
        (0, visual_logging_helpers_js_1.veResize)('Dialog: timeline-status'),
    ], 'Panel: timeline', devToolsPage);
}
async function getTotalTimeFromSummary(devToolsPage) {
    const minCategories = 2;
    const categoryValues = await devToolsPage.waitForMany('.category-value', minCategories);
    const totalVal = categoryValues[categoryValues.length - 1];
    const totalText = await totalVal.evaluate(node => node.textContent);
    return parseInt(totalText, 10);
}
async function getTotalTimeFromPie(devToolsPage) {
    const pieChartTotal = await devToolsPage.waitFor('.pie-chart-total');
    const totalText = await pieChartTotal.evaluate(node => node.textContent);
    return parseInt(totalText, 10);
}
async function retrieveSelectedAndExpandedActivityItems(frontend) {
    const treeItems = await frontend.$$('.expanded > td.activity-column,.selected > td.activity-column');
    const tree = [];
    for (const item of treeItems) {
        tree.push(await frontend.evaluate(el => el.innerText.split('\n')[0], item));
    }
    return tree;
}
async function navigateToSelectorStatsTab(devToolsPage) {
    await devToolsPage.click(SELECTOR_STATS_SELECTOR);
    await devToolsPage.waitFor('#tab-selector-stats.selected');
    await (0, visual_logging_helpers_js_1.expectVeEvents)([
        (0, visual_logging_helpers_js_1.veClick)('Toolbar: sidebar > PanelTabHeader: selector-stats'),
        (0, visual_logging_helpers_js_1.veImpression)('Pane', 'selector-stats', [
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'elapsed-us'),
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'match-attempts'),
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'match-count'),
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'reject-percentage'),
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'selector'),
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'style-sheet-id'),
            (0, visual_logging_helpers_js_1.veImpression)('TableHeader', 'invalidation-count'),
            (0, visual_logging_helpers_js_1.veImpression)('TableRow', undefined, [(0, visual_logging_helpers_js_1.veImpression)('TableCell', 'elapsed-us')]),
        ]),
    ], 'Panel: timeline > Section: timeline.flame-chart-view', devToolsPage);
}
async function selectRecalculateStylesEvent(devToolsPage) {
    await searchForComponent(RECALCULATE_STYLE_TITLE, devToolsPage);
    const title = await devToolsPage.$('.timeline-details-chip-title');
    if (!title) {
        return false;
    }
    const titleText = await title.evaluate(x => x.textContent);
    return titleText === RECALCULATE_STYLE_TITLE;
}
async function enableCSSSelectorStats(devToolsPage) {
    const timelineSettingsPane = await devToolsPage.waitFor(TIMELINE_SETTINGS_PANE);
    if (await timelineSettingsPane.isHidden()) {
        await openCaptureSettings(TIMELINE_SETTINGS_PANE, devToolsPage);
    }
    // Wait for the checkbox to load
    const toggle = await devToolsPage.waitForElementWithTextContent(CSS_SELECTOR_STATS_TITLE);
    await devToolsPage.waitForFunction(() => toggle.evaluate(e => {
        if (e.disabled) {
            return false;
        }
        if (!e.checked) {
            e.click();
        }
        return true;
    }));
    await (0, visual_logging_helpers_js_1.expectVeEvents)([(0, visual_logging_helpers_js_1.veChange)('Panel: timeline > Pane: timeline-settings-pane > Toggle: timeline-capture-selector-stats')], undefined, devToolsPage);
}
function veImpressionForPerformancePanel() {
    return (0, visual_logging_helpers_js_1.veImpression)('Panel', 'timeline', [
        (0, visual_logging_helpers_js_1.veImpression)('Toolbar', undefined, [
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline.toggle-recording'),
            (0, visual_logging_helpers_js_1.veImpression)('Action', 'timeline.record-reload'),
            (0, visual_logging_helpers_js_1.veImpression)('Action', 'timeline.clear'),
            (0, visual_logging_helpers_js_1.veImpression)('Action', 'timeline.load-from-file'),
            (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'history'),
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline-show-screenshots'),
            (0, visual_logging_helpers_js_1.veImpression)('Toggle', 'timeline-show-memory'),
            (0, visual_logging_helpers_js_1.veImpression)('Action', 'components.collect-garbage'),
        ]),
        (0, visual_logging_helpers_js_1.veImpression)('Action', 'timeline.toggle-recording'),
        (0, visual_logging_helpers_js_1.veImpression)('Action', 'timeline.record-reload'),
        (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'cpu-throttling'),
        (0, visual_logging_helpers_js_1.veImpression)('DropDown', 'network-conditions'),
    ]);
}
function veImpressionForStatusDialog() {
    return (0, visual_logging_helpers_js_1.veImpression)('Dialog', 'timeline-status');
}
async function uploadTraceFile(devToolsPage, tracePath) {
    const uploadProfileHandle = await devToolsPage.waitFor('input[type=file]');
    const testTrace = path.join(paths_js_1.GEN_DIR, tracePath);
    if (!fs.existsSync(testTrace)) {
        throw new Error(`Test trace file not found: ${testTrace}`);
    }
    return await loadTraceAndWaitToFullyRender(devToolsPage, () => uploadProfileHandle.uploadFile(testTrace));
}
//# sourceMappingURL=performance-helpers.js.map