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 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/Python, BDD, Page Object), calls an n8n GenAT workflow, and returns (or writes) generated test files.
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
 
@@ -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: package.json + ts/spec vs requirements.txt / py
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
- scriptType = 'typescript';
52
- summaryParts.push('Language: TypeScript/JavaScript');
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 / *_page.py
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 TS or Python Playwright project).
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/Python, BDD, Page Object), and returns generated test files (feature, spec/step defs, page objects). Optionally write files to the project folder.',
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genat-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "mcpName": "io.github.asokans@oclc.org/genat",
5
5
  "description": "MCP server GenAT: generate accessibility tests via n8n workflow (url + project folder)",
6
6
  "type": "module",
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;