muagqa 1.4.2 → 1.4.3
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/package.json +1 -1
- package/src/generate-template.js +50 -0
- package/src/index.js +2 -1
- package/src/templateBuilder.js +42 -8
- package/src/templateMode.js +11 -3
package/package.json
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fetch from "node-fetch";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
|
|
6
|
+
export async function runTemplateGeneration(token) {
|
|
7
|
+
console.log(chalk.cyan("\n▶ Starting smart template generation…"));
|
|
8
|
+
console.log(chalk.gray("Using token:"), chalk.yellow(token));
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const res = await fetch(
|
|
12
|
+
"https://muagqa.vercel.app/api/cli/generate-templates",
|
|
13
|
+
{
|
|
14
|
+
method: "POST",
|
|
15
|
+
headers: { "Content-Type": "application/json" },
|
|
16
|
+
body: JSON.stringify({ token })
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const data = await res.json();
|
|
21
|
+
|
|
22
|
+
if (!res.ok || data.error) {
|
|
23
|
+
console.log(chalk.red("❌ Template generation failed:"), data.error);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Create output folder
|
|
28
|
+
const saveDir = path.join(process.cwd(), "generated-tests", "templates");
|
|
29
|
+
fs.mkdirSync(saveDir, { recursive: true });
|
|
30
|
+
|
|
31
|
+
console.log(chalk.green("\n✔ Templates received — writing files...\n"));
|
|
32
|
+
|
|
33
|
+
// Write each generated template
|
|
34
|
+
for (const [fileName, content] of Object.entries(data.templates)) {
|
|
35
|
+
const filePath = path.join(saveDir, fileName);
|
|
36
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
37
|
+
|
|
38
|
+
console.log(chalk.blue("➤ Created"), chalk.yellow(fileName));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(
|
|
42
|
+
chalk.green(
|
|
43
|
+
`\n✔ Template generation complete! Files saved in generated-tests/templates/\n`
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.error(chalk.red("💥 Template Engine Crash:"), err);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/index.js
CHANGED
package/src/templateBuilder.js
CHANGED
|
@@ -31,7 +31,7 @@ export function buildTemplate(testCase) {
|
|
|
31
31
|
const description = testCase.description || "";
|
|
32
32
|
const expected = testCase.expected || "";
|
|
33
33
|
const startUrl =
|
|
34
|
-
testCase.startUrl || testCase.url || testCase.start_url || "";
|
|
34
|
+
testCase.startUrl || testCase.url || testCase.start_url || "https://example.com";
|
|
35
35
|
|
|
36
36
|
const headerLines = [];
|
|
37
37
|
if (description) {
|
|
@@ -47,17 +47,51 @@ export function buildTemplate(testCase) {
|
|
|
47
47
|
const header = headerLines.length ? `${headerLines.join("\n")}\n` : "";
|
|
48
48
|
|
|
49
49
|
if (lines.length === 0) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const context = `${title} ${description} ${expected}`.toLowerCase();
|
|
51
|
+
const isLogin = context.includes("login") || context.includes("sign in");
|
|
52
|
+
const isSearch = context.includes("search");
|
|
53
|
+
const isCheckout = context.includes("checkout") || context.includes("payment");
|
|
54
|
+
|
|
55
|
+
lines.push(` await page.goto("${startUrl}");`);
|
|
56
|
+
lines.push(" await page.getByRole(\"combobox\").selectOption(\"en\");");
|
|
57
|
+
lines.push(
|
|
58
|
+
" await page.getByLabel(\"Username\").fill(\"user@example.com\");"
|
|
59
|
+
);
|
|
60
|
+
lines.push(
|
|
61
|
+
" await page.getByPlaceholder(\"Password\").fill(\"Password123!\");"
|
|
62
|
+
);
|
|
63
|
+
lines.push(" await page.getByRole(\"button\", { name: \"Show password\" }).click();");
|
|
64
|
+
lines.push(" await page.getByTestId(\"two-factor\").fill(\"123456\");");
|
|
65
|
+
lines.push(" await page.getByTitle(\"Help\").click();");
|
|
66
|
+
lines.push(" await page.getByAltText(\"Company logo\").click();");
|
|
67
|
+
lines.push(" await page.locator(\"input[name='remember']\").check();");
|
|
68
|
+
lines.push(" await page.locator(\"xpath=//button[contains(., 'Continue')]\").click();");
|
|
69
|
+
|
|
70
|
+
if (isSearch) {
|
|
71
|
+
lines.push(
|
|
72
|
+
" await page.getByRole(\"searchbox\", { name: \"Search\" }).fill(\"example query\");"
|
|
73
|
+
);
|
|
74
|
+
lines.push(" await page.getByText(\"Search\", { exact: true }).click();");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (isCheckout) {
|
|
78
|
+
lines.push(" await page.getByRole(\"link\", { name: \"Cart\" }).click();");
|
|
79
|
+
lines.push(" await page.getByRole(\"button\", { name: \"Checkout\" }).click();");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (isLogin) {
|
|
83
|
+
lines.push(" await page.getByRole(\"button\", { name: \"Login\" }).click();");
|
|
53
84
|
} else {
|
|
54
|
-
lines.push("
|
|
85
|
+
lines.push(" await page.getByRole(\"button\", { name: \"Submit\" }).click();");
|
|
55
86
|
}
|
|
56
|
-
|
|
57
|
-
lines.push("
|
|
87
|
+
|
|
88
|
+
lines.push(" await expect(page).toHaveURL(/dashboard|home|welcome/);");
|
|
89
|
+
lines.push(
|
|
90
|
+
" await expect(page.getByRole(\"status\")).toContainText(\"Success\");"
|
|
91
|
+
);
|
|
58
92
|
}
|
|
59
93
|
|
|
60
|
-
return `import { test } from "@playwright/test";
|
|
94
|
+
return `import { test, expect } from "@playwright/test";
|
|
61
95
|
|
|
62
96
|
${header}test("${title}", async ({ page }) => {
|
|
63
97
|
${lines.join("\n")}
|
package/src/templateMode.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import inquirer from "inquirer";
|
|
3
4
|
import chalk from "chalk";
|
|
4
5
|
import { validateSessionToken } from "./api.js";
|
|
5
6
|
import { buildTemplate } from "./templateBuilder.js";
|
|
6
7
|
|
|
7
8
|
export async function generateTemplateTests(sessionToken) {
|
|
8
|
-
|
|
9
|
+
let token = sessionToken || process.env.MUAGQA_SESSION;
|
|
9
10
|
|
|
10
11
|
if (!token) {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
const answer = await inquirer.prompt([
|
|
13
|
+
{
|
|
14
|
+
type: "input",
|
|
15
|
+
name: "token",
|
|
16
|
+
message: "Enter your one-time session token:",
|
|
17
|
+
validate: v => v.trim() !== "" || "Token is required."
|
|
18
|
+
}
|
|
19
|
+
]);
|
|
20
|
+
token = answer.token;
|
|
13
21
|
}
|
|
14
22
|
|
|
15
23
|
const result = await validateSessionToken(token);
|