// #region MigrationE2E [C:3] [TYPE Test] [SEMANTICS e2e, migration, sync, datasets] // @BRIEF E2E tests for dataset/environment migration and sync. // @RELATION BINDS_TO -> [MigrationApi] // @UX_STATE SyncTriggered -> Sync-now request accepted. // @UX_STATE MappingsLoaded -> Synchronized resources table populated. import { test, expect } from '../fixtures/auth.fixture.js'; import { apiGet, apiPost } from '../helpers/api.helper.js'; const FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102'; test.describe('Dataset Environment Sync', () => { test('should show migration settings tab', async ({ authPage }) => { await authPage.goto(`${FRONTEND_URL}/settings#/settings/migration`); await authPage.waitForSelector('text=Синхронизация', { timeout: 10_000 }); // Schedule section visible await expect(authPage.getByText(/Cron-выражение|Schedule/)).toBeVisible(); }); test('should trigger sync and check results via API', async ({ authPage }) => { // Get pre-sync settings const settingsBefore = await apiGet('/api/migration/settings'); expect(settingsBefore).toBeDefined(); expect(settingsBefore.cron).toBeDefined(); // Trigger sync (fire-and-forget, it runs async) let syncResult; try { syncResult = await apiPost('/api/migration/sync-now', {}); console.log('[E2E] Sync triggered:', JSON.stringify(syncResult).slice(0, 200)); } catch (err) { // Sync may timeout or fail if Superset is unreachable — that's acceptable for CI console.log('[E2E] Sync note (non-blocking):', err.message.slice(0, 200)); } // Verify sync mappings endpoint responds const mappings = await apiGet('/api/migration/mappings-data?skip=0&limit=5').catch(() => []); console.log(`[E2E] Mappings count: ${Array.isArray(mappings) ? mappings.length : 'N/A'}`); // If mappings exist, verify structure if (Array.isArray(mappings) && mappings.length > 0) { const mapping = mappings[0]; expect(mapping.resource_name).toBeDefined(); expect(mapping.resource_type).toBeDefined(); } }); }); test.describe('Datasets', () => { test('should list datasets from ss-dev', async ({ authPage }) => { const datasets = await apiGet('/api/datasets?env_id=ss-dev&skip=0&limit=10'); expect(Array.isArray(datasets)).toBeTruthy(); if (datasets.length > 0) { expect(datasets[0].id || datasets[0].table_name).toBeTruthy(); } }); test('should show datasets page in UI', async ({ authPage }) => { await authPage.goto(`${FRONTEND_URL}/datasets`); await authPage.waitForSelector('text=Датасеты', { timeout: 10_000 }); // Dataset table/list skeleton await expect(authPage.locator('main')).toBeVisible(); }); test('should show translate_fact dataset detail', async ({ authPage }) => { // Get translate_fact datasource ID const datasources = await apiGet('/api/translate/datasources?env_id=ss-dev'); const translateFact = datasources.find(ds => ds.table_name === 'translate_fact' && ds.schema === 'dm_view' ); expect(translateFact).toBeDefined(); expect(translateFact.id).toBeDefined(); // Navigate to dataset detail in UI await authPage.goto(`${FRONTEND_URL}/datasets/${translateFact.id}?env_id=ss-dev`); await authPage.waitForTimeout(3000); // Page should load const bodyText = await authPage.locator('body').innerText(); expect(bodyText.length).toBeGreaterThan(0); }); }); // #endregion MigrationE2E