diff --git a/.github/workflows/user-flow-md-report-test.yml b/.github/workflows/user-flow-md-report-test.yml index f23a774f4..60d07e875 100644 --- a/.github/workflows/user-flow-md-report-test.yml +++ b/.github/workflows/user-flow-md-report-test.yml @@ -17,20 +17,25 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Setup node ${{ matrix.node-version }} uses: actions/setup-node@v4 with: cache: 'npm' node-version: ${{ matrix.node-version }} - - name: install + + - name: Clean Install run: npm ci - - name: build - run: npm run nx -- affected:build --base=origin/main --head=HEAD - - name: run - run: npm run md-report-test + + - name: Collect Report + run: npm run @push-based/user-flow -- --rcPath ./examples/github-report/.user-flowrc.json --openReport false + + - name: Rename Report + run: npx tsx --tsconfig ./examples/github-report/tsconfig.json ./examples/github-report/tools/md-report-rename.mts + - name: Add reduced report as comment to the PR uses: marocchino/sticky-pull-request-comment@v2 with: hide_and_recreate: true header: md-report-test - path: ./dist/user-flow/user-flow-gh-integration/md-report.md + path: ./examples/github-report/measures/md-report.md diff --git a/.gitignore b/.gitignore index 99cf13279..46c48a4d1 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,5 @@ Thumbs.db .env .code-pushup + +examples/**/measures/* diff --git a/e2e/cli-e2e/project.json b/e2e/cli-e2e/project.json index 6544f690d..b54a955fb 100644 --- a/e2e/cli-e2e/project.json +++ b/e2e/cli-e2e/project.json @@ -1,7 +1,7 @@ { "name": "cli-e2e", "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "examples/cli-e2e/src", + "sourceRoot": "e2e/cli-e2e/src", "projectType": "application", "targets": { "lint": { diff --git a/examples/github-report/.user-flowrc.json b/examples/github-report/.user-flowrc.json new file mode 100644 index 000000000..0bf470e04 --- /dev/null +++ b/examples/github-report/.user-flowrc.json @@ -0,0 +1,10 @@ +{ + "collect": { + "url": "https://coffee-cart.netlify.app/", + "ufPath": "./examples/github-report/user-flows" + }, + "persist": { + "outPath": "./examples/github-report/measures", + "format": [ "md" ] + } +} diff --git a/examples/github-report/README.md b/examples/github-report/README.md new file mode 100644 index 000000000..6d6e20a98 --- /dev/null +++ b/examples/github-report/README.md @@ -0,0 +1,15 @@ +## Github Comment Report Example + +This example demonstrates how you can easily take you current user-flow reports and add them as comments in a GITHUB PR + +### Description + +The example has a minimal user-flow and is executed in a github workflow. + +You can find the related workflow under `.github/workflows/user-flow-md-report-test.yml`. + +The workflow executes user-flow then with a script transforms and renames the report. + +Then using a GITHUB action it adds it to the pull request as a comment. If there is already a report present it will minimize the previous one when adding a new one. + +![github-report-comment](assets/github-report-comment.png) diff --git a/examples/github-report/assets/github-report-comment.png b/examples/github-report/assets/github-report-comment.png new file mode 100644 index 000000000..e65c7ce35 Binary files /dev/null and b/examples/github-report/assets/github-report-comment.png differ diff --git a/examples/github-report/measures/.gitkeep b/examples/github-report/measures/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/tools/md-report-rename.ts b/examples/github-report/tools/md-report-rename.mts similarity index 67% rename from tools/md-report-rename.ts rename to examples/github-report/tools/md-report-rename.mts index 5ccc073fa..1a62f309b 100644 --- a/tools/md-report-rename.ts +++ b/examples/github-report/tools/md-report-rename.mts @@ -1,19 +1,26 @@ -import {readdirSync, readFileSync, writeFileSync} from 'fs'; -import {join} from 'path'; +import {readdirSync, readFileSync, writeFileSync} from 'node:fs'; +import {join} from 'node:path'; + +console.log(`Rename results for comment action`); + +const path = './examples/github-report/measures'; -console.log(`Reame results for comment action`); -const path = 'dist/user-flow/user-flow-gh-integration'; const reportPath = readdirSync(path)[0]; + if (!reportPath) { throw new Error('Report file not found'); } + const targetPath = join(path, reportPath); const destPath = join(path, 'md-report.md'); + let report = readFileSync(targetPath, {encoding: 'utf8'}); + report = ` ❗❗❗ **report generated by this PR** ❗❗❗ --- ` + report; + writeFileSync(destPath, report); console.log(`Report ${targetPath} renamed to ${destPath}`); diff --git a/examples/github-report/tsconfig.json b/examples/github-report/tsconfig.json new file mode 100644 index 000000000..6ec54f29e --- /dev/null +++ b/examples/github-report/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": {}, + "files": [], + "include": ["**/*"], +} diff --git a/examples/github-report/user-flows/order-coffee.uf.mts b/examples/github-report/user-flows/order-coffee.uf.mts new file mode 100644 index 000000000..13db38621 --- /dev/null +++ b/examples/github-report/user-flows/order-coffee.uf.mts @@ -0,0 +1,67 @@ +import {UserFlowContext, UserFlowInteractionsFn, UserFlowProvider} from '@push-based/user-flow'; + +const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promise => { + const { page, flow, browser, collectOptions } = ctx; + const { url } = collectOptions; + + // Navigate to coffee order site + await flow.navigate(url, { + name: '🧭 Navigate to coffee cart', + }); + + await flow.startTimespan({ name: '☕ Select coffee' }); + + // Select coffee + const cappuccinoItem = '.cup:nth-child(1)'; + await page.waitForSelector(cappuccinoItem); + await page.click(cappuccinoItem); + + await flow.endTimespan(); + + await flow.snapshot({ name: '✔ Coffee selected' }); + + + await flow.startTimespan({ name: '🛒 Checkout order' }); + + // Checkout order + const checkoutBtn = '[data-test=checkout]'; + await page.waitForSelector(checkoutBtn); + await page.click(checkoutBtn); + + const nameInputSelector = '#name'; + await page.waitForSelector(nameInputSelector); + await page.type(nameInputSelector, 'nina'); + + const emailInputSelector = '#email'; + await page.waitForSelector(emailInputSelector); + await page.type(emailInputSelector, 'nina@gmail.com'); + + await flow.endTimespan(); + + await flow.snapshot({ name: '🧾 Order checked out' }); + + await flow.startTimespan({ name: '💌 Submit order' }); + + // Submit order + const submitBtn = '#submit-payment'; + await page.click(submitBtn); + await page.waitForSelector(submitBtn); + const successMsg = '.snackbar.success'; + await page.waitForSelector(successMsg); + + await flow.endTimespan(); + + await flow.snapshot({ name: '📧 Order submitted' }); + + // Navigate to github info site + await flow.navigate(url+'github', { + name: '🧭 Navigate to github' + }); +}; + +const userFlowProvider: UserFlowProvider = { + flowOptions: {name: '☕ Order Coffee ☕'}, + interactions +}; + +module.exports = userFlowProvider; diff --git a/package.json b/package.json index efeda8341..1fa2237a3 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "@push-based/user-flow:init": "npm run @push-based/user-flow -- init -v", "@push-based/user-flow:assert": "npm run @push-based/user-flow -- assert -v", "@push-based/user-flow:collect": "npm run @push-based/user-flow -- collect -v", - "md-report-test": "npm run @push-based/user-flow -- --rcPath ./packages/user-flow-gh-integration/.user-flowrc.json --openReport false && ts-node -P ./tools/tsconfig.tools.json ./tools/md-report-rename.ts", "prepare": "husky install" }, "dependencies": {