"use strict";
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const elements_helpers_js_1 = require("../helpers/elements-helpers.js");
describe('Event listeners in the elements sidebar', () => {
    const loadEventListenersAndSelectButtonNode = async (devToolsPage, inspectedPage) => {
        await inspectedPage.goToResource('elements/sidebar-event-listeners.html');
        await (0, elements_helpers_js_1.waitForElementsStyleSection)(undefined, devToolsPage);
        // Wait for element to be expanded
        await (0, elements_helpers_js_1.waitForSelectedNodeToBeExpanded)(devToolsPage);
        // Select the button that has the events and make sure it's selected
        await devToolsPage.page.keyboard.press('ArrowRight');
        await (0, elements_helpers_js_1.waitForContentOfSelectedElementsNode)('<button id=\u200B"test-button">\u200Bhello world\u200B</button>\u200B', devToolsPage);
    };
    const EVENT_LISTENERS_PANEL_LINK = '[aria-label="Event Listeners"]';
    /* We add :not(.hidden) here as if you create an event listener + remove it via the UI
     * it gets the class of .hidden rather than being removed
     */
    const EVENT_LISTENERS_SELECTOR = 'li[aria-label$="event listener"]:not(.hidden)';
    const getDisplayedEventListenerNames = async (devToolsPage) => {
        const eventListeners = await devToolsPage.$$(EVENT_LISTENERS_SELECTOR);
        const eventListenerNames = await Promise.all(eventListeners.map(listener => listener.evaluate(l => l.textContent)));
        return eventListenerNames;
    };
    const getEventListenerProperties = async (devToolsPage, selector) => {
        const clickEventProperties = await devToolsPage.$$(selector);
        const propertiesOutput = await Promise.all(clickEventProperties.map(n => n.evaluate((node) => {
            const nameNode = node.querySelector('.name');
            const valueNode = node.querySelector('.value');
            if (!nameNode || !valueNode) {
                throw new Error('Could not find a name and value node for event listener properties.');
            }
            const key = nameNode.textContent;
            const value = valueNode.textContent;
            return [key, value];
        })));
        return propertiesOutput;
    };
    const getFirstNodeForEventListener = async (devToolsPage, listenerTypeSelector) => {
        await devToolsPage.click(listenerTypeSelector);
        const listenerNodesSelector = `${listenerTypeSelector} + ol>li`;
        const firstListenerNode = await devToolsPage.waitFor(listenerNodesSelector);
        if (!firstListenerNode) {
            throw new Error(`Could not find listener node for selector ${listenerNodesSelector}`);
        }
        const firstListenerText = await firstListenerNode.evaluate((node) => {
            return node.textContent || '';
        });
        return {
            firstListenerText,
            listenerSelector: listenerNodesSelector,
        };
    };
    const openEventListenersPaneAndWaitForListeners = async (devToolsPage) => {
        let eventListenersPanel = await devToolsPage.$('Event Listeners', undefined, 'aria');
        if (!eventListenersPanel) {
            await devToolsPage.clickMoreTabsButton();
            eventListenersPanel = await devToolsPage.waitFor(EVENT_LISTENERS_PANEL_LINK);
        }
        await devToolsPage.clickElement(eventListenersPanel);
        await devToolsPage.waitFor(EVENT_LISTENERS_SELECTOR);
    };
    it('lists the active event listeners on the page', async ({ devToolsPage, inspectedPage }) => {
        await loadEventListenersAndSelectButtonNode(devToolsPage, inspectedPage);
        await openEventListenersPaneAndWaitForListeners(devToolsPage);
        const eventListenerNames = await getDisplayedEventListenerNames(devToolsPage);
        chai_1.assert.deepEqual(eventListenerNames, ['click', 'custom event', 'hover']);
    });
    it('shows the event listener properties when expanding it', async ({ devToolsPage, inspectedPage }) => {
        await loadEventListenersAndSelectButtonNode(devToolsPage, inspectedPage);
        await openEventListenersPaneAndWaitForListeners(devToolsPage);
        const { firstListenerText, listenerSelector, } = await getFirstNodeForEventListener(devToolsPage, '[aria-label="click, event listener"]');
        // check that we have the right event for the right element
        // we can't use assert.strictEqual() as the text also includes the "Remove" button
        chai_1.assert.include(firstListenerText, 'button#test-button');
        // we have to use keyboard navigation here to expand
        // the event, as single click reveals it in the elements
        // tree and double click triggers the "Remove" button on
        // some platforms.
        await devToolsPage.page.keyboard.press('ArrowRight'); // select
        await devToolsPage.page.keyboard.press('ArrowRight'); // expand
        await devToolsPage.waitFor(`${listenerSelector}[aria-expanded="true"]`);
        const clickEventPropertiesSelector = `${listenerSelector} + ol .name-and-value`;
        await devToolsPage.waitForFunction(async () => {
            const propertiesOutput = await getEventListenerProperties(devToolsPage, clickEventPropertiesSelector);
            const flatProperties = propertiesOutput.flat();
            const expected = [
                ['useCapture', 'false'],
                ['passive', 'false'],
                ['once', 'false'],
                ['handler', '() => {}'],
            ].flat();
            return flatProperties.length === expected.length && !flatProperties.some((v, index) => v !== expected[index]);
        });
    });
    it('shows custom event listeners and their properties correctly', async ({ devToolsPage, inspectedPage }) => {
        await loadEventListenersAndSelectButtonNode(devToolsPage, inspectedPage);
        await openEventListenersPaneAndWaitForListeners(devToolsPage);
        const { firstListenerText, listenerSelector, } = await getFirstNodeForEventListener(devToolsPage, '[aria-label="custom event, event listener"]');
        // check that we have the right event for the right element
        // we can't use assert.strictEqual() as the text also includes the "Remove" button
        chai_1.assert.include(firstListenerText, 'body');
        // we have to use keyboard navigation here to expand
        // the event, as single click reveals it in the elements
        // tree and double click triggers the "Remove" button on
        // some platforms.
        await devToolsPage.page.keyboard.press('ArrowRight'); // select
        await devToolsPage.page.keyboard.press('ArrowRight'); // expand
        await devToolsPage.waitFor(`${listenerSelector}[aria-expanded="true"]`);
        const customEventProperties = `${listenerSelector} + ol .name-and-value`;
        await devToolsPage.waitForFunction(async () => {
            const propertiesOutput = await getEventListenerProperties(devToolsPage, customEventProperties);
            const flatProperties = propertiesOutput.flat();
            const expected = [
                ['useCapture', 'true'],
                ['passive', 'false'],
                ['once', 'true'],
                ['handler', '() => console.log(\'test\')'],
            ].flat();
            return flatProperties.length === expected.length && !flatProperties.some((v, index) => v !== expected[index]);
        });
    });
    it('shows delete button by each node for a given event', async ({ devToolsPage, inspectedPage }) => {
        await loadEventListenersAndSelectButtonNode(devToolsPage, inspectedPage);
        await openEventListenersPaneAndWaitForListeners(devToolsPage);
        const { firstListenerText, listenerSelector, } = await getFirstNodeForEventListener(devToolsPage, '[aria-label="click, event listener"]');
        // Check that we have the right event for the right element
        // and that it has the delete button within it.
        chai_1.assert.include(firstListenerText, 'button#test-button');
        const removeButtonSelector = `${listenerSelector} devtools-button`;
        const removeButton = await devToolsPage.waitFor(removeButtonSelector);
        const buttonTitle = await removeButton.evaluate(n => {
            const button = n.shadowRoot?.querySelector('button');
            return button?.title;
        });
        chai_1.assert.strictEqual(buttonTitle, 'Delete event listener');
        await devToolsPage.click(removeButtonSelector);
        // now we can check that the 'click' event is gone
        const eventListenerNames = await getDisplayedEventListenerNames(devToolsPage);
        chai_1.assert.deepEqual(eventListenerNames, ['custom event', 'hover']);
    });
});
//# sourceMappingURL=sidebar-event-listeners.test.js.map