Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/scripts/merge-ctrf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env node
/**
* Merges UI and Integration CTRF JSON reports into a single playwright-ctrf.json
* for GitHub test reporting. Run after both Playwright test steps in CI.
*/
const fs = require('fs');
const path = require('path');

const dir = path.join(__dirname, '../../playwright-ctrf');
const uiPath = path.join(dir, 'playwright-ctrf-ui.json');
const integrationPath = path.join(dir, 'playwright-ctrf-integration.json');
const outPath = path.join(dir, 'playwright-ctrf.json');

function loadJson(filePath) {
if (!fs.existsSync(filePath)) {
throw new Error(
`CTRF report not found: ${filePath}\n` +
'Ensure both UI and Integration Playwright test steps completed successfully before merging reports.',
);
}
const raw = fs.readFileSync(filePath, 'utf8');
if (!raw.trim()) {
throw new Error(
`CTRF report is empty: ${filePath}\n` +
'The Playwright test step might have failed before producing a report.',
);
}
try {
return JSON.parse(raw);
} catch (e) {
throw new Error(`CTRF report is invalid JSON: ${filePath}\n` + `Parse error: ${e.message}`);
}
}

function mergeSummary(a, b) {
const sum = (x, y) => (x ?? 0) + (y ?? 0);

const starts = [a.start, b.start].filter((v) => v != null);
const stops = [a.stop, b.stop].filter((v) => v != null);

return {
tests: sum(a.tests, b.tests),
passed: sum(a.passed, b.passed),
failed: sum(a.failed, b.failed),
pending: sum(a.pending, b.pending),
skipped: sum(a.skipped, b.skipped),
other: sum(a.other, b.other),
start: starts.length ? Math.min(...starts) : undefined,
stop: stops.length ? Math.max(...stops) : undefined,
};
}

const ui = loadJson(uiPath);
const integration = loadJson(integrationPath);

const r1 = ui.results;
const r2 = integration.results;

const merged = {
results: {
tool: r1.tool ?? r2.tool,
summary: mergeSummary(r1.summary ?? {}, r2.summary ?? {}),
tests: [...(r1.tests ?? []), ...(r2.tests ?? [])],
environment: r1.environment ?? r2.environment ?? {},
},
};

fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(outPath, JSON.stringify(merged, null, 0), 'utf8');
console.log(
`Merged CTRF: ${(r1.tests ?? []).length} UI + ${(r2.tests ?? []).length} Integration tests -> ${outPath}`,
);
41 changes: 40 additions & 1 deletion .github/workflows/playwright-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,52 @@ jobs:
working-directory: content-sources-backend
run: while [[ "$(curl http://localhost:8000/api/content-sources/v1.0/repositories/ -H "$( ./scripts/header.sh 9999 1111)" | jq '.data | all(.status == "Valid")')" == "false" ]]; do sleep 5; done;

- name: Run front-end Playwright tests
- name: Run front-end Playwright tests (UI)
run: yarn playwright test
env:
CURRENTS_PROJECT_ID: ${{ secrets.CURRENTS_PROJECT_ID }}
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}

- name: Set integration test env vars
run: |
# Pass through from CodeBuild env (same vars as int-repo, see nightly-stage-test-action.yml).
# Requires fe-repo CodeBuild project to have these configured.
missing=""
for var in STAGE_LAYERED_REPO_ACCESS_USERNAME STAGE_STABLE_SAM_USERNAME STAGE_ORG_ID STAGE_ACTIVATION_KEY RH_PROXY_URL; do
[ -z "${!var}" ] && missing="$missing $var"
done
if [ -n "$missing" ]; then
echo "::error::CodeBuild env vars missing for Integration tests:$missing"
echo "Add these to the codebuild-content-services-fe-repo project (mirror int-repo config)."
exit 1
fi
echo "LAYERED_REPO_ACCESS_USERNAME=$STAGE_LAYERED_REPO_ACCESS_USERNAME" >> $GITHUB_ENV
echo "LAYERED_REPO_ACCESS_PASSWORD=$STAGE_LAYERED_REPO_ACCESS_PASSWORD" >> $GITHUB_ENV
echo "RHEL_ONLY_ACCESS_USERNAME=$STAGE_RHEL_ONLY_ACCESS_USERNAME" >> $GITHUB_ENV
echo "RHEL_ONLY_ACCESS_PASSWORD=$STAGE_RHEL_ONLY_ACCESS_PASSWORD" >> $GITHUB_ENV
echo "NO_SUBS_USER_USERNAME=$STAGE_NO_SUBS_USER_USERNAME" >> $GITHUB_ENV
echo "NO_SUBS_USER_PASSWORD=$STAGE_NO_SUBS_USER_PASSWORD" >> $GITHUB_ENV
echo "NO_SUBS_USER_ACTIVATION_KEY=$STAGE_NO_SUBS_USER_ACTIVATION_KEY" >> $GITHUB_ENV
echo "NO_SUBS_USER_ORG_ID=$STAGE_NO_SUBS_USER_ORG_ID" >> $GITHUB_ENV
echo "ORG_ID_1=$STAGE_ORG_ID" >> $GITHUB_ENV
echo "ACTIVATION_KEY_1=$STAGE_ACTIVATION_KEY" >> $GITHUB_ENV
echo "LAYERED_REPO_ACCESS_ORG_ID=$STAGE_LAYERED_REPO_ACCESS_ORG_ID" >> $GITHUB_ENV
echo "LAYERED_REPO_ACCESS_ACTIVATION_KEY=$STAGE_LAYERED_REPO_ACCESS_ACTIVATION_KEY" >> $GITHUB_ENV
echo "STABLE_SAM_USERNAME=$STAGE_STABLE_SAM_USERNAME" >> $GITHUB_ENV
echo "STABLE_SAM_PASSWORD=$STAGE_STABLE_SAM_PASSWORD" >> $GITHUB_ENV
echo "RH_CLIENT_PROXY=$RH_PROXY_URL" >> $GITHUB_ENV

- name: Run front-end Playwright tests (Integration)
run: INTEGRATION=true yarn playwright test
env:
CURRENTS_PROJECT_ID: ${{ secrets.CURRENTS_PROJECT_ID }}
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}

- name: Merge CTRF reports
run: node .github/scripts/merge-ctrf.js

- name: Publish front-end Test Report
uses: ctrf-io/github-test-reporter@v1
with:
Expand Down
7 changes: 6 additions & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ export default defineConfig<CurrentsFixtures, CurrentsWorkerFixtures>({
['html', { outputFolder: 'playwright-report' }],
[
'playwright-ctrf-json-reporter',
{ outputDir: 'playwright-ctrf', outputFile: 'playwright-ctrf.json' },
{
outputDir: 'playwright-ctrf',
outputFile: process.env.INTEGRATION
? 'playwright-ctrf-integration.json'
: 'playwright-ctrf-ui.json',
},
],
...(currentsConfig ? [currentsReporter(currentsConfig)] : []),
]
Expand Down
Loading