testdriverai 7.8.0-test.4 → 7.8.0-test.40
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 +18 -0
- package/agent/index.js +6 -5
- package/agent/lib/commands.js +3 -2
- package/agent/lib/http.js +144 -0
- package/agent/lib/sandbox.js +326 -164
- package/agent/lib/sdk.js +4 -2
- package/agent/lib/system.js +25 -65
- package/ai/skills/testdriver-cache/SKILL.md +221 -0
- package/ai/skills/testdriver-errors/SKILL.md +246 -0
- package/ai/skills/testdriver-events/SKILL.md +356 -0
- package/ai/skills/testdriver-mcp/SKILL.md +7 -0
- package/ai/skills/testdriver-provision/SKILL.md +331 -0
- package/ai/skills/testdriver-redraw/SKILL.md +214 -0
- package/ai/skills/testdriver-running-tests/SKILL.md +1 -1
- package/ai/skills/testdriver-screenshots/SKILL.md +184 -0
- package/docs/_data/examples-manifest.json +46 -46
- package/docs/changelog.mdx +155 -3
- package/docs/docs.json +44 -37
- package/docs/images/content/vscode/v7-chat.png +0 -0
- package/docs/images/content/vscode/v7-choose-agent.png +0 -0
- package/docs/images/content/vscode/v7-full.png +0 -0
- package/docs/images/content/vscode/v7-onboarding.png +0 -0
- package/docs/v7/cache.mdx +223 -0
- package/docs/v7/copilot/auto-healing.mdx +265 -0
- package/docs/v7/copilot/creating-tests.mdx +156 -0
- package/docs/v7/copilot/github.mdx +143 -0
- package/docs/v7/copilot/running-tests.mdx +149 -0
- package/docs/v7/copilot/setup.mdx +143 -0
- package/docs/v7/enterprise.mdx +3 -110
- package/docs/v7/errors.mdx +248 -0
- package/docs/v7/events.mdx +358 -0
- package/docs/v7/examples/ai.mdx +1 -1
- package/docs/v7/examples/assert.mdx +1 -1
- package/docs/v7/examples/captcha-api.mdx +1 -1
- package/docs/v7/examples/chrome-extension.mdx +1 -1
- package/docs/v7/examples/drag-and-drop.mdx +1 -1
- package/docs/v7/examples/element-not-found.mdx +1 -1
- package/docs/v7/examples/exec-output.mdx +85 -0
- package/docs/v7/examples/exec-pwsh.mdx +83 -0
- package/docs/v7/examples/focus-window.mdx +62 -0
- package/docs/v7/examples/hover-image.mdx +1 -1
- package/docs/v7/examples/hover-text.mdx +1 -1
- package/docs/v7/examples/installer.mdx +1 -1
- package/docs/v7/examples/launch-vscode-linux.mdx +1 -1
- package/docs/v7/examples/match-image.mdx +1 -1
- package/docs/v7/examples/press-keys.mdx +1 -1
- package/docs/v7/examples/scroll-keyboard.mdx +1 -1
- package/docs/v7/examples/scroll-until-image.mdx +1 -1
- package/docs/v7/examples/scroll-until-text.mdx +1 -1
- package/docs/v7/examples/scroll.mdx +1 -1
- package/docs/v7/examples/type.mdx +1 -1
- package/docs/v7/examples/windows-installer.mdx +1 -1
- package/docs/v7/{cloud.mdx → hosted.mdx} +43 -5
- package/docs/v7/mcp.mdx +9 -0
- package/docs/v7/provision.mdx +333 -0
- package/docs/v7/quickstart.mdx +30 -2
- package/docs/v7/redraw.mdx +216 -0
- package/docs/v7/running-tests.mdx +1 -1
- package/docs/v7/screenshots.mdx +186 -0
- package/docs/v7/self-hosted.mdx +127 -44
- package/interfaces/logger.js +0 -12
- package/interfaces/vitest-plugin.mjs +53 -43
- package/lib/core/Dashcam.js +30 -23
- package/lib/environments.json +18 -0
- package/lib/github-comment.mjs +58 -40
- package/lib/resolve-channel.js +4 -3
- package/lib/sentry.js +5 -0
- package/{examples → manual}/drag-and-drop.test.mjs +1 -1
- package/mcp-server/dist/server.mjs +4 -0
- package/mcp-server/src/server.ts +5 -0
- package/package.json +3 -3
- package/sdk.js +3 -3
- package/setup/aws/install-dev-runner.sh +79 -0
- package/setup/aws/spawn-runner.sh +134 -0
- package/vitest.config.mjs +20 -32
- package/vitest.runner.config.mjs +33 -0
- /package/{examples → manual}/flake-diffthreshold-001.test.mjs +0 -0
- /package/{examples → manual}/flake-diffthreshold-01.test.mjs +0 -0
- /package/{examples → manual}/flake-diffthreshold-05.test.mjs +0 -0
- /package/{examples → manual}/flake-noredraw-cache.test.mjs +0 -0
- /package/{examples → manual}/flake-noredraw-nocache.test.mjs +0 -0
- /package/{examples → manual}/flake-redraw-cache.test.mjs +0 -0
- /package/{examples → manual}/flake-redraw-nocache.test.mjs +0 -0
- /package/{examples → manual}/flake-rocket-match.test.mjs +0 -0
- /package/{examples → manual}/flake-shared.mjs +0 -0
- /package/{examples → manual}/no-provision.test.mjs +0 -0
- /package/{examples → manual}/scroll-until-text.test.mjs +0 -0
package/lib/sentry.js
CHANGED
|
@@ -46,7 +46,7 @@ describe("Drag and Drop Test", () => {
|
|
|
46
46
|
|
|
47
47
|
const recycleBin = await testdriver.find(
|
|
48
48
|
"Recycle Bin, recycle bin icon in the top left corner of the desktop",
|
|
49
|
-
);
|
|
49
|
+
).hover();
|
|
50
50
|
await recycleBin.mouseUp();
|
|
51
51
|
|
|
52
52
|
// Assert "New Text Document" icon is not on the Desktop
|
|
@@ -84,6 +84,10 @@ if (isSentryEnabled()) {
|
|
|
84
84
|
if (error && typeof error === "object" && "name" in error && error.name === "TestFailure") {
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
|
+
// Filter out ElementNotFoundError - expected test outcome, not a crash
|
|
88
|
+
if (error && typeof error === "object" && "name" in error && error.name === "ElementNotFoundError") {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
87
91
|
return event;
|
|
88
92
|
},
|
|
89
93
|
});
|
package/mcp-server/src/server.ts
CHANGED
|
@@ -99,6 +99,11 @@ if (isSentryEnabled()) {
|
|
|
99
99
|
if (error && typeof error === "object" && "name" in error && (error as { name: string }).name === "TestFailure") {
|
|
100
100
|
return null;
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
// Filter out ElementNotFoundError - expected test outcome, not a crash
|
|
104
|
+
if (error && typeof error === "object" && "name" in error && (error as { name: string }).name === "ElementNotFoundError") {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
102
107
|
|
|
103
108
|
return event;
|
|
104
109
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testdriverai",
|
|
3
|
-
"version": "7.8.0-test.
|
|
3
|
+
"version": "7.8.0-test.40",
|
|
4
4
|
"description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
|
|
5
5
|
"main": "sdk.js",
|
|
6
6
|
"types": "sdk.d.ts",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"start": "node bin/testdriverai.js",
|
|
38
38
|
"dev": "DEV=true node bin/testdriverai.js",
|
|
39
39
|
"debug": "DEV=true VERBOSE=true node bin/testdriverai.js",
|
|
40
|
-
"docs": "npm run docs:skills && cd docs && npx mint@latest dev",
|
|
41
|
-
"docs:dev": "cd docs && npx mint dev",
|
|
40
|
+
"docs": "npm run docs:skills && cd docs && npx mint@latest dev --port 3002",
|
|
41
|
+
"docs:dev": "cd docs && npx mint dev --port 3002",
|
|
42
42
|
"docs:build": "npm run docs:skills && cd docs && npx mint@latest build",
|
|
43
43
|
"docs:links": "node docs/_scripts/link-replacer.js",
|
|
44
44
|
"docs:skills": "node docs/_scripts/generate-skills.js",
|
package/sdk.js
CHANGED
|
@@ -2749,6 +2749,9 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
2749
2749
|
}
|
|
2750
2750
|
}
|
|
2751
2751
|
|
|
2752
|
+
// Log environment info immediately so it's visible even if auth fails
|
|
2753
|
+
this._logEnvironmentInfo();
|
|
2754
|
+
|
|
2752
2755
|
// Authenticate first if not already authenticated
|
|
2753
2756
|
if (!this.authenticated) {
|
|
2754
2757
|
await this.auth();
|
|
@@ -2865,9 +2868,6 @@ CAPTCHA_SOLVER_EOF`,
|
|
|
2865
2868
|
sandboxId: this.instance?.instanceId,
|
|
2866
2869
|
});
|
|
2867
2870
|
|
|
2868
|
-
// Log environment info (non-blocking, skip on stable)
|
|
2869
|
-
this._logEnvironmentInfo();
|
|
2870
|
-
|
|
2871
2871
|
return this.instance;
|
|
2872
2872
|
}
|
|
2873
2873
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Usage: ./install-dev-runner.sh <instance-id>
|
|
5
|
+
INSTANCE_ID="${1:?Usage: $0 <instance-id>}"
|
|
6
|
+
AWS_REGION="${AWS_REGION:-us-east-2}"
|
|
7
|
+
|
|
8
|
+
RUNNER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../runner" && pwd)"
|
|
9
|
+
|
|
10
|
+
echo "Packing local runner..."
|
|
11
|
+
TMPDIR=$(mktemp -d)
|
|
12
|
+
pushd "$RUNNER_DIR" > /dev/null
|
|
13
|
+
npm pack --pack-destination "$TMPDIR" > /dev/null 2>&1
|
|
14
|
+
TARBALL=$(ls "$TMPDIR"/*.tgz)
|
|
15
|
+
popd > /dev/null
|
|
16
|
+
echo "Tarball: $TARBALL"
|
|
17
|
+
|
|
18
|
+
echo "Uploading to S3..."
|
|
19
|
+
S3_KEY="runner-dev/$(date +%s)-$(openssl rand -hex 4)/runner.tgz"
|
|
20
|
+
aws s3 cp "$TARBALL" "s3://v7-transfer/${S3_KEY}" --region "$AWS_REGION" > /dev/null
|
|
21
|
+
DOWNLOAD_URL=$(aws s3 presign "s3://v7-transfer/${S3_KEY}" --expires-in 900 --region "$AWS_REGION")
|
|
22
|
+
rm -rf "$TMPDIR"
|
|
23
|
+
|
|
24
|
+
echo "Creating SSM params file..."
|
|
25
|
+
|
|
26
|
+
# Write Python script to temp file to generate valid JSON
|
|
27
|
+
PYTHON_SCRIPT=$(mktemp --suffix=.py)
|
|
28
|
+
cat > "$PYTHON_SCRIPT" << 'PYEOF'
|
|
29
|
+
import json
|
|
30
|
+
import sys
|
|
31
|
+
|
|
32
|
+
url = sys.argv[1]
|
|
33
|
+
|
|
34
|
+
commands = [
|
|
35
|
+
"Write-Host '=== Stopping runner ==='",
|
|
36
|
+
"Stop-ScheduledTask -TaskName RunTestDriverAgent -ErrorAction SilentlyContinue",
|
|
37
|
+
"Stop-Process -Name node -Force -ErrorAction SilentlyContinue",
|
|
38
|
+
"Start-Sleep -Seconds 2",
|
|
39
|
+
"Set-Location 'C:\\testdriver\\sandbox-agent'",
|
|
40
|
+
"$tarball = 'C:\\Windows\\Temp\\runner-dev.tgz'",
|
|
41
|
+
f"Invoke-WebRequest -Uri '{url}' -OutFile $tarball",
|
|
42
|
+
"Write-Host 'Tarball size:'; (Get-Item $tarball).Length",
|
|
43
|
+
"Remove-Item -Path lib -Recurse -Force -ErrorAction SilentlyContinue",
|
|
44
|
+
"tar -xzf $tarball --strip-components=1 -C .",
|
|
45
|
+
"Get-Content 'package.json' | ConvertFrom-Json | Select-Object -ExpandProperty version",
|
|
46
|
+
"Write-Host '=== Starting runner ==='",
|
|
47
|
+
"Start-ScheduledTask -TaskName RunTestDriverAgent",
|
|
48
|
+
"Start-Sleep -Seconds 3",
|
|
49
|
+
"Get-Content 'C:\\testdriver\\log.txt' -Tail 20"
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
params = {"commands": commands}
|
|
53
|
+
print(json.dumps(params))
|
|
54
|
+
PYEOF
|
|
55
|
+
|
|
56
|
+
python3 "$PYTHON_SCRIPT" "$DOWNLOAD_URL" > /tmp/ssm-install-params.json
|
|
57
|
+
rm "$PYTHON_SCRIPT"
|
|
58
|
+
|
|
59
|
+
echo "Sending SSM command..."
|
|
60
|
+
CMD_JSON=$(aws ssm send-command \
|
|
61
|
+
--region "$AWS_REGION" \
|
|
62
|
+
--instance-ids "$INSTANCE_ID" \
|
|
63
|
+
--document-name "AWS-RunPowerShellScript" \
|
|
64
|
+
--parameters "file:///tmp/ssm-install-params.json" \
|
|
65
|
+
--output json)
|
|
66
|
+
|
|
67
|
+
COMMAND_ID=$(echo "$CMD_JSON" | jq -r '.Command.CommandId')
|
|
68
|
+
echo "Command ID: $COMMAND_ID"
|
|
69
|
+
|
|
70
|
+
echo "Waiting for completion..."
|
|
71
|
+
aws ssm wait command-executed --region "$AWS_REGION" --command-id "$COMMAND_ID" --instance-id "$INSTANCE_ID" || true
|
|
72
|
+
|
|
73
|
+
echo "Getting output..."
|
|
74
|
+
aws ssm get-command-invocation \
|
|
75
|
+
--region "$AWS_REGION" \
|
|
76
|
+
--command-id "$COMMAND_ID" \
|
|
77
|
+
--instance-id "$INSTANCE_ID" \
|
|
78
|
+
--query 'StandardOutputContent' \
|
|
79
|
+
--output text
|
|
@@ -141,6 +141,140 @@ while :; do
|
|
|
141
141
|
sleep 20
|
|
142
142
|
done
|
|
143
143
|
|
|
144
|
+
# --- 4) Install/update runner ---
|
|
145
|
+
echo "Installing runner..."
|
|
146
|
+
|
|
147
|
+
# Determine environment and version
|
|
148
|
+
TD_ENV="${TD_ENV:-stable}"
|
|
149
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
150
|
+
SDK_PKG_JSON="${SCRIPT_DIR}/../../../sdk/package.json"
|
|
151
|
+
RUNNER_DIR="${SCRIPT_DIR}/../../../runner"
|
|
152
|
+
|
|
153
|
+
if [ -f "$SDK_PKG_JSON" ]; then
|
|
154
|
+
RUNNER_VERSION=$(jq -r '.version' "$SDK_PKG_JSON")
|
|
155
|
+
echo "Runner version from SDK: $RUNNER_VERSION"
|
|
156
|
+
else
|
|
157
|
+
RUNNER_VERSION="$TD_ENV"
|
|
158
|
+
echo "SDK package.json not found, using env tag: $RUNNER_VERSION"
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
if [ "$TD_ENV" = "dev" ]; then
|
|
162
|
+
echo "Dev mode: packing and uploading local runner to S3..."
|
|
163
|
+
|
|
164
|
+
# Pack local runner
|
|
165
|
+
TMPDIR=$(mktemp -d)
|
|
166
|
+
pushd "$RUNNER_DIR" > /dev/null
|
|
167
|
+
npm pack --pack-destination "$TMPDIR" > /dev/null 2>&1
|
|
168
|
+
TARBALL=$(ls "$TMPDIR"/*.tgz | head -1)
|
|
169
|
+
popd > /dev/null
|
|
170
|
+
|
|
171
|
+
# Upload to S3
|
|
172
|
+
S3_BUCKET="${AWS_BUCKET_IMAGE_TRANSFER:-v7-transfer}"
|
|
173
|
+
S3_KEY="runner-dev/$(date +%s)-$(openssl rand -hex 4)/runner.tgz"
|
|
174
|
+
aws s3 cp "$TARBALL" "s3://${S3_BUCKET}/${S3_KEY}" --region "$AWS_REGION"
|
|
175
|
+
|
|
176
|
+
# Generate presigned URL (15 min)
|
|
177
|
+
DOWNLOAD_URL=$(aws s3 presign "s3://${S3_BUCKET}/${S3_KEY}" --expires-in 900 --region "$AWS_REGION")
|
|
178
|
+
rm -rf "$TMPDIR"
|
|
179
|
+
|
|
180
|
+
# Build SSM parameters JSON in a temp file to avoid shell escaping issues with URL
|
|
181
|
+
PARAMS_FILE=$(mktemp)
|
|
182
|
+
cat > "$PARAMS_FILE" << 'PARAMS_EOF'
|
|
183
|
+
{
|
|
184
|
+
"commands": [
|
|
185
|
+
"Write-Host '=== Starting runner dev install ==='",
|
|
186
|
+
"Write-Host 'Stopping existing runner processes...'",
|
|
187
|
+
"Stop-ScheduledTask -TaskName RunTestDriverAgent -ErrorAction SilentlyContinue",
|
|
188
|
+
"Stop-Process -Name node -Force -ErrorAction SilentlyContinue",
|
|
189
|
+
"Start-Sleep -Seconds 2",
|
|
190
|
+
"Write-Host 'Current runner version:'",
|
|
191
|
+
"Get-Content 'C:\\testdriver\\sandbox-agent\\package.json' | ConvertFrom-Json | Select-Object -ExpandProperty version",
|
|
192
|
+
"Set-Location 'C:\\testdriver\\sandbox-agent'",
|
|
193
|
+
"Write-Host 'Dev mode: downloading runner from S3...'",
|
|
194
|
+
"$tarball = 'C:\\Windows\\Temp\\runner-dev.tgz'",
|
|
195
|
+
PARAMS_EOF
|
|
196
|
+
|
|
197
|
+
# Add the URL line with proper JSON escaping
|
|
198
|
+
echo " \"Invoke-WebRequest -Uri '$(echo "$DOWNLOAD_URL" | sed 's/"/\\"/g')' -OutFile \$tarball\"," >> "$PARAMS_FILE"
|
|
199
|
+
|
|
200
|
+
cat >> "$PARAMS_FILE" << 'PARAMS_EOF'
|
|
201
|
+
"Write-Host 'Downloaded tarball size:'",
|
|
202
|
+
"(Get-Item $tarball).Length",
|
|
203
|
+
"Write-Host 'Extracting runner...'",
|
|
204
|
+
"tar -xzf $tarball -C 'C:\\Windows\\Temp'",
|
|
205
|
+
"Write-Host 'Extracted package contents:'",
|
|
206
|
+
"Get-ChildItem 'C:\\Windows\\Temp\\package' -Recurse | Select-Object FullName",
|
|
207
|
+
"Write-Host 'New runner version in package:'",
|
|
208
|
+
"Get-Content 'C:\\Windows\\Temp\\package\\package.json' | ConvertFrom-Json | Select-Object -ExpandProperty version",
|
|
209
|
+
"Write-Host 'Clearing old lib folder...'",
|
|
210
|
+
"Remove-Item 'C:\\testdriver\\sandbox-agent\\lib' -Recurse -Force -ErrorAction SilentlyContinue",
|
|
211
|
+
"Write-Host 'Copying files to sandbox-agent...'",
|
|
212
|
+
"xcopy 'C:\\Windows\\Temp\\package\\*' 'C:\\testdriver\\sandbox-agent\\' /E /Y /I",
|
|
213
|
+
"Write-Host 'Files after copy:'",
|
|
214
|
+
"Get-ChildItem 'C:\\testdriver\\sandbox-agent' | Select-Object Name",
|
|
215
|
+
"Remove-Item 'C:\\Windows\\Temp\\package' -Recurse -Force -ErrorAction SilentlyContinue",
|
|
216
|
+
"Remove-Item $tarball -Force -ErrorAction SilentlyContinue",
|
|
217
|
+
"Write-Host 'Runner version after copy:'",
|
|
218
|
+
"Get-Content 'C:\\testdriver\\sandbox-agent\\package.json' | ConvertFrom-Json | Select-Object -ExpandProperty version",
|
|
219
|
+
"Write-Host 'Installing npm dependencies...'",
|
|
220
|
+
"npm install --omit=dev 2>&1 | Write-Host",
|
|
221
|
+
"Write-Host 'Final verification - ably-service.js exists:'",
|
|
222
|
+
"Test-Path 'C:\\testdriver\\sandbox-agent\\lib\\ably-service.js'",
|
|
223
|
+
"Write-Host 'Restarting RunTestDriverAgent scheduled task...'",
|
|
224
|
+
"Start-ScheduledTask -TaskName RunTestDriverAgent -ErrorAction SilentlyContinue",
|
|
225
|
+
"Write-Host '=== Runner install complete (dev) ==='"
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
PARAMS_EOF
|
|
229
|
+
|
|
230
|
+
echo "Sending SSM command to download and install runner from S3..."
|
|
231
|
+
INSTALL_CMD=$(aws ssm send-command \
|
|
232
|
+
--region "$AWS_REGION" \
|
|
233
|
+
--instance-ids "$INSTANCE_ID" \
|
|
234
|
+
--document-name "AWS-RunPowerShellScript" \
|
|
235
|
+
--parameters "file://$PARAMS_FILE" \
|
|
236
|
+
--timeout-seconds 180 \
|
|
237
|
+
--output json)
|
|
238
|
+
rm -f "$PARAMS_FILE"
|
|
239
|
+
else
|
|
240
|
+
echo "Installing @testdriverai/runner@${RUNNER_VERSION} via npm..."
|
|
241
|
+
INSTALL_CMD=$(aws ssm send-command \
|
|
242
|
+
--region "$AWS_REGION" \
|
|
243
|
+
--instance-ids "$INSTANCE_ID" \
|
|
244
|
+
--document-name "AWS-RunPowerShellScript" \
|
|
245
|
+
--parameters "commands=[
|
|
246
|
+
\"Set-Location 'C:\\\\testdriver\\\\sandbox-agent'\",
|
|
247
|
+
\"Write-Host 'Installing @testdriverai/runner@${RUNNER_VERSION}...'\",
|
|
248
|
+
\"npm install @testdriverai/runner@${RUNNER_VERSION} --omit=dev 2>&1 | Write-Host\",
|
|
249
|
+
\"Write-Host 'Stopping runner (config not yet provisioned)...'\",
|
|
250
|
+
\"Stop-Process -Name node -Force -ErrorAction SilentlyContinue\",
|
|
251
|
+
\"Stop-ScheduledTask -TaskName RunTestDriverAgent -ErrorAction SilentlyContinue\",
|
|
252
|
+
\"Start-Sleep -Seconds 2\",
|
|
253
|
+
\"Start-ScheduledTask -TaskName RunTestDriverAgent -ErrorAction SilentlyContinue\",
|
|
254
|
+
\"Write-Host 'Runner install complete'\"
|
|
255
|
+
]" \
|
|
256
|
+
--timeout-seconds 120 \
|
|
257
|
+
--output json)
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
INSTALL_CMD_ID=$(jq -r '.Command.CommandId' <<<"$INSTALL_CMD")
|
|
261
|
+
echo "Runner install command sent (Command ID: $INSTALL_CMD_ID)"
|
|
262
|
+
|
|
263
|
+
# Wait for install to complete
|
|
264
|
+
echo "Waiting for runner install to complete..."
|
|
265
|
+
if aws ssm wait command-executed --region "$AWS_REGION" --command-id "$INSTALL_CMD_ID" --instance-id "$INSTANCE_ID" 2>/dev/null; then
|
|
266
|
+
echo "✓ Runner install succeeded"
|
|
267
|
+
else
|
|
268
|
+
INSTALL_STATUS=$(aws ssm get-command-invocation \
|
|
269
|
+
--region "$AWS_REGION" \
|
|
270
|
+
--command-id "$INSTALL_CMD_ID" \
|
|
271
|
+
--instance-id "$INSTANCE_ID" \
|
|
272
|
+
--output json 2>/dev/null || echo '{}')
|
|
273
|
+
echo "⚠ Runner install status: $(jq -r '.Status // "Unknown"' <<<"$INSTALL_STATUS")"
|
|
274
|
+
echo "Output: $(jq -r '.StandardOutputContent // "No output"' <<<"$INSTALL_STATUS" | head -20)"
|
|
275
|
+
echo "Errors: $(jq -r '.StandardErrorContent // "No errors"' <<<"$INSTALL_STATUS" | head -10)"
|
|
276
|
+
fi
|
|
277
|
+
|
|
144
278
|
echo "Getting Public IP..."
|
|
145
279
|
|
|
146
280
|
# --- 5) Get instance Public IP ---
|
package/vitest.config.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import TestDriver from "testdriverai/vitest";
|
|
2
2
|
import { defineConfig } from "vitest/config";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const { resolveEnv, getEnvironmentNames } = require("../shared/resolve-env");
|
|
5
7
|
|
|
6
8
|
// Always include AWS setup - it will be a no-op unless TD_OS=windows
|
|
7
9
|
// Note: dotenv is loaded automatically by the TestDriver SDK
|
|
@@ -25,45 +27,31 @@ const sharedTestConfig = {
|
|
|
25
27
|
include: ["examples/**/*.test.mjs"],
|
|
26
28
|
};
|
|
27
29
|
|
|
28
|
-
// ──
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
35
|
-
const idx = trimmed.indexOf("=");
|
|
36
|
-
if (idx === -1) continue;
|
|
37
|
-
env[trimmed.slice(0, idx)] = trimmed.slice(idx + 1);
|
|
38
|
-
}
|
|
39
|
-
return env;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// ── Load base .env + per-environment overlay ────────────────────────
|
|
43
|
-
const monoRoot = resolve(import.meta.dirname, "..");
|
|
44
|
-
const baseEnv = parseEnvFile(resolve(monoRoot, ".env"));
|
|
45
|
-
|
|
46
|
-
const environments = ["dev", "test", "canary", "stable"];
|
|
30
|
+
// ── Resolve env vars via shared/resolve-env.js ──────────────────────
|
|
31
|
+
// Uses: environments.json (URLs) + envs/{env}.env (overlay) + fixtures (API keys)
|
|
32
|
+
// TD_PLAN selects which plan's API key to use (default: enterprise)
|
|
33
|
+
const plan = process.env.TD_PLAN || "enterprise";
|
|
34
|
+
const defaultEnv = process.env.TD_ENV || "dev";
|
|
35
|
+
const environments = getEnvironmentNames();
|
|
47
36
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
// Apply default env to the main process so the reporter/plugin picks it up
|
|
38
|
+
// (vitest's test.env only propagates to worker processes, not the main process)
|
|
39
|
+
const defaultResolved = resolveEnv(defaultEnv, plan);
|
|
40
|
+
Object.assign(process.env, defaultResolved);
|
|
52
41
|
|
|
53
|
-
// ──
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
// vitest run --project canary --project stable
|
|
42
|
+
// ── Usage ───────────────────────────────────────────────────────────
|
|
43
|
+
// TD_PLAN=enterprise vitest run --project dev
|
|
44
|
+
// TD_PLAN=free vitest run --project test examples/assert.test.mjs
|
|
45
|
+
// vitest run --project canary --project stable
|
|
58
46
|
export default defineConfig({
|
|
59
47
|
test: {
|
|
60
48
|
...sharedTestConfig,
|
|
61
|
-
env:
|
|
49
|
+
env: defaultResolved,
|
|
62
50
|
projects: environments.map((envName) => ({
|
|
63
51
|
extends: true,
|
|
64
52
|
test: {
|
|
65
53
|
name: envName,
|
|
66
|
-
env:
|
|
54
|
+
env: resolveEnv(envName, plan),
|
|
67
55
|
},
|
|
68
56
|
})),
|
|
69
57
|
},
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest config for runner/packer tests.
|
|
3
|
+
* Lives under sdk/ so vitest resolves from sdk/node_modules,
|
|
4
|
+
* but uses shared/resolve-env.js for environment variable loading.
|
|
5
|
+
*/
|
|
6
|
+
import { defineConfig } from "vitest/config";
|
|
7
|
+
import { createRequire } from "module";
|
|
8
|
+
import { dirname, resolve } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const monoRoot = resolve(__dirname, "..");
|
|
13
|
+
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
const { resolveEnv } = require("../shared/resolve-env");
|
|
16
|
+
|
|
17
|
+
const plan = process.env.TD_PLAN || "enterprise";
|
|
18
|
+
const env = process.env.TD_ENV || "dev";
|
|
19
|
+
const resolved = resolveEnv(env, plan);
|
|
20
|
+
|
|
21
|
+
// Apply to the main process so test code sees the vars immediately
|
|
22
|
+
Object.assign(process.env, resolved);
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
test: {
|
|
26
|
+
root: monoRoot,
|
|
27
|
+
testTimeout: 900_000, // 15 min per test
|
|
28
|
+
hookTimeout: 2_400_000, // 40 min for beforeAll (AMI build + spawn)
|
|
29
|
+
reporters: ["default"],
|
|
30
|
+
include: ["runner/packer/test/**/*.test.mjs"],
|
|
31
|
+
env: resolved,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|