testdriverai 7.9.81-test → 7.9.91-test

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.
@@ -13,6 +13,24 @@
13
13
 
14
14
  'use strict';
15
15
 
16
+ /**
17
+ * Extract the major.minor portion of a semver-ish version string.
18
+ *
19
+ * Examples:
20
+ * '7.9.59' -> '7.9'
21
+ * '7.9.59-test' -> '7.9'
22
+ * '7.10.0-canary.3'-> '7.10'
23
+ * '' -> ''
24
+ *
25
+ * @param {string} version
26
+ * @returns {string}
27
+ */
28
+ function majorMinor(version) {
29
+ if (!version || typeof version !== 'string') return '';
30
+ var m = version.match(/^(\d+)\.(\d+)/);
31
+ return m ? m[1] + '.' + m[2] : '';
32
+ }
33
+
16
34
  /**
17
35
  * Build the agent config object written to the sandbox.
18
36
  *
@@ -98,23 +116,27 @@ function windowsProvisionCommands({ channel, configJson, sandboxId, s3DownloadUr
98
116
 
99
117
  // If we know the image version, check whether the baked-in runner already
100
118
  // matches — skip npm install entirely when it does (saves 5-15s per launch).
119
+ // Only the major.minor portion is compared (patch & prerelease suffix are
120
+ // ignored) so trivial patch bumps don't trigger an unnecessary npm install.
101
121
  // Emits a structured RUNNER_VERSION_CHECK line so SSM output / runner logs
102
122
  // capture the outcome for monitoring.
103
123
  if (imageVersion) {
124
+ var expectedMinor = majorMinor(imageVersion);
104
125
  commands.push(
105
126
  "Write-Host 'Checking installed runner version...'",
106
127
  "$installedVersion = ''",
107
128
  "try { $pkg = Get-Content 'node_modules/@testdriverai/runner/package.json' -Raw | ConvertFrom-Json; $installedVersion = $pkg.version } catch {}",
108
- "if ($installedVersion -eq '" + imageVersion + "') {",
109
- " Write-Host 'Runner already at v" + imageVersion + ", skipping update'",
110
- " Write-Host (\"RUNNER_VERSION_CHECK:\" + (ConvertTo-Json -Compress @{ action='skipped'; installedVersion=$installedVersion; expectedVersion='" + imageVersion + "'; channel='" + channel + "'; sandboxId='" + sandboxId + "' }))",
129
+ "$installedMinor = if ($installedVersion) { ($installedVersion -split '[.-]')[0..1] -join '.' } else { '' }",
130
+ "if (('" + expectedMinor + "' -ne '') -and ($installedMinor -eq '" + expectedMinor + "')) {",
131
+ " Write-Host \"Runner already at v$installedVersion (minor " + expectedMinor + "), skipping update\"",
132
+ " Write-Host (\"RUNNER_VERSION_CHECK:\" + (ConvertTo-Json -Compress @{ action='skipped'; installedVersion=$installedVersion; expectedVersion='" + imageVersion + "'; expectedMinor='" + expectedMinor + "'; channel='" + channel + "'; sandboxId='" + sandboxId + "' }))",
111
133
  "} else {",
112
- " Write-Host \"Installed: $installedVersion, expected: " + imageVersion + " — updating...\"",
134
+ " Write-Host \"Installed minor: $installedMinor, expected: " + expectedMinor + " — updating...\"",
113
135
  " Write-Host 'Installing @testdriverai/runner@" + runnerTag + "...'",
114
136
  ' npm install @testdriverai/runner@' + runnerTag + ' --omit=dev 2>&1 | Write-Host',
115
137
  " $newVersion = ''",
116
138
  " try { $newPkg = Get-Content 'node_modules/@testdriverai/runner/package.json' -Raw | ConvertFrom-Json; $newVersion = $newPkg.version } catch {}",
117
- " Write-Host (\"RUNNER_VERSION_CHECK:\" + (ConvertTo-Json -Compress @{ action='updated'; previousVersion=$installedVersion; expectedVersion='" + imageVersion + "'; newVersion=$newVersion; channel='" + channel + "'; sandboxId='" + sandboxId + "' }))",
139
+ " Write-Host (\"RUNNER_VERSION_CHECK:\" + (ConvertTo-Json -Compress @{ action='updated'; previousVersion=$installedVersion; expectedVersion='" + imageVersion + "'; expectedMinor='" + expectedMinor + "'; newVersion=$newVersion; channel='" + channel + "'; sandboxId='" + sandboxId + "' }))",
118
140
  " Write-Host 'Runner install complete'",
119
141
  "}"
120
142
  );
@@ -197,20 +219,24 @@ function linuxRunnerInstallCommand({ channel, s3DownloadUrl, runnerPath, imageVe
197
219
  ].join(' && ');
198
220
  }
199
221
 
200
- // If we know the image version, wrap the install in a version check
222
+ // If we know the image version, wrap the install in a version check.
223
+ // Only the major.minor portion is compared (patch & prerelease suffix are
224
+ // ignored) so trivial patch bumps don't trigger an unnecessary npm install.
201
225
  if (imageVersion) {
226
+ var expectedMinor = majorMinor(imageVersion);
202
227
  return [
203
228
  'INSTALLED_VERSION=$(node -p "try{require(\'' + rp + '/package.json\').version}catch(e){\'\'}" 2>/dev/null || echo "")',
204
- 'if [ "$INSTALLED_VERSION" = "' + imageVersion + '" ]; then',
205
- ' echo "RUNNER_VERSION_CHECK:{\\"action\\":\\"skipped\\",\\"installedVersion\\":\\"$INSTALLED_VERSION\\",\\"expectedVersion\\":\\"' + imageVersion + '\\",\\"channel\\":\\"' + channel + '\\",\\"sandboxId\\":\\"' + sid + '\\"}"',
206
- ' echo "Runner already at v' + imageVersion + ', skipping update"',
229
+ 'INSTALLED_MINOR=$(echo "$INSTALLED_VERSION" | sed -E "s/^([0-9]+\\.[0-9]+).*/\\1/")',
230
+ 'if [ -n "' + expectedMinor + '" ] && [ "$INSTALLED_MINOR" = "' + expectedMinor + '" ]; then',
231
+ ' echo "RUNNER_VERSION_CHECK:{\\"action\\":\\"skipped\\",\\"installedVersion\\":\\"$INSTALLED_VERSION\\",\\"expectedVersion\\":\\"' + imageVersion + '\\",\\"expectedMinor\\":\\"' + expectedMinor + '\\",\\"channel\\":\\"' + channel + '\\",\\"sandboxId\\":\\"' + sid + '\\"}"',
232
+ ' echo "Runner already at v$INSTALLED_VERSION (minor ' + expectedMinor + '), skipping update"',
207
233
  'else',
