e2e-pilot 0.0.69
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/bin.js +3 -0
- package/dist/aria-snapshot.d.ts +95 -0
- package/dist/aria-snapshot.d.ts.map +1 -0
- package/dist/aria-snapshot.js +490 -0
- package/dist/aria-snapshot.js.map +1 -0
- package/dist/bippy.js +971 -0
- package/dist/cdp-relay.d.ts +16 -0
- package/dist/cdp-relay.d.ts.map +1 -0
- package/dist/cdp-relay.js +715 -0
- package/dist/cdp-relay.js.map +1 -0
- package/dist/cdp-session.d.ts +42 -0
- package/dist/cdp-session.d.ts.map +1 -0
- package/dist/cdp-session.js +154 -0
- package/dist/cdp-session.js.map +1 -0
- package/dist/cdp-types.d.ts +63 -0
- package/dist/cdp-types.d.ts.map +1 -0
- package/dist/cdp-types.js +91 -0
- package/dist/cdp-types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +213 -0
- package/dist/cli.js.map +1 -0
- package/dist/create-logger.d.ts +9 -0
- package/dist/create-logger.d.ts.map +1 -0
- package/dist/create-logger.js +25 -0
- package/dist/create-logger.js.map +1 -0
- package/dist/debugger-api.md +458 -0
- package/dist/debugger-examples-types.d.ts +24 -0
- package/dist/debugger-examples-types.d.ts.map +1 -0
- package/dist/debugger-examples-types.js +2 -0
- package/dist/debugger-examples-types.js.map +1 -0
- package/dist/debugger-examples.d.ts +6 -0
- package/dist/debugger-examples.d.ts.map +1 -0
- package/dist/debugger-examples.js +53 -0
- package/dist/debugger-examples.js.map +1 -0
- package/dist/debugger.d.ts +381 -0
- package/dist/debugger.d.ts.map +1 -0
- package/dist/debugger.js +633 -0
- package/dist/debugger.js.map +1 -0
- package/dist/editor-api.md +364 -0
- package/dist/editor-examples.d.ts +11 -0
- package/dist/editor-examples.d.ts.map +1 -0
- package/dist/editor-examples.js +124 -0
- package/dist/editor-examples.js.map +1 -0
- package/dist/editor.d.ts +203 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +336 -0
- package/dist/editor.js.map +1 -0
- package/dist/execute.d.ts +50 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +576 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-client.d.ts +20 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +56 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +720 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mcp.test.d.ts +10 -0
- package/dist/mcp.test.d.ts.map +1 -0
- package/dist/mcp.test.js +2999 -0
- package/dist/mcp.test.js.map +1 -0
- package/dist/network-capture.d.ts +23 -0
- package/dist/network-capture.d.ts.map +1 -0
- package/dist/network-capture.js +98 -0
- package/dist/network-capture.js.map +1 -0
- package/dist/protocol.d.ts +54 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +2 -0
- package/dist/protocol.js.map +1 -0
- package/dist/react-source.d.ts +13 -0
- package/dist/react-source.d.ts.map +1 -0
- package/dist/react-source.js +68 -0
- package/dist/react-source.js.map +1 -0
- package/dist/scoped-fs.d.ts +94 -0
- package/dist/scoped-fs.d.ts.map +1 -0
- package/dist/scoped-fs.js +356 -0
- package/dist/scoped-fs.js.map +1 -0
- package/dist/selector-generator.js +8126 -0
- package/dist/start-relay-server.d.ts +6 -0
- package/dist/start-relay-server.d.ts.map +1 -0
- package/dist/start-relay-server.js +33 -0
- package/dist/start-relay-server.js.map +1 -0
- package/dist/styles-api.md +117 -0
- package/dist/styles-examples.d.ts +8 -0
- package/dist/styles-examples.d.ts.map +1 -0
- package/dist/styles-examples.js +64 -0
- package/dist/styles-examples.js.map +1 -0
- package/dist/styles.d.ts +27 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +234 -0
- package/dist/styles.js.map +1 -0
- package/dist/trace-utils.d.ts +14 -0
- package/dist/trace-utils.d.ts.map +1 -0
- package/dist/trace-utils.js +21 -0
- package/dist/trace-utils.js.map +1 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +75 -0
- package/dist/utils.js.map +1 -0
- package/dist/wait-for-page-load.d.ts +16 -0
- package/dist/wait-for-page-load.d.ts.map +1 -0
- package/dist/wait-for-page-load.js +127 -0
- package/dist/wait-for-page-load.js.map +1 -0
- package/package.json +67 -0
- package/src/aria-snapshot.ts +610 -0
- package/src/assets/aria-labels-github-snapshot.txt +605 -0
- package/src/assets/aria-labels-github.png +0 -0
- package/src/assets/aria-labels-google-snapshot.txt +49 -0
- package/src/assets/aria-labels-google.png +0 -0
- package/src/assets/aria-labels-hacker-news-snapshot.txt +1023 -0
- package/src/assets/aria-labels-hacker-news.png +0 -0
- package/src/cdp-relay.ts +925 -0
- package/src/cdp-session.ts +203 -0
- package/src/cdp-timing.md +128 -0
- package/src/cdp-types.ts +155 -0
- package/src/cli.ts +250 -0
- package/src/create-logger.ts +36 -0
- package/src/debugger-examples-types.ts +13 -0
- package/src/debugger-examples.ts +66 -0
- package/src/debugger.md +453 -0
- package/src/debugger.ts +713 -0
- package/src/editor-examples.ts +148 -0
- package/src/editor.ts +390 -0
- package/src/execute.ts +763 -0
- package/src/index.ts +10 -0
- package/src/mcp-client.ts +78 -0
- package/src/mcp.test.ts +3596 -0
- package/src/mcp.ts +876 -0
- package/src/network-capture.ts +140 -0
- package/src/prompt.bak.md +323 -0
- package/src/prompt.md +7 -0
- package/src/protocol.ts +63 -0
- package/src/react-source.ts +94 -0
- package/src/resource.md +436 -0
- package/src/scoped-fs.ts +411 -0
- package/src/snapshots/hacker-news-focused-accessibility.md +202 -0
- package/src/snapshots/hacker-news-initial-accessibility.md +11 -0
- package/src/snapshots/hacker-news-tabbed-accessibility.md +202 -0
- package/src/snapshots/shadcn-ui-accessibility.md +11 -0
- package/src/start-relay-server.ts +43 -0
- package/src/styles-examples.ts +77 -0
- package/src/styles.ts +345 -0
- package/src/trace-utils.ts +43 -0
- package/src/utils.ts +91 -0
- package/src/wait-for-page-load.ts +174 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BrowserContext } from 'playwright-core'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { formatDateTimeForPath } from './utils.js'
|
|
5
|
+
|
|
6
|
+
export interface ActiveTracing {
|
|
7
|
+
path: string
|
|
8
|
+
name: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function startTracing({
|
|
12
|
+
context,
|
|
13
|
+
baseDir,
|
|
14
|
+
}: {
|
|
15
|
+
context: BrowserContext
|
|
16
|
+
baseDir: string
|
|
17
|
+
}): Promise<ActiveTracing> {
|
|
18
|
+
const now = new Date()
|
|
19
|
+
const dateTimeStr = formatDateTimeForPath(now)
|
|
20
|
+
const name = `trace-${dateTimeStr}`
|
|
21
|
+
|
|
22
|
+
fs.mkdirSync(baseDir, { recursive: true })
|
|
23
|
+
const tracePath = path.join(baseDir, `${dateTimeStr}.zip`)
|
|
24
|
+
|
|
25
|
+
await context.tracing.start({
|
|
26
|
+
name,
|
|
27
|
+
screenshots: true,
|
|
28
|
+
snapshots: true,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
return { path: tracePath, name }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function stopTracing({
|
|
35
|
+
context,
|
|
36
|
+
activeTracing,
|
|
37
|
+
}: {
|
|
38
|
+
context: BrowserContext
|
|
39
|
+
activeTracing: ActiveTracing
|
|
40
|
+
}): Promise<string> {
|
|
41
|
+
await context.tracing.stop({ path: activeTracing.path })
|
|
42
|
+
return activeTracing.path
|
|
43
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import os from 'node:os'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import type { BrowserContext } from 'playwright-core'
|
|
6
|
+
|
|
7
|
+
export const RELAY_PORT = Number(process.env.E2E_PILOT_PORT) || 19988
|
|
8
|
+
|
|
9
|
+
export function getCdpUrl({
|
|
10
|
+
port = 19988,
|
|
11
|
+
host = '127.0.0.1',
|
|
12
|
+
token,
|
|
13
|
+
}: { port?: number; host?: string; token?: string } = {}) {
|
|
14
|
+
const id = `${Math.random().toString(36).substring(2, 15)}_${Date.now()}`
|
|
15
|
+
const queryString = token ? `?token=${token}` : ''
|
|
16
|
+
return `ws://${host}:${port}/cdp/${id}${queryString}`
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const LOG_FILE_PATH =
|
|
20
|
+
process.env.E2E_PILOT_LOG_FILE_PATH || path.join(os.tmpdir(), 'e2e-pilot', 'relay-server.log')
|
|
21
|
+
|
|
22
|
+
const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')
|
|
23
|
+
export const VERSION = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')).version as string
|
|
24
|
+
|
|
25
|
+
export function sleep(ms: number): Promise<void> {
|
|
26
|
+
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function getServerVersion(port: number = RELAY_PORT): Promise<string | null> {
|
|
30
|
+
try {
|
|
31
|
+
const response = await fetch(`http://127.0.0.1:${port}/version`, {
|
|
32
|
+
signal: AbortSignal.timeout(500),
|
|
33
|
+
})
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
const data = (await response.json()) as { version: string }
|
|
38
|
+
return data.version
|
|
39
|
+
} catch {
|
|
40
|
+
return null
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function setDeviceScaleFactorForMacOS(context: BrowserContext): void {
|
|
45
|
+
if (os.platform() !== 'darwin') {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
const options = (context as any)._options
|
|
49
|
+
if (!options || options.deviceScaleFactor === 2) {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
options.deviceScaleFactor = 2
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function preserveSystemColorScheme(context: BrowserContext): void {
|
|
56
|
+
const options = (context as any)._options
|
|
57
|
+
if (!options) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
options.colorScheme = 'no-override'
|
|
61
|
+
options.reducedMotion = 'no-override'
|
|
62
|
+
options.forcedColors = 'no-override'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function formatAsCommentLines(text: string): string {
|
|
66
|
+
return text
|
|
67
|
+
.split('\n')
|
|
68
|
+
.map((line) => {
|
|
69
|
+
return `// ${line}`
|
|
70
|
+
})
|
|
71
|
+
.join('\n')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function formatTimeForPath(date: Date): string {
|
|
75
|
+
const hours = String(date.getHours()).padStart(2, '0')
|
|
76
|
+
const minutes = String(date.getMinutes()).padStart(2, '0')
|
|
77
|
+
const seconds = String(date.getSeconds()).padStart(2, '0')
|
|
78
|
+
return `${hours}-${minutes}-${seconds}`
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function formatDateForPath(date: Date): string {
|
|
82
|
+
return date.toISOString().split('T')[0]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns a combined date_time string for flattened folder structure.
|
|
87
|
+
* Format: YYYY-MM-DD_HH-MM-SS (e.g., 2026-01-13_12-53-00)
|
|
88
|
+
*/
|
|
89
|
+
export function formatDateTimeForPath(date: Date): string {
|
|
90
|
+
return `${formatDateForPath(date)}_${formatTimeForPath(date)}`
|
|
91
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { Page } from 'playwright-core'
|
|
2
|
+
import { sleep } from './utils.js'
|
|
3
|
+
|
|
4
|
+
const FILTERED_DOMAINS = [
|
|
5
|
+
'doubleclick',
|
|
6
|
+
'googlesyndication',
|
|
7
|
+
'googleadservices',
|
|
8
|
+
'google-analytics',
|
|
9
|
+
'googletagmanager',
|
|
10
|
+
'facebook.net',
|
|
11
|
+
'fbcdn.net',
|
|
12
|
+
'twitter.com',
|
|
13
|
+
'linkedin.com',
|
|
14
|
+
'hotjar',
|
|
15
|
+
'mixpanel',
|
|
16
|
+
'segment.io',
|
|
17
|
+
'segment.com',
|
|
18
|
+
'newrelic',
|
|
19
|
+
'datadoghq',
|
|
20
|
+
'sentry.io',
|
|
21
|
+
'fullstory',
|
|
22
|
+
'amplitude',
|
|
23
|
+
'intercom',
|
|
24
|
+
'crisp.chat',
|
|
25
|
+
'zdassets.com',
|
|
26
|
+
'zendesk',
|
|
27
|
+
'tawk.to',
|
|
28
|
+
'hubspot',
|
|
29
|
+
'marketo',
|
|
30
|
+
'pardot',
|
|
31
|
+
'optimizely',
|
|
32
|
+
'crazyegg',
|
|
33
|
+
'mouseflow',
|
|
34
|
+
'clarity.ms',
|
|
35
|
+
'bing.com/bat',
|
|
36
|
+
'ads.',
|
|
37
|
+
'analytics.',
|
|
38
|
+
'tracking.',
|
|
39
|
+
'pixel.',
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
const FILTERED_EXTENSIONS = ['.gif', '.ico', '.cur', '.woff', '.woff2', '.ttf', '.otf', '.eot']
|
|
43
|
+
|
|
44
|
+
export interface WaitForPageLoadOptions {
|
|
45
|
+
page: Page
|
|
46
|
+
timeout?: number
|
|
47
|
+
pollInterval?: number
|
|
48
|
+
minWait?: number
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface WaitForPageLoadResult {
|
|
52
|
+
success: boolean
|
|
53
|
+
readyState: string
|
|
54
|
+
pendingRequests: string[]
|
|
55
|
+
waitTimeMs: number
|
|
56
|
+
timedOut: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function waitForPageLoad(options: WaitForPageLoadOptions): Promise<WaitForPageLoadResult> {
|
|
60
|
+
const { page, timeout = 30000, pollInterval = 100, minWait = 500 } = options
|
|
61
|
+
|
|
62
|
+
const startTime = Date.now()
|
|
63
|
+
let timedOut = false
|
|
64
|
+
let lastReadyState = ''
|
|
65
|
+
let lastPendingRequests: string[] = []
|
|
66
|
+
|
|
67
|
+
const checkPageReady = async (): Promise<{ ready: boolean; readyState: string; pendingRequests: string[] }> => {
|
|
68
|
+
const result = await page.evaluate(
|
|
69
|
+
({ filteredDomains, filteredExtensions, stuckThreshold, slowResourceThreshold }): {
|
|
70
|
+
ready: boolean
|
|
71
|
+
readyState: string
|
|
72
|
+
pendingRequests: string[]
|
|
73
|
+
} => {
|
|
74
|
+
const doc = globalThis.document as { readyState: string }
|
|
75
|
+
const readyState = doc.readyState
|
|
76
|
+
|
|
77
|
+
if (readyState !== 'complete') {
|
|
78
|
+
return { ready: false, readyState, pendingRequests: [`document.readyState: ${readyState}`] }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const resources = (performance as any).getEntriesByType('resource') as Array<{
|
|
82
|
+
name: string
|
|
83
|
+
startTime: number
|
|
84
|
+
responseEnd: number
|
|
85
|
+
}>
|
|
86
|
+
const now = (performance as any).now() as number
|
|
87
|
+
|
|
88
|
+
const pendingRequests = resources
|
|
89
|
+
.filter((r) => {
|
|
90
|
+
if (r.responseEnd > 0) {
|
|
91
|
+
return false
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const elapsed = now - r.startTime
|
|
95
|
+
const url = r.name.toLowerCase()
|
|
96
|
+
|
|
97
|
+
if (url.startsWith('data:')) {
|
|
98
|
+
return false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (filteredDomains.some((domain: string) => url.includes(domain))) {
|
|
102
|
+
return false
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (elapsed > stuckThreshold) {
|
|
106
|
+
return false
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (elapsed > slowResourceThreshold && filteredExtensions.some((ext: string) => url.includes(ext))) {
|
|
110
|
+
return false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return true
|
|
114
|
+
})
|
|
115
|
+
.map((r) => r.name)
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
ready: pendingRequests.length === 0,
|
|
119
|
+
readyState,
|
|
120
|
+
pendingRequests,
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
filteredDomains: FILTERED_DOMAINS,
|
|
125
|
+
filteredExtensions: FILTERED_EXTENSIONS,
|
|
126
|
+
stuckThreshold: 10000,
|
|
127
|
+
slowResourceThreshold: 3000,
|
|
128
|
+
},
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return result
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
await sleep(minWait)
|
|
135
|
+
|
|
136
|
+
while (Date.now() - startTime < timeout) {
|
|
137
|
+
try {
|
|
138
|
+
const { ready, readyState, pendingRequests } = await checkPageReady()
|
|
139
|
+
lastReadyState = readyState
|
|
140
|
+
lastPendingRequests = pendingRequests
|
|
141
|
+
|
|
142
|
+
if (ready) {
|
|
143
|
+
return {
|
|
144
|
+
success: true,
|
|
145
|
+
readyState,
|
|
146
|
+
pendingRequests: [],
|
|
147
|
+
waitTimeMs: Date.now() - startTime,
|
|
148
|
+
timedOut: false,
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.error('[waitForPageLoad] page.evaluate failed:', e)
|
|
153
|
+
return {
|
|
154
|
+
success: false,
|
|
155
|
+
readyState: 'error',
|
|
156
|
+
pendingRequests: ['page.evaluate failed - page may have closed or navigated'],
|
|
157
|
+
waitTimeMs: Date.now() - startTime,
|
|
158
|
+
timedOut: false,
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await sleep(pollInterval)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
timedOut = true
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
success: false,
|
|
169
|
+
readyState: lastReadyState,
|
|
170
|
+
pendingRequests: lastPendingRequests.slice(0, 10),
|
|
171
|
+
waitTimeMs: Date.now() - startTime,
|
|
172
|
+
timedOut,
|
|
173
|
+
}
|
|
174
|
+
}
|