craftdriver 0.0.1
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/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actions.d.ts +50 -0
- package/dist/lib/actions.d.ts.map +1 -0
- package/dist/lib/actions.js +71 -0
- package/dist/lib/actions.js.map +1 -0
- package/dist/lib/browser.d.ts +94 -0
- package/dist/lib/browser.d.ts.map +1 -0
- package/dist/lib/browser.js +133 -0
- package/dist/lib/browser.js.map +1 -0
- package/dist/lib/builder.d.ts +13 -0
- package/dist/lib/builder.d.ts.map +1 -0
- package/dist/lib/builder.js +31 -0
- package/dist/lib/builder.js.map +1 -0
- package/dist/lib/by.d.ts +45 -0
- package/dist/lib/by.d.ts.map +1 -0
- package/dist/lib/by.js +132 -0
- package/dist/lib/by.js.map +1 -0
- package/dist/lib/chrome.d.ts +6 -0
- package/dist/lib/chrome.d.ts.map +1 -0
- package/dist/lib/chrome.js +27 -0
- package/dist/lib/chrome.js.map +1 -0
- package/dist/lib/driver.d.ts +35 -0
- package/dist/lib/driver.d.ts.map +1 -0
- package/dist/lib/driver.js +347 -0
- package/dist/lib/driver.js.map +1 -0
- package/dist/lib/elementHandle.d.ts +17 -0
- package/dist/lib/elementHandle.d.ts.map +1 -0
- package/dist/lib/elementHandle.js +46 -0
- package/dist/lib/elementHandle.js.map +1 -0
- package/dist/lib/expect.d.ts +17 -0
- package/dist/lib/expect.d.ts.map +1 -0
- package/dist/lib/expect.js +56 -0
- package/dist/lib/expect.js.map +1 -0
- package/dist/lib/http.d.ts +7 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +47 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/keyboard.d.ts +14 -0
- package/dist/lib/keyboard.d.ts.map +1 -0
- package/dist/lib/keyboard.js +31 -0
- package/dist/lib/keyboard.js.map +1 -0
- package/dist/lib/keys.d.ts +43 -0
- package/dist/lib/keys.d.ts.map +1 -0
- package/dist/lib/keys.js +146 -0
- package/dist/lib/keys.js.map +1 -0
- package/dist/lib/locator.d.ts +20 -0
- package/dist/lib/locator.d.ts.map +1 -0
- package/dist/lib/locator.js +57 -0
- package/dist/lib/locator.js.map +1 -0
- package/dist/lib/mouse.d.ts +34 -0
- package/dist/lib/mouse.d.ts.map +1 -0
- package/dist/lib/mouse.js +108 -0
- package/dist/lib/mouse.js.map +1 -0
- package/dist/lib/service.d.ts +26 -0
- package/dist/lib/service.d.ts.map +1 -0
- package/dist/lib/service.js +86 -0
- package/dist/lib/service.js.map +1 -0
- package/dist/lib/types.d.ts +23 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/wait.d.ts +25 -0
- package/dist/lib/wait.d.ts.map +1 -0
- package/dist/lib/wait.js +92 -0
- package/dist/lib/wait.js.map +1 -0
- package/dist/lib/webelement.d.ts +20 -0
- package/dist/lib/webelement.d.ts.map +1 -0
- package/dist/lib/webelement.js +64 -0
- package/dist/lib/webelement.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { By } from './by.js';
|
|
2
|
+
import { Key } from './keys.js';
|
|
3
|
+
import { until } from './wait.js';
|
|
4
|
+
function toButtonCode(btn) {
|
|
5
|
+
if (btn === 'middle')
|
|
6
|
+
return 1;
|
|
7
|
+
if (btn === 'right')
|
|
8
|
+
return 2;
|
|
9
|
+
return 0;
|
|
10
|
+
}
|
|
11
|
+
export class MouseController {
|
|
12
|
+
driver;
|
|
13
|
+
constructor(driver) {
|
|
14
|
+
this.driver = driver;
|
|
15
|
+
}
|
|
16
|
+
async resolveElement(selector) {
|
|
17
|
+
const by = typeof selector === 'string' ? By.css(selector) : selector;
|
|
18
|
+
// Wait until element is attached and visible to improve click reliability
|
|
19
|
+
const el = await this.driver.wait(until.elementIsVisible(by), { timeout: 5000 });
|
|
20
|
+
return el;
|
|
21
|
+
}
|
|
22
|
+
async move(target, options) {
|
|
23
|
+
const duration = options?.durationMs ?? 100;
|
|
24
|
+
if (typeof target === 'string' || target.using) {
|
|
25
|
+
const el = await this.resolveElement(target);
|
|
26
|
+
await this.driver.pointerMoveTo(el, undefined, undefined, duration);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const pt = target;
|
|
30
|
+
await this.driver.pointerMoveTo(undefined, pt.x, pt.y, duration);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async down(button = 'left') {
|
|
34
|
+
await this.driver.mouseDown(toButtonCode(button));
|
|
35
|
+
}
|
|
36
|
+
async up(button = 'left') {
|
|
37
|
+
await this.driver.mouseUp(toButtonCode(button));
|
|
38
|
+
}
|
|
39
|
+
async click(target, options) {
|
|
40
|
+
const button = options?.button ?? 'left';
|
|
41
|
+
const count = Math.max(1, options?.clickCount ?? 1);
|
|
42
|
+
const modifiers = options?.modifiers ?? [];
|
|
43
|
+
for (const k of modifiers)
|
|
44
|
+
await this.driver.keyDownCode(Key[k]);
|
|
45
|
+
if (typeof target === 'string' || target.using) {
|
|
46
|
+
const el = await this.resolveElement(target);
|
|
47
|
+
await this.driver.pointerClick(el, undefined, undefined, toButtonCode(button), count, 50);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const pt = target;
|
|
51
|
+
await this.driver.pointerClick(undefined, pt.x, pt.y, toButtonCode(button), count, 50);
|
|
52
|
+
}
|
|
53
|
+
for (const k of modifiers.slice().reverse())
|
|
54
|
+
await this.driver.keyUpCode(Key[k]);
|
|
55
|
+
}
|
|
56
|
+
async dblclick(target, options) {
|
|
57
|
+
await this.click(target, {
|
|
58
|
+
button: options?.button,
|
|
59
|
+
clickCount: 2,
|
|
60
|
+
modifiers: options?.modifiers,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async dragAndDrop(from, to, options) {
|
|
64
|
+
const duration = options?.durationMs ?? 200;
|
|
65
|
+
const modifiers = options?.modifiers ?? [];
|
|
66
|
+
for (const k of modifiers)
|
|
67
|
+
await this.driver.keyDownCode(Key[k]);
|
|
68
|
+
const resolve = async (t) => {
|
|
69
|
+
if (typeof t === 'string' || t.using)
|
|
70
|
+
return await this.resolveElement(t);
|
|
71
|
+
return t;
|
|
72
|
+
};
|
|
73
|
+
const src = await resolve(from);
|
|
74
|
+
const dst = await resolve(to);
|
|
75
|
+
if ('x' in src) {
|
|
76
|
+
await this.driver.pointerMoveTo(undefined, src.x, src.y, 0);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
await this.driver.pointerMoveTo(src, undefined, undefined, 0);
|
|
80
|
+
}
|
|
81
|
+
await this.driver.mouseDown(0);
|
|
82
|
+
if ('x' in dst) {
|
|
83
|
+
await this.driver.pointerMoveTo(undefined, dst.x, dst.y, duration);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
await this.driver.pointerMoveTo(dst, undefined, undefined, duration);
|
|
87
|
+
}
|
|
88
|
+
await this.driver.mouseUp(0);
|
|
89
|
+
for (const k of modifiers.slice().reverse())
|
|
90
|
+
await this.driver.keyUpCode(Key[k]);
|
|
91
|
+
}
|
|
92
|
+
async wheel(deltaX, deltaY, target) {
|
|
93
|
+
if (!target) {
|
|
94
|
+
await this.driver.wheelScroll(deltaX, deltaY);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (typeof target === 'string' || target.using) {
|
|
98
|
+
const el = await this.resolveElement(target);
|
|
99
|
+
const [x, y] = await this.driver.executeScript(`return (function(el){ const r = el.getBoundingClientRect(); return [Math.round(r.left + r.width/2), Math.round(r.top + r.height/2)]; })(arguments[0]);`, [el.toJSON()]);
|
|
100
|
+
await this.driver.wheelScroll(deltaX, deltaY, x, y);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const pt = target;
|
|
104
|
+
await this.driver.wheelScroll(deltaX, deltaY, pt.x, pt.y);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=mouse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mouse.js","sourceRoot":"","sources":["../../src/lib/mouse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ChildProcess } from 'child_process';
|
|
2
|
+
import { WebDriverEndpoint } from './types.js';
|
|
3
|
+
export interface DriverServiceOptions {
|
|
4
|
+
command: string;
|
|
5
|
+
args?: string[];
|
|
6
|
+
hostname?: string;
|
|
7
|
+
port?: number;
|
|
8
|
+
pathBase?: string;
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
readinessPath?: string;
|
|
11
|
+
readinessTimeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class DriverService {
|
|
14
|
+
protected proc?: ChildProcess;
|
|
15
|
+
protected endpoint: WebDriverEndpoint;
|
|
16
|
+
protected readonly opts: Required<Omit<DriverServiceOptions, 'env'>> & {
|
|
17
|
+
env?: NodeJS.ProcessEnv;
|
|
18
|
+
};
|
|
19
|
+
constructor(options: DriverServiceOptions);
|
|
20
|
+
getEndpoint(): WebDriverEndpoint;
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
protected ensureBinaryAvailable(): Promise<void>;
|
|
24
|
+
protected waitUntilReady(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/lib/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,YAAY,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qBAAa,aAAa;IACxB,SAAS,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;IAC9B,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC,GAAG;QACrE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACzB,CAAC;gBAEU,OAAO,EAAE,oBAAoB;IAmBzC,WAAW,IAAI,iBAAiB;IAI1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;cAOX,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;cAsBtC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBhD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { HttpClient } from './http.js';
|
|
3
|
+
export class DriverService {
|
|
4
|
+
proc;
|
|
5
|
+
endpoint;
|
|
6
|
+
opts;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.opts = {
|
|
9
|
+
args: options.args ?? [],
|
|
10
|
+
command: options.command,
|
|
11
|
+
hostname: options.hostname ?? '127.0.0.1',
|
|
12
|
+
port: options.port ?? 9515,
|
|
13
|
+
pathBase: options.pathBase ?? '',
|
|
14
|
+
readinessPath: options.readinessPath ?? '/status',
|
|
15
|
+
readinessTimeoutMs: options.readinessTimeoutMs ?? 5000,
|
|
16
|
+
env: options.env,
|
|
17
|
+
};
|
|
18
|
+
this.endpoint = {
|
|
19
|
+
protocol: 'http',
|
|
20
|
+
hostname: this.opts.hostname,
|
|
21
|
+
port: this.opts.port,
|
|
22
|
+
path: this.opts.pathBase,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
getEndpoint() {
|
|
26
|
+
return this.endpoint;
|
|
27
|
+
}
|
|
28
|
+
async start() {
|
|
29
|
+
if (this.proc)
|
|
30
|
+
return; // already started
|
|
31
|
+
await this.ensureBinaryAvailable();
|
|
32
|
+
this.proc = spawn(this.opts.command, [`--port=${this.opts.port}`, ...this.opts.args], {
|
|
33
|
+
env: { ...process.env, ...this.opts.env },
|
|
34
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
35
|
+
});
|
|
36
|
+
// Wait for readiness
|
|
37
|
+
await this.waitUntilReady();
|
|
38
|
+
}
|
|
39
|
+
async stop() {
|
|
40
|
+
if (!this.proc)
|
|
41
|
+
return;
|
|
42
|
+
const p = this.proc;
|
|
43
|
+
this.proc = undefined;
|
|
44
|
+
p.kill();
|
|
45
|
+
}
|
|
46
|
+
async ensureBinaryAvailable() {
|
|
47
|
+
// Basic check: try "command --version" quickly
|
|
48
|
+
await new Promise((resolve, reject) => {
|
|
49
|
+
const check = spawn(this.opts.command, ['--version'], {
|
|
50
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
51
|
+
});
|
|
52
|
+
let resolved = false;
|
|
53
|
+
check.on('error', (e) => {
|
|
54
|
+
if (!resolved) {
|
|
55
|
+
resolved = true;
|
|
56
|
+
reject(new Error(`Failed to run ${this.opts.command}. Is it installed and on PATH?`));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
check.on('exit', () => {
|
|
60
|
+
if (!resolved) {
|
|
61
|
+
resolved = true;
|
|
62
|
+
resolve();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async waitUntilReady() {
|
|
68
|
+
const client = new HttpClient(this.endpoint);
|
|
69
|
+
const deadline = Date.now() + this.opts.readinessTimeoutMs;
|
|
70
|
+
let lastErr;
|
|
71
|
+
while (Date.now() < deadline) {
|
|
72
|
+
try {
|
|
73
|
+
const res = await client.send({ method: 'GET', path: this.opts.readinessPath });
|
|
74
|
+
// chromedriver responds with { value: { ready: true, message: '...' } } or similar
|
|
75
|
+
if (res && typeof res === 'object')
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
lastErr = e;
|
|
80
|
+
}
|
|
81
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`Driver service not ready at ${this.endpoint.hostname}:${this.endpoint.port} - ${String(lastErr)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/lib/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type Capabilities = Record<string, unknown> & {
|
|
2
|
+
browserName?: string;
|
|
3
|
+
'goog:chromeOptions'?: Record<string, unknown>;
|
|
4
|
+
};
|
|
5
|
+
export interface SessionResponse {
|
|
6
|
+
sessionId: string;
|
|
7
|
+
capabilities: Capabilities;
|
|
8
|
+
}
|
|
9
|
+
export interface CommandResponse<T = any> {
|
|
10
|
+
value: T;
|
|
11
|
+
}
|
|
12
|
+
export interface RequestOptions {
|
|
13
|
+
method: 'GET' | 'POST' | 'DELETE';
|
|
14
|
+
path: string;
|
|
15
|
+
body?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface WebDriverEndpoint {
|
|
18
|
+
protocol: 'http' | 'https';
|
|
19
|
+
hostname: string;
|
|
20
|
+
port: number;
|
|
21
|
+
path?: string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,GAAG;IACtC,KAAK,EAAE,CAAC,CAAC;CACV;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Driver } from './driver.js';
|
|
2
|
+
import { By } from './by.js';
|
|
3
|
+
import { WebElement } from './webelement.js';
|
|
4
|
+
export type Condition<T = any> = (driver: Driver) => Promise<T>;
|
|
5
|
+
export interface WaitOptions {
|
|
6
|
+
timeout?: number;
|
|
7
|
+
interval?: number;
|
|
8
|
+
timeoutMsg?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class WebDriverWait {
|
|
11
|
+
private driver;
|
|
12
|
+
private timeoutMs;
|
|
13
|
+
private intervalMs;
|
|
14
|
+
private timeoutMsg?;
|
|
15
|
+
constructor(driver: Driver, timeoutOrOptions?: number | WaitOptions, intervalMs?: number);
|
|
16
|
+
until<T>(condition: Condition<T>, message?: string): Promise<T>;
|
|
17
|
+
}
|
|
18
|
+
export declare const until: {
|
|
19
|
+
elementLocated: (locator: By) => (driver: Driver) => Promise<WebElement>;
|
|
20
|
+
elementExists: (locator: By) => (driver: Driver) => Promise<any>;
|
|
21
|
+
elementNotExists: (locator: By) => (driver: Driver) => Promise<any>;
|
|
22
|
+
elementIsVisible: (target: By | WebElement) => (driver: Driver) => Promise<any>;
|
|
23
|
+
elementIsNotVisible: (target: By | WebElement) => (driver: Driver) => Promise<any>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=wait.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../src/lib/wait.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IAMtB,OAAO,CAAC,MAAM;IALhB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAS;gBAGlB,MAAM,EAAE,MAAM,EACtB,gBAAgB,CAAC,EAAE,MAAM,GAAG,WAAW,EACvC,UAAU,CAAC,EAAE,MAAM;IAYf,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAoBtE;AAOD,eAAO,MAAM,KAAK;8BACU,EAAE,MAAY,QAAQ,MAAM;6BAI7B,EAAE,MAAY,QAAQ,MAAM;gCASzB,EAAE,MAAY,QAAQ,MAAM;+BAS7B,EAAE,GAAG,UAAU,MAAY,QAAQ,MAAM;kCAUtC,EAAE,GAAG,UAAU,MAAY,QAAQ,MAAM;CAaxE,CAAC"}
|
package/dist/lib/wait.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { WebElement } from './webelement.js';
|
|
2
|
+
export class WebDriverWait {
|
|
3
|
+
driver;
|
|
4
|
+
timeoutMs;
|
|
5
|
+
intervalMs;
|
|
6
|
+
timeoutMsg;
|
|
7
|
+
constructor(driver, timeoutOrOptions, intervalMs) {
|
|
8
|
+
this.driver = driver;
|
|
9
|
+
if (typeof timeoutOrOptions === 'object') {
|
|
10
|
+
this.timeoutMs = timeoutOrOptions?.timeout ?? 5000;
|
|
11
|
+
this.intervalMs = timeoutOrOptions?.interval ?? 100;
|
|
12
|
+
this.timeoutMsg = timeoutOrOptions?.timeoutMsg;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.timeoutMs = timeoutOrOptions ?? 5000;
|
|
16
|
+
this.intervalMs = intervalMs ?? 100;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async until(condition, message) {
|
|
20
|
+
const deadline = Date.now() + this.timeoutMs;
|
|
21
|
+
let lastErr;
|
|
22
|
+
while (Date.now() < deadline) {
|
|
23
|
+
try {
|
|
24
|
+
const result = await condition(this.driver);
|
|
25
|
+
// Resolve on truthy or non-null/undefined result
|
|
26
|
+
if (result || result === 0 || result === false) {
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
lastErr = e;
|
|
32
|
+
}
|
|
33
|
+
await new Promise((r) => setTimeout(r, this.intervalMs));
|
|
34
|
+
}
|
|
35
|
+
const errMsg = message ?? this.timeoutMsg ?? `Wait timed out after ${this.timeoutMs}ms`;
|
|
36
|
+
throw new Error(lastErr ? `${errMsg}: ${String(lastErr?.message ?? lastErr)}` : errMsg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function resolveElement(driver, target) {
|
|
40
|
+
if (target instanceof WebElement)
|
|
41
|
+
return target;
|
|
42
|
+
return await driver.findElement(target);
|
|
43
|
+
}
|
|
44
|
+
export const until = {
|
|
45
|
+
elementLocated: (locator) => async (driver) => {
|
|
46
|
+
return await driver.findElement(locator);
|
|
47
|
+
},
|
|
48
|
+
elementExists: (locator) => async (driver) => {
|
|
49
|
+
try {
|
|
50
|
+
await driver.findElement(locator);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false; // keep waiting
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
elementNotExists: (locator) => async (driver) => {
|
|
58
|
+
try {
|
|
59
|
+
await driver.findElement(locator);
|
|
60
|
+
return false; // still exists, keep waiting
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
elementIsVisible: (target) => async (driver) => {
|
|
67
|
+
const el = await resolveElement(driver, target);
|
|
68
|
+
try {
|
|
69
|
+
const visible = await el.isDisplayed();
|
|
70
|
+
return visible ? el : undefined;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return undefined; // stale/not found -> not visible yet
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
elementIsNotVisible: (target) => async (driver) => {
|
|
77
|
+
try {
|
|
78
|
+
const el = await resolveElement(driver, target);
|
|
79
|
+
try {
|
|
80
|
+
const visible = await el.isDisplayed();
|
|
81
|
+
return visible ? false : true;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return true; // stale/not found counts as not visible
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return true; // not found
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=wait.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/lib/wait.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { WebDriverEndpoint } from './types.js';
|
|
2
|
+
export declare const W3C_ELEMENT_KEY = "element-6066-11e4-a52e-4f735466cecf";
|
|
3
|
+
export declare const LEGACY_ELEMENT_KEY = "ELEMENT";
|
|
4
|
+
export declare class WebElement {
|
|
5
|
+
private endpoint;
|
|
6
|
+
private sessionId;
|
|
7
|
+
private elementId;
|
|
8
|
+
constructor(endpoint: WebDriverEndpoint, sessionId: string, elementId: string);
|
|
9
|
+
getId(): string;
|
|
10
|
+
click(): Promise<void>;
|
|
11
|
+
sendKeys(text: string): Promise<void>;
|
|
12
|
+
getText(): Promise<string>;
|
|
13
|
+
toJSON(): {
|
|
14
|
+
"element-6066-11e4-a52e-4f735466cecf": string;
|
|
15
|
+
ELEMENT: string;
|
|
16
|
+
};
|
|
17
|
+
isDisplayed(): Promise<boolean>;
|
|
18
|
+
screenshotBase64(): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=webelement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webelement.d.ts","sourceRoot":"","sources":["../../src/lib/webelement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAErE,eAAO,MAAM,eAAe,wCAAwC,CAAC;AACrE,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;gBAFT,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM;IAG3B,KAAK,IAAI,MAAM;IAIT,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAUhC,MAAM;;;;IAIA,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAS1C"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { HttpClient } from './http.js';
|
|
2
|
+
export const W3C_ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf';
|
|
3
|
+
export const LEGACY_ELEMENT_KEY = 'ELEMENT';
|
|
4
|
+
export class WebElement {
|
|
5
|
+
endpoint;
|
|
6
|
+
sessionId;
|
|
7
|
+
elementId;
|
|
8
|
+
constructor(endpoint, sessionId, elementId) {
|
|
9
|
+
this.endpoint = endpoint;
|
|
10
|
+
this.sessionId = sessionId;
|
|
11
|
+
this.elementId = elementId;
|
|
12
|
+
}
|
|
13
|
+
getId() {
|
|
14
|
+
return this.elementId;
|
|
15
|
+
}
|
|
16
|
+
async click() {
|
|
17
|
+
const client = new HttpClient(this.endpoint);
|
|
18
|
+
await client.send({
|
|
19
|
+
method: 'POST',
|
|
20
|
+
path: `/session/${this.sessionId}/element/${this.elementId}/click`,
|
|
21
|
+
body: {},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async sendKeys(text) {
|
|
25
|
+
const client = new HttpClient(this.endpoint);
|
|
26
|
+
const payload = { text, value: text.split('') };
|
|
27
|
+
await client.send({
|
|
28
|
+
method: 'POST',
|
|
29
|
+
path: `/session/${this.sessionId}/element/${this.elementId}/value`,
|
|
30
|
+
body: payload,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async getText() {
|
|
34
|
+
const client = new HttpClient(this.endpoint);
|
|
35
|
+
const res = await client.send({
|
|
36
|
+
method: 'GET',
|
|
37
|
+
path: `/session/${this.sessionId}/element/${this.elementId}/text`,
|
|
38
|
+
});
|
|
39
|
+
const value = res?.value ?? res;
|
|
40
|
+
return String(value ?? '');
|
|
41
|
+
}
|
|
42
|
+
toJSON() {
|
|
43
|
+
return { [W3C_ELEMENT_KEY]: this.elementId, [LEGACY_ELEMENT_KEY]: this.elementId };
|
|
44
|
+
}
|
|
45
|
+
async isDisplayed() {
|
|
46
|
+
const client = new HttpClient(this.endpoint);
|
|
47
|
+
const res = await client.send({
|
|
48
|
+
method: 'GET',
|
|
49
|
+
path: `/session/${this.sessionId}/element/${this.elementId}/displayed`,
|
|
50
|
+
});
|
|
51
|
+
const value = res?.value ?? res;
|
|
52
|
+
return Boolean(value);
|
|
53
|
+
}
|
|
54
|
+
async screenshotBase64() {
|
|
55
|
+
const client = new HttpClient(this.endpoint);
|
|
56
|
+
const res = await client.send({
|
|
57
|
+
method: 'GET',
|
|
58
|
+
path: `/session/${this.sessionId}/element/${this.elementId}/screenshot`,
|
|
59
|
+
});
|
|
60
|
+
const value = res?.value ?? res;
|
|
61
|
+
return String(value ?? '');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=webelement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webelement.js","sourceRoot":"","sources":["../../src/lib/webelement.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "craftdriver",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Modern WebDriver automation library for NodeJS",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"prebuild": "rimraf dist",
|
|
10
|
+
"build": "tsc -p tsconfig.json",
|
|
11
|
+
"lint": "eslint . --ext .ts",
|
|
12
|
+
"format": "prettier --write .",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:firefox": "BROWSER_NAME=firefox vitest run",
|
|
15
|
+
"test:chrome": "BROWSER_NAME=chrome vitest run",
|
|
16
|
+
"test:chromium": "BROWSER_NAME=chromium vitest run",
|
|
17
|
+
"clean": "rimraf dist",
|
|
18
|
+
"serve": "http-server ./examples -a 127.0.0.1 -p 8080 -c-1 --cors",
|
|
19
|
+
"examples:start": "npm run serve",
|
|
20
|
+
"prepublishOnly": "npm run build && npm run lint"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"webdriver",
|
|
24
|
+
"bidi",
|
|
25
|
+
"firefox",
|
|
26
|
+
"chrome",
|
|
27
|
+
"chromium",
|
|
28
|
+
"automation",
|
|
29
|
+
"browser-automation",
|
|
30
|
+
"testing",
|
|
31
|
+
"selenium"
|
|
32
|
+
],
|
|
33
|
+
"author": "Dimitar Topuzov",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/dtopuzov/craftdriver.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/dtopuzov/craftdriver/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/dtopuzov/craftdriver#readme",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE"
|
|
50
|
+
],
|
|
51
|
+
"sideEffects": false,
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^20.0.0",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^8.1.0",
|
|
55
|
+
"@typescript-eslint/parser": "^8.1.0",
|
|
56
|
+
"eslint": "^9.8.0",
|
|
57
|
+
"eslint-config-prettier": "^9.1.0",
|
|
58
|
+
"eslint-plugin-import": "^2.29.1",
|
|
59
|
+
"eslint-plugin-n": "^17.10.1",
|
|
60
|
+
"eslint-plugin-promise": "^6.4.0",
|
|
61
|
+
"http-server": "^14.1.1",
|
|
62
|
+
"prettier": "^3.3.3",
|
|
63
|
+
"rimraf": "^6.0.1",
|
|
64
|
+
"typescript": "^5.0.0",
|
|
65
|
+
"vitest": "^1.6.1"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
}
|
|
69
|
+
}
|