playwright-step-decorator-plugin 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,131 @@
1
+ // src/decorator/index.ts
2
+ import { test } from "@playwright/test";
3
+
4
+ // src/decorator/humanizer.ts
5
+ import { humanize } from "@alduino/humanizer/string";
6
+ function scoreParam(value) {
7
+ if (value === null || value === void 0) return 0;
8
+ if (typeof value === "boolean") return 1;
9
+ if (Array.isArray(value) || typeof value === "object") return 2;
10
+ return 3;
11
+ }
12
+ function renderParamValue(name, value) {
13
+ const humanName = humanize(name).toLowerCase();
14
+ if (value === null || value === void 0) {
15
+ return `${humanName}: not provided`;
16
+ }
17
+ if (typeof value === "boolean") {
18
+ return value ? humanName : `not ${humanName}`;
19
+ }
20
+ if (typeof value === "string") {
21
+ return value === "" ? `${humanName}: empty` : `${humanName} "${value}"`;
22
+ }
23
+ if (typeof value === "number") {
24
+ return `${humanName} ${value}`;
25
+ }
26
+ if (Array.isArray(value)) {
27
+ if (value.length === 0) return `no ${humanName}`;
28
+ if (value.length <= 3) return `${humanName} [${value.map((v) => JSON.stringify(v)).join(", ")}]`;
29
+ return `${value.length} ${humanName}`;
30
+ }
31
+ const keys = Object.keys(value);
32
+ if (keys.length === 0) return `empty ${humanName}`;
33
+ if (keys.length <= 2) {
34
+ const entries = keys.map((k) => `${k}: ${JSON.stringify(value[k])}`).join(", ");
35
+ return `${humanName} {${entries}}`;
36
+ }
37
+ return `${humanName} with ${keys.length} fields`;
38
+ }
39
+ function joinParts(parts) {
40
+ if (parts.length === 0) return "";
41
+ if (parts.length === 1) return parts[0];
42
+ return `${parts.slice(0, -1).join(", ")} and ${parts[parts.length - 1]}`;
43
+ }
44
+ function buildParamString(params) {
45
+ if (params.length === 0) return "";
46
+ let top;
47
+ let remaining = 0;
48
+ if (params.length <= 3) {
49
+ top = params;
50
+ } else {
51
+ const scored = params.map((p, originalIndex) => ({ ...p, score: scoreParam(p.value), originalIndex }));
52
+ scored.sort((a, b) => {
53
+ const scoreDiff = b.score - a.score;
54
+ return scoreDiff !== 0 ? scoreDiff : a.originalIndex - b.originalIndex;
55
+ });
56
+ top = scored.slice(0, 3);
57
+ remaining = params.length - 3;
58
+ }
59
+ const parts = top.map((p) => renderParamValue(p.name, p.value));
60
+ const joined = joinParts(parts);
61
+ if (remaining > 0) {
62
+ return `${joined} and ${remaining} more option${remaining === 1 ? "" : "s"}`;
63
+ }
64
+ return joined;
65
+ }
66
+ function buildHumanStepTitle(className, methodName, params) {
67
+ const humanClass = humanize(className);
68
+ const humanMethod = humanize(methodName).toLowerCase();
69
+ const base = `${humanClass}: ${humanMethod}`;
70
+ const paramStr = buildParamString(params);
71
+ return paramStr ? `${base} using ${paramStr}` : base;
72
+ }
73
+ function buildCustomStepTitle(customName, params) {
74
+ const paramStr = buildParamString(params);
75
+ return paramStr ? `${customName} using ${paramStr}` : customName;
76
+ }
77
+ function extractParamNames(fn) {
78
+ const fnStr = fn.toString();
79
+ const match = fnStr.match(/\(([^)]*)\)/);
80
+ if (!match || !match[1].trim()) return [];
81
+ return match[1].split(",").map((param) => {
82
+ const name = param.trim().replace(/^\.\.\./, "").split(/[\s=]/)[0].trim();
83
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : null;
84
+ }).filter((name) => name !== null && name.length > 0);
85
+ }
86
+
87
+ // src/decorator/index.ts
88
+ function isDecoratorContext(v) {
89
+ return typeof v === "object" && v !== null && v.kind === "method";
90
+ }
91
+ function isStepOptions(v) {
92
+ if (typeof v !== "object" || v === null) return false;
93
+ const allowedKeys = /* @__PURE__ */ new Set(["box", "timeout", "noHumanizer"]);
94
+ return Object.keys(v).every((k) => allowedKeys.has(k));
95
+ }
96
+ function applyStep(target, context, customName, opts) {
97
+ const paramNames = extractParamNames(target);
98
+ return function(...args) {
99
+ let stepTitle;
100
+ if (opts.noHumanizer) {
101
+ stepTitle = `${this.constructor.name}.${String(context.name)}`;
102
+ } else {
103
+ const params = paramNames.map((name, i) => ({ name, value: args[i] }));
104
+ if (customName !== void 0) {
105
+ stepTitle = buildCustomStepTitle(customName, params);
106
+ } else {
107
+ stepTitle = buildHumanStepTitle(
108
+ this.constructor.name,
109
+ String(context.name),
110
+ params
111
+ );
112
+ }
113
+ }
114
+ return test.step(stepTitle, () => target.call(this, ...args), {
115
+ box: opts.box,
116
+ timeout: opts.timeout
117
+ });
118
+ };
119
+ }
120
+ function step(nameOrOptionsOrTarget, contextOrOptions) {
121
+ if (typeof nameOrOptionsOrTarget === "function" && isDecoratorContext(contextOrOptions)) {
122
+ return applyStep(nameOrOptionsOrTarget, contextOrOptions, void 0, {});
123
+ }
124
+ const customName = typeof nameOrOptionsOrTarget === "string" ? nameOrOptionsOrTarget : void 0;
125
+ const opts = typeof nameOrOptionsOrTarget === "object" && nameOrOptionsOrTarget !== null && isStepOptions(nameOrOptionsOrTarget) ? nameOrOptionsOrTarget : isStepOptions(contextOrOptions) ? contextOrOptions : {};
126
+ return (target, context) => applyStep(target, context, customName, opts);
127
+ }
128
+ export {
129
+ step
130
+ };
131
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/decorator/index.ts","../../src/decorator/humanizer.ts"],"sourcesContent":["import { test } from '@playwright/test';\nimport {\n buildCustomStepTitle,\n buildHumanStepTitle,\n extractParamNames,\n type ParamDescriptor,\n} from './humanizer.js';\nimport type { StepOptions } from './types.js';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyMethod = (this: any, ...args: unknown[]) => unknown;\ntype StepDecorator = (target: AnyMethod, context: ClassMethodDecoratorContext) => AnyMethod;\n\nfunction isDecoratorContext(v: unknown): v is ClassMethodDecoratorContext {\n return typeof v === 'object' && v !== null && (v as ClassMethodDecoratorContext).kind === 'method';\n}\n\nfunction isStepOptions(v: unknown): v is StepOptions {\n if (typeof v !== 'object' || v === null) return false;\n const allowedKeys = new Set(['box', 'timeout', 'noHumanizer']);\n return Object.keys(v).every(k => allowedKeys.has(k));\n}\n\nfunction applyStep(\n target: AnyMethod,\n context: ClassMethodDecoratorContext,\n customName: string | undefined,\n opts: StepOptions\n): AnyMethod {\n const paramNames = extractParamNames(target);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function (this: any, ...args: unknown[]): unknown {\n let stepTitle: string;\n\n if (opts.noHumanizer) {\n stepTitle = `${this.constructor.name}.${String(context.name)}`;\n } else {\n const params: ParamDescriptor[] = paramNames.map((name, i) => ({ name, value: args[i] }));\n\n if (customName !== undefined) {\n stepTitle = buildCustomStepTitle(customName, params);\n } else {\n stepTitle = buildHumanStepTitle(\n this.constructor.name,\n String(context.name),\n params\n );\n }\n }\n\n return test.step(stepTitle, () => target.call(this, ...args), {\n box: opts.box,\n timeout: opts.timeout,\n });\n };\n}\n\n/**\n * Decorator that wraps a Page Object Model method in a `test.step()` call,\n * automatically generating a human-readable step title.\n *\n * @example Bare usage — humanizes class + method name + runtime params\n * ```ts\n * class LoginPage {\n * @step\n * async login(username: string, password: string) { ... }\n * }\n * // → 'Login page: login using username \"admin\" and password \"secret\"'\n * ```\n *\n * @example Custom step name — params are still appended\n * ```ts\n * class CheckoutPage {\n * @step('Proceed to payment')\n * async submitOrder(orderId: string) { ... }\n * }\n * // → 'Proceed to payment using order id \"ord_99\"'\n * ```\n *\n * @example Options only — humanizes with box + timeout\n * ```ts\n * class ProfilePage {\n * @step({ box: true, timeout: 10_000 })\n * async updateAvatar(file: string) { ... }\n * }\n * ```\n *\n * @example Custom name + options\n * ```ts\n * class CartPage {\n * @step('Add item to cart', { box: true })\n * async addItem(product: Product) { ... }\n * }\n * ```\n *\n * @example Disable humanizer — raw \"ClassName.methodName\", no params\n * ```ts\n * class AdminPage {\n * @step({ noHumanizer: true })\n * async deleteUser(userId: string) { ... }\n * }\n * // → 'AdminPage.deleteUser'\n * ```\n */\nexport function step(target: AnyMethod, context: ClassMethodDecoratorContext): AnyMethod;\nexport function step(name: string, options?: StepOptions): StepDecorator;\nexport function step(options: StepOptions): StepDecorator;\nexport function step(): StepDecorator;\nexport function step(\n nameOrOptionsOrTarget?: string | StepOptions | AnyMethod,\n contextOrOptions?: ClassMethodDecoratorContext | StepOptions\n): AnyMethod | StepDecorator {\n // Case 1: @step (bare, no parentheses)\n if (typeof nameOrOptionsOrTarget === 'function' && isDecoratorContext(contextOrOptions)) {\n return applyStep(nameOrOptionsOrTarget, contextOrOptions, undefined, {});\n }\n\n // Cases 2–4: @step(...) factory\n const customName =\n typeof nameOrOptionsOrTarget === 'string' ? nameOrOptionsOrTarget : undefined;\n\n const opts: StepOptions =\n typeof nameOrOptionsOrTarget === 'object' && nameOrOptionsOrTarget !== null && isStepOptions(nameOrOptionsOrTarget)\n ? nameOrOptionsOrTarget\n : isStepOptions(contextOrOptions)\n ? (contextOrOptions as StepOptions)\n : {};\n\n return (target: AnyMethod, context: ClassMethodDecoratorContext): AnyMethod =>\n applyStep(target, context, customName, opts);\n}\n\nexport type { StepOptions } from './types.js';\n","import { humanize } from '@alduino/humanizer/string';\n\nexport interface ParamDescriptor {\n name: string;\n value: unknown;\n}\n\nfunction scoreParam(value: unknown): number {\n if (value === null || value === undefined) return 0;\n if (typeof value === 'boolean') return 1;\n if (Array.isArray(value) || (typeof value === 'object')) return 2;\n return 3; // string or number\n}\n\nfunction renderParamValue(name: string, value: unknown): string {\n const humanName = humanize(name).toLowerCase();\n\n if (value === null || value === undefined) {\n return `${humanName}: not provided`;\n }\n if (typeof value === 'boolean') {\n return value ? humanName : `not ${humanName}`;\n }\n if (typeof value === 'string') {\n return value === '' ? `${humanName}: empty` : `${humanName} \"${value}\"`;\n }\n if (typeof value === 'number') {\n return `${humanName} ${value}`;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return `no ${humanName}`;\n if (value.length <= 3) return `${humanName} [${value.map(v => JSON.stringify(v)).join(', ')}]`;\n return `${value.length} ${humanName}`;\n }\n // object\n const keys = Object.keys(value as object);\n if (keys.length === 0) return `empty ${humanName}`;\n if (keys.length <= 2) {\n const entries = keys.map(k => `${k}: ${JSON.stringify((value as Record<string, unknown>)[k])}`).join(', ');\n return `${humanName} {${entries}}`;\n }\n return `${humanName} with ${keys.length} fields`;\n}\n\nfunction joinParts(parts: string[]): string {\n if (parts.length === 0) return '';\n if (parts.length === 1) return parts[0];\n return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;\n}\n\nexport function buildParamString(params: ParamDescriptor[]): string {\n if (params.length === 0) return '';\n\n let top: ParamDescriptor[];\n let remaining = 0;\n\n if (params.length <= 3) {\n // All fit — preserve original order\n top = params;\n } else {\n // Select top 3 by significance score, then by original position\n const scored = params.map((p, originalIndex) => ({ ...p, score: scoreParam(p.value), originalIndex }));\n scored.sort((a, b) => {\n const scoreDiff = b.score - a.score;\n return scoreDiff !== 0 ? scoreDiff : a.originalIndex - b.originalIndex;\n });\n top = scored.slice(0, 3);\n remaining = params.length - 3;\n }\n\n const parts = top.map(p => renderParamValue(p.name, p.value));\n const joined = joinParts(parts);\n\n if (remaining > 0) {\n return `${joined} and ${remaining} more option${remaining === 1 ? '' : 's'}`;\n }\n return joined;\n}\n\n/**\n * Builds a human-readable step title from a class name, method name, and runtime parameters.\n *\n * Format: \"<Humanized class>: <humanized method> using <params>\"\n *\n * @example\n * buildHumanStepTitle('LoginPage', 'fillCredentials', [])\n * // → \"Login page: fill credentials\"\n *\n * @example\n * buildHumanStepTitle('LoginPage', 'login', [\n * { name: 'username', value: 'admin@test.com' },\n * { name: 'password', value: 'secret' },\n * ])\n * // → 'Login page: login using username \"admin@test.com\" and password \"secret\"'\n */\nexport function buildHumanStepTitle(\n className: string,\n methodName: string,\n params: ParamDescriptor[]\n): string {\n const humanClass = humanize(className);\n const humanMethod = humanize(methodName).toLowerCase();\n const base = `${humanClass}: ${humanMethod}`;\n\n const paramStr = buildParamString(params);\n return paramStr ? `${base} using ${paramStr}` : base;\n}\n\n/**\n * Builds a human-readable step title from a custom name and runtime parameters.\n *\n * Format: \"<custom name> using <params>\"\n *\n * @example\n * buildCustomStepTitle('Proceed to payment', [\n * { name: 'orderId', value: 'ord_99' },\n * { name: 'retry', value: false },\n * ])\n * // → 'Proceed to payment using order id \"ord_99\" and not retry'\n */\nexport function buildCustomStepTitle(customName: string, params: ParamDescriptor[]): string {\n const paramStr = buildParamString(params);\n return paramStr ? `${customName} using ${paramStr}` : customName;\n}\n\n/**\n * Extracts parameter names from a function's source code via toString().\n * Handles camelCase, default values and rest params; skips destructured params.\n */\nexport function extractParamNames(fn: (...args: unknown[]) => unknown): string[] {\n const fnStr = fn.toString();\n const match = fnStr.match(/\\(([^)]*)\\)/);\n if (!match || !match[1].trim()) return [];\n\n return match[1]\n .split(',')\n .map(param => {\n const name = param\n .trim()\n .replace(/^\\.\\.\\./, '') // rest params\n .split(/[\\s=]/)[0] // default values\n .trim();\n // Skip destructured params ({ ... } or [ ... ])\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : null;\n })\n .filter((name): name is string => name !== null && name.length > 0);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,19 @@
1
+ import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
+
3
+ declare const plugin: {
4
+ meta: {
5
+ name: string;
6
+ version: string;
7
+ };
8
+ rules: {
9
+ 'require-step-decorator': _typescript_eslint_utils_ts_eslint.RuleModule<"missingStepDecorator", [{
10
+ pomPattern?: string;
11
+ decoratorName?: string;
12
+ }], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
13
+ name: string;
14
+ };
15
+ };
16
+ configs: Record<string, unknown>;
17
+ };
18
+
19
+ export { plugin as default };
@@ -0,0 +1,19 @@
1
+ import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
+
3
+ declare const plugin: {
4
+ meta: {
5
+ name: string;
6
+ version: string;
7
+ };
8
+ rules: {
9
+ 'require-step-decorator': _typescript_eslint_utils_ts_eslint.RuleModule<"missingStepDecorator", [{
10
+ pomPattern?: string;
11
+ decoratorName?: string;
12
+ }], unknown, _typescript_eslint_utils_ts_eslint.RuleListener> & {
13
+ name: string;
14
+ };
15
+ };
16
+ configs: Record<string, unknown>;
17
+ };
18
+
19
+ export { plugin as default };