"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const SM_8_10_1 = require("../../fixtures/SM-8.10");
const _setup_1 = require("../../test-setup.js");
const apiHelpers_1 = require("../../utils/apiHelpers");
const sleep_1 = require("../../utils/sleep");
const randomName_1 = require("../../utils/randomName");
const CLUSTER_VAR_NAMES = {
    ORIGINAL_JSON: 'ORIGINAL_API_INFO',
    UPDATABLE_JSON: 'UPDATABLE_API_INFO',
    ORIGINAL_STRING: 'ORIGINAL_APP_VERSION',
    UPDATABLE_STRING: 'UPDATABLE_APP_VERSION',
};
// Resolve cluster variable values from available env vars with fallbacks
const clusterVariableJsonValue = process.env.CLUSTER_VARIABLE_JSON_VALUE || process.env.CLUSTER_VARIABLE_JSON;
const clusterVariableStringValue = process.env.CLUSTER_VARIABLE_STRING_VALUE || 'v1.0.0';
function getConfigByType(type) {
    const configs = {
        JSON: {
            processName: 'Cluster Variable Original JSON',
            processNameUpdatable: 'Cluster Variable Updatable JSON',
            taskName: 'Preview JSON cluster variables',
            taskElementId: 'Activity_1whhatc',
            originalVariableName: CLUSTER_VAR_NAMES.ORIGINAL_JSON,
            updatableVariableName: CLUSTER_VAR_NAMES.UPDATABLE_JSON,
            originalValue: originalJsonClusterVariableValue,
            operateVariableName: 'URL',
            randomValuePrefix: 'https://updated.api.com',
        },
        String: {
            processName: 'Cluster Variable Original String',
            processNameUpdatable: 'Cluster Variable Updatable String',
            taskName: 'Preview String cluster variable',
            taskElementId: 'Activity_1whhatc',
            originalVariableName: CLUSTER_VAR_NAMES.ORIGINAL_STRING,
            updatableVariableName: CLUSTER_VAR_NAMES.UPDATABLE_STRING,
            originalValue: originalStringClusterVariableValue,
            operateVariableName: 'APP_VERSION_VALUE',
            randomValuePrefix: 'v3.0.0-updated',
        },
    };
    return configs[type];
}
let authToken;
let originalJsonClusterVariableValue;
let originalStringClusterVariableValue;
let jsonProcessKeyDisplay;
let jsonProcessKeyUpdate;
let stringProcessKeyDisplay;
let stringProcessKeyUpdate;
SM_8_10_1.test.describe.configure({ mode: 'parallel' });
SM_8_10_1.test.describe('Cluster Variables User Flows', () => {
    SM_8_10_1.test.beforeAll(async () => {
        authToken = await (0, apiHelpers_1.authSmAPI)();
        if (!clusterVariableJsonValue) {
            throw new Error('Neither CLUSTER_VARIABLE_JSON_VALUE nor CLUSTER_VARIABLE_JSON env var is set');
        }
        await Promise.all([
            (0, apiHelpers_1.createJsonClusterVariable)(authToken, 'sm', CLUSTER_VAR_NAMES.ORIGINAL_JSON, clusterVariableJsonValue),
            (0, apiHelpers_1.createJsonClusterVariable)(authToken, 'sm', CLUSTER_VAR_NAMES.UPDATABLE_JSON, clusterVariableJsonValue),
            (0, apiHelpers_1.createStringClusterVariable)(authToken, 'sm', CLUSTER_VAR_NAMES.ORIGINAL_STRING, clusterVariableStringValue),
            (0, apiHelpers_1.createStringClusterVariable)(authToken, 'sm', CLUSTER_VAR_NAMES.UPDATABLE_STRING, clusterVariableStringValue),
        ]);
        originalJsonClusterVariableValue = JSON.parse(clusterVariableJsonValue);
        originalStringClusterVariableValue = clusterVariableStringValue;
        const deployments = [
            {
                path: './resources/cluster_variables/cluster_variable_json_readonly.bpmn',
                assignTo: 'jsonProcessKeyDisplay',
            },
            {
                path: './resources/cluster_variables/cluster_variable_json_mutable.bpmn',
                assignTo: 'jsonProcessKeyUpdate',
            },
            {
                path: './resources/cluster_variables/cluster_variable_json_form.form',
                assignTo: null,
            },
            {
                path: './resources/cluster_variables/cluster_variable_string_readonly.bpmn',
                assignTo: 'stringProcessKeyDisplay',
            },
            {
                path: './resources/cluster_variables/cluster_variable_string_mutable.bpmn',
                assignTo: 'stringProcessKeyUpdate',
            },
            {
                path: './resources/cluster_variables/cluster_variable_string_form.form',
                assignTo: null,
            },
        ];
        const deploymentResults = await Promise.all(deployments.map((d) => (0, apiHelpers_1.deployProcess)(d.path, authToken)));
        jsonProcessKeyDisplay = deploymentResults[0];
        jsonProcessKeyUpdate = deploymentResults[1];
        stringProcessKeyDisplay = deploymentResults[3];
        stringProcessKeyUpdate = deploymentResults[4];
    });
    SM_8_10_1.test.beforeEach(async ({ navigationPage }, testInfo) => {
        await navigationPage.goToOperate((testInfo.workerIndex + 1) * 1000);
    });
    SM_8_10_1.test.afterEach(async ({ page }, testInfo) => {
        await (0, _setup_1.captureScreenshot)(page, testInfo);
        await (0, _setup_1.captureFailureVideo)(page, testInfo);
    });
    SM_8_10_1.test.describe('Global cluster variable', () => {
        const testConfigs = [
            {
                type: 'JSON',
                processKeyDisplay: () => jsonProcessKeyDisplay,
                processKeyUpdate: () => jsonProcessKeyUpdate,
            },
            {
                type: 'String',
                processKeyDisplay: () => stringProcessKeyDisplay,
                processKeyUpdate: () => stringProcessKeyUpdate,
            },
        ];
        for (const config of testConfigs) {
            (0, SM_8_10_1.test)(`User views ${config.type} cluster variable in Tasklist from readonly process and completes task`, async ({ page, navigationPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, }) => {
                SM_8_10_1.test.slow();
                const derived = getConfigByType(config.type);
                const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(config.processKeyDisplay()), authToken);
                await SM_8_10_1.test.step('User can access the process on operate', async () => {
                    await operateHomePage.clickProcessesTab();
                    await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
                    await operateProcessesPage.clickProcessInstanceLink(String(instanceKey));
                    await operateProcessInstancePage.assertActiveTokenIsPresent();
                });
                await SM_8_10_1.test.step(`User can view the process with ${config.type} cluster variable on tasklist`, async () => {
                    await navigationPage.goToTasklist();
                    await (0, sleep_1.sleep)(5000);
                    // Tasklist may display the BPMN element ID instead of the task name
                    // due to inconsistent metadata. Determine which label is visible.
                    const taskNameLocator = taskPanelPage.availableTasks.getByText(derived.taskName, { exact: true });
                    const taskElementIdLocator = taskPanelPage.availableTasks.getByText(derived.taskElementId, { exact: true });
                    let taskLabel = derived.taskName;
                    for (let attempt = 1; attempt <= 30; attempt++) {
                        const [nameVisible, elementIdVisible] = await Promise.all([
                            taskNameLocator
                                .first()
                                .isVisible()
                                .catch(() => false),
                            taskElementIdLocator
                                .first()
                                .isVisible()
                                .catch(() => false),
                        ]);
                        if (nameVisible) {
                            taskLabel = derived.taskName;
                            break;
                        }
                        if (elementIdVisible) {
                            taskLabel = derived.taskElementId;
                            break;
                        }
                        if (attempt < 30) {
                            await page.reload();
                            await (0, sleep_1.sleep)(2000);
                        }
                    }
                    await taskPanelPage.openTask(taskLabel);
                    await taskDetailsPage.clickAssignToMeButton();
                });
                await SM_8_10_1.test.step(`User can view the value of ${config.type} cluster variable and complete the task`, async () => {
                    if (config.type === 'JSON') {
                        for (const value of Object.values(derived.originalValue)) {
                            await taskDetailsPage.assertTextIsPresent(String(value));
                        }
                    }
                    else {
                        await taskDetailsPage.assertTextIsPresent(String(derived.originalValue));
                    }
                    await taskDetailsPage.clickCompleteTaskButton();
                });
                await SM_8_10_1.test.step('User can assert the process is completed on Operate', async () => {
                    await navigationPage.goToOperate();
                    await operateHomePage.clickProcessesTab();
                    await operateProcessesPage.clickProcessCompletedCheckbox();
                    await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
                    await operateProcessesPage.clickProcessInstanceLink(String(instanceKey), 'completed');
                    await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
                });
            });
        }
        for (const config of testConfigs) {
            (0, SM_8_10_1.test)(`User updates ${config.type} cluster variable in Admin UI and verifies changes in Operate`, async ({ navigationPage, ocIdentityHomePage, ocIdentityClusterVariablesPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
                SM_8_10_1.test.slow();
                const derived = getConfigByType(config.type);
                const randomRawValue = await (0, randomName_1.randomNameAgregator)(derived.randomValuePrefix);
                const newValue = config.type === 'JSON'
                    ? JSON.stringify({
                        endpoint: randomRawValue,
                        timeout_ms: '5000',
                        array: ['updated_item1', 'updated_item2'],
                    })
                    : JSON.stringify(randomRawValue);
                await SM_8_10_1.test.step('User navigates to Admin UI', async () => {
                    await navigationPage.goToOCAdmin();
                });
                await SM_8_10_1.test.step('User navigates to Cluster Variables tab', async () => {
                    await ocIdentityHomePage.clickClusterVariablesTab();
                });
                await SM_8_10_1.test.step(`User verifies ${config.type} cluster variable exists`, async () => {
                    await ocIdentityClusterVariablesPage.assertVariableExists(derived.updatableVariableName);
                });
                await SM_8_10_1.test.step(`User updates the ${config.type} cluster variable value`, async () => {
                    await ocIdentityClusterVariablesPage.editVariable(derived.updatableVariableName, newValue);
                });
                await SM_8_10_1.test.step(`User creates a process instance with the updated ${config.type} cluster variable`, async () => {
                    const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(config.processKeyUpdate()), authToken);
                    await SM_8_10_1.test.step('User navigates to the process instance on Operate', async () => {
                        await navigationPage.goToOperate();
                        await operateHomePage.clickProcessesTab();
                        await operateProcessesPage.clickProcessCompletedCheckbox();
                        await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
                        await operateProcessesPage.clickProcessInstanceLink(String(instanceKey), 'completed');
                        await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
                    });
                    await SM_8_10_1.test.step(`User verifies the updated ${config.type} cluster variable value is present in process variables`, async () => {
                        await operateProcessInstancePage.assertProcessVariableContainsText(derived.operateVariableName, randomRawValue);
                    });
                });
            });
        }
    });
});
