"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.modelDiagramFromFile = exports.modelAndRunConnectorsTimerEventDiagram = exports.assertPageTextWithRetry = exports.assertLocatorVisibleWithRetry = exports.modelWebhookConnector = exports.modelIntermediateWebhookConnector = exports.modelRestConnector = exports.completeTaskWithRetry = exports.createAndRunProcess = exports.runMultipleProcesses = exports.deleteAllUserGroups = void 0;
const test_1 = require("@playwright/test");
const fileUpload_1 = require("../../utils/fileUpload");
const sleep_1 = require("../../utils/sleep");
const constants_1 = require("../../utils/constants");
async function deleteAllUserGroups(navigationPage, identityPage) {
    await navigationPage.goToIdentity();
    await identityPage.clickGroupsTab();
    await identityPage.deleteAllGroups();
}
exports.deleteAllUserGroups = deleteAllUserGroups;
async function runMultipleProcesses(modelerHomePage, modelerCreatePage, numberOfProcesses, processName, processId = '') {
    for (let i = 1; i <= numberOfProcesses; i++) {
        await createAndRunProcess(modelerHomePage, modelerCreatePage, processName + i, processId.length > 0 ? processId + i : processId);
    }
}
exports.runMultipleProcesses = runMultipleProcesses;
async function createAndRunProcess(modelerHomePage, modelerCreatePage, processName, processId = '') {
    await modelerHomePage.clickDiagramTypeDropdown();
    await modelerHomePage.clickBpmnTemplateOption();
    await modelerCreatePage.modelCamundaUserTaskDiagram(processName, processId);
    await modelerCreatePage.runProcessInstance();
    await modelerHomePage.clickProjectBreadcrumb();
}
exports.createAndRunProcess = createAndRunProcess;
async function completeTaskWithRetry(page, taskPanelPage, taskDetailsPage, taskName, taskPriority, maxRetries = 5) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
        try {
            await page.waitForLoadState('domcontentloaded');
            await (0, sleep_1.sleep)(1000);
            // Wait for task to appear in the list before trying to open it
            const taskLocator = taskPanelPage.availableTasks
                .getByText(taskName, { exact: true })
                .first();
            try {
                await taskLocator.waitFor({ state: 'visible', timeout: 10000 });
            }
            catch {
                throw new Error(`Task ${taskName} not found in available tasks`);
            }
            await taskPanelPage.openTask(taskName, false);
            await (0, sleep_1.sleep)(500);
            await (0, test_1.expect)(taskDetailsPage.detailsPanel).toBeVisible({ timeout: 30000 });
            // Only assign if not already assigned (handles retry after partial success)
            if (!(await taskDetailsPage.assignedToMeText.isVisible({ timeout: 5000 }))) {
                await (0, test_1.expect)(taskDetailsPage.assignToMeButton).toBeVisible({
                    timeout: 10000,
                });
                await taskDetailsPage.clickAssignToMeButton();
            }
            await (0, sleep_1.sleep)(500);
            await (0, test_1.expect)(taskDetailsPage.detailsPanel.getByText(taskPriority)).toBeVisible({ timeout: 30000 });
            await taskDetailsPage.clickCompleteTaskButton();
            await (0, test_1.expect)(page.getByText('Task completed').first()).toBeVisible({
                timeout: 200000,
            });
            await (0, test_1.expect)(taskPanelPage.availableTasks.getByText(taskName, { exact: true }).first()).not.toBeVisible({ timeout: 10000 });
            console.log(`Successfully completed task: ${taskName}`);
            return;
        }
        catch (error) {
            console.warn(`Attempt ${attempt + 1} failed for completing task ${taskName}:`, error instanceof Error ? error.message : error);
            if (attempt < maxRetries - 1) {
                await page.reload();
                await page.waitForLoadState('domcontentloaded');
                await (0, sleep_1.sleep)(1000);
            }
            else {
                console.error(error);
                throw new Error(`Assertion failed after ${maxRetries} attempts for task ${taskName}`);
            }
        }
    }
}
exports.completeTaskWithRetry = completeTaskWithRetry;
async function modelRestConnector(modelerCreatePage, connectorSettingsPage, connectorMarketplacePage, processName, url, auth, resultExpression, resultVariable = '', basicAuthCredentials = {
    username: '',
    password: '',
}) {
    await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
        timeout: 120000,
    });
    await modelerCreatePage.enterDiagramName(processName);
    await (0, sleep_1.sleep)(1000); // When we go too fast there, modeler will missing the input
    await modelerCreatePage.clickCanvas();
    await modelerCreatePage.clickGeneralPropertiesPanel();
    await modelerCreatePage.clickIdInput();
    await modelerCreatePage.fillIdInput(processName);
    await modelerCreatePage.clickStartEventElement();
    await modelerCreatePage.clickAppendElementButton();
    await modelerCreatePage.clickAppendTaskButton();
    await modelerCreatePage.clickChangeTypeButton();
    try {
        await (0, test_1.expect)(modelerCreatePage.restConnectorOption).toBeVisible({
            timeout: 15000,
        });
    }
    catch (error) {
        await modelerCreatePage.clickMarketPlaceButton();
        await connectorMarketplacePage.clickSearchForConnectorTextbox();
        await connectorMarketplacePage.fillSearchForConnectorTextbox('REST Connector');
        await (0, sleep_1.sleep)(10000);
        await connectorMarketplacePage.downloadConnectorToProject();
    }
    await modelerCreatePage.clickRestConnectorOption();
    if (auth == 'bearer') {
        await connectorSettingsPage.selectAuthenticationType('bearer');
        await (0, test_1.expect)(connectorSettingsPage.bearerTokenInput).toBeVisible({
            timeout: 60000,
        });
        await connectorSettingsPage.clickBearerTokenInput();
        await connectorSettingsPage.fillBearerTokenInput('thisisabearertoken');
        await (0, test_1.expect)(connectorSettingsPage.methodTypeDropdown).toBeVisible({
            timeout: 30000,
        });
        await connectorSettingsPage.selectMethodType('POST');
    }
    else if (auth == 'basic') {
        await connectorSettingsPage.selectAuthenticationType('basic');
        await (0, test_1.expect)(connectorSettingsPage.usernameInput).toBeVisible({
            timeout: 60000,
        });
        await connectorSettingsPage.clickUsernameInput();
        (0, test_1.expect)(basicAuthCredentials['username'].length).toBeGreaterThan(0);
        (0, test_1.expect)(basicAuthCredentials['password'].length).toBeGreaterThan(0);
        await connectorSettingsPage.fillUsernameInput(basicAuthCredentials['username']);
        await connectorSettingsPage.clickPasswordInput();
        await connectorSettingsPage.fillPasswordInput(basicAuthCredentials['password']);
        await connectorSettingsPage.selectMethodType('POST');
    }
    await connectorSettingsPage.clickUrlInput();
    await connectorSettingsPage.fillUrlInput(url);
    if (resultVariable.length > 0) {
        await (0, test_1.expect)(connectorSettingsPage.resultVariableInput).toBeVisible({
            timeout: 60000,
        });
        await connectorSettingsPage.clickResultVariableInput();
        await connectorSettingsPage.fillResultVariableInput('result');
        await (0, sleep_1.sleep)(5000);
    }
    await connectorSettingsPage.clickResultExpressionInput();
    await connectorSettingsPage.fillResultExpressionInput(resultExpression);
    await (0, sleep_1.sleep)(5000);
    await modelerCreatePage.clickAppendElementButton();
    await modelerCreatePage.clickAppendEndEventButton();
    await (0, sleep_1.sleep)(10000); // trying to run the process to fast causes it to miss the process id
}
exports.modelRestConnector = modelRestConnector;
async function modelIntermediateWebhookConnector(modelerCreatePage, connectorMarketplacePage, processName, webhookId) {
    await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
        timeout: 120000,
    });
    await modelerCreatePage.enterDiagramName(processName);
    await (0, sleep_1.sleep)(1000); // When we go too fast there, modeler will missing the input
    await modelerCreatePage.clickCanvas();
    await modelerCreatePage.clickGeneralPropertiesPanel();
    await modelerCreatePage.clickIdInput();
    await modelerCreatePage.fillIdInput(processName);
    await modelerCreatePage.clickStartEventElement();
    await modelerCreatePage.clickAppendElementButton();
    await modelerCreatePage.clickIntermediateBoundaryEvent();
    await modelerCreatePage.clickChangeTypeButton();
    const result = await Promise.race([
        modelerCreatePage.restConnectorOption
            .waitFor({
            timeout: 15000,
        })
            .then(() => 'webhookConnectorOption'),
        modelerCreatePage.marketPlaceButton
            .waitFor({
            timeout: 15000,
        })
            .then(() => 'marketPlaceButton'),
    ]);
    if (result == 'marketPlaceButton') {
        await modelerCreatePage.clickMarketPlaceButton();
        await connectorMarketplacePage.clickSearchForConnectorTextbox();
        await connectorMarketplacePage.fillSearchForConnectorTextbox('Webhook Connector');
        await (0, sleep_1.sleep)(10000);
        await connectorMarketplacePage.downloadConnectorToProject();
        await modelerCreatePage.clickChangeTypeButton();
    }
    await modelerCreatePage.clickIntermediateWebhookConnectorOption();
    await modelerCreatePage.clickWebhookIdInput();
    await modelerCreatePage.clearWebhookIdInput();
    await modelerCreatePage.fillWebhookIdInput(webhookId);
    await modelerCreatePage.clickCorrelationKeyProcessInput();
    await modelerCreatePage.fillCorrelationKeyProcessInput('"test"');
    await modelerCreatePage.clickCorrelationKeyPayloadInput();
    await modelerCreatePage.fillCorrelationKeyPayloadInput('"test"');
    await (0, sleep_1.sleep)(1000);
    await modelerCreatePage.clickAppendElementButton();
    await modelerCreatePage.clickAppendEndEventButton();
    await (0, sleep_1.sleep)(1000); // trying to run the process to fast causes it to miss the process id
}
exports.modelIntermediateWebhookConnector = modelIntermediateWebhookConnector;
async function modelWebhookConnector(modelerCreatePage, connectorMarketplacePage, processName, webhookId) {
    await (0, test_1.expect)(modelerCreatePage.generalPanel).toBeVisible({
        timeout: 120000,
    });
    await modelerCreatePage.enterDiagramName(processName);
    await (0, sleep_1.sleep)(1000); // When we go too fast there, modeler will missing the input
    await modelerCreatePage.clickCanvas();
    await modelerCreatePage.clickGeneralPropertiesPanel();
    await modelerCreatePage.clickIdInput();
    await modelerCreatePage.fillIdInput(processName);
    await modelerCreatePage.clickStartEventElement();
    await modelerCreatePage.clickChangeTypeButton();
    const result = await Promise.race([
        modelerCreatePage.restConnectorOption
            .waitFor({
            timeout: 15000,
        })
            .then(() => 'webhookConnectorOption'),
        modelerCreatePage.marketPlaceButton
            .waitFor({
            timeout: 15000,
        })
            .then(() => 'marketPlaceButton'),
    ]);
    if (result == 'marketPlaceButton') {
        await modelerCreatePage.clickMarketPlaceButton();
        await connectorMarketplacePage.clickSearchForConnectorTextbox();
        await connectorMarketplacePage.fillSearchForConnectorTextbox('Webhook Connector');
        await (0, sleep_1.sleep)(10000);
        await connectorMarketplacePage.downloadConnectorToProject();
        await modelerCreatePage.clickChangeTypeButton();
    }
    await modelerCreatePage.clickWebhookStartEventConnectorOption();
    await modelerCreatePage.clickWebhookIdInput();
    await modelerCreatePage.clearWebhookIdInput();
    await modelerCreatePage.fillWebhookIdInput(webhookId);
    await modelerCreatePage.clickAppendElementButton();
    await modelerCreatePage.clickAppendEndEventButton();
    await (0, sleep_1.sleep)(1000); // trying to run the process to fast causes it to miss the process id
}
exports.modelWebhookConnector = modelWebhookConnector;
async function assertLocatorVisibleWithRetry(page, locator, text, maxRetries = 300) {
    for (let attempt = 0; attempt <= maxRetries; attempt++) {
        try {
            await (0, test_1.expect)(locator).toBeVisible({
                timeout: 1000,
            });
            return;
        }
        catch (error) {
            await page.reload();
            if (attempt < maxRetries - 1) {
                console.warn(`Attempt ${attempt + 1} failed for asserting ${text}. Retrying...`);
            }
            else {
                throw new Error(`Assertion failed after ${maxRetries} attempts`);
            }
        }
    }
}
exports.assertLocatorVisibleWithRetry = assertLocatorVisibleWithRetry;
async function assertPageTextWithRetry(page, text, notVisible, timeout = constants_1._1_SECOND_IN_MS, maxRetries = 300) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
        try {
            if (notVisible == true) {
                await (0, test_1.expect)(page.getByText(text, { exact: true }).first()).not.toBeVisible({
                    timeout: timeout,
                });
            }
            else {
                await (0, test_1.expect)(page.getByText(text, { exact: true }).first()).toBeVisible({
                    timeout: timeout,
                });
            }
            return;
        }
        catch (error) {
            await page.reload();
            if (attempt < maxRetries - 1) {
                console.warn(`Attempt ${attempt + 1} failed for asserting ${text}. Retrying...`);
            }
            else {
                throw new Error(`Assertion failed after ${maxRetries} attempts`);
            }
        }
    }
}
exports.assertPageTextWithRetry = assertPageTextWithRetry;
async function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage, modelerHomePage, processName, page, connectorMarketplacePage, connectorTemplatePage) {
    await modelerHomePage.clickCreateNewProjectButton();
    await modelerHomePage.createCrossComponentProjectFolder();
    await modelerHomePage.clickDiagramTypeDropdown();
    await modelerHomePage.clickUploadFilesButton();
    await (0, fileUpload_1.uploadFile)(page, 'Rest Connector Timer Event.bpmn');
    await modelerHomePage.clickProcessDiagram('Rest Connector Timer Event');
    await modelerCreatePage.clickDiagramBreadcrumb();
    await modelerCreatePage.clickEditDiagramNameButton();
    await modelerCreatePage.enterDiagramName(processName);
    await modelerCreatePage.clickStartEventElement();
    await modelerCreatePage.clickGeneralPropertiesPanel();
    await modelerCreatePage.clickIdInput();
    await modelerCreatePage.fillIdInput(processName);
    await modelerCreatePage.clickStartEventElement();
    await modelerCreatePage.clickEighthPlacedElement();
    await modelerCreatePage.clickChangeTypeButton();
    await (0, test_1.expect)(modelerCreatePage.marketPlaceButton).toBeVisible({
        timeout: 120000,
    });
    await modelerCreatePage.clickMarketPlaceButton();
    await connectorMarketplacePage.clickSearchForConnectorTextbox();
    await connectorMarketplacePage.fillSearchForConnectorTextbox('REST Connector');
    await (0, sleep_1.sleep)(10000);
    await (0, test_1.expect)(page.getByText('REST ConnectorBy CamundaConnect, interact, and synchronize processes')).toBeVisible({
        timeout: 60000,
    });
    await connectorMarketplacePage.downloadConnectorToProject();
    await modelerHomePage.clickProjectBreadcrumb();
    await modelerHomePage.clickProcessDiagram('REST Outbound Connector');
    await connectorTemplatePage.publishConnector();
    await modelerHomePage.clickProjectBreadcrumb();
    await modelerHomePage.clickProcessDiagram(processName);
    await (0, sleep_1.sleep)(5000);
    await page.reload();
    await (0, sleep_1.sleep)(5000);
    await modelerCreatePage.runProcessInstance();
}
exports.modelAndRunConnectorsTimerEventDiagram = modelAndRunConnectorsTimerEventDiagram;
async function modelDiagramFromFile(page, modelerHomePage, modelerCreatePage, processName, fileName) {
    await modelerHomePage.clickDiagramTypeDropdown();
    await modelerHomePage.clickUploadFilesButton();
    await (0, fileUpload_1.uploadFile)(page, fileName + '.bpmn');
    await modelerHomePage.clickProcessDiagram(fileName);
    await modelerCreatePage.clickDiagramBreadcrumb();
    await modelerCreatePage.clickEditDiagramNameButton();
    await modelerCreatePage.enterDiagramName(processName);
    await (0, sleep_1.sleep)(1000);
    await modelerCreatePage.clickGeneralPropertiesPanel();
    await modelerCreatePage.clickIdInput();
    await modelerCreatePage.fillIdInput(processName);
    await (0, sleep_1.sleep)(10000);
}
exports.modelDiagramFromFile = modelDiagramFromFile;