208
- ' echo "Installed: $INSTALLED_VERSION, expected: ' + imageVersion + ' — updating..."',
234
+ ' echo "Installed minor: $INSTALLED_MINOR, expected: ' + expectedMinor + ' — updating..."',
209
235
  ' sudo npm install -g @testdriverai/runner@' + runnerTag + ' --omit=dev --no-audit --no-fund --loglevel=error',
210
236
  ' sudo rm -rf ' + rp,
211
237
  ' sudo ln -sf $(npm root -g)/@testdriverai/runner ' + rp,
212
238
  ' NEW_VERSION=$(node -p "try{require(\'' + rp + '/package.json\').version}catch(e){\'\'}" 2>/dev/null || echo "")',
213
- ' echo "RUNNER_VERSION_CHECK:{\\"action\\":\\"updated\\",\\"previousVersion\\":\\"$INSTALLED_VERSION\\",\\"expectedVersion\\":\\"' + imageVersion + '\\",\\"newVersion\\":\\"$NEW_VERSION\\",\\"channel\\":\\"' + channel + '\\",\\"sandboxId\\":\\"' + sid + '\\"}"',
239
+ ' echo "RUNNER_VERSION_CHECK:{\\"action\\":\\"updated\\",\\"previousVersion\\":\\"$INSTALLED_VERSION\\",\\"expectedVersion\\":\\"' + imageVersion + '\\",\\"expectedMinor\\":\\"' + expectedMinor + '\\",\\"newVersion\\":\\"$NEW_VERSION\\",\\"channel\\":\\"' + channel + '\\",\\"sandboxId\\":\\"' + sid + '\\"}"',
214
240
  ' echo "Runner install complete"',
215
241
  'fi',
216
242
  ].join(' && ');
@@ -227,4 +253,5 @@ module.exports = {
227
253
  buildAgentConfig,
228
254
  windowsProvisionCommands,
229
255
  linuxRunnerInstallCommand,
256
+ majorMinor,
230
257
  };
