genat-mcp 1.0.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 +92 -0
- package/detect-framework.js +134 -0
- package/index.js +155 -0
- package/package.json +22 -0
- package/write-files.js +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# GenAT MCP
|
|
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.
|
|
4
|
+
|
|
5
|
+
Full setup (n8n workflow, services, usage) is in the [project README](../README.md).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
**If the package is published to npm** (otherwise you get 404):
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Global (binary on PATH)
|
|
13
|
+
npm install -g genat-mcp
|
|
14
|
+
|
|
15
|
+
# Or local / project
|
|
16
|
+
npm install genat-mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Until published, or for development**, install from the repo:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# From this repo root
|
|
23
|
+
cd mcp-genat && npm install
|
|
24
|
+
# Then in Cursor MCP use: node with args ["/path/to/n8n_playwright_tests/mcp-genat/index.js"]
|
|
25
|
+
|
|
26
|
+
# Or from another project (local path)
|
|
27
|
+
npm install /path/to/n8n_playwright_tests/mcp-genat
|
|
28
|
+
# Then use npx genat-mcp or node node_modules/genat-mcp/index.js
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Environment
|
|
32
|
+
|
|
33
|
+
| Variable | Required | Default | Description |
|
|
34
|
+
|--------------------|----------|---------|-------------|
|
|
35
|
+
| **N8N_WEBHOOK_URL** | No | `http://localhost:5678/webhook-test/webhook-genat` | n8n GenAT webhook URL. Set this if your n8n instance is elsewhere (e.g. `https://your-n8n-host/webhook-test/webhook-genat`). |
|
|
36
|
+
|
|
37
|
+
## Cursor MCP config
|
|
38
|
+
|
|
39
|
+
**Using npx (local install):**
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"mcpServers": {
|
|
44
|
+
"GenAT": {
|
|
45
|
+
"command": "npx",
|
|
46
|
+
"args": ["genat-mcp"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Using global install:**
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"GenAT": {
|
|
58
|
+
"command": "genat-mcp"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If the global binary is not on PATH, use the full path, e.g. `node $(npm root -g)/genat-mcp/index.js`.
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- **Node.js** 20+
|
|
69
|
+
- **n8n** with the [GenAT workflow](../workflows/genat-accessibility-tests.json) imported and activated (webhook path `webhook-test/webhook-genat`)
|
|
70
|
+
- **DOM Analyzer** and **Accessibility Analyzer** services running (see main README: `npm run services` from repo root)
|
|
71
|
+
|
|
72
|
+
## Tool: GenAT
|
|
73
|
+
|
|
74
|
+
- **url** (string): Page URL to analyze for accessibility.
|
|
75
|
+
- **parentProjectFolder** (string): Path to the project root (TypeScript or Python Playwright).
|
|
76
|
+
- **writeToProject** (boolean, optional): If `true`, write generated files under `tests/accessibility/` in the project folder.
|
|
77
|
+
|
|
78
|
+
Returns JSON with `testCode`, `featureFile`, `stepDefCode`, `pageObjectCode` (and `_written` paths when writing).
|
|
79
|
+
|
|
80
|
+
## Publishing to npm
|
|
81
|
+
|
|
82
|
+
Until the package is published, `npm install genat-mcp` returns 404. To publish:
|
|
83
|
+
|
|
84
|
+
1. Replace `your-username` in `package.json` (`repository`, `homepage`, `bugs`) and in `server.json` if you use the MCP Registry.
|
|
85
|
+
2. **npm requires 2FA or a granular access token with "bypass 2FA" enabled** to publish. Enable 2FA on your npm account (Account → "Require two-factor authentication for writes"), or create an [Automation / granular token](https://docs.npmjs.com/creating-and-viewing-access-tokens) with "bypass 2FA for publish" and use it: `npm login` (paste token as password) or set `NPM_CONFIG_//registry.npmjs.org/:_authToken=your-token`.
|
|
86
|
+
3. From this directory: `npm publish` (or `npm publish --access public` for a scoped package).
|
|
87
|
+
|
|
88
|
+
After publishing, the "Install from npm" instructions above work.
|
|
89
|
+
|
|
90
|
+
## Publishing to the MCP Registry
|
|
91
|
+
|
|
92
|
+
To list this server on the [MCP Registry](https://registry.modelcontextprotocol.io): use your GitHub identity in `package.json` and `server.json`, publish to npm (see above), install [mcp-publisher](https://github.com/modelcontextprotocol/registry/releases), run `mcp-publisher login github` and `mcp-publisher publish`.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect project framework from parent folder: language, BDD framework, Page Object pattern.
|
|
3
|
+
* Used by GenAT MCP before calling n8n.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, readdirSync, existsSync } from 'fs';
|
|
6
|
+
import { join, resolve } from 'path';
|
|
7
|
+
|
|
8
|
+
const ALLOWED_BDD = ['cucumber', 'pytest-bdd', 'behave', 'none'];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} parentProjectFolder - absolute or relative path to project root
|
|
12
|
+
* @returns {{ scriptType: 'typescript'|'python', bddFramework: string, pageObject: boolean, projectSummary: string }}
|
|
13
|
+
*/
|
|
14
|
+
export function detectFramework(parentProjectFolder) {
|
|
15
|
+
const root = resolve(parentProjectFolder);
|
|
16
|
+
if (!existsSync(root) || !readdirSync(root).length) {
|
|
17
|
+
return {
|
|
18
|
+
scriptType: 'typescript',
|
|
19
|
+
bddFramework: 'none',
|
|
20
|
+
pageObject: false,
|
|
21
|
+
projectSummary: 'Folder not found or empty; using defaults.',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let scriptType = 'typescript';
|
|
26
|
+
let bddFramework = 'none';
|
|
27
|
+
let pageObject = false;
|
|
28
|
+
const summaryParts = [];
|
|
29
|
+
|
|
30
|
+
// Language: package.json + ts/spec vs requirements.txt / py
|
|
31
|
+
const hasPackageJson = existsSync(join(root, 'package.json'));
|
|
32
|
+
const hasTsConfig = existsSync(join(root, 'tsconfig.json'));
|
|
33
|
+
const hasRequirements = existsSync(join(root, 'requirements.txt'));
|
|
34
|
+
const hasPyproject = existsSync(join(root, 'pyproject.toml'));
|
|
35
|
+
|
|
36
|
+
function hasExtension(dir, ext) {
|
|
37
|
+
try {
|
|
38
|
+
const files = walk(root, (f) => f.endsWith(ext));
|
|
39
|
+
return files.length > 0;
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const hasTs = hasExtension(root, '.ts') || hasExtension(root, '.spec.ts');
|
|
45
|
+
const hasPy = hasExtension(root, '.py') || hasExtension(root, '_test.py');
|
|
46
|
+
|
|
47
|
+
if (hasPy && (hasRequirements || hasPyproject || hasPy)) {
|
|
48
|
+
scriptType = 'python';
|
|
49
|
+
summaryParts.push('Language: Python');
|
|
50
|
+
} else if (hasPackageJson || hasTsConfig || hasTs) {
|
|
51
|
+
scriptType = 'typescript';
|
|
52
|
+
summaryParts.push('Language: TypeScript/JavaScript');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// BDD: Cucumber (package.json), pytest-bdd, Behave
|
|
56
|
+
if (scriptType === 'typescript' && hasPackageJson) {
|
|
57
|
+
try {
|
|
58
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
59
|
+
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
60
|
+
if (deps['@cucumber/cucumber'] || deps['cucumber']) {
|
|
61
|
+
bddFramework = 'cucumber';
|
|
62
|
+
summaryParts.push('BDD: Cucumber');
|
|
63
|
+
}
|
|
64
|
+
} catch (_) {}
|
|
65
|
+
}
|
|
66
|
+
const hasFeatureFiles = hasExtension(root, '.feature');
|
|
67
|
+
if (scriptType === 'python') {
|
|
68
|
+
try {
|
|
69
|
+
if (hasRequirements) {
|
|
70
|
+
const req = readFileSync(join(root, 'requirements.txt'), 'utf8');
|
|
71
|
+
if (/pytest-bdd/i.test(req)) {
|
|
72
|
+
bddFramework = 'pytest-bdd';
|
|
73
|
+
summaryParts.push('BDD: pytest-bdd');
|
|
74
|
+
} else if (/behave/i.test(req)) {
|
|
75
|
+
bddFramework = 'behave';
|
|
76
|
+
summaryParts.push('BDD: Behave');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (bddFramework === 'none' && existsSync(join(root, 'features'))) {
|
|
80
|
+
bddFramework = 'behave';
|
|
81
|
+
summaryParts.push('BDD: Behave (features/ present)');
|
|
82
|
+
}
|
|
83
|
+
if (bddFramework === 'none' && hasFeatureFiles) summaryParts.push('Found .feature files');
|
|
84
|
+
} catch (_) {}
|
|
85
|
+
}
|
|
86
|
+
if (scriptType === 'typescript' && hasFeatureFiles && bddFramework === 'none') {
|
|
87
|
+
summaryParts.push('Found .feature files (consider Cucumber)');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Page Object: pages/ or *Page.ts / *_page.py
|
|
91
|
+
try {
|
|
92
|
+
if (existsSync(join(root, 'pages'))) {
|
|
93
|
+
pageObject = true;
|
|
94
|
+
summaryParts.push('Page Object: pages/ directory');
|
|
95
|
+
} else {
|
|
96
|
+
const pageTs = walk(root, (f) => f.endsWith('Page.ts') || f.endsWith('Page.tsx'));
|
|
97
|
+
const pagePy = walk(root, (f) => f.endsWith('_page.py') || f.endsWith('Page.py'));
|
|
98
|
+
if (pageTs.length || pagePy.length) {
|
|
99
|
+
pageObject = true;
|
|
100
|
+
summaryParts.push('Page Object: *Page.ts / *_page.py files');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} catch (_) {}
|
|
104
|
+
|
|
105
|
+
const projectSummary = summaryParts.length ? summaryParts.join('; ') : 'No framework hints detected.';
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
scriptType,
|
|
109
|
+
bddFramework: ALLOWED_BDD.includes(bddFramework) ? bddFramework : 'none',
|
|
110
|
+
pageObject,
|
|
111
|
+
projectSummary,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {string} dir
|
|
117
|
+
* @param {(f: string) => boolean} predicate
|
|
118
|
+
* @param {string[]} [acc]
|
|
119
|
+
* @returns {string[]}
|
|
120
|
+
*/
|
|
121
|
+
function walk(dir, predicate, acc = []) {
|
|
122
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
123
|
+
for (const e of entries) {
|
|
124
|
+
const full = join(dir, e.name);
|
|
125
|
+
if (e.isDirectory()) {
|
|
126
|
+
if (e.name !== 'node_modules' && e.name !== '.git' && e.name !== '__pycache__' && e.name !== '.venv' && e.name !== 'venv') {
|
|
127
|
+
walk(full, predicate, acc);
|
|
128
|
+
}
|
|
129
|
+
} else if (predicate(e.name)) {
|
|
130
|
+
acc.push(e.name);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return acc;
|
|
134
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* GenAT MCP server: tool "GenAT" to generate accessibility tests via n8n.
|
|
4
|
+
* Inputs: url, parentProjectFolder (path to TS or Python Playwright project).
|
|
5
|
+
* Detects framework (language, BDD, Page Object), POSTs to n8n webhook, returns generated files.
|
|
6
|
+
*/
|
|
7
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { detectFramework } from './detect-framework.js';
|
|
11
|
+
import { writeGeneratedFiles } from './write-files.js';
|
|
12
|
+
|
|
13
|
+
const N8N_WEBHOOK_URL = process.env.N8N_WEBHOOK_URL || 'http://localhost:5678/webhook-test/webhook-genat';
|
|
14
|
+
|
|
15
|
+
const server = new McpServer(
|
|
16
|
+
{
|
|
17
|
+
name: 'GenAT',
|
|
18
|
+
version: '1.0.0',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
capabilities: {
|
|
22
|
+
tools: {},
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
server.registerTool(
|
|
28
|
+
'GenAT',
|
|
29
|
+
{
|
|
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.',
|
|
32
|
+
inputSchema: {
|
|
33
|
+
url: z.string().describe('Page URL to analyze for accessibility (e.g. https://example.com)'),
|
|
34
|
+
parentProjectFolder: z
|
|
35
|
+
.string()
|
|
36
|
+
.describe('Absolute or relative path to the project root containing TypeScript or Python Playwright code'),
|
|
37
|
+
writeToProject: z
|
|
38
|
+
.boolean()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('If true, write generated files into the project folder (e.g. tests/accessibility/)'),
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
async ({ url, parentProjectFolder, writeToProject }) => {
|
|
44
|
+
if (!url || typeof url !== 'string') {
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'Missing or invalid "url"' }) }],
|
|
47
|
+
isError: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let framework;
|
|
52
|
+
try {
|
|
53
|
+
framework = detectFramework(parentProjectFolder || '.');
|
|
54
|
+
} catch (err) {
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: JSON.stringify({
|
|
60
|
+
error: 'Framework detection failed',
|
|
61
|
+
message: err instanceof Error ? err.message : String(err),
|
|
62
|
+
fallback: { scriptType: 'typescript', bddFramework: 'none', pageObject: false },
|
|
63
|
+
}),
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
isError: true,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const body = {
|
|
71
|
+
url,
|
|
72
|
+
scriptType: framework.scriptType,
|
|
73
|
+
bddFramework: framework.bddFramework,
|
|
74
|
+
pageObject: framework.pageObject,
|
|
75
|
+
projectSummary: framework.projectSummary,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
let response;
|
|
79
|
+
try {
|
|
80
|
+
response = await fetch(N8N_WEBHOOK_URL, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: { 'Content-Type': 'application/json' },
|
|
83
|
+
body: JSON.stringify(body),
|
|
84
|
+
});
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return {
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: 'text',
|
|
90
|
+
text: JSON.stringify({
|
|
91
|
+
error: 'Failed to call n8n webhook',
|
|
92
|
+
message: err instanceof Error ? err.message : String(err),
|
|
93
|
+
hint: 'Set N8N_WEBHOOK_URL to your n8n webhook URL (e.g. https://your-n8n/webhook-test/webhook-genat)',
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
isError: true,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const text = await response.text();
|
|
103
|
+
return {
|
|
104
|
+
content: [
|
|
105
|
+
{
|
|
106
|
+
type: 'text',
|
|
107
|
+
text: JSON.stringify({
|
|
108
|
+
error: `n8n returned ${response.status}`,
|
|
109
|
+
body: text.slice(0, 1000),
|
|
110
|
+
}),
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
isError: true,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let data;
|
|
118
|
+
try {
|
|
119
|
+
data = await response.json();
|
|
120
|
+
} catch {
|
|
121
|
+
return {
|
|
122
|
+
content: [{ type: 'text', text: 'n8n response was not JSON' }],
|
|
123
|
+
isError: true,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (writeToProject && parentProjectFolder && data) {
|
|
128
|
+
try {
|
|
129
|
+
const written = writeGeneratedFiles(parentProjectFolder, data);
|
|
130
|
+
data._written = written;
|
|
131
|
+
} catch (err) {
|
|
132
|
+
data._writeError = err instanceof Error ? err.message : String(err);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
content: [
|
|
138
|
+
{
|
|
139
|
+
type: 'text',
|
|
140
|
+
text: JSON.stringify(data, null, 2),
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
async function main() {
|
|
148
|
+
const transport = new StdioServerTransport();
|
|
149
|
+
await server.connect(transport);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
main().catch((error) => {
|
|
153
|
+
console.error('GenAT MCP server error:', error);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "genat-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"mcpName": "io.github.asokans@oclc.org/genat",
|
|
5
|
+
"description": "MCP server GenAT: generate accessibility tests via n8n workflow (url + project folder)",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "index.js",
|
|
8
|
+
"bin": { "genat-mcp": "index.js" },
|
|
9
|
+
"engines": { "node": ">=20" },
|
|
10
|
+
"files": ["index.js", "detect-framework.js", "write-files.js"],
|
|
11
|
+
"keywords": ["mcp", "accessibility", "playwright", "n8n", "model-context-protocol", "a11y", "testing"],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://git-m1.shr.oclc.org/scm/automation/n8n_playwright_tests.git"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://git-m1.shr.oclc.org/scm/automation/n8n_playwright_tests#readme",
|
|
17
|
+
"bugs": { "url": "https://git-m1.shr.oclc.org/scm/automation/n8n_playwright_tests/issues" },
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
20
|
+
"zod": "^3.25.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/write-files.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write generated accessibility test files into the project folder.
|
|
3
|
+
* Uses suggested paths from the workflow response when present.
|
|
4
|
+
*/
|
|
5
|
+
import { writeFile, mkdir } from 'fs/promises';
|
|
6
|
+
import { join, resolve } from 'path';
|
|
7
|
+
|
|
8
|
+
const DEFAULT_DIR = 'tests/accessibility';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} parentProjectFolder - project root path
|
|
12
|
+
* @param {{ testCode?: string, scriptType?: string, featureFile?: string, stepDefCode?: string, pageObjectCode?: string, suggestedPaths?: Record<string, string> }} data - workflow response
|
|
13
|
+
* @returns {string[]} list of written file paths
|
|
14
|
+
*/
|
|
15
|
+
export async function writeGeneratedFiles(parentProjectFolder, data) {
|
|
16
|
+
const root = resolve(parentProjectFolder);
|
|
17
|
+
const baseDir = join(root, DEFAULT_DIR);
|
|
18
|
+
await mkdir(baseDir, { recursive: true });
|
|
19
|
+
|
|
20
|
+
const written = [];
|
|
21
|
+
const scriptType = (data.scriptType || 'typescript').toLowerCase();
|
|
22
|
+
|
|
23
|
+
const defaultNames = {
|
|
24
|
+
typescript: { spec: 'accessibility.spec.ts', steps: 'steps.ts', page: 'AccessibilityPage.ts' },
|
|
25
|
+
python: { spec: 'accessibility_test.py', steps: 'step_definitions.py', page: 'accessibility_page.py' },
|
|
26
|
+
};
|
|
27
|
+
const names = defaultNames[scriptType] || defaultNames.typescript;
|
|
28
|
+
const suggested = data.suggestedPaths || {};
|
|
29
|
+
|
|
30
|
+
if (data.testCode) {
|
|
31
|
+
const relPath = suggested.spec || join(DEFAULT_DIR, names.spec);
|
|
32
|
+
await writeFile(join(root, relPath), data.testCode, 'utf8');
|
|
33
|
+
written.push(relPath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (data.featureFile) {
|
|
37
|
+
const relPath = suggested.feature || join(DEFAULT_DIR, 'accessibility.feature');
|
|
38
|
+
await writeFile(join(root, relPath), data.featureFile, 'utf8');
|
|
39
|
+
written.push(relPath);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (data.stepDefCode) {
|
|
43
|
+
const relPath = suggested.stepDef || join(DEFAULT_DIR, names.steps);
|
|
44
|
+
await writeFile(join(root, relPath), data.stepDefCode, 'utf8');
|
|
45
|
+
written.push(relPath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (data.pageObjectCode) {
|
|
49
|
+
const relPath = suggested.pageObject || join(DEFAULT_DIR, names.page);
|
|
50
|
+
await writeFile(join(root, relPath), data.pageObjectCode, 'utf8');
|
|
51
|
+
written.push(relPath);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return written;
|
|
55
|
+
}
|