2024-07-23 16:25:11 +08:00
|
|
|
import { tmpdir } from 'os';
|
|
|
|
|
import { basename, join } from 'path';
|
|
|
|
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
|
|
|
import { randomUUID } from 'crypto';
|
|
|
|
|
import assert from 'assert';
|
|
|
|
|
import { Rect } from './types';
|
|
|
|
|
|
|
|
|
|
interface PkgInfo {
|
|
|
|
|
name: string;
|
|
|
|
|
version: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let pkg: PkgInfo | undefined;
|
|
|
|
|
export function getPkgInfo(): PkgInfo {
|
|
|
|
|
if (pkg) {
|
|
|
|
|
return pkg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let pkgJsonFile = '';
|
|
|
|
|
if (existsSync(join(__dirname, '../package.json'))) {
|
|
|
|
|
pkgJsonFile = join(__dirname, '../package.json');
|
|
|
|
|
} else if (existsSync(join(__dirname, '../../../package.json'))) {
|
|
|
|
|
pkgJsonFile = join(__dirname, '../../../package.json');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkgJsonFile) {
|
|
|
|
|
const { name, version } = JSON.parse(readFileSync(pkgJsonFile, 'utf-8'));
|
|
|
|
|
pkg = { name, version };
|
|
|
|
|
return pkg;
|
|
|
|
|
} else {
|
|
|
|
|
return {
|
|
|
|
|
name: 'midscene-unknown-page-name',
|
|
|
|
|
version: '0.0.0',
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let logDir = join(process.cwd(), './midscene_run/');
|
|
|
|
|
let logEnvReady = false;
|
|
|
|
|
export const insightDumpFileExt = 'insight-dump.json';
|
2024-07-25 13:40:46 +08:00
|
|
|
export const groupedActionDumpFileExt = 'web-dump.json';
|
2024-07-23 16:25:11 +08:00
|
|
|
|
|
|
|
|
export function getDumpDir() {
|
|
|
|
|
return logDir;
|
|
|
|
|
}
|
2024-08-01 15:46:40 +08:00
|
|
|
|
2024-07-23 16:25:11 +08:00
|
|
|
export function setDumpDir(dir: string) {
|
|
|
|
|
logDir = dir;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 15:46:40 +08:00
|
|
|
export function getDumpDirPath(type: 'dump' | 'cache') {
|
|
|
|
|
return join(getDumpDir(), type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function writeDumpFile(opts: {
|
|
|
|
|
fileName: string;
|
|
|
|
|
fileExt: string;
|
|
|
|
|
fileContent: string;
|
|
|
|
|
type?: 'dump' | 'cache';
|
|
|
|
|
}) {
|
|
|
|
|
const { fileName, fileExt, fileContent, type = 'dump' } = opts;
|
|
|
|
|
const targetDir = getDumpDirPath(type);
|
|
|
|
|
if (!existsSync(targetDir)) {
|
|
|
|
|
mkdirSync(targetDir, { recursive: true });
|
|
|
|
|
}
|
2024-07-23 16:25:11 +08:00
|
|
|
// Ensure directory exists
|
|
|
|
|
if (!logEnvReady) {
|
2024-08-01 15:46:40 +08:00
|
|
|
assert(targetDir, 'logDir should be set before writing dump file');
|
2024-07-23 16:25:11 +08:00
|
|
|
|
|
|
|
|
// gitIgnore in the parent directory
|
2024-08-01 15:46:40 +08:00
|
|
|
const gitIgnorePath = join(targetDir, '../../.gitignore');
|
2024-07-23 16:25:11 +08:00
|
|
|
let gitIgnoreContent = '';
|
|
|
|
|
if (existsSync(gitIgnorePath)) {
|
|
|
|
|
gitIgnoreContent = readFileSync(gitIgnorePath, 'utf-8');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ignore the log folder
|
|
|
|
|
const logDirName = basename(logDir);
|
|
|
|
|
if (!gitIgnoreContent.includes(`${logDirName}/`)) {
|
|
|
|
|
writeFileSync(
|
|
|
|
|
gitIgnorePath,
|
2024-08-01 19:28:30 +08:00
|
|
|
`${gitIgnoreContent}\n# MidScene.js dump files\n${logDirName}/report\n${logDirName}/dump-logger\n`,
|
2024-07-23 16:25:11 +08:00
|
|
|
'utf-8',
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
logEnvReady = true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-01 15:46:40 +08:00
|
|
|
const filePath = join(targetDir, `${fileName}.${fileExt}`);
|
2024-07-23 16:25:11 +08:00
|
|
|
writeFileSync(filePath, fileContent);
|
2024-08-01 15:46:40 +08:00
|
|
|
|
|
|
|
|
if (type === 'dump') {
|
|
|
|
|
copyFileSync(filePath, join(targetDir, `latest.${fileExt}`));
|
|
|
|
|
}
|
2024-07-23 16:25:11 +08:00
|
|
|
|
|
|
|
|
return filePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getTmpDir() {
|
|
|
|
|
const path = join(tmpdir(), getPkgInfo().name);
|
|
|
|
|
mkdirSync(path, { recursive: true });
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-28 08:49:57 +08:00
|
|
|
export function getTmpFile(fileExtWithoutDot: string) {
|
|
|
|
|
const filename = `${randomUUID()}.${fileExtWithoutDot}`;
|
2024-07-23 16:25:11 +08:00
|
|
|
return join(getTmpDir(), filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function overlapped(container: Rect, target: Rect) {
|
|
|
|
|
// container and the target have some part overlapped
|
|
|
|
|
return (
|
|
|
|
|
container.left < target.left + target.width &&
|
|
|
|
|
container.left + container.width > target.left &&
|
|
|
|
|
container.top < target.top + target.height &&
|
|
|
|
|
container.top + container.height > target.top
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function sleep(ms: number) {
|
|
|
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const commonScreenshotParam = { type: 'jpeg', quality: 75 } as any;
|