craftdriver 1.1.0 → 1.2.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/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/cli/snapshot.js +31 -4
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/lib/bidi/index.d.ts +4 -5
- package/dist/lib/bidi/index.d.ts.map +1 -1
- package/dist/lib/bidi/index.js +18 -8
- package/dist/lib/bidi/index.js.map +1 -1
- package/dist/lib/bidi/logs.d.ts +12 -1
- package/dist/lib/bidi/logs.d.ts.map +1 -1
- package/dist/lib/bidi/logs.js +20 -8
- package/dist/lib/bidi/logs.js.map +1 -1
- package/dist/lib/browser.d.ts +6 -9
- package/dist/lib/browser.d.ts.map +1 -1
- package/dist/lib/browser.js +6 -4
- package/dist/lib/browser.js.map +1 -1
- package/dist/lib/by.d.ts +18 -0
- package/dist/lib/by.d.ts.map +1 -1
- package/dist/lib/by.js +141 -17
- package/dist/lib/by.js.map +1 -1
- package/dist/lib/locator.d.ts +28 -0
- package/dist/lib/locator.d.ts.map +1 -1
- package/dist/lib/locator.js +28 -0
- package/dist/lib/locator.js.map +1 -1
- package/docs/browser-api.md +4 -2
- package/docs/browser-logs.md +8 -23
- package/docs/public/examples/a11y.html +44 -0
- package/docs/public/examples/clock.html +83 -0
- package/docs/public/examples/console-errors.html +344 -0
- package/docs/public/examples/dialogs.html +42 -0
- package/docs/public/examples/download.html +31 -0
- package/docs/public/examples/dynamic.html +131 -0
- package/docs/public/examples/emulate.html +127 -0
- package/docs/public/examples/evaluate.html +28 -0
- package/docs/public/examples/hover-select.html +295 -0
- package/docs/public/examples/iframe-child.html +51 -0
- package/docs/public/examples/iframes.html +35 -0
- package/docs/public/examples/keyboard.html +195 -0
- package/docs/public/examples/locator.html +131 -0
- package/docs/public/examples/login.html +116 -0
- package/docs/public/examples/mobile.html +270 -0
- package/docs/public/examples/mouse.html +505 -0
- package/docs/public/examples/network.html +293 -0
- package/docs/public/examples/popup-target.html +26 -0
- package/docs/public/examples/popup.html +50 -0
- package/docs/public/examples/screenshot.html +99 -0
- package/docs/public/examples/selectors.html +150 -0
- package/docs/public/examples/session.html +514 -0
- package/docs/public/examples/upload.html +36 -0
- package/docs/recipes/accessibility-gate.md +24 -40
- package/docs/recipes/console-error-gate.md +27 -39
- package/docs/recipes/file-upload-download.md +24 -44
- package/docs/recipes/find-elements.md +142 -0
- package/docs/recipes/login-once-reuse-session.md +22 -45
- package/docs/recipes/mobile-flow-with-network-and-logs.md +22 -41
- package/docs/recipes/mock-api-and-assert-network.md +22 -35
- package/docs/recipes/multi-user-contexts.md +32 -43
- package/docs/recipes/page-objects.md +52 -0
- package/docs/recipes/trace-failing-test.md +31 -44
- package/docs/recipes/virtual-clock-time-sensitive-ui.md +24 -40
- package/docs/recipes/vitest-browser-lifecycle.md +15 -15
- package/docs/recipes.md +20 -1
- package/docs/selectors.md +291 -229
- package/docs/tracing.md +2 -2
- package/package.json +5 -1
- package/skills/craftdriver/SKILL.md +3 -2
- package/skills/craftdriver/cheatsheet.md +2 -1
- package/skills/craftdriver/patterns.md +2 -5
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Mobile Emulation Example</title>
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
body {
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
15
|
+
margin: 0;
|
|
16
|
+
padding: 20px;
|
|
17
|
+
background: #f5f5f5;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.card {
|
|
21
|
+
background: white;
|
|
22
|
+
border-radius: 12px;
|
|
23
|
+
padding: 20px;
|
|
24
|
+
margin-bottom: 20px;
|
|
25
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
h1 {
|
|
29
|
+
color: #333;
|
|
30
|
+
font-size: 1.5rem;
|
|
31
|
+
margin-top: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h2 {
|
|
35
|
+
color: #666;
|
|
36
|
+
font-size: 1.1rem;
|
|
37
|
+
margin-top: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.device-info {
|
|
41
|
+
display: grid;
|
|
42
|
+
gap: 10px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.info-row {
|
|
46
|
+
display: flex;
|
|
47
|
+
justify-content: space-between;
|
|
48
|
+
padding: 8px 12px;
|
|
49
|
+
background: #f8f9fa;
|
|
50
|
+
border-radius: 6px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.info-label {
|
|
54
|
+
color: #666;
|
|
55
|
+
font-weight: 500;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.info-value {
|
|
59
|
+
color: #333;
|
|
60
|
+
font-family: monospace;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.touch-area {
|
|
64
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
65
|
+
border-radius: 12px;
|
|
66
|
+
padding: 40px;
|
|
67
|
+
text-align: center;
|
|
68
|
+
color: white;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
user-select: none;
|
|
71
|
+
-webkit-user-select: none;
|
|
72
|
+
touch-action: manipulation;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.touch-area:active {
|
|
76
|
+
transform: scale(0.98);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
#touch-result {
|
|
80
|
+
margin-top: 15px;
|
|
81
|
+
padding: 10px;
|
|
82
|
+
background: #e9ecef;
|
|
83
|
+
border-radius: 6px;
|
|
84
|
+
font-family: monospace;
|
|
85
|
+
min-height: 40px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.responsive-indicator {
|
|
89
|
+
padding: 15px;
|
|
90
|
+
border-radius: 8px;
|
|
91
|
+
text-align: center;
|
|
92
|
+
font-weight: bold;
|
|
93
|
+
margin-bottom: 10px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.mobile-view {
|
|
97
|
+
background: #d4edda;
|
|
98
|
+
color: #155724;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.tablet-view {
|
|
102
|
+
background: #fff3cd;
|
|
103
|
+
color: #856404;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.desktop-view {
|
|
107
|
+
background: #cce5ff;
|
|
108
|
+
color: #004085;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@media (max-width: 480px) {
|
|
112
|
+
.responsive-indicator::before {
|
|
113
|
+
content: '📱 ';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@media (min-width: 481px) and (max-width: 1024px) {
|
|
118
|
+
.responsive-indicator::before {
|
|
119
|
+
content: '📱 ';
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@media (min-width: 1025px) {
|
|
124
|
+
.responsive-indicator::before {
|
|
125
|
+
content: '🖥️ ';
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.orientation-box {
|
|
130
|
+
padding: 20px;
|
|
131
|
+
border-radius: 8px;
|
|
132
|
+
text-align: center;
|
|
133
|
+
font-size: 1.2rem;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.portrait {
|
|
137
|
+
background: #e2e3f3;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.landscape {
|
|
141
|
+
background: #f3e2e3;
|
|
142
|
+
}
|
|
143
|
+
</style>
|
|
144
|
+
</head>
|
|
145
|
+
|
|
146
|
+
<body>
|
|
147
|
+
<h1>📱 Mobile Emulation Test Page</h1>
|
|
148
|
+
|
|
149
|
+
<div class="card">
|
|
150
|
+
<h2>Device Information</h2>
|
|
151
|
+
<div class="device-info">
|
|
152
|
+
<div class="info-row">
|
|
153
|
+
<span class="info-label">Viewport Width</span>
|
|
154
|
+
<span class="info-value" id="viewport-width">-</span>
|
|
155
|
+
</div>
|
|
156
|
+
<div class="info-row">
|
|
157
|
+
<span class="info-label">Viewport Height</span>
|
|
158
|
+
<span class="info-value" id="viewport-height">-</span>
|
|
159
|
+
</div>
|
|
160
|
+
<div class="info-row">
|
|
161
|
+
<span class="info-label">Device Pixel Ratio</span>
|
|
162
|
+
<span class="info-value" id="pixel-ratio">-</span>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="info-row">
|
|
165
|
+
<span class="info-label">Touch Support</span>
|
|
166
|
+
<span class="info-value" id="touch-support">-</span>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="info-row">
|
|
169
|
+
<span class="info-label">User Agent</span>
|
|
170
|
+
<span class="info-value" id="user-agent" style="word-break: break-all; font-size: 11px;">-</span>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="info-row">
|
|
173
|
+
<span class="info-label">Platform</span>
|
|
174
|
+
<span class="info-value" id="platform">-</span>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<div class="card">
|
|
180
|
+
<h2>Responsive Layout Detection</h2>
|
|
181
|
+
<div id="responsive-indicator" class="responsive-indicator">Detecting...</div>
|
|
182
|
+
<div id="orientation-box" class="orientation-box">Checking orientation...</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<div class="card">
|
|
186
|
+
<h2>Touch Event Test</h2>
|
|
187
|
+
<div class="touch-area" id="touch-area">
|
|
188
|
+
Tap or Click Here
|
|
189
|
+
</div>
|
|
190
|
+
<div id="touch-result">Waiting for interaction...</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<script>
|
|
194
|
+
// Update device information
|
|
195
|
+
function updateDeviceInfo() {
|
|
196
|
+
document.getElementById('viewport-width').textContent = window.innerWidth + 'px';
|
|
197
|
+
document.getElementById('viewport-height').textContent = window.innerHeight + 'px';
|
|
198
|
+
document.getElementById('pixel-ratio').textContent = window.devicePixelRatio;
|
|
199
|
+
document.getElementById('user-agent').textContent = navigator.userAgent;
|
|
200
|
+
document.getElementById('platform').textContent = navigator.platform || navigator.userAgentData?.platform || 'Unknown';
|
|
201
|
+
|
|
202
|
+
// Touch support detection
|
|
203
|
+
const hasTouch = 'ontouchstart' in window ||
|
|
204
|
+
navigator.maxTouchPoints > 0 ||
|
|
205
|
+
navigator.msMaxTouchPoints > 0;
|
|
206
|
+
document.getElementById('touch-support').textContent = hasTouch ? 'Yes ✓' : 'No ✗';
|
|
207
|
+
|
|
208
|
+
// Responsive indicator
|
|
209
|
+
const width = window.innerWidth;
|
|
210
|
+
const indicator = document.getElementById('responsive-indicator');
|
|
211
|
+
if (width <= 480) {
|
|
212
|
+
indicator.className = 'responsive-indicator mobile-view';
|
|
213
|
+
indicator.textContent = 'Mobile View (' + width + 'px)';
|
|
214
|
+
} else if (width <= 1024) {
|
|
215
|
+
indicator.className = 'responsive-indicator tablet-view';
|
|
216
|
+
indicator.textContent = 'Tablet View (' + width + 'px)';
|
|
217
|
+
} else {
|
|
218
|
+
indicator.className = 'responsive-indicator desktop-view';
|
|
219
|
+
indicator.textContent = 'Desktop View (' + width + 'px)';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Orientation
|
|
223
|
+
const orientationBox = document.getElementById('orientation-box');
|
|
224
|
+
if (window.innerHeight > window.innerWidth) {
|
|
225
|
+
orientationBox.className = 'orientation-box portrait';
|
|
226
|
+
orientationBox.textContent = '📱 Portrait Mode';
|
|
227
|
+
} else {
|
|
228
|
+
orientationBox.className = 'orientation-box landscape';
|
|
229
|
+
orientationBox.textContent = '📱 Landscape Mode';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Touch area event handling
|
|
234
|
+
const touchArea = document.getElementById('touch-area');
|
|
235
|
+
const touchResult = document.getElementById('touch-result');
|
|
236
|
+
let eventLog = [];
|
|
237
|
+
|
|
238
|
+
function logEvent(type, details) {
|
|
239
|
+
const entry = `${type}: ${details}`;
|
|
240
|
+
eventLog.push(entry);
|
|
241
|
+
if (eventLog.length > 5) eventLog.shift();
|
|
242
|
+
touchResult.textContent = eventLog.join('\n');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
touchArea.addEventListener('touchstart', (e) => {
|
|
246
|
+
e.preventDefault();
|
|
247
|
+
const touch = e.touches[0];
|
|
248
|
+
logEvent('touchstart', `x=${Math.round(touch.clientX)}, y=${Math.round(touch.clientY)}`);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
touchArea.addEventListener('touchend', (e) => {
|
|
252
|
+
logEvent('touchend', 'Touch released');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
touchArea.addEventListener('click', (e) => {
|
|
256
|
+
logEvent('click', `x=${Math.round(e.clientX)}, y=${Math.round(e.clientY)}`);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
touchArea.addEventListener('mousedown', (e) => {
|
|
260
|
+
logEvent('mousedown', `x=${Math.round(e.clientX)}, y=${Math.round(e.clientY)}`);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Initial update and resize listener
|
|
264
|
+
updateDeviceInfo();
|
|
265
|
+
window.addEventListener('resize', updateDeviceInfo);
|
|
266
|
+
window.addEventListener('orientationchange', updateDeviceInfo);
|
|
267
|
+
</script>
|
|
268
|
+
</body>
|
|
269
|
+
|
|
270
|
+
</html>
|