@@ -2,18 +2,18 @@
2
2
  "$schema": "./examples-manifest.schema.json",
3
3
  "examples": {
4
4
  "assert.test.mjs": {
5
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a62d3fb50e9fd352c6501",
6
- "replayUrl": "https://console-test.testdriver.ai/replay/6a0a69f85e84df6215f782f4?share=AaQZE9gfcazcIyAwZ54Dtg",
7
- "embedUrl": "https://console-test.testdriver.ai/replay/6a0a69f85e84df6215f782f4?share=AaQZE9gfcazcIyAwZ54Dtg&embed=true",
8
- "lastUpdated": "2026-05-18T01:23:09.954Z"
5
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a1640e572fbc49ea25d679b",
6
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a164876cdb57a637d2faabd?share=P6veCnmKhjRh1lJK7aMx4g",
7
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a164876cdb57a637d2faabd?share=P6veCnmKhjRh1lJK7aMx4g&embed=true",
8
+ "lastUpdated": "2026-05-27T01:27:24.420Z"
9
9
  },
10
10
  "drag-and-drop.test.mjs": {
11
11
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b42fc0ac3cc632a918b",
12
12
  "lastUpdated": "2026-03-03T00:32:25.275Z"
13
13
  },
14
14
  "exec-pwsh.test.mjs": {
15
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a61f2fb50e9fd352c6475",
16
- "lastUpdated": "2026-05-18T01:02:42.315Z"
15
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16400472fbc49ea25d6715",
16
+ "lastUpdated": "2026-05-27T01:05:05.688Z"
17
17
  },
18
18
  "match-image.test.mjs": {
19
19
  "url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c8738c14b73310c783941d",
@@ -24,92 +24,92 @@
24
24
  "lastUpdated": "2026-03-03T00:32:25.282Z"
25
25
  },
26
26
  "hover-text-with-description.test.mjs": {
27
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6208fb50e9fd352c64ab",
28
- "lastUpdated": "2026-05-18T00:49:12.155Z"
27
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16401b72fbc49ea25d672e",
28
+ "lastUpdated": "2026-05-27T00:51:38.967Z"
29
29
  },
30
30
  "windows-installer.test.mjs": {
31
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6234fb50e9fd352c64f2",
32
- "lastUpdated": "2026-05-18T01:03:48.466Z"
31
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16404872fbc49ea25d6770",
32
+ "lastUpdated": "2026-05-27T01:06:16.047Z"
33
33
  },
34
34
  "exec-output.test.mjs": {
35
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6235fb50e9fd352c64f4",
36
- "lastUpdated": "2026-05-18T01:03:49.902Z"
35
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16404a72fbc49ea25d6773",
36
+ "lastUpdated": "2026-05-27T01:06:17.437Z"
37
37
  },
38
38
  "chrome-extension.test.mjs": {
39
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a61f0fb50e9fd352c646e",
40
- "lastUpdated": "2026-05-18T00:55:44.331Z"
39
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16400272fbc49ea25d6713",
40
+ "lastUpdated": "2026-05-27T00:58:03.997Z"
41
41
  },
42
42
  "launch-vscode-linux.test.mjs": {
43
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a621dfb50e9fd352c64d5",
44
- "replayUrl": "https://console-test.testdriver.ai/replay/6a0a67d35e84df6215f782e4?share=BZj28mmTsITtFqfMHy74Hw",
45
- "embedUrl": "https://console-test.testdriver.ai/replay/6a0a67d35e84df6215f782e4?share=BZj28mmTsITtFqfMHy74Hw&embed=true",
46
- "lastUpdated": "2026-05-18T01:14:01.776Z"
43
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16403372fbc49ea25d6754",
44
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a16461acdb57a637d2faaad?share=FN1SuaLYCODCJGkQQDUsQ",
45
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a16461acdb57a637d2faaad?share=FN1SuaLYCODCJGkQQDUsQ&embed=true",
46
+ "lastUpdated": "2026-05-27T01:17:20.854Z"
47
47
  },
48
48
  "hover-image.test.mjs": {
49
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a624bfb50e9fd352c64f7",
50
- "lastUpdated": "2026-05-18T00:57:17.705Z"
49
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16406072fbc49ea25d6784",
50
+ "lastUpdated": "2026-05-27T00:59:35.750Z"
51
51
  },
52
52
  "installer.test.mjs": {
53
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6264fb50e9fd352c64fc",
54
- "lastUpdated": "2026-05-18T00:50:44.205Z"
53
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16408272fbc49ea25d6790",
54
+ "lastUpdated": "2026-05-27T00:53:10.678Z"
55
55
  },
56
56
  "type.test.mjs": {
57
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a62a5fb50e9fd352c64ff",
58
- "lastUpdated": "2026-05-18T00:58:43.676Z"
57
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a1640b772fbc49ea25d6799",
58
+ "lastUpdated": "2026-05-27T01:01:05.252Z"
59
59
  },
60
60
  "press-keys.test.mjs": {
61
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a62bcfb50e9fd352c6500",
62
- "replayUrl": "https://console-test.testdriver.ai/replay/6a0a69b95e84df6215f782f2?share=YxG4LqDBIszM8ed0axBXCw",
63
- "embedUrl": "https://console-test.testdriver.ai/replay/6a0a69b95e84df6215f782f2?share=YxG4LqDBIszM8ed0axBXCw&embed=true",
64
- "lastUpdated": "2026-05-18T01:22:07.432Z"
61
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a1640cf72fbc49ea25d679a",
62
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a164834cdb57a637d2faabb?share=shwxxjLJAs6ja39RQGXcTA",
63
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a164834cdb57a637d2faabb?share=shwxxjLJAs6ja39RQGXcTA&embed=true",
64
+ "lastUpdated": "2026-05-27T01:26:18.025Z"
65
65
  },
66
66
  "scroll-keyboard.test.mjs": {
67
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6302fb50e9fd352c6503",
68
- "lastUpdated": "2026-05-18T01:07:11.127Z"
67
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16411072fbc49ea25d679d",
68
+ "lastUpdated": "2026-05-27T01:09:42.258Z"
69
69
  },
70
70
  "scroll.test.mjs": {
71
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a631efb50e9fd352c6507",
72
- "replayUrl": "https://console-test.testdriver.ai/replay/6a0a6afe5e84df6215f782fa?share=OuQYCYU4nb44QRLS6JCejQ",
73
- "embedUrl": "https://console-test.testdriver.ai/replay/6a0a6afe5e84df6215f782fa?share=OuQYCYU4nb44QRLS6JCejQ&embed=true",
74
- "lastUpdated": "2026-05-18T01:27:32.768Z"
71
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16412b72fbc49ea25d67a1",
72
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a1649b84a4688499f88ea5d?share=gCsly4DGt4iQxlIjhHiceg",
73
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a1649b84a4688499f88ea5d?share=gCsly4DGt4iQxlIjhHiceg&embed=true",
74
+ "lastUpdated": "2026-05-27T01:32:46.425Z"
75
75
  },
76
76
  "scroll-until-image.test.mjs": {
77
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6304fb50e9fd352c6504",
78
- "lastUpdated": "2026-05-18T00:53:24.479Z"
77
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16411272fbc49ea25d679e",
78
+ "lastUpdated": "2026-05-27T00:55:46.226Z"
79
79
  },
80
80
  "prompt.test.mjs": {
81
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6305fb50e9fd352c6505",
82
- "lastUpdated": "2026-05-18T01:07:14.174Z"
81
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16411372fbc49ea25d679f",
82
+ "lastUpdated": "2026-05-27T01:09:45.225Z"
83
83
  },
84
84
  "focus-window.test.mjs": {
85
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6307fb50e9fd352c6506",
86
- "lastUpdated": "2026-05-18T00:53:27.493Z"
85
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16411472fbc49ea25d67a0",
86
+ "lastUpdated": "2026-05-27T00:55:49.071Z"
87
87
  },
88
88
  "captcha-api.test.mjs": {
89
89
  "url": "https://console.testdriver.ai/runs/698f7df69e27ce1528d7d087/698f7fb0d3b320ad547d9d44",
90
90
  "lastUpdated": "2026-02-13T19:55:05.951Z"
91
91
  },
92
92
  "element-not-found.test.mjs": {
93
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6334fb50e9fd352c6508",
94
- "lastUpdated": "2026-05-18T01:08:01.612Z"
93
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16414272fbc49ea25d67a2",
94
+ "lastUpdated": "2026-05-27T01:10:31.738Z"
95
95
  },
96
96
  "formatted-logging.test.mjs": {
97
97
  "url": "https://console-test.testdriver.ai/runs/69c8738614b73310c7839412/69c873a714b73310c7839450",
98
98
  "lastUpdated": "2026-03-29T00:36:10.628Z"
99
99
  },
100
100
  "hover-text.test.mjs": {
101
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6364fb50e9fd352c650a",
102
- "lastUpdated": "2026-05-18T00:55:00.064Z"
101
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16417072fbc49ea25d67a4",
102
+ "lastUpdated": "2026-05-27T00:57:20.040Z"
103
103
  },
104
104
  "no-provision.test.mjs": {
105
105
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62b7706a177a05bccd1cf",
106
106
  "lastUpdated": "2026-03-03T00:32:25.279Z"
107
107
  },
108
108
  "ai.test.mjs": {
109
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a634dfb50e9fd352c6509",
110
- "replayUrl": "https://console-test.testdriver.ai/replay/6a0a6bbf5e84df6215f782fe?share=EdDcVTwBw6TWT2QyoDOxYg",
111
- "embedUrl": "https://console-test.testdriver.ai/replay/6a0a6bbf5e84df6215f782fe?share=EdDcVTwBw6TWT2QyoDOxYg&embed=true",
112
- "lastUpdated": "2026-05-18T01:30:45.341Z"
109
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16415872fbc49ea25d67a3",
110
+ "replayUrl": "https://console-test.testdriver.ai/replay/6a164a834a4688499f88ea61?share=zG4dSiv1EBheV2pYxjSAA",
111
+ "embedUrl": "https://console-test.testdriver.ai/replay/6a164a834a4688499f88ea61?share=zG4dSiv1EBheV2pYxjSAA&embed=true",
112
+ "lastUpdated": "2026-05-27T01:36:10.091Z"
113
113
  },
114
114
  "popup-loading.test.mjs": {
115
115
  "url": "https://console.testdriver.ai/runs/698bc89f7140c3fa7daaca8d/698bca7f7140c3fa7daacbf7",
@@ -144,12 +144,12 @@
144
144
  "lastUpdated": "2026-02-13T19:55:05.953Z"
145
145
  },
146
146
  "findall-coffee-icons.test.mjs": {
147
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a62ebfb50e9fd352c6502",
148
- "lastUpdated": "2026-05-18T00:59:52.578Z"
147
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a1640fb72fbc49ea25d679c",
148
+ "lastUpdated": "2026-05-27T01:02:17.471Z"
149
149
  },
150
150
  "parse.test.mjs": {
151
- "url": "https://console-test.testdriver.ai/runs/6a0a61dafb50e9fd352c6464/6a0a6379fb50e9fd352c650b",
152
- "lastUpdated": "2026-05-18T01:09:07.859Z"
151
+ "url": "https://console-test.testdriver.ai/runs/6a163feb72fbc49ea25d66f1/6a16418572fbc49ea25d67a5",
152
+ "lastUpdated": "2026-05-27T01:11:39.542Z"
153
153
  },
154
154
  "flake-diffthreshold-001.test.mjs": {
155
155
  "url": "https://console.testdriver.ai/runs/69a62b3aaa712ecd3dea730a/69a62bcafc0ac3cc632a91aa",
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* ai.test.mjs output */}
14
14
  <iframe
15
- src="https://console-test.testdriver.ai/replay/6a0a6bbf5e84df6215f782fe?share=EdDcVTwBw6TWT2QyoDOxYg&embed=true"
15
+ src="https://console-test.testdriver.ai/replay/6a164a834a4688499f88ea61?share=zG4dSiv1EBheV2pYxjSAA&embed=true"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* assert.test.mjs output */}
14
14
  <iframe
