frame.simulator 1.0.2 → 1.0.4
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/batch.ts +154 -15
- package/command.ts +1 -1
- package/commandHandler.ts +5 -7
- package/dist/batch.d.ts +14 -0
- package/dist/batch.js +209 -0
- package/dist/command-server.d.ts +3 -0
- package/dist/command.d.ts +6 -0
- package/dist/command.js +10 -0
- package/dist/commandHandler.d.ts +6 -0
- package/dist/commandHandler.js +25 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +11 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +68 -0
- package/dist/simulator.d.ts +11 -0
- package/dist/simulator.js +85 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.js +2 -0
- package/draw.json +25 -0
- package/index.ts +1 -0
- package/main.ts +73 -0
- package/package.json +12 -3
- package/simulator.ts +3 -15
package/batch.ts
CHANGED
|
@@ -1,11 +1,137 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
1
3
|
import { Command } from './command';
|
|
2
4
|
import { TUserAction } from './types';
|
|
3
5
|
|
|
4
|
-
const PORT: number = parseInt(process.env.PORT || '3010', 10);
|
|
5
|
-
|
|
6
6
|
export class Batch {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
private filename: string;
|
|
8
|
+
port: number;
|
|
9
|
+
|
|
10
|
+
constructor(filename: string, port: number = 3010) {
|
|
11
|
+
const batchFilePath = path.join(process.cwd(), filename);
|
|
12
|
+
this.filename = batchFilePath;
|
|
13
|
+
this.port = port;
|
|
14
|
+
|
|
15
|
+
// Check if batch.json exists
|
|
16
|
+
if (!fs.existsSync(batchFilePath)) {
|
|
17
|
+
console.error(
|
|
18
|
+
'Error: batch.json file not found in the current directory',
|
|
19
|
+
);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async run(
|
|
25
|
+
handleCommand: (batch: Batch, item: any, index: number) => Promise<void>,
|
|
26
|
+
) {
|
|
27
|
+
try {
|
|
28
|
+
// Read the batch.json file
|
|
29
|
+
const fileContent = fs.readFileSync(this.filename, 'utf-8');
|
|
30
|
+
|
|
31
|
+
// Parse the JSON content
|
|
32
|
+
let batchData;
|
|
33
|
+
try {
|
|
34
|
+
batchData = JSON.parse(fileContent);
|
|
35
|
+
} catch (parseError) {
|
|
36
|
+
console.error('Error: Invalid JSON in batch.json file');
|
|
37
|
+
console.error(parseError);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
console.log('Processing batch.json...');
|
|
41
|
+
console.log('='.repeat(50));
|
|
42
|
+
|
|
43
|
+
// Check if batchData is an array or object
|
|
44
|
+
if (Array.isArray(batchData)) {
|
|
45
|
+
// If it's an array of objects, process each object sequentially
|
|
46
|
+
for (let index = 0; index < batchData.length; index++) {
|
|
47
|
+
// console.log(`Processing item ${index + 1}/${batchData.length}...`);
|
|
48
|
+
const item = batchData[index];
|
|
49
|
+
if (typeof item === 'object' && item !== null) {
|
|
50
|
+
// Print all keys in the object
|
|
51
|
+
await handleCommand(this, item, index + 1);
|
|
52
|
+
} else {
|
|
53
|
+
console.log(` Not an object: ${item}`);
|
|
54
|
+
}
|
|
55
|
+
console.log('');
|
|
56
|
+
}
|
|
57
|
+
} else if (typeof batchData === 'object' && batchData !== null) {
|
|
58
|
+
// If it's a single object, print its keys
|
|
59
|
+
console.log('Root object keys:');
|
|
60
|
+
const keys = Object.keys(batchData);
|
|
61
|
+
keys.forEach((key) => {
|
|
62
|
+
console.log(` Key: ${key}`);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// If any values are also objects, print their keys too
|
|
66
|
+
keys.forEach((key) => {
|
|
67
|
+
const value = batchData[key];
|
|
68
|
+
if (
|
|
69
|
+
typeof value === 'object' &&
|
|
70
|
+
value !== null &&
|
|
71
|
+
!Array.isArray(value)
|
|
72
|
+
) {
|
|
73
|
+
console.log(`\nKeys in "${key}" object:`);
|
|
74
|
+
Object.keys(value).forEach((subKey) => {
|
|
75
|
+
console.log(` Key: ${subKey}`);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
console.log(
|
|
81
|
+
'Error: batch.json should contain an object or array of objects',
|
|
82
|
+
);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('Error processing batch.json:');
|
|
87
|
+
console.error(error);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async handleDrawFrame(item: any, index: number) {
|
|
93
|
+
const coordinates = item.payload.coordinates;
|
|
94
|
+
console.log(` Command[${index}]: MainDrawFrame`);
|
|
95
|
+
await this.selectButtonSafe('FDOptions.button.draw-frame');
|
|
96
|
+
|
|
97
|
+
const coords: { x: number; y: number }[] = coordinates.points;
|
|
98
|
+
for (const point of coords) {
|
|
99
|
+
console.log(` Drawing point: (${point.x}, ${point.y})`);
|
|
100
|
+
// Small delay between points to simulate drawing
|
|
101
|
+
// await new Promise(resolve => setTimeout(resolve, 500));
|
|
102
|
+
await this.sampleClickCanvasDrawAt('canvas.draw', point.x, point.y); // Example click to trigger drawing (replace with actual coordinates if needed)
|
|
103
|
+
}
|
|
104
|
+
await this.selectButtonSafe('Finish.button.start-transformation'); // Example button click after drawing (replace with actual testId if needed)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async handleScaleFrame(item: any, index: number) {
|
|
108
|
+
const length = item.payload.length;
|
|
109
|
+
const height = item.payload.height;
|
|
110
|
+
console.log(` Command[${index}]: MainScaleFrame`);
|
|
111
|
+
console.log(
|
|
112
|
+
` Simulating scale frame with length: ${length}, height: ${height}`,
|
|
113
|
+
);
|
|
114
|
+
await this.selectInput('ScaleInput.input.length', length.toString());
|
|
115
|
+
await this.selectInput('ScaleInput.input.height', height.toString());
|
|
116
|
+
await this.selectButtonSafe('ShowOptions.cbx.scaledBox');
|
|
117
|
+
await this.selectButtonSafe('ScaleForm.button.apply');
|
|
118
|
+
await this.selectButtonSafe('ShowOptions.cbx.points');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async handleDefineTrademark(item: any, index: number) {
|
|
122
|
+
const name = item.payload.name;
|
|
123
|
+
console.log(` Command[${index}]: MainDefineTrademark`);
|
|
124
|
+
console.log(` Simulating trademark definition with name: ${name}`);
|
|
125
|
+
await this.selectInput('TrademarkInput.input.name', name);
|
|
126
|
+
await this.selectButtonSafe('TrademarkForm.button.apply');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async selectButtonSafe(testId: string): Promise<void> {
|
|
130
|
+
// Small delay to ensure element is fully ready
|
|
131
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
132
|
+
|
|
133
|
+
// Now click the button
|
|
134
|
+
await this.selectButton(testId);
|
|
9
135
|
}
|
|
10
136
|
|
|
11
137
|
private async sendRequest(
|
|
@@ -14,16 +140,19 @@ export class Batch {
|
|
|
14
140
|
): Promise<string> {
|
|
15
141
|
let status = 'blocked';
|
|
16
142
|
try {
|
|
17
|
-
const response = await fetch(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
143
|
+
const response = await fetch(
|
|
144
|
+
`http://localhost:${this.port}/send-command`,
|
|
145
|
+
{
|
|
146
|
+
method: 'POST',
|
|
147
|
+
headers: {
|
|
148
|
+
'Content-Type': 'application/json',
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
command,
|
|
152
|
+
data,
|
|
153
|
+
}),
|
|
21
154
|
},
|
|
22
|
-
|
|
23
|
-
command,
|
|
24
|
-
data,
|
|
25
|
-
}),
|
|
26
|
-
});
|
|
155
|
+
);
|
|
27
156
|
// console.log(`response: ${JSON.stringify(response, null)}`);
|
|
28
157
|
// console.log(`response.status: ${response.status}`);
|
|
29
158
|
if (response.status === 200) {
|
|
@@ -69,10 +198,20 @@ export class Batch {
|
|
|
69
198
|
}
|
|
70
199
|
}
|
|
71
200
|
|
|
72
|
-
async
|
|
201
|
+
async selectInput(testId: string, value: string): Promise<void> {
|
|
202
|
+
const status = await this.sendRequest(Command.SimulateInput, {
|
|
203
|
+
testId,
|
|
204
|
+
value,
|
|
205
|
+
});
|
|
206
|
+
if (status !== 'ok') {
|
|
207
|
+
console.log('Failed to send input simulation command');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async sampleClickCanvasDrawAt(testId: string, x: number, y: number) {
|
|
73
212
|
console.log(`sampleClickCanvasDrawAt(${x}, ${y})`);
|
|
74
213
|
await this.sendRequest(Command.SimulateClickOnCanvas, {
|
|
75
|
-
testId
|
|
214
|
+
testId,
|
|
76
215
|
x,
|
|
77
216
|
y,
|
|
78
217
|
});
|
package/command.ts
CHANGED
package/commandHandler.ts
CHANGED
|
@@ -8,20 +8,18 @@ export function useCommandHandler() {
|
|
|
8
8
|
|
|
9
9
|
switch (command) {
|
|
10
10
|
case Command.SimulateClick:
|
|
11
|
-
return simulator.
|
|
11
|
+
return simulator.simulateClick(data as TClick);
|
|
12
12
|
case Command.SimulateClickOnCanvas:
|
|
13
13
|
return simulator.simulateClickOnCanvas(data as TClickOnCanvas);
|
|
14
|
-
// case Command.MainScaleFrame:
|
|
15
|
-
// return simulator.simulateScaleFrame(data as TScaleFrame);
|
|
16
14
|
case Command.SimulateInput:
|
|
17
|
-
return simulator.
|
|
15
|
+
return simulator.simulateInput(data as TInput);
|
|
18
16
|
case Command.SimulateCheck:
|
|
19
|
-
return simulator.
|
|
17
|
+
return simulator.simulateCheck(data as TClick);
|
|
20
18
|
default:
|
|
21
19
|
console.warn('Unknown command:', command);
|
|
22
|
-
console.log(`
|
|
20
|
+
console.log(`useCommandHandler: command received with data:`, data);
|
|
23
21
|
throw new Error(
|
|
24
|
-
'
|
|
22
|
+
'command should be handled by useCommandHandler function',
|
|
25
23
|
);
|
|
26
24
|
}
|
|
27
25
|
};
|
package/dist/batch.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class Batch {
|
|
2
|
+
private filename;
|
|
3
|
+
port: number;
|
|
4
|
+
constructor(filename: string, port?: number);
|
|
5
|
+
run(handleCommand: (batch: Batch, item: any, index: number) => Promise<void>): Promise<void>;
|
|
6
|
+
handleDrawFrame(item: any, index: number): Promise<void>;
|
|
7
|
+
handleScaleFrame(item: any, index: number): Promise<void>;
|
|
8
|
+
handleDefineTrademark(item: any, index: number): Promise<void>;
|
|
9
|
+
selectButtonSafe(testId: string): Promise<void>;
|
|
10
|
+
private sendRequest;
|
|
11
|
+
selectButton(testId: string, retries?: number, delay?: number): Promise<void>;
|
|
12
|
+
selectInput(testId: string, value: string): Promise<void>;
|
|
13
|
+
sampleClickCanvasDrawAt(testId: string, x: number, y: number): Promise<void>;
|
|
14
|
+
}
|
package/dist/batch.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Batch = void 0;
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const path = __importStar(require("path"));
|
|
29
|
+
const command_1 = require("./command");
|
|
30
|
+
class Batch {
|
|
31
|
+
constructor(filename, port = 3010) {
|
|
32
|
+
const batchFilePath = path.join(process.cwd(), filename);
|
|
33
|
+
this.filename = batchFilePath;
|
|
34
|
+
this.port = port;
|
|
35
|
+
// Check if batch.json exists
|
|
36
|
+
if (!fs.existsSync(batchFilePath)) {
|
|
37
|
+
console.error('Error: batch.json file not found in the current directory');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async run(handleCommand) {
|
|
42
|
+
try {
|
|
43
|
+
// Read the batch.json file
|
|
44
|
+
const fileContent = fs.readFileSync(this.filename, 'utf-8');
|
|
45
|
+
// Parse the JSON content
|
|
46
|
+
let batchData;
|
|
47
|
+
try {
|
|
48
|
+
batchData = JSON.parse(fileContent);
|
|
49
|
+
}
|
|
50
|
+
catch (parseError) {
|
|
51
|
+
console.error('Error: Invalid JSON in batch.json file');
|
|
52
|
+
console.error(parseError);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
console.log('Processing batch.json...');
|
|
56
|
+
console.log('='.repeat(50));
|
|
57
|
+
// Check if batchData is an array or object
|
|
58
|
+
if (Array.isArray(batchData)) {
|
|
59
|
+
// If it's an array of objects, process each object sequentially
|
|
60
|
+
for (let index = 0; index < batchData.length; index++) {
|
|
61
|
+
// console.log(`Processing item ${index + 1}/${batchData.length}...`);
|
|
62
|
+
const item = batchData[index];
|
|
63
|
+
if (typeof item === 'object' && item !== null) {
|
|
64
|
+
// Print all keys in the object
|
|
65
|
+
await handleCommand(this, item, index + 1);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(` Not an object: ${item}`);
|
|
69
|
+
}
|
|
70
|
+
console.log('');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (typeof batchData === 'object' && batchData !== null) {
|
|
74
|
+
// If it's a single object, print its keys
|
|
75
|
+
console.log('Root object keys:');
|
|
76
|
+
const keys = Object.keys(batchData);
|
|
77
|
+
keys.forEach((key) => {
|
|
78
|
+
console.log(` Key: ${key}`);
|
|
79
|
+
});
|
|
80
|
+
// If any values are also objects, print their keys too
|
|
81
|
+
keys.forEach((key) => {
|
|
82
|
+
const value = batchData[key];
|
|
83
|
+
if (typeof value === 'object' &&
|
|
84
|
+
value !== null &&
|
|
85
|
+
!Array.isArray(value)) {
|
|
86
|
+
console.log(`\nKeys in "${key}" object:`);
|
|
87
|
+
Object.keys(value).forEach((subKey) => {
|
|
88
|
+
console.log(` Key: ${subKey}`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log('Error: batch.json should contain an object or array of objects');
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error('Error processing batch.json:');
|
|
100
|
+
console.error(error);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async handleDrawFrame(item, index) {
|
|
105
|
+
const coordinates = item.payload.coordinates;
|
|
106
|
+
console.log(` Command[${index}]: MainDrawFrame`);
|
|
107
|
+
await this.selectButtonSafe('FDOptions.button.draw-frame');
|
|
108
|
+
const coords = coordinates.points;
|
|
109
|
+
for (const point of coords) {
|
|
110
|
+
console.log(` Drawing point: (${point.x}, ${point.y})`);
|
|
111
|
+
// Small delay between points to simulate drawing
|
|
112
|
+
// await new Promise(resolve => setTimeout(resolve, 500));
|
|
113
|
+
await this.sampleClickCanvasDrawAt('canvas.draw', point.x, point.y); // Example click to trigger drawing (replace with actual coordinates if needed)
|
|
114
|
+
}
|
|
115
|
+
await this.selectButtonSafe('Finish.button.start-transformation'); // Example button click after drawing (replace with actual testId if needed)
|
|
116
|
+
}
|
|
117
|
+
async handleScaleFrame(item, index) {
|
|
118
|
+
const length = item.payload.length;
|
|
119
|
+
const height = item.payload.height;
|
|
120
|
+
console.log(` Command[${index}]: MainScaleFrame`);
|
|
121
|
+
console.log(` Simulating scale frame with length: ${length}, height: ${height}`);
|
|
122
|
+
await this.selectInput('ScaleInput.input.length', length.toString());
|
|
123
|
+
await this.selectInput('ScaleInput.input.height', height.toString());
|
|
124
|
+
await this.selectButtonSafe('ShowOptions.cbx.scaledBox');
|
|
125
|
+
await this.selectButtonSafe('ScaleForm.button.apply');
|
|
126
|
+
await this.selectButtonSafe('ShowOptions.cbx.points');
|
|
127
|
+
}
|
|
128
|
+
async handleDefineTrademark(item, index) {
|
|
129
|
+
const name = item.payload.name;
|
|
130
|
+
console.log(` Command[${index}]: MainDefineTrademark`);
|
|
131
|
+
console.log(` Simulating trademark definition with name: ${name}`);
|
|
132
|
+
await this.selectInput('TrademarkInput.input.name', name);
|
|
133
|
+
await this.selectButtonSafe('TrademarkForm.button.apply');
|
|
134
|
+
}
|
|
135
|
+
async selectButtonSafe(testId) {
|
|
136
|
+
// Small delay to ensure element is fully ready
|
|
137
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
138
|
+
// Now click the button
|
|
139
|
+
await this.selectButton(testId);
|
|
140
|
+
}
|
|
141
|
+
async sendRequest(command, data) {
|
|
142
|
+
let status = 'blocked';
|
|
143
|
+
try {
|
|
144
|
+
const response = await fetch(`http://localhost:${this.port}/send-command`, {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
headers: {
|
|
147
|
+
'Content-Type': 'application/json',
|
|
148
|
+
},
|
|
149
|
+
body: JSON.stringify({
|
|
150
|
+
command,
|
|
151
|
+
data,
|
|
152
|
+
}),
|
|
153
|
+
});
|
|
154
|
+
// console.log(`response: ${JSON.stringify(response, null)}`);
|
|
155
|
+
// console.log(`response.status: ${response.status}`);
|
|
156
|
+
if (response.status === 200) {
|
|
157
|
+
status = 'ok';
|
|
158
|
+
}
|
|
159
|
+
return status;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console.log(`error.status: ${status}`);
|
|
163
|
+
console.error('Error:', error);
|
|
164
|
+
}
|
|
165
|
+
console.log(`return status: ${status}`);
|
|
166
|
+
return status;
|
|
167
|
+
}
|
|
168
|
+
async selectButton(testId, retries = 5, delay = 1000) {
|
|
169
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
170
|
+
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
171
|
+
try {
|
|
172
|
+
if (attempt >= 1) {
|
|
173
|
+
console.log(`Attempt ${attempt}/${retries} to click button: ${testId}`);
|
|
174
|
+
}
|
|
175
|
+
const status = await this.sendRequest(command_1.Command.SimulateClick, {
|
|
176
|
+
testId,
|
|
177
|
+
});
|
|
178
|
+
if (status !== 'ok') {
|
|
179
|
+
console.log('Failed to send button simulation command');
|
|
180
|
+
}
|
|
181
|
+
await sleep(delay);
|
|
182
|
+
return; // Success, exit the retry loop
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error('Error in main:', error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async selectInput(testId, value) {
|
|
190
|
+
const status = await this.sendRequest(command_1.Command.SimulateInput, {
|
|
191
|
+
testId,
|
|
192
|
+
value,
|
|
193
|
+
});
|
|
194
|
+
if (status !== 'ok') {
|
|
195
|
+
console.log('Failed to send input simulation command');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async sampleClickCanvasDrawAt(testId, x, y) {
|
|
199
|
+
console.log(`sampleClickCanvasDrawAt(${x}, ${y})`);
|
|
200
|
+
await this.sendRequest(command_1.Command.SimulateClickOnCanvas, {
|
|
201
|
+
testId,
|
|
202
|
+
x,
|
|
203
|
+
y,
|
|
204
|
+
});
|
|
205
|
+
// Small delay to ensure element is fully ready
|
|
206
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.Batch = Batch;
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Command = void 0;
|
|
4
|
+
var Command;
|
|
5
|
+
(function (Command) {
|
|
6
|
+
Command["SimulateClick"] = "SimulateClick";
|
|
7
|
+
Command["SimulateClickOnCanvas"] = "SimulateClickOnCanvas";
|
|
8
|
+
Command["SimulateInput"] = "SimulateInput";
|
|
9
|
+
Command["SimulateCheck"] = "SimulateCheck";
|
|
10
|
+
})(Command || (exports.Command = Command = {}));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useCommandHandler = useCommandHandler;
|
|
4
|
+
const command_1 = require("./command");
|
|
5
|
+
const simulator_1 = require("./simulator");
|
|
6
|
+
function useCommandHandler() {
|
|
7
|
+
const handleCommand = async (command, data) => {
|
|
8
|
+
const simulator = new simulator_1.Simulator();
|
|
9
|
+
switch (command) {
|
|
10
|
+
case command_1.Command.SimulateClick:
|
|
11
|
+
return simulator.simulateClick(data);
|
|
12
|
+
case command_1.Command.SimulateClickOnCanvas:
|
|
13
|
+
return simulator.simulateClickOnCanvas(data);
|
|
14
|
+
case command_1.Command.SimulateInput:
|
|
15
|
+
return simulator.simulateInput(data);
|
|
16
|
+
case command_1.Command.SimulateCheck:
|
|
17
|
+
return simulator.simulateCheck(data);
|
|
18
|
+
default:
|
|
19
|
+
console.warn('Unknown command:', command);
|
|
20
|
+
console.log(`useCommandHandler: command received with data:`, data);
|
|
21
|
+
throw new Error('command should be handled by useCommandHandler function');
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return { handleCommand };
|
|
25
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Batch = exports.useCommandHandler = exports.Command = exports.Simulator = void 0;
|
|
4
|
+
var simulator_1 = require("./simulator");
|
|
5
|
+
Object.defineProperty(exports, "Simulator", { enumerable: true, get: function () { return simulator_1.Simulator; } });
|
|
6
|
+
var command_1 = require("./command");
|
|
7
|
+
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.Command; } });
|
|
8
|
+
var commandHandler_1 = require("./commandHandler");
|
|
9
|
+
Object.defineProperty(exports, "useCommandHandler", { enumerable: true, get: function () { return commandHandler_1.useCommandHandler; } });
|
|
10
|
+
var batch_1 = require("./batch");
|
|
11
|
+
Object.defineProperty(exports, "Batch", { enumerable: true, get: function () { return batch_1.Batch; } });
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const batch_1 = require("./batch");
|
|
4
|
+
async function handleDrawFrame(batch, item, index) {
|
|
5
|
+
const coordinates = item.payload.coordinates;
|
|
6
|
+
console.log(` Command[${index}]: MainDrawFrame`);
|
|
7
|
+
await batch.selectButtonSafe('FDOptions.button.draw-frame');
|
|
8
|
+
const coords = coordinates.points;
|
|
9
|
+
for (const point of coords) {
|
|
10
|
+
console.log(` Drawing point: (${point.x}, ${point.y})`);
|
|
11
|
+
// Small delay between points to simulate drawing
|
|
12
|
+
// await new Promise(resolve => setTimeout(resolve, 500));
|
|
13
|
+
await batch.sampleClickCanvasDrawAt('canvas.draw', point.x, point.y); // Example click to trigger drawing (replace with actual coordinates if needed)
|
|
14
|
+
}
|
|
15
|
+
await batch.selectButtonSafe('Finish.button.start-transformation'); // Example button click after drawing (replace with actual testId if needed)
|
|
16
|
+
}
|
|
17
|
+
async function handleScaleFrame(batch, item, index) {
|
|
18
|
+
const length = item.payload.length;
|
|
19
|
+
const height = item.payload.height;
|
|
20
|
+
console.log(` Command[${index}]: MainScaleFrame`);
|
|
21
|
+
console.log(` Simulating scale frame with length: ${length}, height: ${height}`);
|
|
22
|
+
await batch.selectInput('ScaleInput.input.length', length.toString());
|
|
23
|
+
await batch.selectInput('ScaleInput.input.height', height.toString());
|
|
24
|
+
await batch.selectButtonSafe('ShowOptions.cbx.scaledBox');
|
|
25
|
+
await batch.selectButtonSafe('ScaleForm.button.apply');
|
|
26
|
+
await batch.selectButtonSafe('ShowOptions.cbx.points');
|
|
27
|
+
}
|
|
28
|
+
async function handleDefineTrademark(batch, item, index) {
|
|
29
|
+
const name = item.payload.name;
|
|
30
|
+
console.log(` Command[${index}]: MainDefineTrademark`);
|
|
31
|
+
console.log(` Simulating trademark definition with name: ${name}`);
|
|
32
|
+
await batch.selectInput('TrademarkInput.input.name', name);
|
|
33
|
+
await batch.selectButtonSafe('TrademarkForm.button.apply');
|
|
34
|
+
}
|
|
35
|
+
async function handleCommand(batch, item, index) {
|
|
36
|
+
// console.log(JSON.stringify(item, null, 2));
|
|
37
|
+
if (item.command) {
|
|
38
|
+
switch (item.command) {
|
|
39
|
+
case 'main-draw-frame':
|
|
40
|
+
await handleDrawFrame(batch, item, index);
|
|
41
|
+
break;
|
|
42
|
+
case 'main-scale-frame':
|
|
43
|
+
await handleScaleFrame(batch, item, index);
|
|
44
|
+
break;
|
|
45
|
+
case 'main-define-trademark':
|
|
46
|
+
await handleDefineTrademark(batch, item, index);
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Unknown command: ${item.command}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log('No command found in this item.');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function main(batchFile) {
|
|
57
|
+
try {
|
|
58
|
+
const batch = new batch_1.Batch(batchFile);
|
|
59
|
+
await batch.run(handleCommand);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error('Error in main:', error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Accept batch file path as command-line argument
|
|
66
|
+
const batchFileArg = process.argv[2] || 'batch.json';
|
|
67
|
+
console.log(`Starting batch processing with file: ${batchFileArg}`);
|
|
68
|
+
main(batchFileArg);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TClick, TClickOnCanvas, TInput } from './types';
|
|
2
|
+
export declare class Simulator {
|
|
3
|
+
constructor();
|
|
4
|
+
findHTMLElement(testId: string, elementType: typeof HTMLElement, type?: string): HTMLElement | null;
|
|
5
|
+
simulateClickOnCanvas(data: TClickOnCanvas): void;
|
|
6
|
+
simulateClick(data: TClick): void;
|
|
7
|
+
simulateCheck(data: TClick): void;
|
|
8
|
+
simulateInput(data: TInput): {
|
|
9
|
+
status: string;
|
|
10
|
+
} | undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Simulator = void 0;
|
|
4
|
+
const frame_constants_1 = require("frame.constants");
|
|
5
|
+
class Simulator {
|
|
6
|
+
constructor() {
|
|
7
|
+
console.log('Simulator initialized');
|
|
8
|
+
}
|
|
9
|
+
findHTMLElement(testId, elementType, type) {
|
|
10
|
+
if (type) {
|
|
11
|
+
console.log(`${frame_constants_1.green}Simulating ${type} on element with testId: ${testId}${frame_constants_1.reset}`);
|
|
12
|
+
}
|
|
13
|
+
const element = document.querySelector(`[data-testid="${testId}"]`);
|
|
14
|
+
if (element) {
|
|
15
|
+
if (element instanceof elementType) {
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.error(`Element found but not a ${elementType.name} for ${type} simulation: ${testId}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.error(`Element not found for ${type} simulation: ${testId}`);
|
|
23
|
+
}
|
|
24
|
+
return element;
|
|
25
|
+
}
|
|
26
|
+
simulateClickOnCanvas(data) {
|
|
27
|
+
const { x, y } = data;
|
|
28
|
+
const canvas = this.findHTMLElement('canvas.draw', HTMLCanvasElement, 'click');
|
|
29
|
+
if (canvas) {
|
|
30
|
+
const rect = canvas.getBoundingClientRect();
|
|
31
|
+
const event = new MouseEvent('click', {
|
|
32
|
+
clientX: rect.left + rect.width / 2 + x, // Convert canvas-relative to screen coordinates
|
|
33
|
+
clientY: rect.top + rect.height / 2 - y, // Convert canvas-relative to screen coordinates (flip Y)
|
|
34
|
+
bubbles: true,
|
|
35
|
+
});
|
|
36
|
+
// Set batch properties
|
|
37
|
+
// @ts-ignore - Add custom properties for batch identification
|
|
38
|
+
event.isBatch = true;
|
|
39
|
+
// @ts-ignore - Store original canvas-relative coordinates
|
|
40
|
+
event.batchX = x;
|
|
41
|
+
// @ts-ignore - Store original canvas-relative coordinates
|
|
42
|
+
event.batchY = y;
|
|
43
|
+
canvas.dispatchEvent(event);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
simulateClick(data) {
|
|
47
|
+
const { testId } = data;
|
|
48
|
+
const element = this.findHTMLElement(testId, HTMLButtonElement, 'click');
|
|
49
|
+
if (element) {
|
|
50
|
+
const event = new MouseEvent('click', { bubbles: true });
|
|
51
|
+
// @ts-ignore - Add custom property to identify this as a batch click
|
|
52
|
+
event.isBatch = true;
|
|
53
|
+
element.click();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
simulateCheck(data) {
|
|
57
|
+
const { testId } = data;
|
|
58
|
+
const element = this.findHTMLElement(testId, HTMLInputElement, 'check');
|
|
59
|
+
if (element) {
|
|
60
|
+
const event = new MouseEvent('click', { bubbles: true });
|
|
61
|
+
// @ts-ignore - Add custom property to identify this as a batch click
|
|
62
|
+
event.isBatch = true;
|
|
63
|
+
element.dispatchEvent(event);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
simulateInput(data) {
|
|
67
|
+
const { testId, value } = data;
|
|
68
|
+
const element = this.findHTMLElement(testId, HTMLDivElement, 'input');
|
|
69
|
+
if (element) {
|
|
70
|
+
if (element instanceof HTMLInputElement) {
|
|
71
|
+
element.value = value.toString();
|
|
72
|
+
element.dispatchEvent(new Event('input', { bubbles: true }));
|
|
73
|
+
return { status: 'ok' };
|
|
74
|
+
}
|
|
75
|
+
else if (element instanceof HTMLDivElement) {
|
|
76
|
+
const childElement = element.firstChild;
|
|
77
|
+
if (childElement instanceof HTMLInputElement) {
|
|
78
|
+
childElement.value = value || '';
|
|
79
|
+
childElement.dispatchEvent(new Event('input', { bubbles: true }));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.Simulator = Simulator;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../batch.ts","../command-server.ts","../command.ts","../commandhandler.ts","../index.ts","../main.ts","../simulator.ts","../types.ts"],"version":"5.6.3"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type TClick = {
|
|
2
|
+
testId: string;
|
|
3
|
+
};
|
|
4
|
+
export type TInput = {
|
|
5
|
+
testId: string;
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
export type TClickOnCanvas = {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
};
|
|
12
|
+
export type TScaleFrame = {
|
|
13
|
+
length: number;
|
|
14
|
+
height: number;
|
|
15
|
+
};
|
|
16
|
+
export type TUserAction = TClickOnCanvas | TScaleFrame | TClick | TInput;
|
package/dist/types.js
ADDED
package/draw.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"command": "main-draw-frame",
|
|
4
|
+
"payload": {
|
|
5
|
+
"coordinates": {
|
|
6
|
+
"points": [
|
|
7
|
+
{ "x": 200, "y": 100 },
|
|
8
|
+
{ "x": -100, "y": 100 },
|
|
9
|
+
{ "x": -60, "y": 0 },
|
|
10
|
+
{ "x": -100, "y": -100 },
|
|
11
|
+
{ "x": 200, "y": -100 }
|
|
12
|
+
],
|
|
13
|
+
"universeCenter": { "x": 300, "y": 200 }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"command": "main-scale-frame",
|
|
19
|
+
"payload": { "length": 500, "height": 250 }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"command": "main-define-trademark",
|
|
23
|
+
"payload": { "x": -95, "y": 62 }
|
|
24
|
+
}
|
|
25
|
+
]
|
package/index.ts
CHANGED
package/main.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Batch } from './batch';
|
|
2
|
+
|
|
3
|
+
async function handleDrawFrame(batch: Batch, item: any, index: number) {
|
|
4
|
+
const coordinates = item.payload.coordinates;
|
|
5
|
+
console.log(` Command[${index}]: MainDrawFrame`);
|
|
6
|
+
await batch.selectButtonSafe('FDOptions.button.draw-frame');
|
|
7
|
+
|
|
8
|
+
const coords: { x: number; y: number }[] = coordinates.points;
|
|
9
|
+
for (const point of coords) {
|
|
10
|
+
console.log(` Drawing point: (${point.x}, ${point.y})`);
|
|
11
|
+
// Small delay between points to simulate drawing
|
|
12
|
+
// await new Promise(resolve => setTimeout(resolve, 500));
|
|
13
|
+
await batch.sampleClickCanvasDrawAt('canvas.draw', point.x, point.y); // Example click to trigger drawing (replace with actual coordinates if needed)
|
|
14
|
+
}
|
|
15
|
+
await batch.selectButtonSafe('Finish.button.start-transformation'); // Example button click after drawing (replace with actual testId if needed)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function handleScaleFrame(batch: Batch, item: any, index: number) {
|
|
19
|
+
const length = item.payload.length;
|
|
20
|
+
const height = item.payload.height;
|
|
21
|
+
console.log(` Command[${index}]: MainScaleFrame`);
|
|
22
|
+
console.log(
|
|
23
|
+
` Simulating scale frame with length: ${length}, height: ${height}`,
|
|
24
|
+
);
|
|
25
|
+
await batch.selectInput('ScaleInput.input.length', length.toString());
|
|
26
|
+
await batch.selectInput('ScaleInput.input.height', height.toString());
|
|
27
|
+
await batch.selectButtonSafe('ShowOptions.cbx.scaledBox');
|
|
28
|
+
await batch.selectButtonSafe('ScaleForm.button.apply');
|
|
29
|
+
await batch.selectButtonSafe('ShowOptions.cbx.points');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function handleDefineTrademark(batch: Batch, item: any, index: number) {
|
|
33
|
+
const name = item.payload.name;
|
|
34
|
+
console.log(` Command[${index}]: MainDefineTrademark`);
|
|
35
|
+
console.log(` Simulating trademark definition with name: ${name}`);
|
|
36
|
+
await batch.selectInput('TrademarkInput.input.name', name);
|
|
37
|
+
await batch.selectButtonSafe('TrademarkForm.button.apply');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function handleCommand(batch: Batch, item: any, index: number) {
|
|
41
|
+
// console.log(JSON.stringify(item, null, 2));
|
|
42
|
+
if (item.command) {
|
|
43
|
+
switch (item.command) {
|
|
44
|
+
case 'main-draw-frame':
|
|
45
|
+
await handleDrawFrame(batch, item, index);
|
|
46
|
+
break;
|
|
47
|
+
case 'main-scale-frame':
|
|
48
|
+
await handleScaleFrame(batch, item, index);
|
|
49
|
+
break;
|
|
50
|
+
case 'main-define-trademark':
|
|
51
|
+
await handleDefineTrademark(batch, item, index);
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unknown command: ${item.command}`);
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
console.log('No command found in this item.');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function main(batchFile: string) {
|
|
62
|
+
try {
|
|
63
|
+
const batch = new Batch(batchFile);
|
|
64
|
+
await batch.run(handleCommand);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('Error in main:', error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Accept batch file path as command-line argument
|
|
71
|
+
const batchFileArg = process.argv[2] || 'batch.json';
|
|
72
|
+
console.log(`Starting batch processing with file: ${batchFileArg}`);
|
|
73
|
+
main(batchFileArg);
|
package/package.json
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frame.simulator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A simulator for testing form interactions in a controlled environment.",
|
|
5
|
-
"main": "index.js",
|
|
6
5
|
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
7
15
|
"scripts": {
|
|
8
16
|
"build": "tsc -b",
|
|
9
|
-
"command-server": "tsx command-server.ts"
|
|
17
|
+
"command-server": "tsx command-server.ts",
|
|
18
|
+
"draw": "tsx main.ts draw.json"
|
|
10
19
|
},
|
|
11
20
|
"peerDependencies": {
|
|
12
21
|
"frame.constants": "^1.0.5"
|
package/simulator.ts
CHANGED
|
@@ -55,7 +55,7 @@ export class Simulator {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
simulateClick(data: TClick) {
|
|
59
59
|
const { testId } = data;
|
|
60
60
|
const element = this.findHTMLElement(testId, HTMLButtonElement, 'click');
|
|
61
61
|
if (element) {
|
|
@@ -66,7 +66,7 @@ export class Simulator {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
simulateCheck(data: TClick) {
|
|
70
70
|
const { testId } = data;
|
|
71
71
|
const element = this.findHTMLElement(testId, HTMLInputElement, 'check');
|
|
72
72
|
if (element) {
|
|
@@ -77,7 +77,7 @@ export class Simulator {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
simulateInput(data: TInput) {
|
|
81
81
|
const { testId, value } = data;
|
|
82
82
|
const element = this.findHTMLElement(testId, HTMLDivElement, 'input');
|
|
83
83
|
|
|
@@ -95,16 +95,4 @@ export class Simulator {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
|
|
99
|
-
// simulateScaleFrame(scaleValues: TScaleFrame) {
|
|
100
|
-
// const { length, height } = scaleValues;
|
|
101
|
-
// console.log(
|
|
102
|
-
// `${red}Simulating scale frame with length: ${length}, height: ${height}${reset}`,
|
|
103
|
-
// );
|
|
104
|
-
// this.simulateUserInput('ScaleInput.input.length', length.toString());
|
|
105
|
-
// this.simulateUserInput('ScaleInput.input.height', height.toString());
|
|
106
|
-
// this.simulateUserCheck({ testId: 'ShowOptions.cbx.scaledBox' });
|
|
107
|
-
// this.simulateUserClick({ testId: 'ScaleForm.button.apply' });
|
|
108
|
-
// this.simulateUserCheck({ testId: 'ShowOptions.cbx.points' });
|
|
109
|
-
// }
|
|
110
98
|
}
|