=> {
- const { flow, collectOptions, page } = ctx as any;
- const { url } = collectOptions;
- const testUrl = url;
- console.log("interactions collectOptions: ", collectOptions);
-
- // # Navigation
- await flow.navigate(testUrl);
-
- // # Timespan
- const btn = '#btn';
- const img = '#img';
-
- await page.waitForSelector(btn);
-
- // record timespan
- await flow.startTimespan();
-
- // relevant interactions
- await page.click(btn);
- await page.waitForSelector(img);
-
- await flow.endTimespan();
-
- // # Snapshot
- await flow.snapshot();
-
- },
- launchOptions: {
- // to be able to run tests in the CLI without chrome popping up (for debugging switch it off)
- headless: false
- }
-};
-`;
diff --git a/packages/test-data/src/lib/sandboxes/static/index.ts b/packages/test-data/src/lib/sandboxes/static/index.ts
deleted file mode 100644
index 765689f70..000000000
--- a/packages/test-data/src/lib/sandboxes/static/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './rc';
-export * from './cfg';
-export * from './flow1.uf';
diff --git a/packages/test-data/src/lib/sandboxes/static/rc.ts b/packages/test-data/src/lib/sandboxes/static/rc.ts
deleted file mode 100644
index 0d03eda01..000000000
--- a/packages/test-data/src/lib/sandboxes/static/rc.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { join } from 'path';
-import { RcJson, SANDBOX_BASE_RC_JSON, SERVE_COMMAND_PORT } from '@push-based/user-flow-cli-testing';
-import { STATIC_USERFLOW_NAME, STATIC_USERFLOW_TITLE } from './flow1.uf';
-
-export const STATIC_RC_NAME = '.user-flow.static.json';
-export const STATIC_RC_JSON: RcJson = {
- ...SANDBOX_BASE_RC_JSON,
- 'collect': {
- 'url': 'http://127.0.0.1:' + SERVE_COMMAND_PORT,
- 'ufPath': './src/lib/user-flows',
- 'serveCommand': 'npm run start',
- 'awaitServeStdout': 'Available on:'
- },
- persist: {
- ...SANDBOX_BASE_RC_JSON.persist,
- 'format': ['json']
- }
-};
-
-export const STATIC_HTML_REPORT_NAME = STATIC_USERFLOW_TITLE + '.html';
-export const STATIC_JSON_REPORT_NAME = STATIC_USERFLOW_TITLE + '.json';
-export const STATIC_MD_REPORT_NAME = STATIC_USERFLOW_TITLE + '.md';
-export const STATIC_USERFLOW_PATH = join(STATIC_RC_JSON.collect.ufPath, STATIC_USERFLOW_NAME);
-
diff --git a/packages/test-data/src/lib/sandboxes/static/static-app/favico.ts b/packages/test-data/src/lib/sandboxes/static/static-app/favico.ts
deleted file mode 100644
index a53f97c56..000000000
--- a/packages/test-data/src/lib/sandboxes/static/static-app/favico.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export const STATIC_APP_FAVICON_NAME = 'favicon.ico';
-export const STATIC_APP_FAVICON_CONTENT = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABRElEQVQ4jcWTzWrCYBBFT2oiiT+pgpYiYhHB0EXfojsfsw/Q93BVLHZTieCHFTUEjSD5Yup0ZajYjbXQu52Zwx3ujCEiwgW6umT47wHL5fIyQBAEZ0OOAO+vHzw9jwmC4KhJKQWAiBDHMdvtNquZ3xtX6zyDN4OhN6Tb7aKUotFo4Ps+YRhSLpfRWmPbNu12+9TBS3TNY2+G67oopRiNRkRRRKVSYTweE4YhIoJlWT878G4jHm7uyOfzdDodWq0WtVqNKIpoNpu4rst8PqdYLJ4CRATn0ydJ7rFtm+l0ymQyoV6vs9vt2O/3JElCoVDA87wMYBwucbVasVgsGAwG9Ho91us1pmmSy+WwLAutNYZhkKYp1Wo1WyNzsNlsmM1mpGmK4zg4jnOURKlUOonwYF1EROI4ln6/L1prOUfZCr/V/z/TF9g/xfnZMeCgAAAAAElFTkSuQmCC'
diff --git a/packages/test-data/src/lib/sandboxes/static/static-app/index.html.ts b/packages/test-data/src/lib/sandboxes/static/static-app/index.html.ts
deleted file mode 100644
index 6ffdf6f9e..000000000
--- a/packages/test-data/src/lib/sandboxes/static/static-app/index.html.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export const STATIC_APP_INDEX_NAME = 'index.html';
-export const STATIC_APP_INDEX_CONTENT = `
-
-
-
-
-
-
-
- Sandbox - Setup
-
-
-
-
-
-
-Sandbox - Setup
-
- A simple web project to test lighthouse user-flow CLI
-
-
-
-
-
-`;
diff --git a/packages/test-data/src/lib/sandboxes/static/static-app/index.ts b/packages/test-data/src/lib/sandboxes/static/static-app/index.ts
deleted file mode 100644
index 7d8009100..000000000
--- a/packages/test-data/src/lib/sandboxes/static/static-app/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './index.html';
-export * from './user-flow-square';
-export * from './favico';
diff --git a/packages/test-data/src/lib/sandboxes/static/static-app/user-flow-square.ts b/packages/test-data/src/lib/sandboxes/static/static-app/user-flow-square.ts
deleted file mode 100644
index 34b7938ac..000000000
--- a/packages/test-data/src/lib/sandboxes/static/static-app/user-flow-square.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const STATIC_APP_IMG_NAME = 'user-flow-square.png';
export const STATIC_APP_IMG_CONTENT = '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RgwcOBBl/rU91QF6IevXr//uu+9Q7587J18kAC2Qs7PzHXfc8dhjj7Vt25aVPjUI1vt09eh0OuTv7t27xWxFRUXXrl39/f1tbW3KSotPnErPKfISq8zptFL/7tKMRzU+9RjWRosSFRV17NixlStX/vTTT7gvTKPwl1ef5+Dg4OrqisRHmT906NAePXpc2zPXZ2Vl7dixY968eVu2bMnOzpaXShKapeHDh991111oHRn61FCY+3T1IJTLy8s3bdqEehwdTTs7O09PTySavb190wD72PjMk6eyjdqq3+VaWUp3DNe0C0WzIS+pTq+vPI//yZMnt23btnbt2p9//nnnzp2nT5+uclQ+4E6R+D179hQDO/369bvmZzRD+/fnn39++OGHiH7xymChlZVVYGAgQv/xxx/v1avXNTmWlG5WzH26eiwsLNLT00+dOhUTE4PZvLw85H5YWJiPj49Wq3WwM5w+k5CWF2h+6D1Cf2B36YGxGjsbqcZiv7i4GOV8dHT0+vXrV61atXjxYpTM8fHxGRkZVYbyUS+7ubm1bdv2jjvumDBhwuDBg6+HkZPU1NSvvvoKoY9WSgl9tGG+vr4o8++5555WrVqx0qeGxfF9utqQZb///nthYeWh96Ghoc8///xjjz0mRnAWLo/83/KS1IKOpg0r+XtLL02R+nW5IPLxpoWSkpLExETk5t69ew8fPnz06FHU+1hrfkFEAe0NEh9JOmjQoD59+qClCQkJkdddO3gKeMDiiol48PJSU+iHh4ePHDly/PjxnTt3lpcSNRzmPl09BoNh9+7dn3766dq1a1GnY4mVldVDDz305JNPtm/fHrP5BWVRMWUvf2yZlWuF2R4dpLtGabqESbam33XhvYpMzMnJwX5OnDiRlJS0a9euffv2ZWVloVjGwsqNqvH29vbw8OjXr9+AAQNQO7dp0+Z6OCQGjxY9ErwU3333nflglL29fXBw8O2333733XcHBQVdqyOL6ObG3KerBOU5ytuffvpp6dKl586dEzGN3G/duvX06dPHjBlja2uLWC8uMW7eKy3/S2rmX3nIZs+OGnvbysEcbI/SPi8v78iRIxEREbGxsfv378/NzcVuqxf4gpeXl7+/P0pmlPm4l+bNm9f25a1erxcJK7odVwHavzfeeOPvv/82/wDiMXTp0uWBBx645ZZbAgMDeaJNaiTMfbpK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'
\ No newline at end of file
diff --git a/packages/test-data/src/lib/sandboxes/user-flowrc.base.ts b/packages/test-data/src/lib/sandboxes/user-flowrc.base.ts
deleted file mode 100644
index 28f9f37ee..000000000
--- a/packages/test-data/src/lib/sandboxes/user-flowrc.base.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import {
- DEFAULT_COLLECT_UF_PATH,
- DEFAULT_COLLECT_URL,
- DEFAULT_PERSIST_OUT_PATH,
- getEnvPreset,
- RcJson,
- ReportFormat
-} from '@push-based/user-flow-cli-testing';
-export const DEFAULT_RC_NAME = '.user-flowrc.json';
-export const CLI_DEFAULT_RC_JSON: RcJson = {
- 'collect': {
- 'url': DEFAULT_COLLECT_URL,
- 'ufPath': DEFAULT_COLLECT_UF_PATH
- },
- 'persist': {
- 'outPath': DEFAULT_PERSIST_OUT_PATH,
- 'format': getEnvPreset().format as ReportFormat[]
- },
- 'assert': {}
-};
-
-export const SANDBOX_BASE_RC_JSON: RcJson = {
- 'collect': {
- 'url': DEFAULT_COLLECT_URL,
- 'ufPath': './src/lib/user-flows', // DEFAULT_COLLECT_UF_PATH
- },
- 'persist': {
- 'outPath': './src/lib/measures', //DEFAULT_PERSIST_OUT_PATH,
- 'format': getEnvPreset().format as ReportFormat[]
- },
- 'assert': {}
-};
diff --git a/packages/test-data/src/lib/user-flows/index.ts b/packages/test-data/src/lib/user-flows/index.ts
deleted file mode 100644
index 649317ba1..000000000
--- a/packages/test-data/src/lib/user-flows/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './wrong-mod-export.example.uf';
-export * from './wrong-ext.example.uf';
-export * from './valide.example.uf';
diff --git a/packages/test-data/src/lib/user-flows/valide.example.uf.ts b/packages/test-data/src/lib/user-flows/valide.example.uf.ts
deleted file mode 100644
index 3d4f47548..000000000
--- a/packages/test-data/src/lib/user-flows/valide.example.uf.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-export const VALIDE_EXAMPLE_USERFLOW_NAME = 'valide.example.uf.ts';
-export const VALIDE_EXAMPLE_USERFLOW_TITLE = VALIDE_EXAMPLE_USERFLOW_NAME.slice(0, -3);
-export const VALIDE_EXAMPLE_USERFLOW_CONTENT = `
-module.exports = {
- flowOptions: {
- name: '${VALIDE_EXAMPLE_USERFLOW_TITLE}'
- },
- interactions: async (ctx: Record): Promise => {
- const { flow, collectOptions } = ctx;
- const { url } = collectOptions;
- const testUrl = url;
- await flow.navigate(testUrl);
- },
- launchOptions: {
- // to be able to run tests in the CLI without chrome popping up (for debugging switch it off)
- headless: true
- }
-};
-`;
diff --git a/packages/test-data/src/lib/user-flows/wrong-ext.example.uf.ts b/packages/test-data/src/lib/user-flows/wrong-ext.example.uf.ts
deleted file mode 100644
index 720a08e0b..000000000
--- a/packages/test-data/src/lib/user-flows/wrong-ext.example.uf.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export const WRONG_EXT_USERFLOW_NAME = 'wrong-ext.example.uf.yaml';
-export const WRONG_EXT_USERFLOW_TITLE = WRONG_EXT_USERFLOW_NAME.slice(0, -3);
-export const WRONG_EXT_USERFLOW_CONTENT = `
-import {
-UserFlowInteractionsFn,
-UserFlowContext,
-UserFlowProvider,
-} from '@push-based/user-flow';
-
- // Your custom interactions with the page
-const interactions: UserFlowInteractionsFn = async (
- ctx: UserFlowContext
-): Promise => {
- const { flow, collectOptions } = ctx;
- const { url } = collectOptions;
-
- await flow.navigate(url, {
- stepName: 'Navigate to coffee cart',
-});
-
- // Select coffee
-
- // Checkout order
-
- // Submit order
-};
-
-const userFlowProvider: UserFlowProvider = {
- flowOptions: { name: 'Order Coffee' },
- interactions,
-};
-
- module.exports = userFlowProvider;
- `
diff --git a/packages/test-data/src/lib/user-flows/wrong-mod-export.example.uf.ts b/packages/test-data/src/lib/user-flows/wrong-mod-export.example.uf.ts
deleted file mode 100644
index aa7087269..000000000
--- a/packages/test-data/src/lib/user-flows/wrong-mod-export.example.uf.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export const WRONG_MOD_EXPORT_USERFLOW_NAME = 'wrong-ext.example.uf.ts';
-export const WRONG_MOD_EXPORT_USERFLOW_TITLE = WRONG_MOD_EXPORT_USERFLOW_NAME.slice(0, -3);
-export const WRONG_MOD_EXPORT_USERFLOW_CONTENT = `
-module.exports = {
- interactionas: async (ctx: Record): Promise => {
- return Promise.reject();
- }
-};
-`;
diff --git a/packages/test-data/tsconfig.lib.json b/packages/test-data/tsconfig.lib.json
deleted file mode 100644
index 7bfc80f73..000000000
--- a/packages/test-data/tsconfig.lib.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "declaration": true,
- "types": ["node"]
- },
- "include": ["**/*.ts"],
- "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
-}
diff --git a/packages/test-data/tsconfig.spec.json b/packages/test-data/tsconfig.spec.json
deleted file mode 100644
index 546f12877..000000000
--- a/packages/test-data/tsconfig.spec.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "module": "commonjs",
- "types": ["jest", "node"]
- },
- "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
-}
diff --git a/packages/user-flow-cli-testing/.eslintrc.json b/packages/user-flow-cli-testing/.eslintrc.json
deleted file mode 100644
index 647c8ed3b..000000000
--- a/packages/user-flow-cli-testing/.eslintrc.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": ["../../.eslintrc.json"],
- "ignorePatterns": ["!**/*"],
- "parserOptions": {
- "project": ["packages/cli/tsconfig.*?.json"]
- }
-}
diff --git a/packages/user-flow-cli-testing/README.md b/packages/user-flow-cli-testing/README.md
deleted file mode 100644
index a9a280094..000000000
--- a/packages/user-flow-cli-testing/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# user-flow-cli-testing
-
-This library was generated with [Nx](https://nx.dev).
-
-## Building
-
-Run `nx build user-flow-cli-testing` to build the library.
-
-## Running unit tests
-
-Run `nx test user-flow-cli-testing` to execute the unit tests via [Jest](https://jestjs.io).
diff --git a/packages/user-flow-cli-testing/jest.config.ts b/packages/user-flow-cli-testing/jest.config.ts
deleted file mode 100644
index d1e205aaa..000000000
--- a/packages/user-flow-cli-testing/jest.config.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/* eslint-disable */
-export default {
- displayName: 'user-flow-cli-testing',
- preset: '../../jest.preset.js',
- globals: {
- 'ts-jest': {
- tsconfig: '/tsconfig.spec.json',
- },
- },
- transform: {
- '^.+\\.[tj]s$': 'ts-jest',
- },
- moduleFileExtensions: ['ts', 'js', 'html'],
- coverageDirectory: '../../coverage/libs/user-flow-cli-testing',
-};
diff --git a/packages/user-flow-cli-testing/project.json b/packages/user-flow-cli-testing/project.json
deleted file mode 100644
index 41be904c3..000000000
--- a/packages/user-flow-cli-testing/project.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "user-flow-cli-testing",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "sourceRoot": "packages/user-flow-cli-testing/src",
- "projectType": "library",
- "targets": {
- "build": {
- "executor": "@nx/js:tsc",
- "outputs": ["{options.outputPath}"],
- "options": {
- "outputPath": "dist/packages/user-flow-cli-testing",
- "main": "packages/user-flow-cli-testing/src/index.ts",
- "tsConfig": "packages/user-flow-cli-testing/tsconfig.lib.json",
- "assets": ["packages/user-flow-cli-testing/*.md"]
- },
- "dependsOn": [
- {
- "target": "build",
- "dependencies": true
- }
- ]
- },
- "lint": {
- "executor": "@nx/eslint:lint",
- "outputs": ["{options.outputFile}"],
- "options": {
- "lintFilePatterns": ["packages/user-flow-cli-testing/**/*"]
- }
- }
- },
- "tags": []
-}
diff --git a/packages/user-flow-cli-testing/src/index.ts b/packages/user-flow-cli-testing/src/index.ts
deleted file mode 100644
index 14173ae9a..000000000
--- a/packages/user-flow-cli-testing/src/index.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export {
- DEFAULT_COLLECT_UF_PATH,
- DEFAULT_COLLECT_URL,
- DEFAULT_PERSIST_OUT_PATH,
- getEnvPreset
-} from '@push-based/user-flow';
-export {ENTER, DOWN, SPACE, DECLINE_BOOLEAN, ACCEPT_BOOLEAN} from '@push-based/node-cli-testing';
-export * from './lib/constants';
-export * from './lib/types';
-export * from './lib/utils/cli-mode';
-export * from './lib/data/constants';
-export * from './lib/data/user-flowrc.base';
-export * from './lib/user-flow-cli';
diff --git a/packages/user-flow-cli-testing/src/lib/constants.ts b/packages/user-flow-cli-testing/src/lib/constants.ts
deleted file mode 100644
index 8bbd65908..000000000
--- a/packages/user-flow-cli-testing/src/lib/constants.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const DEFAULT_RC_NAME = '.user-flowrc.json';
-export const LH_NAVIGATION_BUDGETS_NAME_DEFAULT = 'budgets.json';
-export const LH_CONFIG_NAME_DEFAULT = 'config.json';
-
diff --git a/packages/user-flow-cli-testing/src/lib/data/constants.ts b/packages/user-flow-cli-testing/src/lib/data/constants.ts
deleted file mode 100644
index 378fc7d13..000000000
--- a/packages/user-flow-cli-testing/src/lib/data/constants.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const SERVE_COMMAND_PORT = '5032';
diff --git a/packages/user-flow-cli-testing/src/lib/data/user-flowrc.base.ts b/packages/user-flow-cli-testing/src/lib/data/user-flowrc.base.ts
deleted file mode 100644
index e60b077fb..000000000
--- a/packages/user-flow-cli-testing/src/lib/data/user-flowrc.base.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import {
- DEFAULT_COLLECT_UF_PATH,
- DEFAULT_COLLECT_URL,
- DEFAULT_PERSIST_OUT_PATH,
- getEnvPreset,
- RcJson,
- ReportFormat
-} from '@push-based/user-flow';
-
-export const CLI_DEFAULT_RC_JSON: RcJson = {
- 'collect': {
- 'url': DEFAULT_COLLECT_URL,
- 'ufPath': DEFAULT_COLLECT_UF_PATH
- },
- 'persist': {
- 'outPath': DEFAULT_PERSIST_OUT_PATH,
- 'format': getEnvPreset().format as ReportFormat[]
- },
- 'assert': {}
-};
-
-export const SANDBOX_BASE_RC_JSON: RcJson = {
- 'collect': {
- 'url': DEFAULT_COLLECT_URL,
- 'ufPath': './src/lib/user-flows', // DEFAULT_COLLECT_UF_PATH
- },
- 'persist': {
- 'outPath': './src/lib/measures', //DEFAULT_PERSIST_OUT_PATH,
- 'format': getEnvPreset().format as ReportFormat[]
- },
- 'assert': {}
-};
diff --git a/packages/user-flow-cli-testing/src/lib/types.ts b/packages/user-flow-cli-testing/src/lib/types.ts
deleted file mode 100644
index 1c6c0a2be..000000000
--- a/packages/user-flow-cli-testing/src/lib/types.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { ProjectConfig } from '@push-based/node-cli-testing';
-import { CLI_MODES, RcJson } from '@push-based/user-flow';
-
-export {
- RcJson,
- UserFlowInteractionsFn,
- UserFlowContext,
- UserFlowProvider,
- LhConfigJson,
- ReportFormat
-} from '@push-based/user-flow';
-
-export type UserFlowProjectConfig = ProjectConfig & UserFlowOnlyProjectConfig;
-export type UserFlowOnlyProjectConfig = {
- cliMode?: CLI_MODES,
- serveCommandPort?: number
-}
diff --git a/packages/user-flow-cli-testing/src/lib/user-flow-cli.ts b/packages/user-flow-cli-testing/src/lib/user-flow-cli.ts
deleted file mode 100644
index cf889c3d0..000000000
--- a/packages/user-flow-cli-testing/src/lib/user-flow-cli.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-import { readdirSync, readFileSync } from 'fs';
-import { join } from 'path';
-import Budget from 'lighthouse/types/lhr/budget';
-import { CliProject, getFolderContent, ProcessParams, TestResult, withProject, ProjectConfig } from '@push-based/node-cli-testing';
-import {
- CollectCommandArgv,
- DEFAULT_PERSIST_OUT_PATH,
- getEnvPreset,
- GlobalOptionsArgv,
- LhConfigJson,
- RcJson,
- ReportFormat
-} from '@push-based/user-flow';
-import { SANDBOX_BASE_RC_JSON } from './data/user-flowrc.base';
-import { SERVE_COMMAND_PORT } from './data/constants';
-import { kill } from './utils/kill';
-import { UserFlowProjectConfig } from './types';
-import { getEnvVarsByCliModeAndDeleteOld } from './utils/cli-mode';
-import { DEFAULT_RC_NAME, LH_CONFIG_NAME_DEFAULT, LH_NAVIGATION_BUDGETS_NAME_DEFAULT } from './constants';
-
-export class UserFlowCliProjectFactory {
- static async create(cfg: UserFlowProjectConfig): Promise {
- const prj = new UserFlowCliProject();
- await prj._setup(cfg);
- return prj;
- }
-}
-
-type FileResult = {
- content: string | {} | unknown[] | T,
- reportPath: string
-}
-export class UserFlowCliProject extends CliProject {
- envPreset = getEnvPreset();
- serveCommandPort = SERVE_COMMAND_PORT;
-
- constructor() {
- super();
- }
-
- override async _setup(cfg: UserFlowProjectConfig): Promise {
- cfg.delete = (cfg?.delete || []);
- cfg.create = (cfg?.create || {});
- // if no value is provided we add the default rc file to the map
- cfg.rcFile = cfg.rcFile || { [this.envPreset?.rcPath]: SANDBOX_BASE_RC_JSON };
-
- cfg.cliMode = (cfg.cliMode || 'SANDBOX');
- cfg.cliMode && (cfg.env = {
- ...cfg.env,
- ...getEnvVarsByCliModeAndDeleteOld(cfg.cliMode)
- } as any);
-
- // console.log('cfg: ', cfg);
- // handle user-flow related output folders defined in rcFiles and related configurations
- // the rc file creation is done in the CliProject class
- if (typeof cfg.rcFile === 'object' && Object.entries(cfg.rcFile).length > 0) {
- Object.entries(cfg.rcFile).forEach(([_, rcJson]) => {
- const ufPath: string = (rcJson as RcJson).collect.ufPath;
- const outPath: string = (rcJson as RcJson).persist.outPath;
- cfg.create = cfg?.create || {};
- cfg.create['./' + ufPath] = undefined;
- cfg.create['./' + outPath] = undefined;
- cfg.delete = cfg?.delete?.concat([ufPath, outPath]) || [];
- });
- }
- this.logVerbose('Cfg after user-flow operations: ', cfg);
- return super._setup(cfg);
- }
-
- override async teardown(): Promise {
- await super.teardown();
- await kill({ port: this.serveCommandPort });
- }
-
- $init(processParams?: Partial<{} & GlobalOptionsArgv>, userInput?: string[]): Promise {
- const prcParams: ProcessParams = { _: 'init', ...processParams } as unknown as ProcessParams;
- // If a rcFile is created delete it on teardown
- this.deleteFiles.push(prcParams['rcPath'] || this.envPreset?.rcPath);
-
- return this.exec(prcParams, userInput);
- }
-
- $collect(processParams?: Partial, userInput?: string[]): Promise {
- const prcParams: ProcessParams = { _: 'collect', ...processParams } as unknown as ProcessParams;
- return this.exec(prcParams, userInput);
- }
-
- readRcJson(rcFileName: string = DEFAULT_RC_NAME): RcJson {
- return JSON.parse(readFileSync(this.rcJsonPath(rcFileName)) as any);
- }
-
- rcJsonPath(rcFileName: string = DEFAULT_RC_NAME): string {
- return join(this.root, rcFileName);
- }
-
- readBudget(budgetName: string = LH_NAVIGATION_BUDGETS_NAME_DEFAULT): Budget[] {
- return JSON.parse(readFileSync(this.budgetPath(budgetName)) as any);
- }
-
- budgetPath(budgetName: string = LH_NAVIGATION_BUDGETS_NAME_DEFAULT): string {
- return join(this.root, budgetName);
- }
-
- readConfig(configName: string = LH_CONFIG_NAME_DEFAULT): LhConfigJson {
- return JSON.parse(readFileSync(this.configPath(configName)) as any);
- }
-
- configPath(configName: string = LH_CONFIG_NAME_DEFAULT): string {
- return join(this.root, configName);
- }
-
- readOutput(userFlowName: string, format: ReportFormat | undefined = undefined, rcFileName: string = DEFAULT_RC_NAME, ): FileResult[] {
- const outputFiles = readdirSync(this.outputPath());
- const reportPaths = outputFiles.filter((name) => {
- if (format) {
- return name.endsWith(format) && name.includes(name);
- }
- return name.includes(name);
- }) || userFlowName;
- return reportPaths.reduce((res, reportPath: string) => {
- let content = readFileSync(this.outputPath(reportPath, rcFileName)).toString('utf8');
- content = reportPath.includes('.json') ? JSON.parse(content) : content;
- res.push({ reportPath, content });
- return res;
- }, [] as FileResult[]);
- }
-
- outputPath(reportName: string = '', rcFileName: string = DEFAULT_RC_NAME): string {
- if(!this.rcFile[rcFileName]) {
- throw new Error(`Rc file "${rcFileName}" does not exist in: ${Object.keys(this.rcFile).join(', ')}`);
- }
- return join(this.root, this.rcFile[rcFileName].persist.outPath, reportName);
- }
-
- readUserFlow(userFlowName: string = DEFAULT_PERSIST_OUT_PATH, rcFileName: string = DEFAULT_RC_NAME): string[][] {
- const flowPath = this.userFlowPath(userFlowName, rcFileName);
- const files = getFolderContent([flowPath]);
- return files.map(f => ([f, readFileSync(flowPath).toString('utf8')]));
- }
-
- userFlowPath(userFlowName: string = '', rcFileName: string = DEFAULT_RC_NAME): string {
- return join(this.root, this.rcFile[rcFileName].collect.ufPath, userFlowName);
- }
-
-}
-
-export function withUserFlowProject(
- cfg: ProjectConfig,
- fn: (prj: UserFlowCliProject) => Promise
-): () => Promise {
- return withProject(cfg, fn as any, UserFlowCliProjectFactory.create as any);
-}
diff --git a/packages/user-flow-cli-testing/src/lib/utils/cli-mode.ts b/packages/user-flow-cli-testing/src/lib/utils/cli-mode.ts
deleted file mode 100644
index db89ee337..000000000
--- a/packages/user-flow-cli-testing/src/lib/utils/cli-mode.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { CLI_MODES, CI_PROPERTY, CLI_MODE_PROPERTY } from '@push-based/user-flow';
-
-export function setupEnvVars(env: CLI_MODES): void {
- if (env === 'DEFAULT') {
- delete process.env[CI_PROPERTY];
- } else {
- process.env[CI_PROPERTY] = (env === 'CI' ? true : 'SANDBOX') as string;
- }
-}
-
-export function teardownEnvVars() {
- delete process.env[CI_PROPERTY];
- delete process.env[CLI_MODE_PROPERTY];
-}
-
-// @TODO: move into cli-project as it deals with env vars
-export function getEnvVarsByCliModeAndDeleteOld(cliMode: CLI_MODES): Record {
-
- if (cliMode === 'DEFAULT') {
- delete process.env[CI_PROPERTY];
- return {};
- }
-
- // CI mode value
- let ciValue = 'true';
- if (cliMode === 'SANDBOX') {
- // emulate sandbox env by setting CI to SANDBOX
- ciValue = 'SANDBOX';
- }
- return { [CI_PROPERTY]: ciValue };
-}
diff --git a/packages/user-flow-cli-testing/src/lib/utils/kill.ts b/packages/user-flow-cli-testing/src/lib/utils/kill.ts
deleted file mode 100644
index d0aa48901..000000000
--- a/packages/user-flow-cli-testing/src/lib/utils/kill.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-// @ts-ignore
-import * as killPort from 'kill-port';
-
-export function kill(args: { port: string | string[], method?: string, verbose?: boolean }): Promise {
- let { verbose, port, method } = args;
- port = port ? port.toString().split(',') : [];
- const logVerbose = getLogVerbose(Boolean(verbose));
- method = method || 'tcp';
-
- if (!Array.isArray(port)) {
- port = [port];
- }
-
- return Promise.all(port.map(current => {
- return killPort(current, method)
- .then((result: any) => {
- logVerbose(`Process on port ${current} killed`, result);
- })
- .catch((error: any) => {
- logVerbose(`Could not kill process on port ${port}`, error);
- });
- }));
-
-}
-
-
-/**
- * logs messages only if the CLI parameter -v or --verbose is passed as true
- *
- * @example
- * user-flow collect -v // log is present
- * user-flow collect -v=false // log is NOT present
- *
- * @param message
- */
-function getLogVerbose(verbose: boolean) {
- return (...message: Array>): void => {
- if (verbose) {
- return console.log(...message);
- }
- }
-}
diff --git a/packages/user-flow-cli-testing/tsconfig.json b/packages/user-flow-cli-testing/tsconfig.json
deleted file mode 100644
index f5b85657a..000000000
--- a/packages/user-flow-cli-testing/tsconfig.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "module": "commonjs",
- "forceConsistentCasingInFileNames": true,
- "strict": true,
- "noImplicitOverride": true,
- "noPropertyAccessFromIndexSignature": true,
- "noImplicitReturns": true,
- "noFallthroughCasesInSwitch": true
- },
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- },
- {
- "path": "./tsconfig.spec.json"
- }
- ]
-}
diff --git a/packages/user-flow-cli-testing/tsconfig.lib.json b/packages/user-flow-cli-testing/tsconfig.lib.json
deleted file mode 100644
index bad8d1d28..000000000
--- a/packages/user-flow-cli-testing/tsconfig.lib.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "declaration": true,
- "types": ["node"],
- "paths": {
- "@push-based/user-flow": [
- "dist/packages/user-flow"
- ]
- }
- },
- "include": ["**/*.ts"],
- "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
-}
diff --git a/packages/user-flow-cli-testing/tsconfig.spec.json b/packages/user-flow-cli-testing/tsconfig.spec.json
deleted file mode 100644
index 546f12877..000000000
--- a/packages/user-flow-cli-testing/tsconfig.spec.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "module": "commonjs",
- "types": ["jest", "node"]
- },
- "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
-}
diff --git a/packages/user-flow-example/.user-flowrc.json b/packages/user-flow-example/.user-flowrc.json
index 3d2bcd4a7..b0803e4c2 100644
--- a/packages/user-flow-example/.user-flowrc.json
+++ b/packages/user-flow-example/.user-flowrc.json
@@ -1,42 +1,10 @@
{
"collect": {
"url": "https://coffee-cart.netlify.app/",
- "ufPath": "packages/user-flow-example/user-flows",
- "budgets": [
- {
- "resourceSizes": [
- {
- "resourceType": "total",
- "budget": 26
- },
- {
- "resourceType": "script",
- "budget": 150
- }
- ],
- "resourceCounts": [
- {
- "resourceType": "third-party",
- "budget": 100
- }
- ],
- "timings": [
- {
- "metric": "interactive",
- "budget": 5000
- },
- {
- "metric": "first-meaningful-paint",
- "budget": 2000
- }
- ]
- }
- ]
+ "ufPath": "packages/user-flow-example/user-flows"
},
"persist": {
"outputPath": "dist/user-flow/user-flow-example",
- "format": [
- "md"
- ]
+ "format": ["md"]
}
}
diff --git a/packages/user-flow-example/package.json b/packages/user-flow-example/package.json
deleted file mode 100644
index fb4de6936..000000000
--- a/packages/user-flow-example/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "@user-flow/user-flow-example",
- "version": "0.0.1",
- "type": "commonjs"
-}
diff --git a/packages/user-flow-example/project.json b/packages/user-flow-example/project.json
index a159b3a3a..51be84f6c 100644
--- a/packages/user-flow-example/project.json
+++ b/packages/user-flow-example/project.json
@@ -3,14 +3,10 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/user-flow-example/src",
"projectType": "library",
+ "tags": [],
"targets": {
"lint": {
- "executor": "@nx/eslint:lint",
- "outputs": ["{options.outputFile}"],
- "options": {
- "lintFilePatterns": ["packages/user-flow-example/**/*"]
- }
+ "executor": "@nx/eslint:lint"
}
- },
- "tags": []
+ }
}
diff --git a/packages/user-flow-example/recordings/order-coffee-3.replay.json b/packages/user-flow-example/recordings/order-coffee-3.replay.json
index 9676300f5..0346e2394 100644
--- a/packages/user-flow-example/recordings/order-coffee-3.replay.json
+++ b/packages/user-flow-example/recordings/order-coffee-3.replay.json
@@ -5,13 +5,13 @@
"type": "navigate",
"url": "https://coffee-cart.netlify.app/",
"stepOptions": {
- "stepName": "Navigate to coffee cart"
+ "name": "Navigate to coffee cart"
}
},
{
"type": "startTimespan",
"stepOptions": {
- "stepName": "Select coffee"
+ "name": "Select coffee"
}
},
{
@@ -32,13 +32,13 @@
{
"type": "snapshot",
"stepOptions": {
- "stepName": "Coffee selected"
+ "name": "Coffee selected"
}
},
{
"type": "startTimespan",
"stepOptions": {
- "stepName": "Checkout order"
+ "name": "Checkout order"
}
},
{
@@ -90,13 +90,13 @@
{
"type": "snapshot",
"stepOptions": {
- "stepName": "Order checked out"
+ "name": "Order checked out"
}
},
{
"type": "startTimespan",
"stepOptions": {
- "stepName": "Submit order"
+ "name": "Submit order"
}
},
{
@@ -117,7 +117,7 @@
{
"type": "snapshot",
"stepOptions": {
- "stepName": "Order submitted"
+ "name": "Order submitted"
}
}
]
diff --git a/packages/user-flow-example/replay-examples/order-coffee-1-replay.uf.ts b/packages/user-flow-example/replay-examples/order-coffee-1-replay.uf.ts
index f6ef33538..20100b8a5 100644
--- a/packages/user-flow-example/replay-examples/order-coffee-1-replay.uf.ts
+++ b/packages/user-flow-example/replay-examples/order-coffee-1-replay.uf.ts
@@ -1,26 +1,22 @@
import {createUserFlowRunner, UserFlowContext, UserFlowInteractionsFn, UserFlowProvider} from '@push-based/user-flow';
-// @TODO refactor when v10 update lands
-import {UserFlow as LhUserFlow} from 'lighthouse/lighthouse-core/fraggle-rock/user-flow';
const interactions: UserFlowInteractionsFn = async (
ctx: UserFlowContext
): Promise => {
- const {flow, page, browser} = ctx;
- const lhFlow: LhUserFlow = flow;
+ const {flow} = ctx;
- await flow.startTimespan({stepName: 'Checkout order'});
+
+ await flow.startTimespan({name: 'Checkout order'});
// Use the create function to instanciate a the user-flow runner.
const path = './recordings/order-coffee-1.replay.json';
- const runner = await createUserFlowRunner( path, { page, browser, lhFlow });
+ const runner = await createUserFlowRunner( path, ctx);
await runner.run();
await flow.endTimespan();
};
-const userFlowProvider: UserFlowProvider = {
+export default {
flowOptions: { name: "Order Coffee 1" },
interactions,
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-example/replay-examples/order-coffee-2-replay.uf.ts b/packages/user-flow-example/replay-examples/order-coffee-2-replay.uf.ts
index c69d19e73..707f34b19 100644
--- a/packages/user-flow-example/replay-examples/order-coffee-2-replay.uf.ts
+++ b/packages/user-flow-example/replay-examples/order-coffee-2-replay.uf.ts
@@ -1,21 +1,16 @@
import {createUserFlowRunner, UserFlowContext, UserFlowInteractionsFn, UserFlowProvider} from '@push-based/user-flow';
-import {UserFlow as LhUserFlow} from 'lighthouse/lighthouse-core/fraggle-rock/user-flow';
const interactions: UserFlowInteractionsFn = async (
ctx: UserFlowContext
): Promise => {
- const {browser, page, flow } = ctx;
- const lhFlow: LhUserFlow = flow;
const path = './recordings/order-coffee-2.replay.json';
- const runner = await createUserFlowRunner(path, {browser, page, lhFlow });
+ const runner = await createUserFlowRunner(path, ctx);
await runner.run();
};
-const userFlowProvider: UserFlowProvider = {
- flowOptions: { name: "Order Coffee 2" },
+export default {
+ flowOptions: { name: "Order Coffee 1" },
interactions,
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-example/tsconfig.json b/packages/user-flow-example/tsconfig.json
index f5b85657a..a83f883e4 100644
--- a/packages/user-flow-example/tsconfig.json
+++ b/packages/user-flow-example/tsconfig.json
@@ -1,22 +1,5 @@
{
"extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "module": "commonjs",
- "forceConsistentCasingInFileNames": true,
- "strict": true,
- "noImplicitOverride": true,
- "noPropertyAccessFromIndexSignature": true,
- "noImplicitReturns": true,
- "noFallthroughCasesInSwitch": true
- },
"files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- },
- {
- "path": "./tsconfig.spec.json"
- }
- ]
+ "include": ["**/*"],
}
diff --git a/packages/user-flow-example/tsconfig.spec.json b/packages/user-flow-example/tsconfig.spec.json
deleted file mode 100644
index 67bf1bee7..000000000
--- a/packages/user-flow-example/tsconfig.spec.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "module": "commonjs",
- "types": [
- "jest",
- "node"
- ]
- },
- "include": [
- "jest.config.ts",
- "**/*.test.ts",
- "**/*.spec.ts",
- "**/*.d.ts"
- ]
-}
diff --git a/packages/user-flow-example/ufo/checkout.form.ts b/packages/user-flow-example/ufo/checkout.form.ts
index 3b45f58eb..0cf7e9ea9 100644
--- a/packages/user-flow-example/ufo/checkout.form.ts
+++ b/packages/user-flow-example/ufo/checkout.form.ts
@@ -1,4 +1,4 @@
-import {Ufo} from '../../cli/src/lib/ufo';
+import {Ufo} from '@push-based/user-flow';
import {
checkoutBtnSelector,
emailInputSelector,
diff --git a/packages/user-flow-example/ufo/coffee.ufo.ts b/packages/user-flow-example/ufo/coffee.ufo.ts
index 72b87efa6..0a50a67b2 100644
--- a/packages/user-flow-example/ufo/coffee.ufo.ts
+++ b/packages/user-flow-example/ufo/coffee.ufo.ts
@@ -1,4 +1,5 @@
-import {Ufo} from '../../cli/src/lib/ufo';
+import {Ufo} from '@push-based/user-flow';
+
import {cappuccinoSelector} from '../fixtures/coffee.fixture';
export class Coffee extends Ufo {
diff --git a/packages/user-flow-example/user-flows/order-coffee-1.uf.ts b/packages/user-flow-example/user-flows/order-coffee-1.uf.ts
index 7ca287d4d..72aea2e24 100644
--- a/packages/user-flow-example/user-flows/order-coffee-1.uf.ts
+++ b/packages/user-flow-example/user-flows/order-coffee-1.uf.ts
@@ -10,7 +10,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
const { url } = collectOptions;
await flow.navigate(url, {
- stepName: 'Navigate to coffee cart',
+ name: 'Navigate to coffee cart',
});
// Select coffee
@@ -21,9 +21,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
};
-const userFlowProvider: UserFlowProvider = {
+export default {
flowOptions: {name: 'Order Coffee'},
interactions
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-example/user-flows/order-coffee-2.uf.ts b/packages/user-flow-example/user-flows/order-coffee-2.uf.ts
index a0f6f36f5..49b80f52b 100644
--- a/packages/user-flow-example/user-flows/order-coffee-2.uf.ts
+++ b/packages/user-flow-example/user-flows/order-coffee-2.uf.ts
@@ -1,4 +1,4 @@
-import {UserFlowContext, UserFlowInteractionsFn, UserFlowProvider} from '@push-based/';
+import { UserFlowContext, UserFlowInteractionsFn, UserFlowProvider } from '@push-based/user-flow';
// Your custom interactions with the page
const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promise => {
@@ -6,7 +6,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
const { url } = collectOptions;
await flow.navigate(url, {
- stepName: 'Navigate to coffee cart',
+ name: 'Navigate to coffee cart',
});
@@ -37,9 +37,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
};
-const userFlowProvider: UserFlowProvider = {
+export default {
flowOptions: {name: 'Order Coffee'},
interactions
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-example/user-flows/order-coffee-3.uf.ts b/packages/user-flow-example/user-flows/order-coffee-3.uf.ts
index 9184cb320..43a638125 100644
--- a/packages/user-flow-example/user-flows/order-coffee-3.uf.ts
+++ b/packages/user-flow-example/user-flows/order-coffee-3.uf.ts
@@ -7,10 +7,10 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
// Navigate to coffee order site
await flow.navigate(url, {
- stepName: 'Navigate to coffee cart',
+ name: 'Navigate to coffee cart',
});
- await flow.startTimespan({ stepName: 'Select coffee' });
+ await flow.startTimespan({ name: 'Select coffee' });
// Select coffee
const cappuccinoItem = '.cup:nth-child(1)';
@@ -20,7 +20,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
await flow.endTimespan();
- await flow.startTimespan({ stepName: 'Checkout order' });
+ await flow.startTimespan({ name: 'Checkout order' });
// Checkout order
const checkoutBtn = '[data-test=checkout]';
@@ -38,7 +38,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
await flow.endTimespan();
- await flow.startTimespan({ stepName: 'Submit order' });
+ await flow.startTimespan({ name: 'Submit order' });
// Submit order
const submitBtn = '#submit-payment';
@@ -51,9 +51,7 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
};
-const userFlowProvider: UserFlowProvider = {
+export default {
flowOptions: {name: 'Order Coffee'},
interactions
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-example/user-flows/order-coffee-4.uf.ts b/packages/user-flow-example/user-flows/order-coffee-4.uf.ts
index b09c2ba73..6feadbdf5 100644
--- a/packages/user-flow-example/user-flows/order-coffee-4.uf.ts
+++ b/packages/user-flow-example/user-flows/order-coffee-4.uf.ts
@@ -7,10 +7,10 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
// Navigate to coffee order site
await flow.navigate(url, {
- stepName: 'Navigate to coffee cart',
+ name: 'Navigate to coffee cart',
});
- await flow.startTimespan({ stepName: 'Select coffee' });
+ await flow.startTimespan({ name: 'Select coffee' });
// Select coffee
const cappuccinoItem = '.cup:nth-child(1)';
@@ -19,10 +19,10 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
await flow.endTimespan();
- await flow.snapshot({ stepName: 'Coffee selected' });
+ await flow.snapshot({ name: 'Coffee selected' });
- await flow.startTimespan({ stepName: 'Checkout order' });
+ await flow.startTimespan({ name: 'Checkout order' });
// Checkout order
const checkoutBtn = '[data-test=checkout]';
@@ -39,9 +39,9 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
await flow.endTimespan();
- await flow.snapshot({ stepName: 'Order checked out' });
+ await flow.snapshot({ name: 'Order checked out' });
- await flow.startTimespan({ stepName: 'Submit order' });
+ await flow.startTimespan({ name: 'Submit order' });
// Submit order
const submitBtn = '#submit-payment';
@@ -52,13 +52,11 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
await flow.endTimespan();
- await flow.snapshot({ stepName: 'Order submitted' });
+ await flow.snapshot({ name: 'Order submitted' });
};
-const userFlowProvider: UserFlowProvider = {
+export default {
flowOptions: {name: 'Order Coffee'},
interactions
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-example/user-flows/order-coffee-5.uf.ts b/packages/user-flow-example/user-flows/order-coffee-5.uf.ts
index d2ff03cf5..e06300ff6 100644
--- a/packages/user-flow-example/user-flows/order-coffee-5.uf.ts
+++ b/packages/user-flow-example/user-flows/order-coffee-5.uf.ts
@@ -17,32 +17,30 @@ const interactions: UserFlowInteractionsFn = async (ctx: UserFlowContext): Promi
// Navigate to coffee order site
await flow.navigate(url, {
- stepName: 'Navigate to coffee cart'
+ name: 'Navigate to coffee cart'
});
- await flow.startTimespan({ stepName: 'Select coffee' });
+ await flow.startTimespan({ name: 'Select coffee' });
// Select coffee
coffeeUfo.selectCappuccino();
await flow.endTimespan();
- await flow.snapshot({ stepName: 'Coffee selected' });
+ await flow.snapshot({ name: 'Coffee selected' });
- await flow.startTimespan({ stepName: 'Checkout order' });
+ await flow.startTimespan({ name: 'Checkout order' });
// Checkout order
await checkoutFormUfo.openOrder();
await checkoutFormUfo.fillCheckoutForm(formData);
await flow.endTimespan();
- await flow.snapshot({ stepName: 'Order checked out' });
+ await flow.snapshot({ name: 'Order checked out' });
- await flow.startTimespan({ stepName: 'Submit order' });
+ await flow.startTimespan({ name: 'Submit order' });
// Submit order
await checkoutFormUfo.submitOrder();
await flow.endTimespan();
- await flow.snapshot({ stepName: 'Order submitted' });
+ await flow.snapshot({ name: 'Order submitted' });
};
-const userFlowProvider: UserFlowProvider = {
+export default {
flowOptions: { name: 'Order Coffee' },
interactions
-};
-
-module.exports = userFlowProvider;
+} satisfies UserFlowProvider;
diff --git a/packages/user-flow-gh-integration/.user-flowrc.json b/packages/user-flow-gh-integration/.user-flowrc.json
index c9392c004..dd151fc17 100644
--- a/packages/user-flow-gh-integration/.user-flowrc.json
+++ b/packages/user-flow-gh-integration/.user-flowrc.json
@@ -1,77 +1,7 @@
{
"collect": {
"url": "https://coffee-cart.netlify.app/",
- "ufPath": "./packages/user-flow-gh-integration/user-flows",
- "budgets": [
- {
- "resourceCounts": [
- {
- "resourceType": "document",
- "budget": 1
- },
- {
- "resourceType": "script",
- "budget": 1
- },
- {
- "resourceType": "stylesheet",
- "budget": 1
- },
- {
- "resourceType": "image",
- "budget": 0
- },
- {
- "resourceType": "media",
- "budget": 0
- },
- {
- "resourceType": "font",
- "budget": 0
- },
- {
- "resourceType": "other",
- "budget": 0
- },
- {
- "resourceType": "third-party",
- "budget": 0
- }
- ],
- "resourceSizes": [
- {
- "resourceType": "script",
- "budget": 0
- },
- {
- "resourceType": "stylesheet",
- "budget": 0
- }
- ],
- "timings": [
- {
- "metric": "first-contentful-paint",
- "budget": 10
- },
- {
- "metric": "speed-index",
- "budget": 10
- },
- {
- "metric": "largest-contentful-paint",
- "budget": 10
- },
- {
- "metric": "cumulative-layout-shift",
- "budget": 0
- },
- {
- "metric": "total-blocking-time",
- "budget": 10
- }
- ]
- }
- ]
+ "ufPath": "./packages/user-flow-gh-integration/user-flows"
},
"persist": {
"outPath": "./dist/user-flow/user-flow-gh-integration",
diff --git a/packages/user-flow-gh-integration/README.md b/packages/user-flow-gh-integration/README.md
index 8d07f2a6a..1b5672071 100644
--- a/packages/user-flow-gh-integration/README.md
+++ b/packages/user-flow-gh-integration/README.md
@@ -1,4 +1,3 @@
# user-flo-ci-integration
-This folder contains the user flow examples fo the CI integration.
-
+This folder contains the user flow examples for the CI integration.
diff --git a/packages/user-flow-gh-integration/data/checkout.data.ts b/packages/user-flow-gh-integration/data/checkout.data.ts
deleted file mode 100644
index 6b5c8b603..000000000
--- a/packages/user-flow-gh-integration/data/checkout.data.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const formData = { name: 'nina', email: 'nina@gmail.com' };
diff --git a/packages/user-flow-gh-integration/package.json b/packages/user-flow-gh-integration/package.json
deleted file mode 100644
index d37b68e18..000000000
--- a/packages/user-flow-gh-integration/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "@user-flow/user-flow-gh-integration",
- "version": "0.0.1",
- "type": "commonjs"
-}
diff --git a/packages/user-flow-gh-integration/project.json b/packages/user-flow-gh-integration/project.json
index f15efb031..4685d8273 100644
--- a/packages/user-flow-gh-integration/project.json
+++ b/packages/user-flow-gh-integration/project.json
@@ -3,14 +3,10 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/user-flow-gh-integration/src",
"projectType": "library",
+ "tags": [],
"targets": {
"lint": {
- "executor": "@nx/eslint:lint",
- "outputs": ["{options.outputFile}"],
- "options": {
- "lintFilePatterns": ["packages/user-flow-gh-integration/**/*"]
- }
+ "executor": "@nx/eslint:lint"
}
- },
- "tags": []
+ }
}
diff --git a/packages/user-flow-gh-integration/tsconfig.json b/packages/user-flow-gh-integration/tsconfig.json
deleted file mode 100644
index 592e5cc4e..000000000
--- a/packages/user-flow-gh-integration/tsconfig.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "module": "CommonJS",
- "forceConsistentCasingInFileNames": true,
- "strict": true,
- "noImplicitOverride": true,
- "noPropertyAccessFromIndexSignature": true,
- "noImplicitReturns": true,
- "noFallthroughCasesInSwitch": true
- },
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- },
- {
- "path": "./tsconfig.spec.json"
- }
- ]
-}
diff --git a/project.json b/project.json
new file mode 100644
index 000000000..fa39ae5b2
--- /dev/null
+++ b/project.json
@@ -0,0 +1,32 @@
+{
+ "name": "@push-based/user-flow-source",
+ "$schema": "node_modules/nx/schemas/project-schema.json",
+ "targets": {
+ "local-registry": {
+ "executor": "@nx/js:verdaccio",
+ "options": {
+ "port": 4873,
+ "config": ".verdaccio/config.yml",
+ "storage": "tmp/local-registry/storage"
+ }
+ },
+ "version": {
+ "executor": "@jscutlery/semver:version",
+ "options": {
+ "syncVersions": true,
+ "preset": "angular",
+ "commitMessageFormat": "release: {version} [skip ci]",
+ "postTargets": ["github"],
+ "push": true,
+ "skipProjectChangelog": true
+ }
+ },
+ "github": {
+ "executor": "@jscutlery/semver:github",
+ "options": {
+ "tag": "{tag}",
+ "notes": "{notes}"
+ }
+ }
+ }
+}
diff --git a/tools/scripts/publish.mjs b/tools/scripts/publish.mjs
new file mode 100644
index 000000000..934580b7b
--- /dev/null
+++ b/tools/scripts/publish.mjs
@@ -0,0 +1,59 @@
+/**
+ * This is a minimal script to publish your package to "npm".
+ * This is meant to be used as-is or customize as you see fit.
+ *
+ * This script is executed on "dist/path/to/library" as "cwd" by default.
+ *
+ * You might need to authenticate with NPM before running this script.
+ */
+import devkit from '@nx/devkit';
+import { execSync } from 'node:child_process';
+import { readFileSync, writeFileSync } from 'node:fs';
+
+const { readCachedProjectGraph } = devkit;
+
+function invariant(condition, message) {
+ if (!condition) {
+ console.error(message);
+ process.exit(1);
+ }
+}
+
+// Executing publish script: node path/to/publish.mjs {name} --version {version} --tag {tag}
+// Default "tag" to "next" so we won't publish the "latest" tag by accident.
+const [, , name, version, tag = 'next'] = process.argv;
+
+// A simple SemVer validation to validate the version
+const validVersion = /^\d+\.\d+\.\d+(-\w+\.\d+)?/;
+invariant(
+ version && validVersion.test(version),
+ `No version provided or version did not match Semantic Versioning, expected: #.#.#-tag.# or #.#.#, got ${version}.`,
+);
+
+const graph = readCachedProjectGraph();
+const project = graph.nodes[name];
+
+invariant(
+ project,
+ `Could not find project "${name}" in the workspace. Is the project.json configured correctly?`,
+);
+
+const outputPath = project.data?.targets?.build?.options?.outputPath;
+invariant(
+ outputPath,
+ `Could not find "build.options.outputPath" of project "${name}". Is project.json configured correctly?`,
+);
+
+process.chdir(outputPath);
+
+// Updating the version in "package.json" before publishing
+try {
+ const json = JSON.parse(readFileSync(`package.json`).toString());
+ json.version = version;
+ writeFileSync(`package.json`, JSON.stringify(json, null, 2));
+} catch (e) {
+ console.error(`Error reading package.json file from library build output.`);
+}
+
+// Execute "npm publish" to publish
+execSync(`npm publish --access public --tag ${tag}`);
diff --git a/tools/scripts/start-local-registry.ts b/tools/scripts/start-local-registry.ts
new file mode 100644
index 000000000..fb6fecf5e
--- /dev/null
+++ b/tools/scripts/start-local-registry.ts
@@ -0,0 +1,103 @@
+/**
+ * This script starts a local registry for e2e testing purposes.
+ * It is meant to be called in jest's globalSetup.
+ */
+import { execFileSync, execSync, spawn } from 'node:child_process';
+
+export default async () => {
+ console.log('Starting local registry...');
+ // local registry target to run
+ const localRegistryTarget = '@push-based/user-flow-source:local-registry';
+ // storage folder for the local registry
+ const storage = './tmp/local-registry/storage';
+
+ const stopLocalRegistryFn = await startLocalRegistry({
+ localRegistryTarget,
+ storage,
+ verbose: true,
+ });
+
+ // is is also possible to use nx release to publish the packages to the local registry
+ execFileSync(
+ 'npx',
+ [
+ 'nx',
+ 'run-many',
+ '--targets',
+ 'publish',
+ '--ver',
+ '1.0.0',
+ '--tag',
+ 'e2e',
+ ],
+ { env: process.env, stdio: 'inherit', shell: true },
+ );
+ return stopLocalRegistryFn
+};
+
+// soft copy from https://github.com/nrwl/nx/blob/16.9.x/packages/js/src/plugins/jest/start-local-registry.ts
+// original function does not work, because it uses require.resolve('nx') and fork,
+// and it does not work with vite
+function startLocalRegistry({
+ localRegistryTarget,
+ storage,
+ verbose,
+}: {
+ localRegistryTarget: string;
+ storage?: string;
+ verbose?: boolean;
+}) {
+ if (!localRegistryTarget) {
+ throw new Error(`localRegistryTarget is required`);
+ }
+ return new Promise<() => void>((resolve, reject) => {
+ const childProcess = spawn(
+ 'npx',
+ [
+ 'nx',
+ ...`run ${localRegistryTarget} --location none --clear true`.split(' '),
+ ...(storage ? [`--storage`, storage] : []),
+ ],
+ { stdio: 'pipe', shell: true },
+ );
+
+ const listener = data => {
+ if (verbose) {
+ process.stdout.write(data);
+ }
+ if (data.toString().includes('http://localhost:')) {
+ const port = parseInt(
+ data.toString().match(/localhost:(?\d+)/)?.groups?.port,
+ );
+ console.info('Local registry started on port ' + port);
+
+ process.env.npm_config_registry = `http://localhost:${port}`;
+ execSync(
+ `npm config set //localhost:${port}/:_authToken "secretVerdaccioToken"`,
+ );
+
+ resolve(() => {
+ childProcess.kill();
+ execSync(`npm config delete //localhost:${port}/:_authToken`);
+ });
+ childProcess?.stdout?.off('data', listener);
+ }
+ };
+ childProcess?.stdout?.on('data', listener);
+ childProcess?.stderr?.on('data', data => {
+ process.stderr.write(data);
+ });
+ childProcess.on('error', err => {
+ console.error('local registry error', err);
+ reject(err);
+ });
+ childProcess.on('exit', code => {
+ console.info('local registry exit', code);
+ if (code !== 0) {
+ reject(code);
+ } else {
+ resolve(() => {});
+ }
+ });
+ });
+}
diff --git a/tools/scripts/stop-local-registry.ts b/tools/scripts/stop-local-registry.ts
new file mode 100644
index 000000000..23500aad5
--- /dev/null
+++ b/tools/scripts/stop-local-registry.ts
@@ -0,0 +1,12 @@
+/**
+ * This script stops the local registry for e2e testing purposes.
+ * It is meant to be called in jest's globalTeardown.
+ */
+
+export default () => {
+ console.log('Teardown registry')
+ if (global.stopLocalRegistry) {
+ global.stopLocalRegistry();
+ console.log('Registry down')
+ }
+};
diff --git a/tsconfig.base.json b/tsconfig.base.json
index b2230af07..eabf3b939 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -8,20 +8,15 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
- "target": "es2015",
+ "target": "es2022",
"module": "esnext",
- "lib": ["es2017", "dom"],
+ "lib": ["es2022", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {
"@push-based/user-flow": ["packages/cli/src/index.ts"],
- "@push-based/user-flow-cli-testing": [
- "packages/user-flow-cli-testing/src/index.ts"
- ],
"@push-based/user-flow-nx-plugin": ["packages/nx-plugin/src/index.ts"],
- "sandbox": ["packages/sandbox/src/index.ts"],
- "test-data": ["packages/test-data/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp", "code-pushup.config.ts"]