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.
Files changed (152) hide show
  1. package/bin.js +3 -0
  2. package/dist/aria-snapshot.d.ts +95 -0
  3. package/dist/aria-snapshot.d.ts.map +1 -0
  4. package/dist/aria-snapshot.js +490 -0
  5. package/dist/aria-snapshot.js.map +1 -0
  6. package/dist/bippy.js +971 -0
  7. package/dist/cdp-relay.d.ts +16 -0
  8. package/dist/cdp-relay.d.ts.map +1 -0
  9. package/dist/cdp-relay.js +715 -0
  10. package/dist/cdp-relay.js.map +1 -0
  11. package/dist/cdp-session.d.ts +42 -0
  12. package/dist/cdp-session.d.ts.map +1 -0
  13. package/dist/cdp-session.js +154 -0
  14. package/dist/cdp-session.js.map +1 -0
  15. package/dist/cdp-types.d.ts +63 -0
  16. package/dist/cdp-types.d.ts.map +1 -0
  17. package/dist/cdp-types.js +91 -0
  18. package/dist/cdp-types.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +213 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/create-logger.d.ts +9 -0
  24. package/dist/create-logger.d.ts.map +1 -0
  25. package/dist/create-logger.js +25 -0
  26. package/dist/create-logger.js.map +1 -0
  27. package/dist/debugger-api.md +458 -0
  28. package/dist/debugger-examples-types.d.ts +24 -0
  29. package/dist/debugger-examples-types.d.ts.map +1 -0
  30. package/dist/debugger-examples-types.js +2 -0
  31. package/dist/debugger-examples-types.js.map +1 -0
  32. package/dist/debugger-examples.d.ts +6 -0
  33. package/dist/debugger-examples.d.ts.map +1 -0
  34. package/dist/debugger-examples.js +53 -0
  35. package/dist/debugger-examples.js.map +1 -0
  36. package/dist/debugger.d.ts +381 -0
  37. package/dist/debugger.d.ts.map +1 -0
  38. package/dist/debugger.js +633 -0
  39. package/dist/debugger.js.map +1 -0
  40. package/dist/editor-api.md +364 -0
  41. package/dist/editor-examples.d.ts +11 -0
  42. package/dist/editor-examples.d.ts.map +1 -0
  43. package/dist/editor-examples.js +124 -0
  44. package/dist/editor-examples.js.map +1 -0
  45. package/dist/editor.d.ts +203 -0
  46. package/dist/editor.d.ts.map +1 -0
  47. package/dist/editor.js +336 -0
  48. package/dist/editor.js.map +1 -0
  49. package/dist/execute.d.ts +50 -0
  50. package/dist/execute.d.ts.map +1 -0
  51. package/dist/execute.js +576 -0
  52. package/dist/execute.js.map +1 -0
  53. package/dist/index.d.ts +11 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +7 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/mcp-client.d.ts +20 -0
  58. package/dist/mcp-client.d.ts.map +1 -0
  59. package/dist/mcp-client.js +56 -0
  60. package/dist/mcp-client.js.map +1 -0
  61. package/dist/mcp.d.ts +5 -0
  62. package/dist/mcp.d.ts.map +1 -0
  63. package/dist/mcp.js +720 -0
  64. package/dist/mcp.js.map +1 -0
  65. package/dist/mcp.test.d.ts +10 -0
  66. package/dist/mcp.test.d.ts.map +1 -0
  67. package/dist/mcp.test.js +2999 -0
  68. package/dist/mcp.test.js.map +1 -0
  69. package/dist/network-capture.d.ts +23 -0
  70. package/dist/network-capture.d.ts.map +1 -0
  71. package/dist/network-capture.js +98 -0
  72. package/dist/network-capture.js.map +1 -0
  73. package/dist/protocol.d.ts +54 -0
  74. package/dist/protocol.d.ts.map +1 -0
  75. package/dist/protocol.js +2 -0
  76. package/dist/protocol.js.map +1 -0
  77. package/dist/react-source.d.ts +13 -0
  78. package/dist/react-source.d.ts.map +1 -0
  79. package/dist/react-source.js +68 -0
  80. package/dist/react-source.js.map +1 -0
  81. package/dist/scoped-fs.d.ts +94 -0
  82. package/dist/scoped-fs.d.ts.map +1 -0
  83. package/dist/scoped-fs.js +356 -0
  84. package/dist/scoped-fs.js.map +1 -0
  85. package/dist/selector-generator.js +8126 -0
  86. package/dist/start-relay-server.d.ts +6 -0
  87. package/dist/start-relay-server.d.ts.map +1 -0
  88. package/dist/start-relay-server.js +33 -0
  89. package/dist/start-relay-server.js.map +1 -0
  90. package/dist/styles-api.md +117 -0
  91. package/dist/styles-examples.d.ts +8 -0
  92. package/dist/styles-examples.d.ts.map +1 -0
  93. package/dist/styles-examples.js +64 -0
  94. package/dist/styles-examples.js.map +1 -0
  95. package/dist/styles.d.ts +27 -0
  96. package/dist/styles.d.ts.map +1 -0
  97. package/dist/styles.js +234 -0
  98. package/dist/styles.js.map +1 -0
  99. package/dist/trace-utils.d.ts +14 -0
  100. package/dist/trace-utils.d.ts.map +1 -0
  101. package/dist/trace-utils.js +21 -0
  102. package/dist/trace-utils.js.map +1 -0
  103. package/dist/utils.d.ts +20 -0
  104. package/dist/utils.d.ts.map +1 -0
  105. package/dist/utils.js +75 -0
  106. package/dist/utils.js.map +1 -0
  107. package/dist/wait-for-page-load.d.ts +16 -0
  108. package/dist/wait-for-page-load.d.ts.map +1 -0
  109. package/dist/wait-for-page-load.js +127 -0
  110. package/dist/wait-for-page-load.js.map +1 -0
  111. package/package.json +67 -0
  112. package/src/aria-snapshot.ts +610 -0
  113. package/src/assets/aria-labels-github-snapshot.txt +605 -0
  114. package/src/assets/aria-labels-github.png +0 -0
  115. package/src/assets/aria-labels-google-snapshot.txt +49 -0
  116. package/src/assets/aria-labels-google.png +0 -0
  117. package/src/assets/aria-labels-hacker-news-snapshot.txt +1023 -0
  118. package/src/assets/aria-labels-hacker-news.png +0 -0
  119. package/src/cdp-relay.ts +925 -0
  120. package/src/cdp-session.ts +203 -0
  121. package/src/cdp-timing.md +128 -0
  122. package/src/cdp-types.ts +155 -0
  123. package/src/cli.ts +250 -0
  124. package/src/create-logger.ts +36 -0
  125. package/src/debugger-examples-types.ts +13 -0
  126. package/src/debugger-examples.ts +66 -0
  127. package/src/debugger.md +453 -0
  128. package/src/debugger.ts +713 -0
  129. package/src/editor-examples.ts +148 -0
  130. package/src/editor.ts +390 -0
  131. package/src/execute.ts +763 -0
  132. package/src/index.ts +10 -0
  133. package/src/mcp-client.ts +78 -0
  134. package/src/mcp.test.ts +3596 -0
  135. package/src/mcp.ts +876 -0
  136. package/src/network-capture.ts +140 -0
  137. package/src/prompt.bak.md +323 -0
  138. package/src/prompt.md +7 -0
  139. package/src/protocol.ts +63 -0
  140. package/src/react-source.ts +94 -0
  141. package/src/resource.md +436 -0
  142. package/src/scoped-fs.ts +411 -0
  143. package/src/snapshots/hacker-news-focused-accessibility.md +202 -0
  144. package/src/snapshots/hacker-news-initial-accessibility.md +11 -0
  145. package/src/snapshots/hacker-news-tabbed-accessibility.md +202 -0
  146. package/src/snapshots/shadcn-ui-accessibility.md +11 -0
  147. package/src/start-relay-server.ts +43 -0
  148. package/src/styles-examples.ts +77 -0
  149. package/src/styles.ts +345 -0
  150. package/src/trace-utils.ts +43 -0
  151. package/src/utils.ts +91 -0
  152. 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
+ }