15
- src="https://console-test.testdriver.ai/replay/6a0a69f85e84df6215f782f4?share=AaQZE9gfcazcIyAwZ54Dtg&embed=true"
15
+ src="https://console-test.testdriver.ai/replay/6a164876cdb57a637d2faabd?share=P6veCnmKhjRh1lJK7aMx4g&embed=true"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* chrome-extension.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a61f0fb50e9fd352c646e/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16400272fbc49ea25d6713/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -75,18 +75,35 @@ describe("Chrome Extension Test", () => {
75
75
  // The hello-world extension adds a puzzle piece icon to the toolbar
76
76
  // When clicked, it shows a popup with "Hello Extensions"
77
77
 
78
- // Click on the extensions button (puzzle piece icon) in Chrome toolbar
79
- const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true, verify: true});
80
- await extensionsButton.click();
81
-
82
- // Look for the hello world extension in the extensions menu
83
- const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown", {zoom: true, verify: true});
84
- await helloExtension.click();
85
-
86
- await testdriver.wait(2000); // wait for the popup to open
87
-
88
- // Verify the extension popup shows "Hello Extensions" text
89
- const popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
78
+ // Retry opening the extension popup and verifying it up to 3 times
79
+ let popupResult;
80
+ let lastError;
81
+ for (let attempt = 1; attempt <= 3; attempt++) {
82
+ try {
83
+ // Click on the extensions button (puzzle piece icon) in Chrome toolbar
84
+ const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true, verify: true, timeout: 10000});
85
+ await extensionsButton.click();
86
+
87
+ // Look for the hello world extension in the extensions menu
88
+ const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown", {zoom: true, verify: true, timeout: 10000});
89
+ await helloExtension.click();
90
+
91
+ await testdriver.wait(2000); // wait for the popup to open
92
+
93
+ // Verify the extension popup shows "Hello Extensions" text
94
+ popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
95
+ if (popupResult) break;
96
+ } catch (err) {
97
+ lastError = err;
98
+ console.log(`Attempt ${attempt} failed:`, err.message);
99
+ }
100
+ if (attempt < 3) {
101
+ // Dismiss any open popup/menu before retrying
102
+ await testdriver.pressKeys(["escape"]);
103
+ await testdriver.wait(1000);
104
+ }
105
+ }
106
+ if (!popupResult && lastError) throw lastError;
90
107
  expect(popupResult).toBeTruthy();
