chrome-e2e-sdk 0.0.0-stage → 1.0.0
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 +739 -2
- package/dist/assertion/Assertion.d.ts +87 -0
- package/dist/assertion/Assertion.d.ts.map +1 -0
- package/dist/assertion/Assertion.js +459 -0
- package/dist/assertion/Assertion.js.map +1 -0
- package/dist/assertion/recorder.d.ts +41 -0
- package/dist/assertion/recorder.d.ts.map +1 -0
- package/dist/assertion/recorder.js +37 -0
- package/dist/assertion/recorder.js.map +1 -0
- package/dist/browser/Browser.d.ts +44 -0
- package/dist/browser/Browser.d.ts.map +1 -0
- package/dist/browser/Browser.js +167 -0
- package/dist/browser/Browser.js.map +1 -0
- package/dist/browser/Locator.d.ts +94 -0
- package/dist/browser/Locator.d.ts.map +1 -0
- package/dist/browser/Locator.js +533 -0
- package/dist/browser/Locator.js.map +1 -0
- package/dist/browser/Page.d.ts +272 -0
- package/dist/browser/Page.d.ts.map +1 -0
- package/dist/browser/Page.js +979 -0
- package/dist/browser/Page.js.map +1 -0
- package/dist/client/MCPClient.d.ts +72 -0
- package/dist/client/MCPClient.d.ts.map +1 -0
- package/dist/client/MCPClient.js +302 -0
- package/dist/client/MCPClient.js.map +1 -0
- package/dist/client/MCPCommand.d.ts +51 -0
- package/dist/client/MCPCommand.d.ts.map +1 -0
- package/dist/client/MCPCommand.js +74 -0
- package/dist/client/MCPCommand.js.map +1 -0
- package/dist/env/loadEnv.d.ts +8 -0
- package/dist/env/loadEnv.d.ts.map +1 -0
- package/dist/env/loadEnv.js +19 -0
- package/dist/env/loadEnv.js.map +1 -0
- package/dist/errors/E2EError.d.ts +50 -0
- package/dist/errors/E2EError.d.ts.map +1 -0
- package/dist/errors/E2EError.js +90 -0
- package/dist/errors/E2EError.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +12 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +57 -0
- package/dist/logger.js.map +1 -0
- package/dist/network/Network.d.ts +72 -0
- package/dist/network/Network.d.ts.map +1 -0
- package/dist/network/Network.js +236 -0
- package/dist/network/Network.js.map +1 -0
- package/dist/test/HtmlReport.d.ts +26 -0
- package/dist/test/HtmlReport.d.ts.map +1 -0
- package/dist/test/HtmlReport.js +653 -0
- package/dist/test/HtmlReport.js.map +1 -0
- package/dist/test/Runner.d.ts +146 -0
- package/dist/test/Runner.d.ts.map +1 -0
- package/dist/test/Runner.js +390 -0
- package/dist/test/Runner.js.map +1 -0
- package/dist/test/index.d.ts +4 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +3 -0
- package/dist/test/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/package.json +63 -4
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
const storage = new AsyncLocalStorage();
|
|
3
|
+
/**
|
|
4
|
+
* Records a passing assertion, if a test is currently collecting.
|
|
5
|
+
*
|
|
6
|
+
* A no-op outside a collected run, so `expect()` stays usable on its own -
|
|
7
|
+
* from a script, or from a test written against a different runner.
|
|
8
|
+
*/
|
|
9
|
+
export function recordCheck(check) {
|
|
10
|
+
storage.getStore()?.push(check);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Runs `fn` with a fresh list and returns what it recorded, plus whatever it
|
|
14
|
+
* threw.
|
|
15
|
+
*
|
|
16
|
+
* The error is returned rather than propagated because a test that fails on its
|
|
17
|
+
* tenth assertion still made nine passes worth showing, and losing them would
|
|
18
|
+
* hide exactly the context the report exists to give. A caller that only wants
|
|
19
|
+
* the checks can ignore it.
|
|
20
|
+
*
|
|
21
|
+
* AsyncLocalStorage rather than a module-level variable: the list has to
|
|
22
|
+
* survive every `await` inside the test body while staying invisible to a
|
|
23
|
+
* second test running concurrently, and nothing about the public assertion API
|
|
24
|
+
* should have to change to carry it.
|
|
25
|
+
*/
|
|
26
|
+
export async function collectChecks(fn) {
|
|
27
|
+
const checks = [];
|
|
28
|
+
let error;
|
|
29
|
+
try {
|
|
30
|
+
await storage.run(checks, fn);
|
|
31
|
+
}
|
|
32
|
+
catch (caught) {
|
|
33
|
+
error = caught;
|
|
34
|
+
}
|
|
35
|
+
return { error, checks };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/assertion/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAkBpD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAmB,CAAA;AAExD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAuB;IAEvB,MAAM,MAAM,GAAoB,EAAE,CAAA;IAClC,IAAI,KAAc,CAAA;IAElB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC/B,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,KAAK,GAAG,MAAM,CAAA;IAChB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MCPClient, type MCPClientOptions } from '../client/MCPClient.js';
|
|
2
|
+
import { Page } from './Page.js';
|
|
3
|
+
export interface PageInfo {
|
|
4
|
+
id: number;
|
|
5
|
+
url: string;
|
|
6
|
+
title: string;
|
|
7
|
+
isActive: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface BrowserOptions extends MCPClientOptions {
|
|
10
|
+
timeout?: number;
|
|
11
|
+
defaultTimeout?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class Browser {
|
|
14
|
+
private mcpClient;
|
|
15
|
+
private pagesMap;
|
|
16
|
+
private defaultTimeout;
|
|
17
|
+
private closed;
|
|
18
|
+
private readonly logger;
|
|
19
|
+
private constructor();
|
|
20
|
+
private createLogger;
|
|
21
|
+
static connect(options?: BrowserOptions): Promise<Browser>;
|
|
22
|
+
pages(): Promise<Page[]>;
|
|
23
|
+
currentPage(): Promise<Page>;
|
|
24
|
+
newPage(url?: string): Promise<Page>;
|
|
25
|
+
selectPage(pageId: number): Promise<Page>;
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
getDefaultTimeout(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Updates the default timeout for this browser and every page already handed
|
|
30
|
+
* out, so locators and network waits created earlier pick up the new value.
|
|
31
|
+
*/
|
|
32
|
+
setDefaultTimeout(timeout: number): void;
|
|
33
|
+
isClosed(): boolean;
|
|
34
|
+
getMCPClient(): MCPClient;
|
|
35
|
+
/**
|
|
36
|
+
* Reloads the page list, reusing existing `Page` instances so previously
|
|
37
|
+
* obtained locators keep pointing at a live page object.
|
|
38
|
+
*/
|
|
39
|
+
private refreshPages;
|
|
40
|
+
private parsePages;
|
|
41
|
+
private ensureNotClosed;
|
|
42
|
+
}
|
|
43
|
+
export declare function connect(options?: BrowserOptions): Promise<Browser>;
|
|
44
|
+
//# sourceMappingURL=Browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Browser.d.ts","sourceRoot":"","sources":["../../src/browser/Browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IAEjE,OAAO;IAMP,OAAO,CAAC,YAAY;WAQP,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB9D,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAMxB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BpC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B,iBAAiB,IAAI,MAAM;IAI3B;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAWxC,QAAQ,IAAI,OAAO;IAInB,YAAY,IAAI,SAAS;IAIzB;;;OAGG;YACW,YAAY;IAmB1B,OAAO,CAAC,UAAU;IAgClB,OAAO,CAAC,eAAe;CAKxB;AAcD,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5E"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { MCPClient } from '../client/MCPClient.js';
|
|
2
|
+
import { DEFAULT_TIMEOUT_MS } from '../client/MCPCommand.js';
|
|
3
|
+
import { Page } from './Page.js';
|
|
4
|
+
import { E2EError, E2EErrorCode } from '../errors/E2EError.js';
|
|
5
|
+
export class Browser {
|
|
6
|
+
mcpClient;
|
|
7
|
+
pagesMap = new Map();
|
|
8
|
+
defaultTimeout;
|
|
9
|
+
closed = false;
|
|
10
|
+
logger;
|
|
11
|
+
constructor(mcpClient, defaultTimeout) {
|
|
12
|
+
this.mcpClient = mcpClient;
|
|
13
|
+
this.defaultTimeout = defaultTimeout;
|
|
14
|
+
this.logger = this.createLogger();
|
|
15
|
+
}
|
|
16
|
+
createLogger() {
|
|
17
|
+
return (level, message) => {
|
|
18
|
+
if (process.env['DEBUG']?.includes('chrome-e2e')) {
|
|
19
|
+
console.error(`[ChromeE2E:Browser] ${level.toUpperCase()}: ${message}`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
static async connect(options = {}) {
|
|
24
|
+
const defaultTimeout = options.defaultTimeout ?? options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
25
|
+
// Extract MCPClient options (exclude SDK timeout aliases)
|
|
26
|
+
const { defaultTimeout: _, timeout: __, ...mcpOptions } = options;
|
|
27
|
+
const mcpClient = new MCPClient(mcpOptions);
|
|
28
|
+
await mcpClient.connect();
|
|
29
|
+
const browser = new Browser(mcpClient, defaultTimeout);
|
|
30
|
+
// Initialize pages list
|
|
31
|
+
await browser.refreshPages();
|
|
32
|
+
return browser;
|
|
33
|
+
}
|
|
34
|
+
async pages() {
|
|
35
|
+
this.ensureNotClosed();
|
|
36
|
+
await this.refreshPages();
|
|
37
|
+
return Array.from(this.pagesMap.values());
|
|
38
|
+
}
|
|
39
|
+
async currentPage() {
|
|
40
|
+
this.ensureNotClosed();
|
|
41
|
+
await this.refreshPages();
|
|
42
|
+
const activePage = Array.from(this.pagesMap.values()).find((p) => p.isActive());
|
|
43
|
+
if (!activePage) {
|
|
44
|
+
throw new E2EError(E2EErrorCode.PAGE_NOT_FOUND, 'No active page found');
|
|
45
|
+
}
|
|
46
|
+
return activePage;
|
|
47
|
+
}
|
|
48
|
+
async newPage(url) {
|
|
49
|
+
this.ensureNotClosed();
|
|
50
|
+
this.logger('debug', `Creating new page${url ? `: ${url}` : ''}`);
|
|
51
|
+
const result = await this.mcpClient.call('new_page', {
|
|
52
|
+
url: url ?? 'about:blank'
|
|
53
|
+
});
|
|
54
|
+
// `new_page` returns the full page list; the newly created tab is the selected one.
|
|
55
|
+
const selectedPage = this.parsePages(result).find((pageInfo) => pageInfo.active);
|
|
56
|
+
if (!selectedPage) {
|
|
57
|
+
throw new E2EError(E2EErrorCode.PAGE_NOT_FOUND, 'new_page did not report a selected page in its response');
|
|
58
|
+
}
|
|
59
|
+
const page = this.pagesMap.get(selectedPage.id) ?? new Page(this.mcpClient, selectedPage.id, this.defaultTimeout);
|
|
60
|
+
page.updatePageInfo(selectedPage.url, selectedPage.title, true);
|
|
61
|
+
this.pagesMap.set(selectedPage.id, page);
|
|
62
|
+
this.logger('debug', `New page created: ${selectedPage.id}`);
|
|
63
|
+
return page;
|
|
64
|
+
}
|
|
65
|
+
async selectPage(pageId) {
|
|
66
|
+
this.ensureNotClosed();
|
|
67
|
+
this.logger('debug', `Selecting page: ${pageId}`);
|
|
68
|
+
await this.mcpClient.call('select_page', { pageId, bringToFront: true });
|
|
69
|
+
const page = this.pagesMap.get(pageId) ?? new Page(this.mcpClient, pageId, this.defaultTimeout);
|
|
70
|
+
page.updatePageInfo(undefined, undefined, true);
|
|
71
|
+
this.pagesMap.set(pageId, page);
|
|
72
|
+
return page;
|
|
73
|
+
}
|
|
74
|
+
async close() {
|
|
75
|
+
if (this.closed) {
|
|
76
|
+
this.logger('debug', 'Browser already closed');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.logger('debug', 'Closing browser...');
|
|
80
|
+
this.pagesMap.clear();
|
|
81
|
+
// Close the MCP client connection. This intentionally does not close Chrome tabs.
|
|
82
|
+
await this.mcpClient.close();
|
|
83
|
+
this.closed = true;
|
|
84
|
+
this.logger('debug', 'Browser closed');
|
|
85
|
+
}
|
|
86
|
+
getDefaultTimeout() {
|
|
87
|
+
return this.defaultTimeout;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Updates the default timeout for this browser and every page already handed
|
|
91
|
+
* out, so locators and network waits created earlier pick up the new value.
|
|
92
|
+
*/
|
|
93
|
+
setDefaultTimeout(timeout) {
|
|
94
|
+
if (!Number.isFinite(timeout) || timeout < 0) {
|
|
95
|
+
throw E2EError.invalidArgument('timeout', 'non-negative number', timeout);
|
|
96
|
+
}
|
|
97
|
+
this.defaultTimeout = timeout;
|
|
98
|
+
for (const page of this.pagesMap.values()) {
|
|
99
|
+
page.setDefaultTimeout(timeout);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
isClosed() {
|
|
103
|
+
return this.closed;
|
|
104
|
+
}
|
|
105
|
+
getMCPClient() {
|
|
106
|
+
return this.mcpClient;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Reloads the page list, reusing existing `Page` instances so previously
|
|
110
|
+
* obtained locators keep pointing at a live page object.
|
|
111
|
+
*/
|
|
112
|
+
async refreshPages() {
|
|
113
|
+
const result = await this.mcpClient.call('list_pages', {});
|
|
114
|
+
const pageInfos = this.parsePages(result);
|
|
115
|
+
const seen = new Set();
|
|
116
|
+
for (const pageInfo of pageInfos) {
|
|
117
|
+
seen.add(pageInfo.id);
|
|
118
|
+
const page = this.pagesMap.get(pageInfo.id) ?? new Page(this.mcpClient, pageInfo.id, this.defaultTimeout);
|
|
119
|
+
page.updatePageInfo(pageInfo.url, pageInfo.title, pageInfo.active);
|
|
120
|
+
this.pagesMap.set(pageInfo.id, page);
|
|
121
|
+
}
|
|
122
|
+
for (const pageId of [...this.pagesMap.keys()]) {
|
|
123
|
+
if (!seen.has(pageId)) {
|
|
124
|
+
this.pagesMap.delete(pageId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
parsePages(result) {
|
|
129
|
+
if (typeof result === 'object' && result !== null && Array.isArray(result.pages)) {
|
|
130
|
+
return result.pages.map((page) => ({
|
|
131
|
+
id: page.id,
|
|
132
|
+
url: page.url,
|
|
133
|
+
title: page.title || page.url,
|
|
134
|
+
active: page.selected
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
const text = String(result);
|
|
138
|
+
return text
|
|
139
|
+
.split(/\r?\n/)
|
|
140
|
+
.map((line) => {
|
|
141
|
+
const match = line.match(/^(\d+):\s+(?:(.*?)\s+\(([^)]*)\)|(.*?))(\s+\[selected\])?(?:\s+isolatedContext=.*)?$/);
|
|
142
|
+
if (!match)
|
|
143
|
+
return null;
|
|
144
|
+
const id = Number(match[1]);
|
|
145
|
+
const title = (match[2] ?? '').trim();
|
|
146
|
+
const bareUrl = (match[4] ?? '').trim();
|
|
147
|
+
const url = match[3] ?? bareUrl;
|
|
148
|
+
return {
|
|
149
|
+
id,
|
|
150
|
+
url,
|
|
151
|
+
title: title || url,
|
|
152
|
+
active: Boolean(match[5])
|
|
153
|
+
};
|
|
154
|
+
})
|
|
155
|
+
.filter((pageInfo) => pageInfo !== null);
|
|
156
|
+
}
|
|
157
|
+
ensureNotClosed() {
|
|
158
|
+
if (this.closed) {
|
|
159
|
+
throw E2EError.browserClosed();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Convenience function
|
|
164
|
+
export async function connect(options = {}) {
|
|
165
|
+
return Browser.connect(options);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=Browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Browser.js","sourceRoot":"","sources":["../../src/browser/Browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Page } from './Page.js';
|
|
2
|
+
import { type Selector } from '../errors/E2EError.js';
|
|
3
|
+
export interface LocatorOptions {
|
|
4
|
+
timeout?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class Locator {
|
|
7
|
+
private page;
|
|
8
|
+
private selector;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
constructor(page: Page, selector: Selector);
|
|
11
|
+
/**
|
|
12
|
+
* The selector this locator was built from. Read-only copy for diagnostics.
|
|
13
|
+
*/
|
|
14
|
+
getSelector(): Selector;
|
|
15
|
+
private get spec();
|
|
16
|
+
/**
|
|
17
|
+
* Human readable selector description, used in error messages.
|
|
18
|
+
*/
|
|
19
|
+
describe(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Timeout is read from the owning page on every call so that
|
|
22
|
+
* `browser.setDefaultTimeout()` reaches locators that were created earlier.
|
|
23
|
+
*/
|
|
24
|
+
private get defaultTimeout();
|
|
25
|
+
private createLogger;
|
|
26
|
+
click(options?: LocatorOptions): Promise<void>;
|
|
27
|
+
fill(value: string, options?: LocatorOptions): Promise<void>;
|
|
28
|
+
type(text: string, options?: LocatorOptions & {
|
|
29
|
+
delay?: number;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
press(key: string, options?: LocatorOptions): Promise<void>;
|
|
32
|
+
hover(options?: LocatorOptions): Promise<void>;
|
|
33
|
+
dragTo(target: Locator, options?: LocatorOptions): Promise<void>;
|
|
34
|
+
setInputFiles(files: string | string[], options?: LocatorOptions): Promise<void>;
|
|
35
|
+
handleDialog(action: 'accept' | 'dismiss', promptText?: string, options?: LocatorOptions): Promise<void>;
|
|
36
|
+
textContent(options?: LocatorOptions): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* `value` is read as a DOM property, every other name as an attribute.
|
|
39
|
+
*
|
|
40
|
+
* The attribute only ever holds what the markup shipped with. Typing into a
|
|
41
|
+
* field changes the property, so `getAttribute('value')` returns null for
|
|
42
|
+
* anything the user entered, and `toHaveValue()` then fails on a field that
|
|
43
|
+
* visibly contains the right text. The label path already special-cased this;
|
|
44
|
+
* the css and role/text paths did not, so the same locator behaved
|
|
45
|
+
* differently depending on how it was written.
|
|
46
|
+
*/
|
|
47
|
+
private static readAttributeScript;
|
|
48
|
+
getAttribute(name: string, options?: LocatorOptions): Promise<string | null>;
|
|
49
|
+
isVisible(options?: LocatorOptions): Promise<boolean>;
|
|
50
|
+
isEnabled(options?: LocatorOptions): Promise<boolean>;
|
|
51
|
+
isChecked(options?: LocatorOptions): Promise<boolean>;
|
|
52
|
+
waitForVisible(options?: LocatorOptions): Promise<void>;
|
|
53
|
+
waitForHidden(options?: LocatorOptions): Promise<void>;
|
|
54
|
+
boundingBox(options?: LocatorOptions): Promise<{
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
} | null>;
|
|
60
|
+
screenshot(options?: LocatorOptions): Promise<Buffer>;
|
|
61
|
+
/**
|
|
62
|
+
* Resolve this locator to a Chrome node uid.
|
|
63
|
+
*
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
resolve(): Promise<{
|
|
67
|
+
uid: string;
|
|
68
|
+
}>;
|
|
69
|
+
getByText(text: string, options?: {
|
|
70
|
+
exact?: boolean;
|
|
71
|
+
}): Locator;
|
|
72
|
+
getByRole(role: string, options?: {
|
|
73
|
+
name?: string;
|
|
74
|
+
exact?: boolean;
|
|
75
|
+
}): Locator;
|
|
76
|
+
getByLabel(label: string, options?: {
|
|
77
|
+
exact?: boolean;
|
|
78
|
+
}): Locator;
|
|
79
|
+
locator(selector: string): Locator;
|
|
80
|
+
first(): Locator;
|
|
81
|
+
nth(index: number): Locator;
|
|
82
|
+
count(options?: LocatorOptions): Promise<number>;
|
|
83
|
+
private runCssAction;
|
|
84
|
+
private runLabelAction;
|
|
85
|
+
private countSnapshotMatches;
|
|
86
|
+
private matchesText;
|
|
87
|
+
/**
|
|
88
|
+
* State checks such as `isVisible()` return `false` when the element cannot be
|
|
89
|
+
* reached, but genuine failures (MCP errors, closed pages) must not be masked.
|
|
90
|
+
*/
|
|
91
|
+
private rethrowIfFatal;
|
|
92
|
+
private withTimeout;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=Locator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Locator.d.ts","sourceRoot":"","sources":["../../src/browser/Locator.ts"],"names":[],"mappings":"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"}
|