Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): migrate to lh v11 #277

Merged
merged 70 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
075b882
feat(cli): migrate to lh v11
ChristopherPHolder Apr 22, 2024
2cb7ca1
fix(cli): ignore replay runner errors
ChristopherPHolder Apr 22, 2024
22422f1
fix(cli): replace imports
ChristopherPHolder Apr 22, 2024
ad75f62
fix(cli): replace imports
ChristopherPHolder Apr 22, 2024
36a30b0
fix(cli): esm migration wip
ChristopherPHolder Apr 25, 2024
7e07c7a
fix(cli): esm migration wip
ChristopherPHolder Apr 25, 2024
154f30c
fix(cli): fix test
ChristopherPHolder Apr 26, 2024
fd72436
fix(cli): fix default flow and test
ChristopherPHolder Apr 26, 2024
49f2ffd
fix(cli): fix test
ChristopherPHolder Apr 26, 2024
60a330f
fix(cli): fix test
ChristopherPHolder Apr 26, 2024
b87b771
fix(cli): fix package version
ChristopherPHolder Apr 26, 2024
8c31066
fix(cli): convert ts register loader hook
ChristopherPHolder May 3, 2024
ccc2b59
fix(cli): convert ts register loader hook
ChristopherPHolder May 3, 2024
468bd1b
fix(cli): remove budgets
ChristopherPHolder Aug 23, 2024
0a939ca
fix(cli): remove budgets
ChristopherPHolder Aug 23, 2024
5b3b9a2
test(e2e): setup e2e base
ChristopherPHolder Apr 27, 2024
a1bc17f
test(e2e): setup e2e exec process base
ChristopherPHolder Apr 27, 2024
2df8c1c
test(e2e): setup local registry
ChristopherPHolder Apr 27, 2024
0b063b0
fix(workspace): migrate nx
ChristopherPHolder Aug 23, 2024
adbed43
fix(workspace): migrate nx
ChristopherPHolder Aug 23, 2024
2189443
fix(workspace): migrate e2e test
ChristopherPHolder Aug 24, 2024
f70944c
fix(workspace): remove migration file
ChristopherPHolder Aug 24, 2024
51c691a
fix(workspace): upgrade packages
ChristopherPHolder Aug 24, 2024
e7ce539
fix(workspace): fix build nx-plugin-integration
ChristopherPHolder Aug 25, 2024
51f5ca3
fix(workspace): remove source build issue
ChristopherPHolder Aug 25, 2024
9686b25
fix(workspace): remove source build issue
ChristopherPHolder Aug 25, 2024
653d5cc
fix(workspace): reset lock
ChristopherPHolder Aug 25, 2024
3d6e410
fix(workspace): upgrade vite
ChristopherPHolder Aug 25, 2024
3f8dad6
fix(workspace): lock fixing
ChristopherPHolder Aug 25, 2024
7c0ddb4
fix(workspace): lock fixing
ChristopherPHolder Aug 25, 2024
c95cd01
fix(workspace): fix build issue
ChristopherPHolder Aug 25, 2024
0d41c57
fix(workspace): remove budgets
ChristopherPHolder Aug 25, 2024
841b22b
fix(workspace): allow mts format
ChristopherPHolder Aug 25, 2024
db59173
fix(workspace): migrate init test
ChristopherPHolder Aug 25, 2024
d741f8b
fix(workspace): migrate init rc-config test
ChristopherPHolder Aug 25, 2024
cdc99dd
fix(workspace): migrate init rc-config test
ChristopherPHolder Aug 25, 2024
aedde71
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
c5a6b53
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
1a87553
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
dc1ac39
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
e6245ca
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
54d3b52
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
633869a
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
a6403c0
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
c39117f
fix(workspace): migrate test
ChristopherPHolder Aug 25, 2024
1e11849
fix(workspace): migrate test
ChristopherPHolder Aug 26, 2024
78d6839
fix(workspace): migrate test
ChristopherPHolder Aug 26, 2024
d3be6f8
fix(workspace): migrate test
ChristopherPHolder Aug 26, 2024
d099694
fix(workspace): migrate test
ChristopherPHolder Aug 26, 2024
4eb5fd1
fix(workspace): migrate test
ChristopherPHolder Aug 26, 2024
727934c
fix(workspace): e2e target to test
ChristopherPHolder Aug 26, 2024
3502f27
fix(workspace): remove unnecessry config
ChristopherPHolder Aug 26, 2024
67e2d76
fix(workspace): fix headless bug
ChristopherPHolder Aug 26, 2024
81df6fe
fix(workspace): fix e2e preset issues
ChristopherPHolder Aug 26, 2024
7d90f8e
fix(workspace): fix gh e2e
ChristopherPHolder Aug 26, 2024
5c3cd5a
fix(workspace): remove unused test
ChristopherPHolder Aug 26, 2024
9145527
fix(workspace): remove unused test
ChristopherPHolder Aug 26, 2024
d3bb69e
fix(workspace): remove unused test
ChristopherPHolder Aug 26, 2024
4e7474e
test(cli): migrate sandbox to verdaccio
ChristopherPHolder Aug 26, 2024
2d71b2a
fix(workspace): fix config
ChristopherPHolder Aug 26, 2024
232dbcf
fix(workspace): fix gh-report example
ChristopherPHolder Aug 26, 2024
408f8f1
fix(workspace): fix gh-report example
ChristopherPHolder Aug 26, 2024
b9656ae
fix(workspace): fix gh-report example
ChristopherPHolder Aug 26, 2024
b3a9cc1
fix(workspace): fix gh-report example
ChristopherPHolder Aug 26, 2024
0ed1286
test(cli): fix github md report report and test
ChristopherPHolder Aug 26, 2024
3ea4393
fix(workspace): update examples and docs
ChristopherPHolder Aug 26, 2024
e3fa1d9
fix(workspace): update examples and docs
ChristopherPHolder Aug 26, 2024
a5bb40f
fix(workspace): fix test
ChristopherPHolder Aug 26, 2024
88b003a
fix(workspace): fix test
ChristopherPHolder Aug 26, 2024
b8b8f5b
docs: update examples and docs
ChristopherPHolder Aug 26, 2024
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
17 changes: 11 additions & 6 deletions .github/workflows/user-flow-md-report-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ testem.log
.DS_Store
Thumbs.db