91
108
  });
92
109
 
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* element-not-found.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a6334fb50e9fd352c6508/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16414272fbc49ea25d67a2/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
18
18
 
19
19
  {/* findall-coffee-icons.test.mjs output */}
20
20
  <iframe
21
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a62ebfb50e9fd352c6502/replay"
21
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a1640fb72fbc49ea25d679c/replay"
22
22
  width="100%"
23
23
  height="600"
24
24
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* hover-image.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a624bfb50e9fd352c64f7/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16406072fbc49ea25d6784/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
18
18
 
19
19
  {/* hover-text-with-description.test.mjs output */}
20
20
  <iframe
21
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a6208fb50e9fd352c64ab/replay"
21
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16401b72fbc49ea25d672e/replay"
22
22
  width="100%"
23
23
  height="600"
24
24
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* hover-text.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a6364fb50e9fd352c650a/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16417072fbc49ea25d67a4/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* installer.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a6264fb50e9fd352c64fc/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16408272fbc49ea25d6790/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* launch-vscode-linux.test.mjs output */}
14
14
  <iframe
15
- src="https://console-test.testdriver.ai/replay/6a0a67d35e84df6215f782e4?share=BZj28mmTsITtFqfMHy74Hw&embed=true"
15
+ src="https://console-test.testdriver.ai/replay/6a16461acdb57a637d2faaad?share=FN1SuaLYCODCJGkQQDUsQ&embed=true"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -18,7 +18,7 @@ Watch this test execute in a real sandbox environment:
18
18
 
