genat-mcp 1.0.0 → 1.1.0
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.
- package/README.md +3 -3
- package/detect-framework.js +20 -10
- package/index.js +3 -3
- package/package.json +1 -1
- package/write-files.js +1 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GenAT MCP
|
|
2
2
|
|
|
3
|
-
MCP server that exposes a **GenAT** tool: generate accessibility tests for a URL based on your project folder. It detects framework (TypeScript
|
|
3
|
+
MCP server that exposes a **GenAT** tool: generate accessibility tests for a URL based on your project folder. It detects framework (TypeScript, JavaScript, or Python, BDD, Page Object), calls an n8n GenAT workflow, and returns (or writes) generated test files.
|
|
4
4
|
|
|
5
5
|
Full setup (n8n workflow, services, usage) is in the [project README](../README.md).
|
|
6
6
|
|
|
@@ -72,10 +72,10 @@ If the global binary is not on PATH, use the full path, e.g. `node $(npm root -g
|
|
|
72
72
|
## Tool: GenAT
|
|
73
73
|
|
|
74
74
|
- **url** (string): Page URL to analyze for accessibility.
|
|
75
|
-
- **parentProjectFolder** (string): Path to the project root (TypeScript or Python Playwright).
|
|
75
|
+
- **parentProjectFolder** (string): Path to the project root (TypeScript, JavaScript, or Python Playwright).
|
|
76
76
|
- **writeToProject** (boolean, optional): If `true`, write generated files under `tests/accessibility/` in the project folder.
|
|
77
77
|
|
|
78
|
-
Returns JSON with `testCode`, `featureFile`, `stepDefCode`, `pageObjectCode` (and `_written` paths when writing).
|
|
78
|
+
Framework detection: language (TypeScript vs JavaScript vs Python), BDD (Cucumber, pytest-bdd, Behave), and Page Object pattern (e.g. `pages/` directory or `*Page.ts`, `*Page.js`, `*_page.py` files). Returns JSON with `testCode`, `featureFile`, `stepDefCode`, `pageObjectCode` (and `_written` paths when writing).
|
|
79
79
|
|
|
80
80
|
## Publishing to npm
|
|
81
81
|
|
package/detect-framework.js
CHANGED
|
@@ -9,7 +9,7 @@ const ALLOWED_BDD = ['cucumber', 'pytest-bdd', 'behave', 'none'];
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {string} parentProjectFolder - absolute or relative path to project root
|
|
12
|
-
* @returns {{ scriptType: 'typescript'|'python', bddFramework: string, pageObject: boolean, projectSummary: string }}
|
|
12
|
+
* @returns {{ scriptType: 'typescript'|'javascript'|'python', bddFramework: string, pageObject: boolean, projectSummary: string }}
|
|
13
13
|
*/
|
|
14
14
|
export function detectFramework(parentProjectFolder) {
|
|
15
15
|
const root = resolve(parentProjectFolder);
|
|
@@ -27,7 +27,7 @@ export function detectFramework(parentProjectFolder) {
|
|
|
27
27
|
let pageObject = false;
|
|
28
28
|
const summaryParts = [];
|
|
29
29
|
|
|
30
|
-
// Language:
|
|
30
|
+
// Language: Python first, then TypeScript vs JavaScript (Node)
|
|
31
31
|
const hasPackageJson = existsSync(join(root, 'package.json'));
|
|
32
32
|
const hasTsConfig = existsSync(join(root, 'tsconfig.json'));
|
|
33
33
|
const hasRequirements = existsSync(join(root, 'requirements.txt'));
|
|
@@ -42,18 +42,27 @@ export function detectFramework(parentProjectFolder) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
const hasTs = hasExtension(root, '.ts') || hasExtension(root, '.spec.ts');
|
|
45
|
+
const hasJs = hasExtension(root, '.js') || hasExtension(root, '.spec.js') || hasExtension(root, '.jsx') || hasExtension(root, '.spec.jsx');
|
|
45
46
|
const hasPy = hasExtension(root, '.py') || hasExtension(root, '_test.py');
|
|
46
47
|
|
|
47
48
|
if (hasPy && (hasRequirements || hasPyproject || hasPy)) {
|
|
48
49
|
scriptType = 'python';
|
|
49
50
|
summaryParts.push('Language: Python');
|
|
50
|
-
} else if (hasPackageJson || hasTsConfig || hasTs) {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
} else if (hasPackageJson || hasTsConfig || hasTs || hasJs) {
|
|
52
|
+
if (hasTsConfig || hasTs) {
|
|
53
|
+
scriptType = 'typescript';
|
|
54
|
+
summaryParts.push('Language: TypeScript');
|
|
55
|
+
} else if (hasJs) {
|
|
56
|
+
scriptType = 'javascript';
|
|
57
|
+
summaryParts.push('Language: JavaScript');
|
|
58
|
+
} else {
|
|
59
|
+
scriptType = 'typescript';
|
|
60
|
+
summaryParts.push('Language: TypeScript/JavaScript');
|
|
61
|
+
}
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
// BDD: Cucumber (package.json), pytest-bdd, Behave
|
|
56
|
-
if (scriptType === 'typescript' && hasPackageJson) {
|
|
65
|
+
if ((scriptType === 'typescript' || scriptType === 'javascript') && hasPackageJson) {
|
|
57
66
|
try {
|
|
58
67
|
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
59
68
|
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
@@ -83,21 +92,22 @@ export function detectFramework(parentProjectFolder) {
|
|
|
83
92
|
if (bddFramework === 'none' && hasFeatureFiles) summaryParts.push('Found .feature files');
|
|
84
93
|
} catch (_) {}
|
|
85
94
|
}
|
|
86
|
-
if (scriptType === 'typescript' && hasFeatureFiles && bddFramework === 'none') {
|
|
95
|
+
if ((scriptType === 'typescript' || scriptType === 'javascript') && hasFeatureFiles && bddFramework === 'none') {
|
|
87
96
|
summaryParts.push('Found .feature files (consider Cucumber)');
|
|
88
97
|
}
|
|
89
98
|
|
|
90
|
-
// Page Object: pages/ or *Page.ts
|
|
99
|
+
// Page Object: pages/ or *Page.ts, *Page.js, *_page.py
|
|
91
100
|
try {
|
|
92
101
|
if (existsSync(join(root, 'pages'))) {
|
|
93
102
|
pageObject = true;
|
|
94
103
|
summaryParts.push('Page Object: pages/ directory');
|
|
95
104
|
} else {
|
|
96
105
|
const pageTs = walk(root, (f) => f.endsWith('Page.ts') || f.endsWith('Page.tsx'));
|
|
106
|
+
const pageJs = walk(root, (f) => f.endsWith('Page.js') || f.endsWith('Page.jsx'));
|
|
97
107
|
const pagePy = walk(root, (f) => f.endsWith('_page.py') || f.endsWith('Page.py'));
|
|
98
|
-
if (pageTs.length || pagePy.length) {
|
|
108
|
+
if (pageTs.length || pageJs.length || pagePy.length) {
|
|
99
109
|
pageObject = true;
|
|
100
|
-
summaryParts.push('Page Object: *Page.ts / *_page.py files');
|
|
110
|
+
summaryParts.push('Page Object: *Page.ts / *Page.js / *_page.py files');
|
|
101
111
|
}
|
|
102
112
|
}
|
|
103
113
|
} catch (_) {}
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* GenAT MCP server: tool "GenAT" to generate accessibility tests via n8n.
|
|
4
|
-
* Inputs: url, parentProjectFolder (path to
|
|
4
|
+
* Inputs: url, parentProjectFolder (path to TypeScript, JavaScript, or Python Playwright project).
|
|
5
5
|
* Detects framework (language, BDD, Page Object), POSTs to n8n webhook, returns generated files.
|
|
6
6
|
*/
|
|
7
7
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
@@ -28,12 +28,12 @@ server.registerTool(
|
|
|
28
28
|
'GenAT',
|
|
29
29
|
{
|
|
30
30
|
description:
|
|
31
|
-
'Generate accessibility tests for a URL based on the project folder. Analyzes the page (DOM + a11y), detects project framework (TypeScript
|
|
31
|
+
'Generate accessibility tests for a URL based on the project folder. Analyzes the page (DOM + a11y), detects project framework (TypeScript, JavaScript, or Python, BDD, Page Object), and returns generated test files (feature, spec/step defs, page objects). Optionally write files to the project folder.',
|
|
32
32
|
inputSchema: {
|
|
33
33
|
url: z.string().describe('Page URL to analyze for accessibility (e.g. https://example.com)'),
|
|
34
34
|
parentProjectFolder: z
|
|
35
35
|
.string()
|
|
36
|
-
.describe('Absolute or relative path to the project root containing TypeScript or Python Playwright code'),
|
|
36
|
+
.describe('Absolute or relative path to the project root containing TypeScript, JavaScript, or Python Playwright code'),
|
|
37
37
|
writeToProject: z
|
|
38
38
|
.boolean()
|
|
39
39
|
.optional()
|
package/package.json
CHANGED
package/write-files.js
CHANGED
|
@@ -22,6 +22,7 @@ export async function writeGeneratedFiles(parentProjectFolder, data) {
|
|
|
22
22
|
|
|
23
23
|
const defaultNames = {
|
|
24
24
|
typescript: { spec: 'accessibility.spec.ts', steps: 'steps.ts', page: 'AccessibilityPage.ts' },
|
|
25
|
+
javascript: { spec: 'accessibility.spec.js', steps: 'steps.js', page: 'AccessibilityPage.js' },
|
|
25
26
|
python: { spec: 'accessibility_test.py', steps: 'step_definitions.py', page: 'accessibility_page.py' },
|
|
26
27
|
};
|
|
27
28
|
const names = defaultNames[scriptType] || defaultNames.typescript;
|