@rettangoli/vt 0.0.9 → 0.0.11
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/cli/generate.js +23 -30
- package/src/common.js +12 -10
- package/src/createSteps.js +5 -0
package/package.json
CHANGED
package/src/cli/generate.js
CHANGED
|
@@ -9,9 +9,8 @@ import {
|
|
|
9
9
|
readYaml,
|
|
10
10
|
} from "../common.js";
|
|
11
11
|
|
|
12
|
-
const libraryTemplatesPath = new URL(
|
|
13
|
-
const libraryStaticPath = new URL(
|
|
14
|
-
|
|
12
|
+
const libraryTemplatesPath = new URL("./templates", import.meta.url).pathname;
|
|
13
|
+
const libraryStaticPath = new URL("./static", import.meta.url).pathname;
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Main function that orchestrates the entire process
|
|
@@ -21,14 +20,14 @@ async function main(options) {
|
|
|
21
20
|
skipScreenshots = false,
|
|
22
21
|
vtPath = "./vt",
|
|
23
22
|
screenshotWaitTime = 0,
|
|
24
|
-
port = 3001
|
|
23
|
+
port = 3001,
|
|
25
24
|
} = options;
|
|
26
25
|
|
|
27
26
|
const specsPath = join(vtPath, "specs");
|
|
28
27
|
const mainConfigPath = "rettangoli.config.yaml";
|
|
29
28
|
const siteOutputPath = join(".rettangoli", "vt", "_site");
|
|
30
29
|
const candidatePath = join(siteOutputPath, "candidate");
|
|
31
|
-
|
|
30
|
+
|
|
32
31
|
// Read VT config from main rettangoli.config.yaml
|
|
33
32
|
let configData = {};
|
|
34
33
|
try {
|
|
@@ -38,32 +37,30 @@ async function main(options) {
|
|
|
38
37
|
console.log("Main config file not found, using defaults");
|
|
39
38
|
}
|
|
40
39
|
|
|
40
|
+
const configUrl = configData.url;
|
|
41
|
+
|
|
41
42
|
// Clear candidate directory
|
|
42
43
|
await rm(candidatePath, { recursive: true, force: true });
|
|
43
44
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
44
45
|
|
|
45
46
|
// Copy static files from library to site directory
|
|
46
47
|
await cp(libraryStaticPath, siteOutputPath, { recursive: true });
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
// Copy user's static files if they exist
|
|
49
50
|
const userStaticPath = join(vtPath, "static");
|
|
50
51
|
if (existsSync(userStaticPath)) {
|
|
51
52
|
await cp(userStaticPath, siteOutputPath, { recursive: true });
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
//
|
|
55
|
+
// Resolve template paths
|
|
55
56
|
const localTemplatesPath = join(vtPath, "templates");
|
|
56
|
-
|
|
57
57
|
const defaultTemplatePath = existsSync(join(localTemplatesPath, "default.html"))
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// Resolve index template path
|
|
58
|
+
? join(localTemplatesPath, "default.html")
|
|
59
|
+
: join(libraryTemplatesPath, "default.html");
|
|
62
60
|
const indexTemplatePath = existsSync(join(localTemplatesPath, "index.html"))
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
? join(localTemplatesPath, "index.html")
|
|
62
|
+
: join(libraryTemplatesPath, "index.html");
|
|
65
63
|
|
|
66
|
-
// Build template configuration for per-file/section templates
|
|
67
64
|
const templateConfig = {
|
|
68
65
|
defaultTemplate: defaultTemplatePath,
|
|
69
66
|
vtPath: vtPath,
|
|
@@ -74,40 +71,36 @@ async function main(options) {
|
|
|
74
71
|
specsPath,
|
|
75
72
|
defaultTemplatePath,
|
|
76
73
|
candidatePath,
|
|
77
|
-
templateConfig
|
|
74
|
+
templateConfig,
|
|
78
75
|
);
|
|
79
76
|
|
|
80
|
-
// Generate overview page
|
|
77
|
+
// Generate overview page
|
|
81
78
|
generateOverview(
|
|
82
79
|
generatedFiles,
|
|
83
80
|
indexTemplatePath,
|
|
84
81
|
join(siteOutputPath, "index.html"),
|
|
85
|
-
configData
|
|
82
|
+
configData,
|
|
86
83
|
);
|
|
87
84
|
|
|
85
|
+
// Take screenshots
|
|
88
86
|
if (!skipScreenshots) {
|
|
89
|
-
|
|
90
|
-
const server = startWebServer(
|
|
91
|
-
siteOutputPath,
|
|
92
|
-
vtPath,
|
|
93
|
-
port
|
|
94
|
-
);
|
|
87
|
+
const server = configUrl ? null : startWebServer(siteOutputPath, vtPath, port);
|
|
95
88
|
try {
|
|
96
|
-
// Take screenshots with specified concurrency
|
|
97
89
|
await takeScreenshots(
|
|
98
90
|
generatedFiles,
|
|
99
91
|
`http://localhost:${port}`,
|
|
100
92
|
candidatePath,
|
|
101
93
|
24,
|
|
102
|
-
screenshotWaitTime
|
|
94
|
+
screenshotWaitTime,
|
|
95
|
+
configUrl,
|
|
103
96
|
);
|
|
104
97
|
} finally {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
if (server) {
|
|
99
|
+
server.close();
|
|
100
|
+
console.log("Server stopped");
|
|
101
|
+
}
|
|
108
102
|
}
|
|
109
103
|
}
|
|
110
|
-
|
|
111
104
|
}
|
|
112
105
|
|
|
113
106
|
export default main;
|
package/src/common.js
CHANGED
|
@@ -83,9 +83,8 @@ function getAllFiles(dirPath, arrayOfFiles = []) {
|
|
|
83
83
|
* Extract frontmatter from content
|
|
84
84
|
*/
|
|
85
85
|
function extractFrontMatter(content) {
|
|
86
|
-
const frontMatterRegex = /^---\s*\n([\s\S]*?)\n---\s
|
|
86
|
+
const frontMatterRegex = /^---\s*\n([\s\S]*?)\n---\s*(\r?\n|$)/;
|
|
87
87
|
const match = content.match(frontMatterRegex);
|
|
88
|
-
|
|
89
88
|
if (!match) {
|
|
90
89
|
return {
|
|
91
90
|
content: content,
|
|
@@ -180,7 +179,6 @@ function startWebServer(artifactsDir, staticDir, port) {
|
|
|
180
179
|
const server = http.createServer((req, res) => {
|
|
181
180
|
const url = new URL(req.url, `http://localhost:${port}`);
|
|
182
181
|
let path = url.pathname;
|
|
183
|
-
|
|
184
182
|
// Default to index.html for root path
|
|
185
183
|
if (path === "/") {
|
|
186
184
|
path = "/index.html";
|
|
@@ -249,7 +247,8 @@ async function takeScreenshots(
|
|
|
249
247
|
serverUrl,
|
|
250
248
|
screenshotsDir,
|
|
251
249
|
concurrency = 8,
|
|
252
|
-
waitTime = 0
|
|
250
|
+
waitTime = 0,
|
|
251
|
+
configUrl = undefined,
|
|
253
252
|
) {
|
|
254
253
|
// Ensure screenshots directory exists
|
|
255
254
|
ensureDirectoryExists(screenshotsDir);
|
|
@@ -258,13 +257,13 @@ async function takeScreenshots(
|
|
|
258
257
|
console.log("Launching browser to take screenshots...");
|
|
259
258
|
const browser = await chromium.launch();
|
|
260
259
|
|
|
261
|
-
const takeAndSaveScreenshot = async (page, basePath, suffix =
|
|
260
|
+
const takeAndSaveScreenshot = async (page, basePath, suffix = "") => {
|
|
262
261
|
const finalPath = suffix ? `${basePath}-${suffix}` : basePath;
|
|
263
262
|
const tempPngPath = join(screenshotsDir, `${finalPath}.png`);
|
|
264
263
|
const screenshotPath = join(screenshotsDir, `${finalPath}.webp`);
|
|
265
264
|
ensureDirectoryExists(dirname(screenshotPath));
|
|
266
265
|
|
|
267
|
-
await page.screenshot({ path: tempPngPath, fullPage: true});
|
|
266
|
+
await page.screenshot({ path: tempPngPath, fullPage: true });
|
|
268
267
|
await sharp(tempPngPath).webp({ quality: 85 }).toFile(screenshotPath);
|
|
269
268
|
|
|
270
269
|
if (existsSync(tempPngPath)) {
|
|
@@ -288,10 +287,13 @@ async function takeScreenshots(
|
|
|
288
287
|
let screenshotIndex = 0;
|
|
289
288
|
|
|
290
289
|
try {
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
`${serverUrl}/candidate/${file.path.replace(/\\/g,
|
|
290
|
+
const frontMatterUrl = file.frontMatter?.url;
|
|
291
|
+
const constructedUrl = convertToHtmlExtension(
|
|
292
|
+
`${serverUrl}/candidate/${file.path.replace(/\\/g, "/")}`,
|
|
294
293
|
);
|
|
294
|
+
const url = frontMatterUrl ?? configUrl ?? constructedUrl;
|
|
295
|
+
const fileUrl = url.startsWith("http") ? url : new URL(url, serverUrl).href;
|
|
296
|
+
|
|
295
297
|
console.log(`Navigating to ${fileUrl}`);
|
|
296
298
|
await page.goto(fileUrl, { waitUntil: "networkidle" });
|
|
297
299
|
if (waitTime > 0) {
|
|
@@ -300,7 +302,7 @@ async function takeScreenshots(
|
|
|
300
302
|
const baseName = removeExtension(file.path);
|
|
301
303
|
|
|
302
304
|
const initialScreenshotPath = await takeAndSaveScreenshot(page, baseName);
|
|
303
|
-
console.log(`
|
|
305
|
+
console.log(`Screenshot saved: ${initialScreenshotPath}`);
|
|
304
306
|
|
|
305
307
|
const stepContext = {
|
|
306
308
|
baseName,
|
package/src/createSteps.js
CHANGED
|
@@ -48,6 +48,10 @@ async function move(page, args) {
|
|
|
48
48
|
await page.mouse.move(Number(args[0]), Number(args[1]));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
async function scroll(page, args){
|
|
52
|
+
await page.mouse.wheel(Number(args[0]), Number(args[1]));
|
|
53
|
+
}
|
|
54
|
+
|
|
51
55
|
async function rclick(page, args, context, selectedElement) {
|
|
52
56
|
if (selectedElement) {
|
|
53
57
|
await selectedElement.click({ button: 'right' });
|
|
@@ -106,6 +110,7 @@ export function createSteps(page, context) {
|
|
|
106
110
|
mouseUp,
|
|
107
111
|
move,
|
|
108
112
|
rclick,
|
|
113
|
+
scroll,
|
|
109
114
|
rMouseDown,
|
|
110
115
|
rMouseUp,
|
|
111
116
|
screenshot,
|