19
19
  {/* parse.test.mjs output */}
20
20
  <iframe
21
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a6379fb50e9fd352c650b/replay"
21
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16418572fbc49ea25d67a5/replay"
22
22
  width="100%"
23
23
  height="600"
24
24
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* press-keys.test.mjs output */}
14
14
  <iframe
15
- src="https://console-test.testdriver.ai/replay/6a0a69b95e84df6215f782f2?share=YxG4LqDBIszM8ed0axBXCw&embed=true"
15
+ src="https://console-test.testdriver.ai/replay/6a164834cdb57a637d2faabb?share=shwxxjLJAs6ja39RQGXcTA&embed=true"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* scroll-keyboard.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a6302fb50e9fd352c6503/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a16411072fbc49ea25d679d/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* scroll.test.mjs output */}
14
14
  <iframe
15
- src="https://console-test.testdriver.ai/replay/6a0a6afe5e84df6215f782fa?share=OuQYCYU4nb44QRLS6JCejQ&embed=true"
15
+ src="https://console-test.testdriver.ai/replay/6a1649b84a4688499f88ea5d?share=gCsly4DGt4iQxlIjhHiceg&embed=true"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -12,7 +12,7 @@ Watch this test execute in a real sandbox environment:
12
12
 
13
13
  {/* type.test.mjs output */}
