/** * GitLab Integration — End-to-End Tests * * Validates the GitLab SCM connector lifecycle against the real GitLab CE instance: * 1. Container health + direct probe * 2. Connector CRUD via API (create, test-connection, health, delete) * 3. UI: SCM tab shows GitLab row * * Workaround for "heavy profile": Instead of checking Docker CLI (which may * not be available from Playwright workers), we probe GitLab's HTTP endpoint * directly. If it responds, the tests run; otherwise they skip gracefully. */ import { execSync } from 'child_process'; import { test, expect } from './live-auth.fixture'; import { INTEGRATION_CONFIGS, createIntegrationViaApi, cleanupIntegrations, snap, waitForAngular, } from './helpers'; const BASE = process.env['PLAYWRIGHT_BASE_URL'] || 'https://stella-ops.local'; const runId = process.env['E2E_RUN_ID'] || 'run1'; const GITLAB_URL = 'http://127.1.2.7:8929'; /** * Probe GitLab via HTTP instead of Docker CLI. * Returns true if GitLab responds (any status < 500) within 3 seconds. */ function gitlabReachable(): boolean { try { // Use curl (available on both Windows and Linux) with a short timeout const out = execSync( `curl -sf -o /dev/null -w "%{http_code}" --connect-timeout 3 ${GITLAB_URL}/`, { encoding: 'utf-8', timeout: 5_000 }, ).trim(); const code = parseInt(out, 10); return code > 0 && code < 500; } catch { return false; } } const gitlabRunning = gitlabReachable(); // --------------------------------------------------------------------------- // 1. Reachability // --------------------------------------------------------------------------- test.describe('GitLab Integration — Reachability', () => { test.skip(!gitlabRunning, 'GitLab not reachable at 127.1.2.7:8929'); test('GitLab responds to HTTP probe', async ({ playwright }) => { const ctx = await playwright.request.newContext({ ignoreHTTPSErrors: true }); try { const resp = await ctx.get(`${GITLAB_URL}/`, { timeout: 10_000 }); // 302 redirect to login = GitLab is running expect(resp.status()).toBeLessThan(500); } finally { await ctx.dispose(); } }); }); // --------------------------------------------------------------------------- // 2. Connector Lifecycle (API) // --------------------------------------------------------------------------- test.describe('GitLab Integration — Connector Lifecycle', () => { test.skip(!gitlabRunning, 'GitLab not reachable'); test('create GitLab integration and verify CRUD operations', async ({ apiRequest }) => { // Create const id = await createIntegrationViaApi(apiRequest, INTEGRATION_CONFIGS.gitlab, runId); expect(id).toBeTruthy(); try { // Verify created with correct fields const getResp = await apiRequest.get(`/api/v1/integrations/${id}`); expect(getResp.status()).toBe(200); const integration = await getResp.json(); expect(integration.type).toBe(2); // Scm expect(integration.provider).toBe(201); // GitLabServer expect(integration.name).toContain('GitLab'); expect(integration.endpoint).toContain('gitlab'); // Test connection — returns structured response // May return success=false if GitLab requires auth token for /api/v4/version const testResp = await apiRequest.post(`/api/v1/integrations/${id}/test`); expect(testResp.status()).toBe(200); const testBody = await testResp.json(); expect(typeof testBody.success).toBe('boolean'); expect(testBody.message).toBeTruthy(); // Health check — returns structured response const healthResp = await apiRequest.get(`/api/v1/integrations/${id}/health`); expect(healthResp.status()).toBe(200); const healthBody = await healthResp.json(); expect(typeof healthBody.status).toBe('number'); } finally { await cleanupIntegrations(apiRequest, [id]); } }); }); // --------------------------------------------------------------------------- // 3. UI: SCM Tab // --------------------------------------------------------------------------- test.describe('GitLab Integration — UI Verification', () => { test.skip(!gitlabRunning, 'GitLab not reachable'); test('SCM tab shows GitLab integration', async ({ apiRequest, liveAuthPage: page }) => { const id = await createIntegrationViaApi(apiRequest, INTEGRATION_CONFIGS.gitlab, `ui-${runId}`); try { await page.goto(`${BASE}/setup/integrations/scm`, { waitUntil: 'domcontentloaded', timeout: 45_000, }); await waitForAngular(page); await expect(page.locator('text=GitLab').first()).toBeVisible({ timeout: 15_000 }); await snap(page, 'gitlab-scm-tab'); } finally { await cleanupIntegrations(apiRequest, [id]); } }); });