@hieutran094/ghost-cursor-playwright
v2.1.6
Published
Move your mouse like a human in playwright or generate realistic movements on any 2D plane
Maintainers
Readme
ghost-cursor-playwright
Modification of actual ghost-cursor for puppeteer, with more functionality and rewrite to work well with playwright. Note! target elements rendered in the DOM will be scrolled vertically and horizontally to be visible in viewport
✨ Tính năng mới: Timeout cho Mouse Movement
Script sẽ tiếp tục di chuyển chuột đến vị trí cuối cùng và bắn ra exception nếu quá thời gian timeout.
Download
git clone https://github.com/reaz1995/ghost-cursor-playwright.git cursor
cd cursor
npm installexample of usage in src/example.ts to run example use
npm run examplefor wsl2 don't forget to set up display
Download as package
npm i ghost-cursor-playwrightimport { createCursor } from 'ghost-cursor-playwright';
or;
const { createCursor } = require('ghost-cursor-playwright');How to use
Create and attach cursor to page
// Tạo cursor với timeout mặc định (5 giây)
const cursor = await createCursor(page);
// Hoặc tạo cursor với timeout tùy chỉnh
const cursor = await createCursor(page, { timeout: 3000 }); // 3 giâymanipulate the cursor via:
cursor.actions.move(target: string | BoundingBox | Vector, moveOptions?: moveOptions): Promise<void>;
type moveOptions = {
paddingPercentage?: number;
waitForSelector?: number;
waitBeforeMove?: [number, number];
};
cursor.actions.click(clickOptions?: clickOptions, moveOptions?: moveOptions): Promise<void>;
type clickOptions = {
target?: string | BoundingBox | Vector;
waitBeforeClick?: [number, number];
waitBetweenClick?: [number, number];
doubleClick?: boolean;
};
// if target is given then cursor will use move function before click
// if target is JS path string, then function will check if for sure is on correct target (sometimes rendered objects are covered in viewport by menu bar or dialogs etc.), if false will proceed fallback to native click
util functions
// actual position of cursor is mounted on window.mousePos, its value can be retrieve by
cursor.getActualPosOfMouse(): Promise<Vector>;
// actual target of cursor is mounted on window.mouseTarget, to compare target under cursor with given JS PATH selector use:
cursor.compareTargetOfMouse(selector: string): Promise<boolean>
// random Vector of element
cursor.getElemBoundingBox(selector: string): Promise<BoundingBox>
cursor.getRandomPointInsideElem(elemBoundingBox: BoundingBox, paddingPercentage?): Vector
// random Vector of viewport
cursor.getRandomPointOnViewport(paddingPercentage?): Promise<Vector>⏱️ Timeout và Error Handling
Cách hoạt động:
- Timeout mặc định: 5 giây cho toàn bộ quá trình di chuyển chuột (không phải từng điểm)
- Tiếp tục di chuyển: Script sẽ tiếp tục di chuyển đến vị trí cuối cùng ngay cả khi chuột thật di chuyển
- Exception rõ ràng: Nếu quá timeout, script sẽ bắn ra exception với thông báo rõ ràng
- Timeout thông minh: Click có timeout riêng (tối đa 1 giây) để không bị chậm
Ví dụ sử dụng:
import { createCursor, GhostCursorTimeoutError, GhostCursorMovementError, GhostCursorClickError } from 'ghost-cursor-playwright';
try {
const cursor = await createCursor(page, { timeout: 3000 }); // 3 giây timeout
await cursor.actions.move({ x: 100, y: 100 });
await cursor.actions.click();
} catch (error) {
if (error instanceof GhostCursorTimeoutError) {
console.log('⏰ Timeout Error:', error.message);
console.log('Operation:', error.operation); // 'move', 'click', 'mouseDown', 'mouseUp'
} else if (error instanceof GhostCursorMovementError) {
console.log('🖱️ Movement Error:', error.message);
} else if (error instanceof GhostCursorClickError) {
console.log('👆 Click Error:', error.message);
}
}Custom Exception Types:
GhostCursorTimeoutError: Khi operation bị timeoutoperation: 'move' | 'click' | 'mouseDown' | 'mouseUp'
GhostCursorMovementError: Khi di chuyển chuột thất bạioperation: 'move' | 'click'
GhostCursorClickError: Khi click thất bạioperation: 'click' | 'mouseDown' | 'mouseUp'
Reset State:
// Reset cursor state sau khi bị lỗi
cursor.resetState();
// Ví dụ sử dụng trong error handling
try {
await cursor.actions.move({ x: 100, y: 100 });
} catch (error) {
if (error instanceof GhostCursorTimeoutError) {
console.log('Bị timeout, reset state...');
cursor.resetState();
// Thử lại hoặc xử lý khác
}
}Lợi ích:
- ✅ Script không bị treo khi chuột thật di chuyển
- ✅ Tiếp tục di chuyển đến vị trí cuối cùng
- ✅ Báo lỗi rõ ràng khi quá timeout
- ✅ Có thể tùy chỉnh thời gian timeout