.nx/cache
.nx

.env
.code-pushup

examples/**/measures/*
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
/dist
/coverage

/.nx/cache
/.nx/cache
/.nx/workspace-data
28 changes: 28 additions & 0 deletions .verdaccio/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# path to a directory with all packages
storage: ../tmp/local-registry/storage

# a list of other known repositories we can talk to
uplinks:
npmjs:
url: https://registry.npmjs.org/
maxage: 60m

packages:
'**':
# give all users (including non-authenticated users) full access
# because it is a local registry
access: $all
publish: $all
unpublish: $all

# if package is not available locally, proxy requests to npm registry
proxy: npmjs

# log settings
log:
type: stdout
format: pretty
level: warn

publish:
allow_offline: true # set offline to true to allow publish offline
38 changes: 9 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ In addition, it is always up-to-date with the latest Chrome DevTools features.
- ⚙ [Run it in your CI ](https://github.com/push-based/user-flow#github-workflow-integration-of-lighthouse-user-flows-in-your-pr)
- ▶ [Execute ChromeDevTools recorder exports](https://github.com/push-based/user-flow#working-with-devtools-recorder-exports)
- 🏃‍♀️ Measure Runtime performance
- 🔒 [Performance budgets](https://github.com/push-based/user-flow#performance-budgets)
- 🦮 Zero setup cost
- 🤓 Excellent DX through `--dryRun` and friends
- ⚙ Nx plugin [user-flow-nx-plugin]() to generate/execute/migrate lighthouse user flows
Expand Down Expand Up @@ -103,11 +102,11 @@ _./.user-flowrc.json_
}
```

2. The CLI automatically creates an example user-flow. (`./user-flows/basic-navigation.uf.ts`)
2. The CLI automatically creates an example user-flow. (`./user-flows/basic-navigation.uf.mts`)

It is a simple navigation measurement to start from.

_./basic-navigation.uf.ts_
_./basic-navigation.uf.mts_
```typescript
import {
UserFlowInteractionsFn,
Expand All @@ -122,17 +121,15 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi

// Navigate to URL
await flow.navigate(url, {
stepName: `Navigate to ${url}`,
name: `Navigate to ${url}`,
});

};

const userFlowProvider: UserFlowProvider = {
flowOptions: {name: 'Order Coffee'},
interactions
};

module.exports = userFlowProvider;
export default {
flowOptions: { name: "Order Coffee" },
interactions,
} satisfies UserFlowProvider;
```

3. Run CLI
Expand All @@ -147,7 +144,7 @@ This will execute the user flow and opens the HTML report in the browser:

For more information on how to write user-flows read in the [Writing user flows for the CLI](https://github.com/push-based/user-flow/blob/main/packages/cli/docs/writing-basic-user-flows.md) section.

Optionally you can pass params to overwrite the values form `.user-flowrc.ts` in the file directly or over the CLI:
Optionally you can pass params to overwrite the values form `.user-flowrc.json` in the file directly or over the CLI:

```bash
npx user-flow --ufPath=./user-flows-new --outPath=./user-flows-reports --url=https://localhost:4200
Expand Down Expand Up @@ -192,8 +189,6 @@ This command helps you to set up a `.user-flowrc.json` and asks for input over C
| ---------------------------------- | --------- | ---------------------- |----------------------------------------------------------------------------------------------------------|
| **`-h`**, **`--generateFlow`** | `boolean` | n/a | Generate basic user-flow file under `ufPath` |
| **`-g`**, **`--generateGhWorkflow`** | `boolean` | n/a | Generate `user-flow.yml` file under `.github/workflows` |
| **`-x`**, **`--generateBudgets`** | `boolean` | n/a | Generate `budget.json` file under the current working directury |
| **`--lhr`** | `string` | n/a | Used together with `--generateBudgets`. Path to lighthouse report for initial budget |

<img width="960" alt="getting-started-resulting-navigation-report" src="https://user-images.githubusercontent.com/10064416/168185483-c6ca499e-a8a6-40b7-b450-448de8784454.PNG">

Expand All @@ -214,9 +209,8 @@ This command executes a set of user-flow definitions against the target URL and
| Option | Type | Default | Description |
|------------------------------------|-----------|------------------------|---------------------------------------------------------------------------------------------------------|
| **`-t`**, **`--url`** | `string` | n/a | URL to analyze |
| **`-u`**, **`--ufPath`** | `string` | `./user-flows` | Path to user-flow file or folder containing user-flow files to run. (`*.uf.ts` or`*.uf.js`) |
| **`-u`**, **`--ufPath`** | `string` | `./user-flows` | Path to user-flow file or folder containing user-flow files to run. (`*.uf.mts` or`*.uf.js`) |
| **`-c`**, **`--configPath`** | `string` | n/a | Path to the lighthouse `config.json` file |
| **`-b`**, **`--budgetPath`** | `string` | n/a | Path to the lighthouse `budget.json` file |
| **`-s`**, **`--serveCommand`** | `string` | n/a | Runs a npm script to serve the target app. This has to be used in combination with `--awaitServeStdout` |
| **`-a`**, **`--awaitServeStdout`** | `string` | `.user-flowrc` setting | Waits for stdout from the serve command to start collecting user-flows |
| **`-f`**, **`--format`** | `string` | `html`, `json` setting | Format of the creates reports ( `html`, `json`, `md`, `stdout`) |
Expand Down Expand Up @@ -279,20 +273,6 @@ This library provides a way to replay and enrich those interactions over the CLI

See [recorder-exports](https://github.com/push-based/user-flow/blob/main/packages/cli/docs/recorder-exports.md) for more details.

## [Performance Budgets](https://github.com/push-based/user-flow/blob/main/packages/cli/docs/performance-budgets.md)

Implementing performance improvements without breaking something is hard.
**Even harder is it, to keep it that way. 🔒**

![img-budgets-mode-support](https://user-images.githubusercontent.com/10064416/164581870-3534f8b0-b7c1-4252-9f44-f07febaa7359.PNG)

Automatically create budgets with:
`npx user-flow init --generateBudgets`
Automatically create budgets from an existing lhr with:
`npx user-flow init --generateBudgets --lhr path/to/lhr.json`

See [performance-budgets](https://github.com/push-based/user-flow/blob/main/packages/cli/docs/performance-budgets.md) for more details.

## [GitHub workflow integration of lighthouse user flows in your PR](https://github.com/push-based/user-flow/blob/main/packages/cli/docs/github-workflow-integration.md)

With just a few steps you can run your user flows in as a GitHub workflow to enrich your PR's with report summaries as
Expand Down
File renamed without changes.
21 changes: 21 additions & 0 deletions e2e/cli-e2e/mocks/user-flows/basic-navigation.uf.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-ignore // This is a mock file!
import { UserFlowContext, UserFlowInteractionsFn, UserFlowProvider } from '@push-based/user-flow';

const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promise<any> => {
const { flow, collectOptions } = ctx;
const { url } = collectOptions;

await flow.navigate(url, {
name: `Navigate to ${url}`,
});

// ℹ Tip:
// Read more about the other measurement modes here:
// https://github.com/push-based/user-flow/blob/main/packages/cli/docs/writing-basic-user-flows.md

};

export default {
flowOptions: {name: 'Basic Navigation Example'},
interactions
} satisfies UserFlowProvider;
25 changes: 25 additions & 0 deletions e2e/cli-e2e/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "cli-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "e2e/cli-e2e/src",
"projectType": "application",
"targets": {
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["e2e/cli-e2e/**/*.ts"]
}
},
"test": {
"executor": "@nx/vite:test",
"options": {
"config": "e2e/cli-e2e/vite.config.e2e.mts"
}
}
},
"implicitDependencies": [
"cli"
],
"tags": ["type:e2e"]
}
135 changes: 135 additions & 0 deletions e2e/cli-e2e/setup.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { afterAll, beforeAll, beforeEach, afterEach } from 'vitest';

import { cpSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
import { join, normalize, sep } from 'node:path';

import { CliTest, E2E_DIR, normalizePath } from './utils/setup';
import { spawn } from 'node:child_process';

const ANSI_ESCAPE_REGEX = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;

function filePath(p: string): string {
const paths = normalizePath(p).split(sep);
return paths.splice(0, paths.length - 1).join();
}

beforeAll((ctx) => {
mkdirSync(join(E2E_DIR, filePath(ctx.name)), { recursive: true });
});

beforeEach<CliTest>((ctx) => {
ctx.root = join(E2E_DIR, filePath(ctx.task.file.name), normalizePath(join(ctx.task.suite.name, ctx.task.name)));

ctx.setupFns = {
setupRcJson: (rc: {}, rcName= `.user-flowrc.json`) => {
writeFileSync(
join(ctx.root, rcName),
JSON.stringify(rc, null, 4),
{ encoding: 'utf8' }
);
},
setupUserFlows: (mockUserFlow: string, userFlowDir = 'user-flows') => {
cpSync(mockUserFlow, join(ctx.root, userFlowDir, normalize(mockUserFlow).split(sep).at(-1)))
}
}

mkdirSync(ctx.root, { recursive: true });
});

export type CliProcessResult = {
stdout: string;
stderr: string;
code: number | null;
}

beforeEach<CliTest>((ctx) => {
ctx.cli = {} as any;
ctx.cli.stdout = '';
ctx.cli.stderr = '';
ctx.cli.code = null;


ctx.cli.run = (command: string, args: string[] = [], waitForClose = true) => new Promise<CliProcessResult>((resolve) => {
ctx.cli.process = spawn(command, args, { stdio: 'pipe', shell: true, cwd: ctx.root });

ctx.cli.process.stdout.on('data', (data) => {
const stdout = String(data).replace(ANSI_ESCAPE_REGEX, '');

if (ctx.cli.verbose) {
console.log(stdout);
}

ctx.cli.stdout += stdout;
});


ctx.cli.process.stderr.on('data', (data) => {
const stderr = String(data).replace(ANSI_ESCAPE_REGEX, '');

if (ctx.cli.verbose) {
console.log(stderr);
}

ctx.cli.stderr += stderr;
});


ctx.cli.process.on('close', code => {
ctx.cli.code = code;

if (ctx.cli.verbose) {
console.log(code);
}

resolve({
stdout: ctx.cli.stdout,
stderr: ctx.cli.stderr,
code: ctx.cli.code
});
});

if (!waitForClose) {
resolve({
stdout: ctx.cli.stdout,
stderr: ctx.cli.stderr,
code: ctx.cli.code
});
}
});

ctx.cli.waitForStdout = (expectedStdout: string) => {
return new Promise((resolve) => {
ctx.cli.process.stdout.on('data', (data) => {
const stdout = String(data).replace(ANSI_ESCAPE_REGEX, '');
if (stdout.includes(expectedStdout)) {
resolve();
}
});
});
};

ctx.cli.waitForClose = () => {
return new Promise((resolve) => {
ctx.cli.process.on('close', (code) => {
ctx.cli.code = code;
resolve({
stdout: ctx.cli.stdout,
stderr: ctx.cli.stderr,
code: ctx.cli.code
});
});
});
};

ctx.cli.type = (inputs: string) => {
ctx.cli.process.stdin.write(inputs);
};
});

afterEach<CliTest>((ctx) => {
rmSync(ctx.root, { recursive: true });
});

afterAll((ctx) => {
rmSync(join(E2E_DIR, filePath(ctx.name)), { recursive: true });
});
Loading
Loading