const { test, expect } = require('@playwright/test'); const { getCurrentWorkspace, login, localized } = require('./helpers'); test('wizard loads and protocol selection updates flow', async ({ page }) => { await login(page); await page.goto('/wizard/'); await expect(page.locator('[data-step-counter]').first()).toContainText(localized('Step', 'Шаг')); await expect(page.locator('#step-panel-1 .step-panel-title')).toContainText(localized('Choose a protocol', 'Выберите протокол')); await page.locator('[data-testid="wizard-protocol-rest"]').click(); await page.locator('#btn-continue').click(); await expect(page.locator('#step-panel-2 .step-panel-title')).toContainText(localized('Select upstream', 'Выберите upstream')); }); test('community wizard hides premium protocols and explains edition scope', async ({ page }) => { await login(page); await page.goto('/wizard/'); await expect(page.locator('[data-testid="wizard-protocol-rest"]')).toBeVisible(); await expect(page.locator('[data-testid="wizard-protocol-graphql"]')).toBeHidden(); await expect(page.locator('[data-testid="wizard-protocol-grpc"]')).toBeHidden(); await expect(page.locator('[data-testid="wizard-protocol-websocket"]')).toBeHidden(); await expect(page.locator('[data-testid="wizard-protocol-soap"]')).toBeHidden(); await expect(page.locator('#wizard-edition-protocol-note')).toContainText( localized('Commercial editions unlock', 'коммерческих редакциях') ); await page.locator('[data-testid="wizard-protocol-rest"]').click(); await page.locator('#btn-continue').click(); await page.locator('#btn-continue').click(); await page.locator('#btn-continue').click(); await page.locator('#btn-continue').click(); await expect(page.locator('#wizard-streaming-config-card')).toBeHidden(); await expect(page.locator('#wizard-streaming-capability-note')).toHaveCount(0); }); test('wizard edit mode hydrates fields from operation version snapshot', async ({ page }) => { await login(page); const workspace = await getCurrentWorkspace(page); const operationId = 'frankfurter_monthly_rates'; const version = 7; await page.route( `/api/admin/workspaces/${encodeURIComponent(workspace.id)}/operations/${operationId}`, async (route) => { await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ id: operationId, workspace_id: workspace.id, name: operationId, display_name: 'Frankfurter monthly rates', category: 'finance', protocol: 'rest', security_level: 'standard', status: 'draft', current_draft_version: version, latest_published_version: null, created_at: '2026-06-19T00:00:00Z', updated_at: '2026-06-19T00:00:00Z', published_at: null, draft_version_ref: { version, status: 'draft' }, published_version_ref: null, agent_refs: [], }), }); }, ); await page.route( `/api/admin/workspaces/${encodeURIComponent(workspace.id)}/operations/${operationId}/versions/${version}`, async (route) => { await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ operation_id: operationId, workspace_id: workspace.id, version, status: 'draft', change_note: null, created_at: '2026-06-19T00:00:00Z', created_by: null, snapshot: { id: operationId, name: operationId, display_name: 'Frankfurter monthly rates', category: 'finance', protocol: 'rest', security_level: 'standard', status: 'draft', version, target: { kind: 'rest', base_url: 'https://api.frankfurter.app', method: 'GET', path_template: '/2024-01..2024-03', static_headers: {}, }, input_schema: { type: 'object', description: null, required: false, nullable: false, default_value: null, fields: { from: { type: 'string', description: 'Base currency', required: true, nullable: false, default_value: null, fields: {}, items: null, enum_values: [], variants: [], }, }, items: null, enum_values: [], variants: [], }, output_schema: { type: 'object', description: null, required: false, nullable: false, default_value: null, fields: { rates: { type: 'object', description: 'Rates by date', required: true, nullable: false, default_value: null, fields: {}, items: null, enum_values: [], variants: [], }, }, items: null, enum_values: [], variants: [], }, input_mapping: { rules: [ { source: '$.mcp.from', target: '$.request.body.from' }, ], }, output_mapping: { rules: [ { source: '$.response.body.rates', target: '$.output.rates' }, ], }, execution_config: { timeout_ms: 9000, retry_policy: { max_attempts: 2 }, auth_profile_ref: null, headers: {}, protocol_options: null, streaming: null, }, tool_description: { title: 'Получить историю курсов за месяц', description: 'Возвращает историю курсов валют Frankfurter за заданный период.', tags: [], examples: [], }, samples: [], generated_draft: null, config_export: null, }, }), }); }, ); await page.goto(`/wizard/?mode=edit&operationId=${operationId}`); await expect(page.locator('#tool-name')).toHaveValue(operationId); await expect(page.locator('#tool-display-name')).toHaveValue('Frankfurter monthly rates'); await expect(page.locator('#new-upstream-url')).toHaveValue('https://api.frankfurter.app'); await expect(page.locator('#endpoint-path')).toHaveValue('/2024-01..2024-03'); await expect(page.locator('.method-card.active')).toHaveAttribute('data-method', 'GET'); await expect(page.locator('#tool-title')).toHaveValue('Получить историю курсов за месяц'); await expect(page.locator('#tool-input-schema')).toHaveValue(/"from"/); await expect(page.locator('#tool-input-schema')).not.toHaveValue(/first_name/); await expect(page.locator('#tool-output-schema')).toHaveValue(/"rates"/); await expect(page.locator('#tool-exec-config')).toHaveValue(/9000/); });