bangonit 0.5.4 → 0.5.7
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/app/desktopapp/dist/main/index.js +56 -17
- package/app/desktopapp/dist/main/tabs.js +0 -9
- package/app/webapp/.next/standalone/app/webapp/.next/BUILD_ID +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/app-build-manifest.json +6 -6
- package/app/webapp/.next/standalone/app/webapp/.next/build-manifest.json +3 -3
- package/app/webapp/.next/standalone/app/webapp/.next/prerender-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/required-server-files.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found/page.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found.rsc +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/api/chat/route.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/api/screenshot/route.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app/page.js +5 -5
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app.rsc +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/index.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/index.rsc +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/page.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/chunks/679.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/middleware-build-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages/404.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages/500.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/server-reference-manifest.json +1 -1
- package/app/webapp/.next/{static/chunks/app/app/page-4c6dfbf12230aab7.js → standalone/app/webapp/.next/static/chunks/app/app/page-f4f042a34d2b4471.js} +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/layout-40f50d9380154ecf.js +1 -0
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/{main-app-106dd83f859b9dfa.js → main-app-76384b941f0b51cb.js} +1 -1
- package/app/webapp/.next/standalone/app/webapp/server.js +1 -1
- package/app/webapp/.next/standalone/package.json +2 -2
- package/app/webapp/.next/{standalone/app/webapp/.next/static/chunks/app/app/page-4c6dfbf12230aab7.js → static/chunks/app/app/page-f4f042a34d2b4471.js} +1 -1
- package/app/webapp/.next/static/chunks/app/layout-40f50d9380154ecf.js +1 -0
- package/app/webapp/.next/static/chunks/{main-app-106dd83f859b9dfa.js → main-app-76384b941f0b51cb.js} +1 -1
- package/bin/src/cli/bangonit.js +221 -79
- package/package.json +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/layout-57acb80d8da0067a.js +0 -1
- package/app/webapp/.next/static/chunks/app/layout-57acb80d8da0067a.js +0 -1
- /package/app/webapp/.next/standalone/app/webapp/.next/static/{96Rcgc5VRl40T_EbDikOw → Ovp2DYnS7hdkdiH-qvRCj}/_buildManifest.js +0 -0
- /package/app/webapp/.next/standalone/app/webapp/.next/static/{96Rcgc5VRl40T_EbDikOw → Ovp2DYnS7hdkdiH-qvRCj}/_ssgManifest.js +0 -0
- /package/app/webapp/.next/static/{96Rcgc5VRl40T_EbDikOw → Ovp2DYnS7hdkdiH-qvRCj}/_buildManifest.js +0 -0
- /package/app/webapp/.next/static/{96Rcgc5VRl40T_EbDikOw → Ovp2DYnS7hdkdiH-qvRCj}/_ssgManifest.js +0 -0
package/bin/src/cli/bangonit.js
CHANGED
|
@@ -44,6 +44,7 @@ const fs = __importStar(require("fs"));
|
|
|
44
44
|
const net = __importStar(require("net"));
|
|
45
45
|
const readline = __importStar(require("readline"));
|
|
46
46
|
const TOML = __importStar(require("@iarna/toml"));
|
|
47
|
+
const Minio = __importStar(require("minio"));
|
|
47
48
|
const yargs_1 = __importDefault(require("yargs"));
|
|
48
49
|
const helpers_1 = require("yargs/helpers");
|
|
49
50
|
const is_ci_1 = __importDefault(require("is-ci"));
|
|
@@ -362,47 +363,6 @@ Create new Bang On It! test plan files.
|
|
|
362
363
|
console.log("");
|
|
363
364
|
const setupCi = await p.askChoice("Set up GitHub Actions?", ["y", "n"], "y");
|
|
364
365
|
if (setupCi === "y") {
|
|
365
|
-
// Build the comment shell script once, reused by both workflows
|
|
366
|
-
const commentScript = `OUTPUT="\${{ github.workspace }}/bangonit-output.json"
|
|
367
|
-
if [ ! -f "$OUTPUT" ]; then
|
|
368
|
-
BODY="## \${{ github.workflow }} — ❌ Failed\\n\\nNo test output was produced. Check the [workflow logs](\${{ github.server_url }}/\${{ github.repository }}/actions/runs/\${{ github.run_id }})."
|
|
369
|
-
else
|
|
370
|
-
STATUS=$(jq -r '.status' "$OUTPUT")
|
|
371
|
-
if [ "$STATUS" = "pass" ]; then
|
|
372
|
-
HEADER="## \${{ github.workflow }} — ✅ Passed"
|
|
373
|
-
else
|
|
374
|
-
HEADER="## \${{ github.workflow }} — ❌ Failed"
|
|
375
|
-
fi
|
|
376
|
-
|
|
377
|
-
TABLE="| Test | Status | Duration | Recording |\\n|------|--------|----------|-----------|"
|
|
378
|
-
for row in $(jq -r '.tests[] | @base64' "$OUTPUT"); do
|
|
379
|
-
NAME=$(echo "$row" | base64 -d | jq -r '.name')
|
|
380
|
-
TEST_STATUS=$(echo "$row" | base64 -d | jq -r '.status')
|
|
381
|
-
DURATION=$(echo "$row" | base64 -d | jq -r '(.duration / 1000 * 10 | round / 10)')
|
|
382
|
-
if [ "$TEST_STATUS" = "pass" ]; then
|
|
383
|
-
EMOJI="✅"
|
|
384
|
-
else
|
|
385
|
-
EMOJI="❌"
|
|
386
|
-
fi
|
|
387
|
-
RECORDING=""
|
|
388
|
-
RECORDING_URL=$(jq -r --arg name "$NAME" '.recordings[]? | select(.name | contains($name)) | .url // empty' "$OUTPUT" 2>/dev/null || true)
|
|
389
|
-
if [ -z "$RECORDING_URL" ] && [ -n "$BANGONIT_S3_BASE_URL" ] && [ -d "recordings" ]; then
|
|
390
|
-
for rdir in recordings/*/index.html; do
|
|
391
|
-
if [ -f "$rdir" ]; then
|
|
392
|
-
RNAME=$(basename "$(dirname "$rdir")")
|
|
393
|
-
RECORDING_URL="$BANGONIT_S3_BASE_URL/$RNAME/index.html"
|
|
394
|
-
break
|
|
395
|
-
fi
|
|
396
|
-
done
|
|
397
|
-
fi
|
|
398
|
-
if [ -n "$RECORDING_URL" ]; then
|
|
399
|
-
RECORDING="[View recording]($RECORDING_URL)"
|
|
400
|
-
fi
|
|
401
|
-
TABLE="$TABLE\\n| $NAME | $EMOJI $TEST_STATUS | \${DURATION}s | $RECORDING |"
|
|
402
|
-
done
|
|
403
|
-
|
|
404
|
-
BODY="$HEADER\\n\\n$TABLE"
|
|
405
|
-
fi`;
|
|
406
366
|
const smokeWorkflow = `# Bang On It! — Smoke Tests
|
|
407
367
|
# Runs on every push to main/master and on pull requests.
|
|
408
368
|
#
|
|
@@ -471,10 +431,7 @@ jobs:
|
|
|
471
431
|
- name: Comment test starting
|
|
472
432
|
id: start-comment
|
|
473
433
|
if: github.event_name == 'pull_request'
|
|
474
|
-
run:
|
|
475
|
-
COMMENT_ID=$(gh api repos/\${{ github.repository }}/issues/\${{ github.event.pull_request.number }}/comments \\
|
|
476
|
-
--method POST --field "body=🧪 **Bang On It!** smoke tests starting..." --jq '.id')
|
|
477
|
-
echo "comment_id=$COMMENT_ID" >> "$GITHUB_OUTPUT"
|
|
434
|
+
run: boi ci comment-starting --repo \${{ github.repository }} --pr \${{ github.event.pull_request.number }} >> "$GITHUB_OUTPUT"
|
|
478
435
|
env:
|
|
479
436
|
GH_TOKEN: \${{ github.token }}
|
|
480
437
|
|
|
@@ -488,37 +445,26 @@ jobs:
|
|
|
488
445
|
# Requires AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY secrets.
|
|
489
446
|
# - name: Upload recordings to S3
|
|
490
447
|
# if: always()
|
|
491
|
-
# run:
|
|
492
|
-
#
|
|
493
|
-
#
|
|
494
|
-
#
|
|
495
|
-
# DIRNAME=$(basename "$dir")
|
|
496
|
-
# aws s3 sync "$dir" "s3://MY-BUCKET/bangonit/$DIRNAME/" \\
|
|
497
|
-
# --endpoint-url https://s3.us-east-1.amazonaws.com --no-progress
|
|
498
|
-
# aws s3api list-objects-v2 --bucket MY-BUCKET --prefix "bangonit/$DIRNAME/" \\
|
|
499
|
-
# --endpoint-url https://s3.us-east-1.amazonaws.com --query 'Contents[].Key' --output text | tr '\\t' '\\n' | while read -r key; do
|
|
500
|
-
# aws s3api put-object-acl --bucket MY-BUCKET --key "$key" --acl public-read \\
|
|
501
|
-
# --endpoint-url https://s3.us-east-1.amazonaws.com
|
|
502
|
-
# done
|
|
503
|
-
# fi
|
|
504
|
-
# done
|
|
505
|
-
# fi
|
|
448
|
+
# run: >-
|
|
449
|
+
# boi ci upload-recordings
|
|
450
|
+
# --bucket MY-BUCKET --prefix bangonit
|
|
451
|
+
# --endpoint-url https://s3.us-east-1.amazonaws.com
|
|
506
452
|
|
|
507
453
|
- name: Comment test results
|
|
508
454
|
if: always()
|
|
509
455
|
run: |
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
--method POST --field "body=@-"
|
|
456
|
+
ARGS="--repo \${{ github.repository }}"
|
|
457
|
+
ARGS="$ARGS --output \${{ github.workspace }}/bangonit-output.json"
|
|
458
|
+
ARGS="$ARGS --workflow-name \\"\${{ github.workflow }}\\""
|
|
459
|
+
ARGS="$ARGS --sha \${{ github.sha }}"
|
|
460
|
+
ARGS="$ARGS --run-url \\"\${{ github.server_url }}/\${{ github.repository }}/actions/runs/\${{ github.run_id }}\\""
|
|
461
|
+
if [ -n "\${{ github.event.pull_request.number }}" ]; then
|
|
462
|
+
ARGS="$ARGS --pr \${{ github.event.pull_request.number }}"
|
|
463
|
+
fi
|
|
464
|
+
if [ -n "\${{ steps.start-comment.outputs.comment_id }}" ]; then
|
|
465
|
+
ARGS="$ARGS --comment-id \${{ steps.start-comment.outputs.comment_id }}"
|
|
521
466
|
fi
|
|
467
|
+
eval "boi ci comment-results $ARGS"
|
|
522
468
|
env:
|
|
523
469
|
GH_TOKEN: \${{ github.token }}
|
|
524
470
|
|
|
@@ -592,16 +538,20 @@ jobs:
|
|
|
592
538
|
# EDIT: Uncomment to upload recordings to S3 (see bangonit-smoke.yml for full example)
|
|
593
539
|
# - name: Upload recordings to S3
|
|
594
540
|
# if: always()
|
|
595
|
-
# run:
|
|
596
|
-
#
|
|
541
|
+
# run: >-
|
|
542
|
+
# boi ci upload-recordings
|
|
543
|
+
# --bucket MY-BUCKET --prefix bangonit
|
|
544
|
+
# --endpoint-url https://s3.us-east-1.amazonaws.com
|
|
597
545
|
|
|
598
546
|
- name: Comment test results on commit
|
|
599
547
|
if: always()
|
|
600
|
-
run:
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
548
|
+
run: >-
|
|
549
|
+
boi ci comment-results
|
|
550
|
+
--repo \${{ github.repository }}
|
|
551
|
+
--output \${{ github.workspace }}/bangonit-output.json
|
|
552
|
+
--workflow-name "\${{ github.workflow }}"
|
|
553
|
+
--sha \${{ github.sha }}
|
|
554
|
+
--run-url "\${{ github.server_url }}/\${{ github.repository }}/actions/runs/\${{ github.run_id }}"
|
|
605
555
|
env:
|
|
606
556
|
GH_TOKEN: \${{ github.token }}
|
|
607
557
|
|
|
@@ -825,6 +775,153 @@ async function run(argv, config) {
|
|
|
825
775
|
process.exit(code ?? 1);
|
|
826
776
|
});
|
|
827
777
|
}
|
|
778
|
+
// --- ci commands ---
|
|
779
|
+
function ghExec(args) {
|
|
780
|
+
try {
|
|
781
|
+
return (0, child_process_1.execSync)(`gh ${args}`, { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
782
|
+
}
|
|
783
|
+
catch (err) {
|
|
784
|
+
const stderr = err.stderr?.toString().trim() || err.message;
|
|
785
|
+
die(`gh command failed: ${stderr}`);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
function ciCommentStarting(argv) {
|
|
789
|
+
const commentId = ghExec(`api repos/${argv.repo}/issues/${argv.pr}/comments --method POST --field "body=🧪 **Bang On It!** tests starting..." --jq '.id'`);
|
|
790
|
+
// Output in GitHub Actions format so the workflow can capture it
|
|
791
|
+
process.stdout.write(`comment_id=${commentId}\n`);
|
|
792
|
+
}
|
|
793
|
+
function ciCommentResults(argv) {
|
|
794
|
+
let body;
|
|
795
|
+
if (!fs.existsSync(argv.output)) {
|
|
796
|
+
const logsLink = argv.runUrl ? ` Check the [workflow logs](${argv.runUrl}).` : "";
|
|
797
|
+
body = `## ${argv.workflowName} — ❌ Failed\n\nNo test output was produced.${logsLink}`;
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
800
|
+
const data = JSON.parse(fs.readFileSync(argv.output, "utf-8"));
|
|
801
|
+
const passed = data.status === "pass";
|
|
802
|
+
const header = `## ${argv.workflowName} — ${passed ? "✅ Passed" : "❌ Failed"}`;
|
|
803
|
+
const rows = [];
|
|
804
|
+
for (const test of data.tests || []) {
|
|
805
|
+
const emoji = test.status === "pass" ? "✅" : "❌";
|
|
806
|
+
const duration = (test.duration / 1000).toFixed(1);
|
|
807
|
+
let recording = "";
|
|
808
|
+
// Check output JSON for recording URLs first
|
|
809
|
+
const rec = (data.recordings || []).find((r) => r.name && test.name && r.name.includes(test.name));
|
|
810
|
+
if (rec?.url) {
|
|
811
|
+
recording = `[View recording](${rec.url})`;
|
|
812
|
+
}
|
|
813
|
+
else if (argv.s3BaseUrl && fs.existsSync(argv.recordingsDir)) {
|
|
814
|
+
// Fall back to constructing URL from local recording dirs
|
|
815
|
+
try {
|
|
816
|
+
const dirs = fs
|
|
817
|
+
.readdirSync(argv.recordingsDir)
|
|
818
|
+
.filter((d) => fs.existsSync(path.join(argv.recordingsDir, d, "index.html")));
|
|
819
|
+
if (dirs.length > 0) {
|
|
820
|
+
recording = `[View recording](${argv.s3BaseUrl}/${dirs[0]}/index.html)`;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
catch {
|
|
824
|
+
// ignore
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
rows.push(`| ${test.name} | ${emoji} ${test.status} | ${duration}s | ${recording} |`);
|
|
828
|
+
}
|
|
829
|
+
const table = `| Test | Status | Duration | Recording |\n|------|--------|----------|-----------|${rows.length > 0 ? "\n" + rows.join("\n") : ""}`;
|
|
830
|
+
body = `${header}\n\n${table}`;
|
|
831
|
+
}
|
|
832
|
+
// Post the comment via gh, passing body on stdin to avoid shell escaping issues
|
|
833
|
+
if (argv.pr && argv.commentId) {
|
|
834
|
+
(0, child_process_1.execSync)(`gh api repos/${argv.repo}/issues/comments/${argv.commentId} --method PATCH --field "body=@-"`, {
|
|
835
|
+
input: body,
|
|
836
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
else if (argv.pr) {
|
|
840
|
+
(0, child_process_1.execSync)(`gh api repos/${argv.repo}/issues/${argv.pr}/comments --method POST --field "body=@-"`, {
|
|
841
|
+
input: body,
|
|
842
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
else if (argv.sha) {
|
|
846
|
+
(0, child_process_1.execSync)(`gh api repos/${argv.repo}/commits/${argv.sha}/comments --method POST --field "body=@-"`, {
|
|
847
|
+
input: body,
|
|
848
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
else {
|
|
852
|
+
// No target — print to stdout
|
|
853
|
+
console.log(body);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
async function uploadDirToS3(client, localDir, bucket, prefix) {
|
|
857
|
+
const uploaded = [];
|
|
858
|
+
const entries = fs.readdirSync(localDir, { withFileTypes: true });
|
|
859
|
+
for (const entry of entries) {
|
|
860
|
+
const fullPath = path.join(localDir, entry.name);
|
|
861
|
+
const objectName = `${prefix}/${entry.name}`;
|
|
862
|
+
if (entry.isDirectory()) {
|
|
863
|
+
uploaded.push(...(await uploadDirToS3(client, fullPath, bucket, objectName)));
|
|
864
|
+
}
|
|
865
|
+
else {
|
|
866
|
+
await client.fPutObject(bucket, objectName, fullPath, {});
|
|
867
|
+
uploaded.push(objectName);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return uploaded;
|
|
871
|
+
}
|
|
872
|
+
async function setObjectPublicRead(client, bucket, objectName) {
|
|
873
|
+
const c = client;
|
|
874
|
+
await new Promise((resolve, reject) => {
|
|
875
|
+
c.makeRequest({
|
|
876
|
+
method: "PUT",
|
|
877
|
+
bucketName: bucket,
|
|
878
|
+
objectName,
|
|
879
|
+
query: "acl",
|
|
880
|
+
headers: { "x-amz-acl": "public-read" },
|
|
881
|
+
}, "", [200], "", true, (err) => {
|
|
882
|
+
if (err)
|
|
883
|
+
reject(err);
|
|
884
|
+
else
|
|
885
|
+
resolve();
|
|
886
|
+
});
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
async function ciUploadRecordings(argv) {
|
|
890
|
+
if (!fs.existsSync(argv.recordingsDir)) {
|
|
891
|
+
console.log("No recordings directory found, skipping upload.");
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const dirs = fs.readdirSync(argv.recordingsDir).filter((d) => {
|
|
895
|
+
const full = path.join(argv.recordingsDir, d);
|
|
896
|
+
return fs.statSync(full).isDirectory();
|
|
897
|
+
});
|
|
898
|
+
if (dirs.length === 0) {
|
|
899
|
+
console.log("No recording directories found, skipping upload.");
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
const accessKey = argv.accessKey || process.env.AWS_ACCESS_KEY_ID || "";
|
|
903
|
+
const secretKey = argv.secretKey || process.env.AWS_SECRET_ACCESS_KEY || "";
|
|
904
|
+
const region = argv.region || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || "us-east-1";
|
|
905
|
+
let client;
|
|
906
|
+
if (argv.endpointUrl) {
|
|
907
|
+
const useSSL = !argv.endpointUrl.startsWith("http://");
|
|
908
|
+
const endPoint = argv.endpointUrl.replace(/^https?:\/\//, "");
|
|
909
|
+
client = new Minio.Client({ endPoint, useSSL, accessKey, secretKey, region });
|
|
910
|
+
}
|
|
911
|
+
else {
|
|
912
|
+
client = new Minio.Client({ endPoint: "s3.amazonaws.com", useSSL: true, accessKey, secretKey, region });
|
|
913
|
+
}
|
|
914
|
+
for (const dir of dirs) {
|
|
915
|
+
const localPath = path.join(argv.recordingsDir, dir);
|
|
916
|
+
console.log(`Uploading ${dir}...`);
|
|
917
|
+
const uploaded = await uploadDirToS3(client, localPath, argv.bucket, `${argv.prefix}/${dir}`);
|
|
918
|
+
for (const key of uploaded) {
|
|
919
|
+
await setObjectPublicRead(client, argv.bucket, key);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
console.log(`Uploaded ${dirs.length} recording(s).`);
|
|
923
|
+
process.exit(0);
|
|
924
|
+
}
|
|
828
925
|
// --- main ---
|
|
829
926
|
const ciDefaults = is_ci_1.default ? { headless: true, exit: true } : {};
|
|
830
927
|
(0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
@@ -882,6 +979,51 @@ const ciDefaults = is_ci_1.default ? { headless: true, exit: true } : {};
|
|
|
882
979
|
timeout: argv.timeout,
|
|
883
980
|
}, config);
|
|
884
981
|
})
|
|
982
|
+
.command("ci", "CI helper commands (used by generated GitHub Actions workflows)", (y) => y
|
|
983
|
+
.command("comment-starting", "Post a 'tests starting' comment on a PR", (y) => y
|
|
984
|
+
.option("repo", { type: "string", demandOption: true, describe: "GitHub repo (owner/repo)" })
|
|
985
|
+
.option("pr", { type: "number", demandOption: true, describe: "PR number" }), (argv) => ciCommentStarting({ repo: argv.repo, pr: argv.pr }))
|
|
986
|
+
.command("comment-results", "Post test results as a PR or commit comment", (y) => y
|
|
987
|
+
.option("repo", { type: "string", demandOption: true, describe: "GitHub repo (owner/repo)" })
|
|
988
|
+
.option("output", { type: "string", demandOption: true, describe: "Path to bangonit-output.json" })
|
|
989
|
+
.option("workflow-name", { type: "string", demandOption: true, describe: "Workflow name for the header" })
|
|
990
|
+
.option("pr", { type: "number", describe: "PR number (for PR comments)" })
|
|
991
|
+
.option("comment-id", { type: "string", describe: "Existing comment ID to edit" })
|
|
992
|
+
.option("sha", { type: "string", describe: "Commit SHA (for commit comments)" })
|
|
993
|
+
.option("run-url", { type: "string", describe: "URL to workflow run logs" })
|
|
994
|
+
.option("s3-base-url", {
|
|
995
|
+
type: "string",
|
|
996
|
+
describe: "Base URL for S3 recording links",
|
|
997
|
+
default: process.env.BANGONIT_S3_BASE_URL || "",
|
|
998
|
+
})
|
|
999
|
+
.option("recordings-dir", { type: "string", describe: "Recordings directory", default: "recordings" }), (argv) => ciCommentResults({
|
|
1000
|
+
repo: argv.repo,
|
|
1001
|
+
output: argv.output,
|
|
1002
|
+
workflowName: argv.workflowName,
|
|
1003
|
+
pr: argv.pr,
|
|
1004
|
+
commentId: argv.commentId,
|
|
1005
|
+
sha: argv.sha,
|
|
1006
|
+
runUrl: argv.runUrl,
|
|
1007
|
+
s3BaseUrl: argv.s3BaseUrl || undefined,
|
|
1008
|
+
recordingsDir: argv.recordingsDir,
|
|
1009
|
+
}))
|
|
1010
|
+
.command("upload-recordings", "Upload recordings to S3-compatible storage", (y) => y
|
|
1011
|
+
.option("bucket", { type: "string", demandOption: true, describe: "S3 bucket name" })
|
|
1012
|
+
.option("prefix", { type: "string", demandOption: true, describe: "S3 key prefix" })
|
|
1013
|
+
.option("recordings-dir", { type: "string", describe: "Local recordings directory", default: "recordings" })
|
|
1014
|
+
.option("endpoint-url", { type: "string", describe: "S3 endpoint URL" })
|
|
1015
|
+
.option("access-key", { type: "string", describe: "S3 access key (default: AWS_ACCESS_KEY_ID env)" })
|
|
1016
|
+
.option("secret-key", { type: "string", describe: "S3 secret key (default: AWS_SECRET_ACCESS_KEY env)" })
|
|
1017
|
+
.option("region", { type: "string", describe: "S3 region (default: us-east-1)" }), (argv) => ciUploadRecordings({
|
|
1018
|
+
bucket: argv.bucket,
|
|
1019
|
+
prefix: argv.prefix,
|
|
1020
|
+
recordingsDir: argv.recordingsDir,
|
|
1021
|
+
endpointUrl: argv.endpointUrl,
|
|
1022
|
+
accessKey: argv.accessKey,
|
|
1023
|
+
secretKey: argv.secretKey,
|
|
1024
|
+
region: argv.region,
|
|
1025
|
+
}))
|
|
1026
|
+
.demandCommand(1, "Specify a ci subcommand: comment-starting, comment-results, upload-recordings"))
|
|
885
1027
|
.example("$0 run test.md", "Run a test plan file")
|
|
886
1028
|
.example("$0 run --plan 'test login flow'", "Run an inline test plan")
|
|
887
1029
|
.example("$0 run -t checkout", "Run test plans matching 'checkout'")
|
|
@@ -890,4 +1032,4 @@ const ciDefaults = is_ci_1.default ? { headless: true, exit: true } : {};
|
|
|
890
1032
|
.strict()
|
|
891
1033
|
.help()
|
|
892
1034
|
.alias("h", "help")
|
|
893
|
-
.
|
|
1035
|
+
.parseAsync();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bangonit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "AI-powered E2E testing tool",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bangonit": "bin/src/cli/bangonit.js",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@iarna/toml": "^2.2.5",
|
|
62
|
-
"diff": "^8.0.3",
|
|
63
62
|
"dotenv": "^17.3.1",
|
|
64
63
|
"electron": "^40.8.0",
|
|
65
64
|
"is-ci": "^4.1.0",
|
|
65
|
+
"minio": "^8.0.7",
|
|
66
66
|
"yargs": "^18.0.0",
|
|
67
67
|
"zod": "^3.25.0"
|
|
68
68
|
},
|
package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/layout-57acb80d8da0067a.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{4143:function(n,e,u){Promise.resolve().then(u.t.bind(u,2625,23))},2625:function(){}},function(n){n.O(0,[387,293,528,744],function(){return n(n.s=4143)}),_N_E=n.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[185],{4143:function(n,e,u){Promise.resolve().then(u.t.bind(u,2625,23))},2625:function(){}},function(n){n.O(0,[387,293,528,744],function(){return n(n.s=4143)}),_N_E=n.O()}]);
|
|
File without changes
|
|
File without changes
|
/package/app/webapp/.next/static/{96Rcgc5VRl40T_EbDikOw → Ovp2DYnS7hdkdiH-qvRCj}/_buildManifest.js
RENAMED
|
File without changes
|
/package/app/webapp/.next/static/{96Rcgc5VRl40T_EbDikOw → Ovp2DYnS7hdkdiH-qvRCj}/_ssgManifest.js
RENAMED
|
File without changes
|