121 lines
5.5 KiB
JavaScript
121 lines
5.5 KiB
JavaScript
const { execSync } = require('child_process');
|
|
const { When, Then } = require('@cucumber/cucumber');
|
|
const path = require('path');
|
|
|
|
const PROJECT_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
const MOCK_SCRIPT = path.join(PROJECT_ROOT, 'tests', 'helpers', 'mock-api.sh');
|
|
const REPORT_SCRIPT = path.join(PROJECT_ROOT, 'scripts', 'report-status.sh');
|
|
|
|
function bash(cmd) {
|
|
try {
|
|
const out = execSync(`bash -c '${cmd}'`, {
|
|
cwd: PROJECT_ROOT,
|
|
encoding: 'utf-8',
|
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
});
|
|
return { status: 0, stdout: out };
|
|
} catch (e) {
|
|
return { status: e.status, stdout: e.stdout || '', stderr: e.stderr || '' };
|
|
}
|
|
}
|
|
|
|
function bashQuiet(cmd) {
|
|
execSync(`bash -c '${cmd}'`, {
|
|
cwd: PROJECT_ROOT,
|
|
stdio: 'ignore',
|
|
});
|
|
}
|
|
|
|
function runReportStatus(args) {
|
|
return bash(`export GITEA_API_URL="http://localhost:18080" GITEA_TOKEN="test-token-abc123" PAGES_HOST="reports.example.com" GITHUB_REPOSITORY="test-owner/test-repo" GITHUB_SHA="abc123def456789012345678901234567890abcd" GITHUB_RUN_ID="42"; bash "${REPORT_SCRIPT}" ${args}`);
|
|
}
|
|
|
|
function getMockBody() {
|
|
return bash(`source "${MOCK_SCRIPT}" && _get_request_file && mock_get_request_body`).stdout.trim();
|
|
}
|
|
|
|
function getMockPath() {
|
|
return bash(`source "${MOCK_SCRIPT}" && _get_request_file && mock_get_request_path`).stdout.trim();
|
|
}
|
|
|
|
When('a build step starts executing', function () {
|
|
const r = runReportStatus('pending "Building project"');
|
|
if (r.status !== 0) throw new Error(`Expected exit 0, got ${r.status}: ${r.stderr}`);
|
|
});
|
|
|
|
Then('the commit shows a pending status with a description of the step', function () {
|
|
const body = getMockBody();
|
|
if (!body.includes('"state":"pending"')) throw new Error('Expected pending status');
|
|
if (!body.includes('"description":"Building project"')) throw new Error('Expected description');
|
|
});
|
|
|
|
When('a build step completes successfully and reports its results', function () {
|
|
const r = runReportStatus('success "Unit tests OK" unit-test cucumber/');
|
|
if (r.status !== 0) throw new Error(`Expected exit 0, got ${r.status}`);
|
|
});
|
|
|
|
Then('the commit shows a success status with a clickable link to the results', function () {
|
|
const body = getMockBody();
|
|
if (!body.includes('"state":"success"')) throw new Error('Expected success status');
|
|
if (!body.includes('"target_url":"https://reports.example.com/test-owner/test-repo/reports/abc123de/cucumber/"')) throw new Error('Expected URL');
|
|
});
|
|
|
|
When('a build step fails', function () {
|
|
const r = runReportStatus('failure "Tests failed: 3 of 10"');
|
|
if (r.status !== 0) throw new Error(`Expected exit 0, got ${r.status}`);
|
|
});
|
|
|
|
Then('the commit shows a failure status with a description of what went wrong', function () {
|
|
const body = getMockBody();
|
|
if (!body.includes('"state":"failure"')) throw new Error('Expected failure status');
|
|
if (!body.includes('"description":"Tests failed: 3 of 10"')) throw new Error('Expected failure description');
|
|
});
|
|
|
|
When('several build steps each report their own status to the same commit', function () {
|
|
runReportStatus('pending "Build started" ci-build');
|
|
execSync('sleep 0.3', { stdio: 'ignore' });
|
|
runReportStatus('success "Unit tests passed" unit-test');
|
|
execSync('sleep 0.3', { stdio: 'ignore' });
|
|
runReportStatus('success "Integration tests passed" integration-test');
|
|
});
|
|
|
|
Then('each status appears under a unique label on the commit', function () {
|
|
const requestFile = bash(`source "${MOCK_SCRIPT}" && _get_request_file`).stdout.trim();
|
|
if (!requestFile || requestFile === '/dev/null') throw new Error('Mock request file not found');
|
|
bashQuiet('sync');
|
|
const allRequestsRaw = bash(`cat "${requestFile}"`);
|
|
const allRequests = allRequestsRaw.stdout;
|
|
const postCount = (allRequests.match(/POST /g) || []).length;
|
|
if (postCount < 3) throw new Error(`Expected 3 POST requests, got ${postCount}. Content: ${allRequests.substring(0, 1000)}`);
|
|
if (!allRequests.includes('"context":"ci-build"')) throw new Error('Missing ci-build');
|
|
if (!allRequests.includes('"context":"unit-test"')) throw new Error('Missing unit-test');
|
|
if (!allRequests.includes('"context":"integration-test"')) throw new Error('Missing integration-test');
|
|
});
|
|
|
|
When('a deployment finishes for a commit that originated from another repository', function () {
|
|
const r = runReportStatus('success "Deployed to staging" deploy-staging');
|
|
if (r.status !== 0) throw new Error(`Expected exit 0, got ${r.status}`);
|
|
});
|
|
|
|
Then('the source commit shows the deployment status alongside the build status', function () {
|
|
const body = getMockBody();
|
|
if (!body.includes('"state":"success"')) throw new Error('Expected success');
|
|
if (!body.includes('"context":"deploy-staging"')) throw new Error('Expected deploy-staging context');
|
|
|
|
const pathStr = getMockPath();
|
|
if (!pathStr.includes('test-owner/test-repo')) throw new Error('Expected default repo target');
|
|
if (!pathStr.includes('abc123def456789012345678901234567890abcd')) throw new Error('Expected default commit');
|
|
});
|
|
|
|
When('a build step tries to report status but the build system is unavailable', function () {
|
|
bashQuiet(`source "${MOCK_SCRIPT}" && mock_stop`);
|
|
execSync('sleep 0.3', { stdio: 'ignore' });
|
|
bashQuiet(`source "${MOCK_SCRIPT}" && mock_set_response 500 && mock_start`);
|
|
const r = runReportStatus('success "Should fail"');
|
|
this.reportStatusFailed = (r.status !== 0);
|
|
});
|
|
|
|
Then('the pipeline fails with a clear error message', function () {
|
|
if (!this.reportStatusFailed) throw new Error('Expected pipeline to fail (exit code != 0)');
|
|
});
|