@rpascene/shared 0.30.9 → 0.30.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/README.md +2 -3
- package/dist/es/common.mjs +7 -7
- package/dist/es/constants/example-code.mjs +10 -10
- package/dist/es/env/init-debug.mjs +2 -2
- package/dist/es/env/model-config-manager.mjs +1 -1
- package/dist/es/extractor/debug.mjs +2 -2
- package/dist/es/extractor/util.mjs +11 -11
- package/dist/es/extractor/web-extractor.mjs +7 -7
- package/dist/es/logger.mjs +3 -3
- package/dist/es/node/fs.mjs +6 -6
- package/dist/es/utils.mjs +2 -2
- package/dist/lib/common.js +15 -15
- package/dist/lib/constants/example-code.js +10 -10
- package/dist/lib/env/init-debug.js +2 -2
- package/dist/lib/env/model-config-manager.js +1 -1
- package/dist/lib/extractor/debug.js +1 -1
- package/dist/lib/extractor/util.js +16 -16
- package/dist/lib/extractor/web-extractor.js +6 -6
- package/dist/lib/logger.js +2 -2
- package/dist/lib/node/fs.js +6 -6
- package/dist/lib/utils.js +2 -2
- package/dist/types/common.d.ts +5 -5
- package/dist/types/constants/example-code.d.ts +2 -2
- package/dist/types/env/types.d.ts +1 -1
- package/dist/types/extractor/util.d.ts +2 -2
- package/dist/types/node/fs.d.ts +1 -1
- package/package.json +12 -12
- package/src/common.ts +7 -7
- package/src/constants/example-code.ts +10 -10
- package/src/env/init-debug.ts +2 -2
- package/src/env/model-config-manager.ts +1 -1
- package/src/env/types.ts +1 -1
- package/src/extractor/debug.ts +2 -2
- package/src/extractor/util.ts +15 -15
- package/src/extractor/web-extractor.ts +7 -7
- package/src/logger.ts +3 -3
- package/src/node/fs.ts +5 -5
- package/src/utils.ts +2 -2
package/README.md
CHANGED
package/dist/es/common.mjs
CHANGED
|
@@ -4,14 +4,14 @@ import node_path from "node:path";
|
|
|
4
4
|
import { getBasicEnvValue } from "./env/basic.mjs";
|
|
5
5
|
import { MIDSCENE_RUN_DIR } from "./env/types.mjs";
|
|
6
6
|
import { ifInNode } from "./utils.mjs";
|
|
7
|
-
const defaultRunDirName = '
|
|
8
|
-
const
|
|
7
|
+
const defaultRunDirName = 'rpascene_run';
|
|
8
|
+
const getRpasceneRunDir = ()=>{
|
|
9
9
|
if (!ifInNode) return '';
|
|
10
10
|
return getBasicEnvValue(MIDSCENE_RUN_DIR) || defaultRunDirName;
|
|
11
11
|
};
|
|
12
|
-
const
|
|
12
|
+
const getRpasceneRunBaseDir = ()=>{
|
|
13
13
|
if (!ifInNode) return '';
|
|
14
|
-
let basePath = node_path.resolve(process.cwd(),
|
|
14
|
+
let basePath = node_path.resolve(process.cwd(), getRpasceneRunDir());
|
|
15
15
|
if (!existsSync(basePath)) try {
|
|
16
16
|
mkdirSync(basePath, {
|
|
17
17
|
recursive: true
|
|
@@ -24,9 +24,9 @@ const getMidsceneRunBaseDir = ()=>{
|
|
|
24
24
|
}
|
|
25
25
|
return basePath;
|
|
26
26
|
};
|
|
27
|
-
const
|
|
27
|
+
const getRpasceneRunSubDir = (subdir)=>{
|
|
28
28
|
if (!ifInNode) return '';
|
|
29
|
-
const basePath =
|
|
29
|
+
const basePath = getRpasceneRunBaseDir();
|
|
30
30
|
const logPath = node_path.join(basePath, subdir);
|
|
31
31
|
if (!existsSync(logPath)) mkdirSync(logPath, {
|
|
32
32
|
recursive: true
|
|
@@ -34,4 +34,4 @@ const getMidsceneRunSubDir = (subdir)=>{
|
|
|
34
34
|
return logPath;
|
|
35
35
|
};
|
|
36
36
|
const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED = 'NOT_IMPLEMENTED_AS_DESIGNED';
|
|
37
|
-
export { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED, defaultRunDirName,
|
|
37
|
+
export { ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED, defaultRunDirName, getRpasceneRunBaseDir, getRpasceneRunDir, getRpasceneRunSubDir };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const PLAYWRIGHT_EXAMPLE_CODE = `
|
|
2
|
-
// Reference the following code to generate
|
|
3
|
-
// The following is test code for
|
|
2
|
+
// Reference the following code to generate Rpascene test cases
|
|
3
|
+
// The following is test code for Rpascene AI, for reference
|
|
4
4
|
// The following is Playwright syntax, you can use Playwright to assist in test generation
|
|
5
5
|
IMPORTANT: Follow these exact type signatures for AI functions:
|
|
6
6
|
|
|
@@ -17,8 +17,8 @@ aiAssert(assertion: string): Promise<void>
|
|
|
17
17
|
aiQuery<T>(queryObject: Record<string, string>): Promise<T> // Extracts data from page based on descriptions
|
|
18
18
|
|
|
19
19
|
// examples:
|
|
20
|
-
// Reference the following code to generate
|
|
21
|
-
// The following is test code for
|
|
20
|
+
// Reference the following code to generate Rpascene test cases
|
|
21
|
+
// The following is test code for Rpascene AI, for reference
|
|
22
22
|
// The following is Playwright syntax, you can use Playwright to assist in test generation
|
|
23
23
|
import { test as base } from '@playwright/test';
|
|
24
24
|
import type { PlayWrightAiFixtureType } from '@rpascene/web/playwright';
|
|
@@ -127,33 +127,33 @@ tasks:
|
|
|
127
127
|
# Tap an element described by a prompt.
|
|
128
128
|
- aiTap: <prompt>
|
|
129
129
|
deepThink: <boolean> # Optional, whether to use deepThink to precisely locate the element. Defaults to False.
|
|
130
|
-
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided,
|
|
130
|
+
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Rpascene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.
|
|
131
131
|
cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.
|
|
132
132
|
|
|
133
133
|
# Double click an element described by a prompt.
|
|
134
134
|
- aiDoubleClick: <prompt>
|
|
135
135
|
deepThink: <boolean> # Optional, whether to use deepThink to precisely locate the element. Defaults to False.
|
|
136
|
-
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided,
|
|
136
|
+
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Rpascene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.
|
|
137
137
|
cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.
|
|
138
138
|
|
|
139
139
|
# Hover over an element described by a prompt.
|
|
140
140
|
- aiHover: <prompt>
|
|
141
141
|
deepThink: <boolean> # Optional, whether to use deepThink to precisely locate the element. Defaults to False.
|
|
142
|
-
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided,
|
|
142
|
+
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Rpascene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.
|
|
143
143
|
cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.
|
|
144
144
|
|
|
145
145
|
# Input text into an element described by a prompt.
|
|
146
146
|
- aiInput: <final text content of the input>
|
|
147
147
|
locate: <prompt>
|
|
148
148
|
deepThink: <boolean> # Optional, whether to use deepThink to precisely locate the element. Defaults to False.
|
|
149
|
-
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided,
|
|
149
|
+
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Rpascene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.
|
|
150
150
|
cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.
|
|
151
151
|
|
|
152
152
|
# Press a key (e.g., Enter, Tab, Escape) on an element described by a prompt.
|
|
153
153
|
- aiKeyboardPress: <key>
|
|
154
154
|
locate: <prompt>
|
|
155
155
|
deepThink: <boolean> # Optional, whether to use deepThink to precisely locate the element. Defaults to False.
|
|
156
|
-
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided,
|
|
156
|
+
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Rpascene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.
|
|
157
157
|
cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.
|
|
158
158
|
|
|
159
159
|
# Scroll globally or on an element described by a prompt.
|
|
@@ -163,7 +163,7 @@ tasks:
|
|
|
163
163
|
distance: <number> # Optional, the scroll distance in pixels.
|
|
164
164
|
locate: <prompt> # Optional, the element to scroll on.
|
|
165
165
|
deepThink: <boolean> # Optional, whether to use deepThink to precisely locate the element. Defaults to False.
|
|
166
|
-
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided,
|
|
166
|
+
xpath: <xpath> # Optional, the xpath of the target element for the operation. If provided, Rpascene will prioritize this xpath to find the element before using the cache and the AI model. Defaults to empty.
|
|
167
167
|
cacheable: <boolean> # Optional, whether to cache the result of this API call when the [caching feature](./caching.mdx) is enabled. Defaults to True.
|
|
168
168
|
|
|
169
169
|
# Log the current screenshot with a description in the report file.
|
|
@@ -5,12 +5,12 @@ const initDebugConfig = ()=>{
|
|
|
5
5
|
const shouldPrintTiming = getBasicEnvValue(MIDSCENE_DEBUG_AI_PROFILE);
|
|
6
6
|
let debugConfig = '';
|
|
7
7
|
if (shouldPrintTiming) {
|
|
8
|
-
console.warn('MIDSCENE_DEBUG_AI_PROFILE is deprecated, use DEBUG=
|
|
8
|
+
console.warn('MIDSCENE_DEBUG_AI_PROFILE is deprecated, use DEBUG=rpascene:ai:profile instead');
|
|
9
9
|
debugConfig = 'ai:profile';
|
|
10
10
|
}
|
|
11
11
|
const shouldPrintAIResponse = getBasicEnvValue(MIDSCENE_DEBUG_AI_RESPONSE);
|
|
12
12
|
if (shouldPrintAIResponse) {
|
|
13
|
-
console.warn('MIDSCENE_DEBUG_AI_RESPONSE is deprecated, use DEBUG=
|
|
13
|
+
console.warn('MIDSCENE_DEBUG_AI_RESPONSE is deprecated, use DEBUG=rpascene:ai:response instead');
|
|
14
14
|
debugConfig = debugConfig ? 'ai:*' : 'ai:call';
|
|
15
15
|
}
|
|
16
16
|
if (debugConfig) enableDebug(debugConfig);
|
|
@@ -83,7 +83,7 @@ class ModelConfigManager {
|
|
|
83
83
|
}
|
|
84
84
|
throwErrorIfNonVLModel(intent = 'grounding') {
|
|
85
85
|
const modelConfig = this.getModelConfig(intent);
|
|
86
|
-
if (!modelConfig.vlMode) throw new Error('No visual language model (VL model) detected for the current scenario. Element localization may be inaccurate. Please verify your model configuration. Learn more: https://
|
|
86
|
+
if (!modelConfig.vlMode) throw new Error('No visual language model (VL model) detected for the current scenario. Element localization may be inaccurate. Please verify your model configuration. Learn more: https://rpascenejs.com/choose-a-model');
|
|
87
87
|
}
|
|
88
88
|
constructor(modelConfigFn){
|
|
89
89
|
_define_property(this, "modelConfigMap", void 0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { webExtractTextWithPosition } from "./index.mjs";
|
|
2
|
-
import { setExtractTextWithPositionOnWindow,
|
|
2
|
+
import { setExtractTextWithPositionOnWindow, setRpasceneVisibleRectOnWindow } from "./util.mjs";
|
|
3
3
|
console.log(webExtractTextWithPosition(document.body, true));
|
|
4
4
|
console.log(JSON.stringify(webExtractTextWithPosition(document.body, true)));
|
|
5
5
|
setExtractTextWithPositionOnWindow();
|
|
6
|
-
|
|
6
|
+
setRpasceneVisibleRectOnWindow();
|
|
@@ -197,22 +197,22 @@ function getNodeAttributes(node, currentWindow) {
|
|
|
197
197
|
});
|
|
198
198
|
return Object.fromEntries(attributesList);
|
|
199
199
|
}
|
|
200
|
-
function
|
|
200
|
+
function rpasceneGenerateHash(node, content, rect) {
|
|
201
201
|
const slicedHash = generateHashId(rect, content);
|
|
202
202
|
if (node) {
|
|
203
|
-
if (!window.
|
|
203
|
+
if (!window.rpasceneNodeHashCacheList) setNodeHashCacheListOnWindow();
|
|
204
204
|
setNodeToCacheList(node, slicedHash);
|
|
205
205
|
}
|
|
206
206
|
return slicedHash;
|
|
207
207
|
}
|
|
208
208
|
function setNodeHashCacheListOnWindow() {
|
|
209
|
-
if ('undefined' != typeof window) window.
|
|
209
|
+
if ('undefined' != typeof window) window.rpasceneNodeHashCacheList = [];
|
|
210
210
|
}
|
|
211
211
|
function setNodeToCacheList(node, id) {
|
|
212
212
|
if ('undefined' != typeof window) {
|
|
213
|
-
var
|
|
213
|
+
var _window_rpasceneNodeHashCacheList;
|
|
214
214
|
if (getNodeFromCacheList(id)) return;
|
|
215
|
-
null == (
|
|
215
|
+
null == (_window_rpasceneNodeHashCacheList = window.rpasceneNodeHashCacheList) || _window_rpasceneNodeHashCacheList.push({
|
|
216
216
|
node,
|
|
217
217
|
id
|
|
218
218
|
});
|
|
@@ -220,8 +220,8 @@ function setNodeToCacheList(node, id) {
|
|
|
220
220
|
}
|
|
221
221
|
function getNodeFromCacheList(id) {
|
|
222
222
|
if ('undefined' != typeof window) {
|
|
223
|
-
var
|
|
224
|
-
return null == (
|
|
223
|
+
var _window_rpasceneNodeHashCacheList_find, _window_rpasceneNodeHashCacheList;
|
|
224
|
+
return null == (_window_rpasceneNodeHashCacheList = window.rpasceneNodeHashCacheList) ? void 0 : null == (_window_rpasceneNodeHashCacheList_find = _window_rpasceneNodeHashCacheList.find((item)=>item.id === id)) ? void 0 : _window_rpasceneNodeHashCacheList_find.node;
|
|
225
225
|
}
|
|
226
226
|
return null;
|
|
227
227
|
}
|
|
@@ -229,10 +229,10 @@ function generateId(numberId) {
|
|
|
229
229
|
return `${numberId}`;
|
|
230
230
|
}
|
|
231
231
|
function setGenerateHashOnWindow() {
|
|
232
|
-
if ('undefined' != typeof window) window.
|
|
232
|
+
if ('undefined' != typeof window) window.rpasceneGenerateHash = rpasceneGenerateHash;
|
|
233
233
|
}
|
|
234
|
-
function
|
|
235
|
-
if ('undefined' != typeof window) window.
|
|
234
|
+
function setRpasceneVisibleRectOnWindow() {
|
|
235
|
+
if ('undefined' != typeof window) window.rpasceneVisibleRect = elementRect;
|
|
236
236
|
}
|
|
237
237
|
function setExtractTextWithPositionOnWindow() {
|
|
238
238
|
if ('undefined' != typeof window) window.extractTextWithPosition = extractTextWithPosition;
|
|
@@ -241,4 +241,4 @@ function getTopDocument() {
|
|
|
241
241
|
const container = document.body || document;
|
|
242
242
|
return container;
|
|
243
243
|
}
|
|
244
|
-
export { elementRect, generateId, getDebugMode, getNodeAttributes, getNodeFromCacheList, getPseudoElementContent, getRect, getTopDocument, hasOverflowY, isElementPartiallyInViewport, logger,
|
|
244
|
+
export { elementRect, generateId, getDebugMode, getNodeAttributes, getNodeFromCacheList, getPseudoElementContent, getRect, getTopDocument, hasOverflowY, isElementPartiallyInViewport, logger, overlappedRect, rpasceneGenerateHash, setDebugMode, setExtractTextWithPositionOnWindow, setGenerateHashOnWindow, setNodeHashCacheListOnWindow, setNodeToCacheList, setRpasceneVisibleRectOnWindow, validTextNodeContent };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CONTAINER_MINI_HEIGHT, CONTAINER_MINI_WIDTH, NodeType } from "../constants/index.mjs";
|
|
2
2
|
import { isAElement, isButtonElement, isContainerElement, isFormElement, isImgElement, isTextElement } from "./dom-util.mjs";
|
|
3
3
|
import { descriptionOfTree } from "./tree.mjs";
|
|
4
|
-
import { elementRect, getNodeAttributes, getPseudoElementContent, getRect, getTopDocument, logger,
|
|
4
|
+
import { elementRect, getNodeAttributes, getPseudoElementContent, getRect, getTopDocument, logger, rpasceneGenerateHash, setDebugMode } from "./util.mjs";
|
|
5
5
|
import { onWindowMessage, postWindowMessage } from "./cs_postmessage.mjs";
|
|
6
6
|
import { getContainerPath, getLocators } from "./customLocator.mjs";
|
|
7
7
|
let indexId = 0;
|
|
@@ -34,7 +34,7 @@ function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1,
|
|
|
34
34
|
if (isFormElement(node, currentWindow)) {
|
|
35
35
|
const attributes = getNodeAttributes(node, currentWindow);
|
|
36
36
|
let valueContent = attributes.value || attributes.placeholder || node.textContent || '';
|
|
37
|
-
const nodeHashId =
|
|
37
|
+
const nodeHashId = rpasceneGenerateHash(node, valueContent, rect);
|
|
38
38
|
const tagName = node.tagName.toLowerCase();
|
|
39
39
|
if ('select' === node.tagName.toLowerCase()) {
|
|
40
40
|
const selectedOption = node.options[node.selectedIndex];
|
|
@@ -68,7 +68,7 @@ function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1,
|
|
|
68
68
|
const attributes = getNodeAttributes(node, currentWindow);
|
|
69
69
|
const pseudo = getPseudoElementContent(node, currentWindow);
|
|
70
70
|
const content = node.innerText || pseudo.before || pseudo.after || '';
|
|
71
|
-
const nodeHashId =
|
|
71
|
+
const nodeHashId = rpasceneGenerateHash(node, content, rect);
|
|
72
72
|
const elementInfo = {
|
|
73
73
|
id: nodeHashId,
|
|
74
74
|
indexId: indexId++,
|
|
@@ -93,7 +93,7 @@ function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1,
|
|
|
93
93
|
if (isImgElement(node, currentWindow)) {
|
|
94
94
|
var _node_nodeName;
|
|
95
95
|
const attributes = getNodeAttributes(node, currentWindow);
|
|
96
|
-
const nodeHashId =
|
|
96
|
+
const nodeHashId = rpasceneGenerateHash(node, '', rect);
|
|
97
97
|
const elementInfo = {
|
|
98
98
|
id: nodeHashId,
|
|
99
99
|
indexId: indexId++,
|
|
@@ -125,7 +125,7 @@ function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1,
|
|
|
125
125
|
const attributes = getNodeAttributes(node, currentWindow);
|
|
126
126
|
const attributeKeys = Object.keys(attributes);
|
|
127
127
|
if (!text.trim() && 0 === attributeKeys.length) return null;
|
|
128
|
-
const nodeHashId =
|
|
128
|
+
const nodeHashId = rpasceneGenerateHash(node, text, rect);
|
|
129
129
|
const elementInfo = {
|
|
130
130
|
id: nodeHashId,
|
|
131
131
|
indexId: indexId++,
|
|
@@ -151,7 +151,7 @@ function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1,
|
|
|
151
151
|
const attributes = getNodeAttributes(node, currentWindow);
|
|
152
152
|
const pseudo = getPseudoElementContent(node, currentWindow);
|
|
153
153
|
const content = node.innerText || pseudo.before || pseudo.after || '';
|
|
154
|
-
const nodeHashId =
|
|
154
|
+
const nodeHashId = rpasceneGenerateHash(node, content, rect);
|
|
155
155
|
const elementInfo = {
|
|
156
156
|
id: nodeHashId,
|
|
157
157
|
indexId: indexId++,
|
|
@@ -175,7 +175,7 @@ function collectElementInfo(node, currentWindow, currentDocument, baseZoom = 1,
|
|
|
175
175
|
}
|
|
176
176
|
if (isContainerElement(node, currentWindow) || isContainer) {
|
|
177
177
|
const attributes = getNodeAttributes(node, currentWindow);
|
|
178
|
-
const nodeHashId =
|
|
178
|
+
const nodeHashId = rpasceneGenerateHash(node, '', rect);
|
|
179
179
|
const elementInfo = {
|
|
180
180
|
id: nodeHashId,
|
|
181
181
|
nodeHashId,
|
package/dist/es/logger.mjs
CHANGED
|
@@ -2,15 +2,15 @@ import node_fs from "node:fs";
|
|
|
2
2
|
import node_path from "node:path";
|
|
3
3
|
import node_util from "node:util";
|
|
4
4
|
import debug from "debug";
|
|
5
|
-
import {
|
|
5
|
+
import { getRpasceneRunSubDir } from "./common.mjs";
|
|
6
6
|
import { ifInNode } from "./utils.mjs";
|
|
7
|
-
const topicPrefix = '
|
|
7
|
+
const topicPrefix = 'rpascene';
|
|
8
8
|
const logStreams = new Map();
|
|
9
9
|
const debugInstances = new Map();
|
|
10
10
|
function getLogStream(topic) {
|
|
11
11
|
const topicFileName = topic.replace(/:/g, '-');
|
|
12
12
|
if (!logStreams.has(topicFileName)) {
|
|
13
|
-
const logFile = node_path.join(
|
|
13
|
+
const logFile = node_path.join(getRpasceneRunSubDir('log'), `${topicFileName}.log`);
|
|
14
14
|
const stream = node_fs.createWriteStream(logFile, {
|
|
15
15
|
flags: 'a'
|
|
16
16
|
});
|