14
14
  <iframe
15
- src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a0a62a5fb50e9fd352c64ff/replay"
15
+ src="https://api-test.testdriver.ai/api/v1/testdriver/testcase/6a1640b772fbc49ea25d6799/replay"
16
16
  width="100%"
17
17
  height="390"
18
18
  style={{ border: "1px solid #333", borderRadius: "8px" }}
@@ -52,18 +52,35 @@ describe("Chrome Extension Test", () => {
52
52
  // The hello-world extension adds a puzzle piece icon to the toolbar
53
53
  // When clicked, it shows a popup with "Hello Extensions"
54
54
 
55
- // Click on the extensions button (puzzle piece icon) in Chrome toolbar
56
- const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true, verify: true});
57
- await extensionsButton.click();
58
-
59
- // Look for the hello world extension in the extensions menu
60
- const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown", {zoom: true, verify: true});
61
- await helloExtension.click();
62
-
63
- await testdriver.wait(2000); // wait for the popup to open
64
-
65
- // Verify the extension popup shows "Hello Extensions" text
66
- const popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
55
+ // Retry opening the extension popup and verifying it up to 3 times
56
+ let popupResult;
57
+ let lastError;
58
+ for (let attempt = 1; attempt <= 3; attempt++) {
59
+ try {
60
+ // Click on the extensions button (puzzle piece icon) in Chrome toolbar
61
+ const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true, verify: true, timeout: 10000});
62
+ await extensionsButton.click();
63
+
64
+ // Look for the hello world extension in the extensions menu
65
+ const helloExtension = await testdriver.find("Hello Extensions extension in the extensions dropdown", {zoom: true, verify: true, timeout: 10000});
66
+ await helloExtension.click();
67
+
68
+ await testdriver.wait(2000); // wait for the popup to open
69
+
70
+ // Verify the extension popup shows "Hello Extensions" text
71
+ popupResult = await testdriver.assert("a popup shows with the text 'Hello Extensions'");
72
+ if (popupResult) break;
73
+ } catch (err) {
74
+ lastError = err;
75
+ console.log(`Attempt ${attempt} failed:`, err.message);
76
+ }
77
+ if (attempt < 3) {
78
+ // Dismiss any open popup/menu before retrying
79
+ await testdriver.pressKeys(["escape"]);
80
+ await testdriver.wait(1000);
81
+ }
82
+ }
83
+ if (!popupResult && lastError) throw lastError;
67
84
  expect(popupResult).toBeTruthy();
68
85
  });
69
86
 
@@ -174,6 +174,24 @@ class Dashcam {
174
174
  this._log("debug", "Auth output:", authOutput);
175
175
  } else {
176
176
  // Linux/Mac authentication with TD_API_ROOT
177
+
178
+ // Workaround for dashcam <1.5.0: webLogsDaemon.js writes its state to a
179
+ // `.dashcam` directory relative to process.cwd(). When launched by the
180
+ // runner, cwd is /usr/lib/node_modules/@testdriverai/runner (root-owned),
181
+ // so the daemon can't mkdir its state dir as user `user` and silently
182
+ // dies — recordings never start. Pre-create world-writable .dashcam dirs
183
+ // at both the current cwd and the known global-install path so the
184
+ // daemon survives regardless of which path dashcam ends up using.
185
+ // TODO: remove once dashcam >=1.5.0 (which uses $HOME) is bundled.
186
+ await this.client.exec(
187
+ shell,
188
+ `sudo mkdir -p "$(pwd)/.dashcam" /usr/lib/node_modules/@testdriverai/runner/.dashcam 2>/dev/null; ` +
189
+ `sudo chmod 0777 "$(pwd)/.dashcam" /usr/lib/node_modules/@testdriverai/runner/.dashcam 2>/dev/null; ` +
190
+ `true`,
191
+ 10000,
192
+ process.env.TD_DEBUG == "true" ? false : true,
193
+ );
194
+
177
195
  const authOutput = await this.client.exec(
178
196
  shell,
179
197
  `TD_API_ROOT="${apiRoot}" dashcam auth ${key}`,