@supatest/cli 0.0.44 → 0.0.45
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/dist/index.js +175 -92
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6146,7 +6146,7 @@ var init_shared_es = __esm({
|
|
|
6146
6146
|
assigned: numberType(),
|
|
6147
6147
|
completed: numberType(),
|
|
6148
6148
|
failed: numberType(),
|
|
6149
|
-
|
|
6149
|
+
unassigned: numberType()
|
|
6150
6150
|
})
|
|
6151
6151
|
});
|
|
6152
6152
|
assigneeInfoSchema = objectType({
|
|
@@ -6218,7 +6218,7 @@ var init_shared_es = __esm({
|
|
|
6218
6218
|
assigned: numberType(),
|
|
6219
6219
|
completed: numberType(),
|
|
6220
6220
|
failed: numberType(),
|
|
6221
|
-
|
|
6221
|
+
unassigned: numberType()
|
|
6222
6222
|
})
|
|
6223
6223
|
});
|
|
6224
6224
|
bulkReassignResponseSchema = objectType({
|
|
@@ -6688,7 +6688,7 @@ var CLI_VERSION;
|
|
|
6688
6688
|
var init_version = __esm({
|
|
6689
6689
|
"src/version.ts"() {
|
|
6690
6690
|
"use strict";
|
|
6691
|
-
CLI_VERSION = "0.0.
|
|
6691
|
+
CLI_VERSION = "0.0.45";
|
|
6692
6692
|
}
|
|
6693
6693
|
});
|
|
6694
6694
|
|
|
@@ -7424,15 +7424,39 @@ var init_api_client = __esm({
|
|
|
7424
7424
|
return data;
|
|
7425
7425
|
}
|
|
7426
7426
|
/**
|
|
7427
|
-
*
|
|
7427
|
+
* Bulk get test details for multiple tests
|
|
7428
|
+
* @param testIds - Array of test IDs
|
|
7429
|
+
* @returns Array of test details (null for not found tests)
|
|
7430
|
+
*/
|
|
7431
|
+
async getTestDetailsBulk(testIds) {
|
|
7432
|
+
const url = `${this.apiUrl}/v1/reporting/tests/bulk`;
|
|
7433
|
+
logger.debug(`Bulk fetching ${testIds.length} test details`);
|
|
7434
|
+
const response = await fetch(url, {
|
|
7435
|
+
method: "POST",
|
|
7436
|
+
headers: {
|
|
7437
|
+
"Content-Type": "application/json",
|
|
7438
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
7439
|
+
},
|
|
7440
|
+
body: JSON.stringify({ testIds })
|
|
7441
|
+
});
|
|
7442
|
+
if (!response.ok) {
|
|
7443
|
+
const errorText = await response.text();
|
|
7444
|
+
throw new ApiError(response.status, response.statusText, errorText);
|
|
7445
|
+
}
|
|
7446
|
+
const data = await response.json();
|
|
7447
|
+
logger.debug(`Fetched ${data.tests.length} test details`);
|
|
7448
|
+
return data.tests;
|
|
7449
|
+
}
|
|
7450
|
+
/**
|
|
7451
|
+
* Assign a test to yourself (or someone else)
|
|
7428
7452
|
* @param params - Assignment parameters
|
|
7429
|
-
* @returns Assignment result
|
|
7453
|
+
* @returns Assignment result
|
|
7430
7454
|
*/
|
|
7431
|
-
async
|
|
7432
|
-
const url = `${this.apiUrl}/v1/
|
|
7433
|
-
logger.debug(`Assigning
|
|
7434
|
-
|
|
7435
|
-
|
|
7455
|
+
async assignTest(params) {
|
|
7456
|
+
const url = `${this.apiUrl}/v1/tests-catalog/assign`;
|
|
7457
|
+
logger.debug(`Assigning test`, {
|
|
7458
|
+
testId: params.testId,
|
|
7459
|
+
assignedTo: params.assignedTo
|
|
7436
7460
|
});
|
|
7437
7461
|
const response = await fetch(url, {
|
|
7438
7462
|
method: "POST",
|
|
@@ -7441,7 +7465,37 @@ var init_api_client = __esm({
|
|
|
7441
7465
|
Authorization: `Bearer ${this.apiKey}`
|
|
7442
7466
|
},
|
|
7443
7467
|
body: JSON.stringify({
|
|
7444
|
-
|
|
7468
|
+
testId: params.testId,
|
|
7469
|
+
assignedTo: params.assignedTo
|
|
7470
|
+
})
|
|
7471
|
+
});
|
|
7472
|
+
if (!response.ok) {
|
|
7473
|
+
const errorText = await response.text();
|
|
7474
|
+
throw new ApiError(response.status, response.statusText, errorText);
|
|
7475
|
+
}
|
|
7476
|
+
const data = await response.json();
|
|
7477
|
+
logger.debug(`Test assigned: ${params.testId} -> ${params.assignedTo}`);
|
|
7478
|
+
return data;
|
|
7479
|
+
}
|
|
7480
|
+
/**
|
|
7481
|
+
* Bulk assign multiple tests to yourself (or someone else)
|
|
7482
|
+
* @param params - Bulk assignment parameters
|
|
7483
|
+
* @returns Bulk assignment result with successful assignments and conflicts
|
|
7484
|
+
*/
|
|
7485
|
+
async assignTestsBulk(params) {
|
|
7486
|
+
const url = `${this.apiUrl}/v1/tests-catalog/assign-bulk`;
|
|
7487
|
+
logger.debug(`Bulk assigning ${params.testIds.length} tests`, {
|
|
7488
|
+
testIds: params.testIds,
|
|
7489
|
+
assignedTo: params.assignedTo
|
|
7490
|
+
});
|
|
7491
|
+
const response = await fetch(url, {
|
|
7492
|
+
method: "POST",
|
|
7493
|
+
headers: {
|
|
7494
|
+
"Content-Type": "application/json",
|
|
7495
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
7496
|
+
},
|
|
7497
|
+
body: JSON.stringify({
|
|
7498
|
+
testIds: params.testIds,
|
|
7445
7499
|
assignedTo: params.assignedTo
|
|
7446
7500
|
})
|
|
7447
7501
|
});
|
|
@@ -7451,18 +7505,18 @@ var init_api_client = __esm({
|
|
|
7451
7505
|
}
|
|
7452
7506
|
const data = await response.json();
|
|
7453
7507
|
logger.debug(
|
|
7454
|
-
`
|
|
7508
|
+
`Bulk assigned ${data.successful.length} tests, ${data.conflicts.length} conflicts`
|
|
7455
7509
|
);
|
|
7456
7510
|
return data;
|
|
7457
7511
|
}
|
|
7458
7512
|
/**
|
|
7459
|
-
* Mark assignment as complete
|
|
7513
|
+
* Mark assignment as complete or failed
|
|
7460
7514
|
* @param params - Completion parameters
|
|
7461
7515
|
* @returns Success status
|
|
7462
7516
|
*/
|
|
7463
7517
|
async completeAssignment(params) {
|
|
7464
|
-
const url = `${this.apiUrl}/v1/
|
|
7465
|
-
logger.debug(`
|
|
7518
|
+
const url = `${this.apiUrl}/v1/tests-catalog/${params.assignmentId}/status`;
|
|
7519
|
+
logger.debug(`Updating assignment status`, {
|
|
7466
7520
|
assignmentId: params.assignmentId,
|
|
7467
7521
|
status: params.status
|
|
7468
7522
|
});
|
|
@@ -7474,7 +7528,7 @@ var init_api_client = __esm({
|
|
|
7474
7528
|
},
|
|
7475
7529
|
body: JSON.stringify({
|
|
7476
7530
|
status: params.status,
|
|
7477
|
-
|
|
7531
|
+
notes: params.notes
|
|
7478
7532
|
})
|
|
7479
7533
|
});
|
|
7480
7534
|
if (!response.ok) {
|
|
@@ -7482,7 +7536,7 @@ var init_api_client = __esm({
|
|
|
7482
7536
|
throw new ApiError(response.status, response.statusText, errorText);
|
|
7483
7537
|
}
|
|
7484
7538
|
const data = await response.json();
|
|
7485
|
-
logger.debug(`Assignment
|
|
7539
|
+
logger.debug(`Assignment updated: ${params.assignmentId} -> ${params.status}`);
|
|
7486
7540
|
return data;
|
|
7487
7541
|
}
|
|
7488
7542
|
/**
|
|
@@ -7491,7 +7545,7 @@ var init_api_client = __esm({
|
|
|
7491
7545
|
* @returns Success status
|
|
7492
7546
|
*/
|
|
7493
7547
|
async releaseAssignment(assignmentId) {
|
|
7494
|
-
const url = `${this.apiUrl}/v1/
|
|
7548
|
+
const url = `${this.apiUrl}/v1/tests-catalog/${assignmentId}`;
|
|
7495
7549
|
logger.debug(`Releasing assignment: ${assignmentId}`);
|
|
7496
7550
|
const response = await fetch(url, {
|
|
7497
7551
|
method: "DELETE",
|
|
@@ -7508,12 +7562,12 @@ var init_api_client = __esm({
|
|
|
7508
7562
|
return data;
|
|
7509
7563
|
}
|
|
7510
7564
|
/**
|
|
7511
|
-
* Get my current assignments
|
|
7512
|
-
* @returns List of current assignments
|
|
7565
|
+
* Get my current work (active test assignments)
|
|
7566
|
+
* @returns List of current assignments with test info
|
|
7513
7567
|
*/
|
|
7514
|
-
async
|
|
7515
|
-
const url = `${this.apiUrl}/v1/
|
|
7516
|
-
logger.debug(`Fetching my assignments`);
|
|
7568
|
+
async getMyWork() {
|
|
7569
|
+
const url = `${this.apiUrl}/v1/tests-catalog/my-work`;
|
|
7570
|
+
logger.debug(`Fetching my work assignments`);
|
|
7517
7571
|
const response = await fetch(url, {
|
|
7518
7572
|
method: "GET",
|
|
7519
7573
|
headers: {
|
|
@@ -7525,17 +7579,22 @@ var init_api_client = __esm({
|
|
|
7525
7579
|
throw new ApiError(response.status, response.statusText, errorText);
|
|
7526
7580
|
}
|
|
7527
7581
|
const data = await response.json();
|
|
7528
|
-
logger.debug(`Fetched ${data.assignments
|
|
7529
|
-
return
|
|
7582
|
+
logger.debug(`Fetched ${data.assignments?.length || 0} active assignments`);
|
|
7583
|
+
return data;
|
|
7530
7584
|
}
|
|
7531
7585
|
/**
|
|
7532
|
-
* Get
|
|
7586
|
+
* Get test catalog tests for a run (to show tests and their assignment status)
|
|
7533
7587
|
* @param runId - The run ID
|
|
7534
|
-
* @
|
|
7588
|
+
* @param query - Optional query parameters for filtering
|
|
7589
|
+
* @returns List of tests with their assignment info
|
|
7535
7590
|
*/
|
|
7536
|
-
async
|
|
7537
|
-
const
|
|
7538
|
-
|
|
7591
|
+
async getRunTestsCatalog(runId, query2) {
|
|
7592
|
+
const urlParams = new URLSearchParams();
|
|
7593
|
+
if (query2?.page) urlParams.set("page", query2.page.toString());
|
|
7594
|
+
if (query2?.limit) urlParams.set("limit", query2.limit.toString());
|
|
7595
|
+
if (query2?.status) urlParams.set("status", query2.status);
|
|
7596
|
+
const url = `${this.apiUrl}/v1/tests-catalog/runs/${runId}?${urlParams.toString()}`;
|
|
7597
|
+
logger.debug(`Fetching tests catalog for run: ${runId}`);
|
|
7539
7598
|
const response = await fetch(url, {
|
|
7540
7599
|
method: "GET",
|
|
7541
7600
|
headers: {
|
|
@@ -7547,14 +7606,10 @@ var init_api_client = __esm({
|
|
|
7547
7606
|
throw new ApiError(response.status, response.statusText, errorText);
|
|
7548
7607
|
}
|
|
7549
7608
|
const data = await response.json();
|
|
7550
|
-
logger.debug(
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
assignedTo: a.assignedTo,
|
|
7555
|
-
assignedAt: a.assignedAt
|
|
7556
|
-
}))
|
|
7557
|
-
};
|
|
7609
|
+
logger.debug(
|
|
7610
|
+
`Fetched ${data.tests?.length || 0} tests for run ${runId}`
|
|
7611
|
+
);
|
|
7612
|
+
return data;
|
|
7558
7613
|
}
|
|
7559
7614
|
};
|
|
7560
7615
|
}
|
|
@@ -12615,36 +12670,22 @@ var init_TestSelector = __esm({
|
|
|
12615
12670
|
run,
|
|
12616
12671
|
onSelect,
|
|
12617
12672
|
onCancel,
|
|
12618
|
-
assignments =
|
|
12673
|
+
assignments = /* @__PURE__ */ new Map()
|
|
12619
12674
|
}) => {
|
|
12620
12675
|
const [allTests, setAllTests] = useState7([]);
|
|
12621
12676
|
const [selectedTests, setSelectedTests] = useState7(/* @__PURE__ */ new Set());
|
|
12622
12677
|
const [cursorIndex, setCursorIndex] = useState7(0);
|
|
12623
12678
|
const [isLoading, setIsLoading] = useState7(false);
|
|
12624
|
-
const [isLoadingAssignments, setIsLoadingAssignments] = useState7(true);
|
|
12625
12679
|
const [hasMore, setHasMore] = useState7(true);
|
|
12626
12680
|
const [totalTests, setTotalTests] = useState7(0);
|
|
12627
12681
|
const [error, setError] = useState7(null);
|
|
12628
12682
|
const [showAvailableOnly, setShowAvailableOnly] = useState7(true);
|
|
12629
12683
|
const [groupByFile, setGroupByFile] = useState7(false);
|
|
12630
|
-
const assignedTestMap =
|
|
12631
|
-
const assignedTestIds = new Set(assignments.
|
|
12684
|
+
const assignedTestMap = assignments;
|
|
12685
|
+
const assignedTestIds = new Set(assignments.keys());
|
|
12632
12686
|
useEffect7(() => {
|
|
12633
12687
|
loadMoreTests();
|
|
12634
12688
|
}, []);
|
|
12635
|
-
useEffect7(() => {
|
|
12636
|
-
fetchAssignments();
|
|
12637
|
-
}, [run.id]);
|
|
12638
|
-
const fetchAssignments = async () => {
|
|
12639
|
-
setIsLoadingAssignments(true);
|
|
12640
|
-
try {
|
|
12641
|
-
const result = await apiClient.getRunAssignments(run.id);
|
|
12642
|
-
} catch (err) {
|
|
12643
|
-
console.error("Failed to load assignments:", err);
|
|
12644
|
-
} finally {
|
|
12645
|
-
setIsLoadingAssignments(false);
|
|
12646
|
-
}
|
|
12647
|
-
};
|
|
12648
12689
|
const loadMoreTests = async () => {
|
|
12649
12690
|
if (isLoading || !hasMore) {
|
|
12650
12691
|
return;
|
|
@@ -12653,15 +12694,16 @@ var init_TestSelector = __esm({
|
|
|
12653
12694
|
setError(null);
|
|
12654
12695
|
try {
|
|
12655
12696
|
const page = Math.floor(allTests.length / PAGE_SIZE2) + 1;
|
|
12656
|
-
const result = await apiClient.
|
|
12697
|
+
const result = await apiClient.getRunTestsCatalog(run.id, {
|
|
12657
12698
|
page,
|
|
12658
12699
|
limit: PAGE_SIZE2,
|
|
12659
12700
|
status: "failed"
|
|
12660
12701
|
// Only fetch failed tests
|
|
12661
12702
|
});
|
|
12662
|
-
setTotalTests(result.total);
|
|
12703
|
+
setTotalTests(result.total ?? result.tests.length);
|
|
12663
12704
|
const loadedCount = allTests.length + result.tests.length;
|
|
12664
|
-
|
|
12705
|
+
const total = result.total ?? loadedCount;
|
|
12706
|
+
setHasMore(result.tests.length === PAGE_SIZE2 && loadedCount < total);
|
|
12665
12707
|
setAllTests((prev) => [...prev, ...result.tests]);
|
|
12666
12708
|
} catch (err) {
|
|
12667
12709
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -12732,7 +12774,7 @@ var init_TestSelector = __esm({
|
|
|
12732
12774
|
setSelectedTests(newSelected);
|
|
12733
12775
|
};
|
|
12734
12776
|
useInput3((input, key) => {
|
|
12735
|
-
if (allTests.length === 0 && !isLoading
|
|
12777
|
+
if (allTests.length === 0 && !isLoading) {
|
|
12736
12778
|
if (key.escape || input === "q") {
|
|
12737
12779
|
onCancel();
|
|
12738
12780
|
}
|
|
@@ -12863,7 +12905,7 @@ var init_TestSelector = __esm({
|
|
|
12863
12905
|
const displayAssignee = assignee.startsWith("cli:") ? assignee.slice(4) : assignee;
|
|
12864
12906
|
return /* @__PURE__ */ React21.createElement(Box18, { key: test.id, marginBottom: 0 }, /* @__PURE__ */ React21.createElement(Text16, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "black" : isAssigned ? theme.text.dim : theme.text.primary }, indicator), /* @__PURE__ */ React21.createElement(Text16, { backgroundColor: bgColor, color: isAssigned ? theme.text.dim : isChecked ? "green" : isSelected ? "black" : theme.text.dim }, isAssigned ? "\u{1F504}" : checkbox), /* @__PURE__ */ React21.createElement(Text16, null, " "), /* @__PURE__ */ React21.createElement(Text16, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "black" : isAssigned ? theme.text.dim : theme.text.primary }, file, line && /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? "black" : theme.text.dim }, ":", line), isAssigned && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, displayAssignee)), /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? "black" : theme.text.dim }, " - "), title));
|
|
12865
12907
|
})
|
|
12866
|
-
)), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginTop: 1 }, !groupByFile && filteredTests.length > VISIBLE_ITEMS2 && /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, "Showing ", adjustedStart + 1, "-", adjustedEnd, " of ", filteredTests.length, " ", showAvailableOnly ? "available" : "", " tests", hasMore && !isLoading && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, " (scroll for more)"))), groupByFile && /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, "Showing ", fileGroups.length, " file", fileGroups.length !== 1 ? "s" : "", " \u2022 ", filteredTests.length, " total test", filteredTests.length !== 1 ? "s" : "")), /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Space"), " toggle \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "n"), " none \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "s"), " next 10 \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "f"), " group files \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "t"), " toggle filter \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Enter"), " fix selected")), selectedTests.size > 0 && /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "green" }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")),
|
|
12908
|
+
)), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginTop: 1 }, !groupByFile && filteredTests.length > VISIBLE_ITEMS2 && /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, "Showing ", adjustedStart + 1, "-", adjustedEnd, " of ", filteredTests.length, " ", showAvailableOnly ? "available" : "", " tests", hasMore && !isLoading && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, " (scroll for more)"))), groupByFile && /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, "Showing ", fileGroups.length, " file", fileGroups.length !== 1 ? "s" : "", " \u2022 ", filteredTests.length, " total test", filteredTests.length !== 1 ? "s" : "")), /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Space"), " toggle \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "n"), " none \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "s"), " next 10 \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "f"), " group files \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "t"), " toggle filter \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Enter"), " fix selected")), selectedTests.size > 0 && /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "green" }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")), isLoading && /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "cyan" }, "Loading more tests..."))));
|
|
12867
12909
|
};
|
|
12868
12910
|
}
|
|
12869
12911
|
});
|
|
@@ -12889,7 +12931,8 @@ var init_FixFlow = __esm({
|
|
|
12889
12931
|
const [step, setStep] = useState8(initialRunId ? "select-run" : "select-run");
|
|
12890
12932
|
const [selectedRun, setSelectedRun] = useState8(null);
|
|
12891
12933
|
const [selectedTests, setSelectedTests] = useState8([]);
|
|
12892
|
-
const [assignments, setAssignments] = useState8(
|
|
12934
|
+
const [assignments, setAssignments] = useState8(/* @__PURE__ */ new Map());
|
|
12935
|
+
const [testCatalogMap, setTestCatalogMap] = useState8(/* @__PURE__ */ new Map());
|
|
12893
12936
|
const [assignmentIds, setAssignmentIds] = useState8(/* @__PURE__ */ new Map());
|
|
12894
12937
|
const [loadingProgress, setLoadingProgress] = useState8({ current: 0, total: 0 });
|
|
12895
12938
|
const [loadError, setLoadError] = useState8(null);
|
|
@@ -12913,8 +12956,25 @@ var init_FixFlow = __esm({
|
|
|
12913
12956
|
};
|
|
12914
12957
|
const fetchAssignments = async (runId) => {
|
|
12915
12958
|
try {
|
|
12916
|
-
const result = await apiClient.
|
|
12917
|
-
|
|
12959
|
+
const result = await apiClient.getRunTestsCatalog(runId, {
|
|
12960
|
+
status: "failed",
|
|
12961
|
+
limit: 1e3
|
|
12962
|
+
// Get all failed tests for assignment lookup
|
|
12963
|
+
});
|
|
12964
|
+
const assignmentMap = /* @__PURE__ */ new Map();
|
|
12965
|
+
const catalogMap = /* @__PURE__ */ new Map();
|
|
12966
|
+
for (const test of result.tests) {
|
|
12967
|
+
catalogMap.set(test.id, test.testId);
|
|
12968
|
+
if (test.assignment) {
|
|
12969
|
+
assignmentMap.set(test.id, {
|
|
12970
|
+
testId: test.testId,
|
|
12971
|
+
assignedTo: test.assignment.assignedTo,
|
|
12972
|
+
assignedAt: test.assignment.assignedAt
|
|
12973
|
+
});
|
|
12974
|
+
}
|
|
12975
|
+
}
|
|
12976
|
+
setAssignments(assignmentMap);
|
|
12977
|
+
setTestCatalogMap(catalogMap);
|
|
12918
12978
|
} catch (err) {
|
|
12919
12979
|
console.error("Failed to load assignments:", err);
|
|
12920
12980
|
}
|
|
@@ -12924,16 +12984,46 @@ var init_FixFlow = __esm({
|
|
|
12924
12984
|
setStep("claiming-tests");
|
|
12925
12985
|
setLoadError(null);
|
|
12926
12986
|
try {
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
if (
|
|
12933
|
-
|
|
12934
|
-
|
|
12987
|
+
const assignmentMap = /* @__PURE__ */ new Map();
|
|
12988
|
+
const testCatalogUuids = [];
|
|
12989
|
+
const testRunToCatalogMap = /* @__PURE__ */ new Map();
|
|
12990
|
+
for (const test of tests) {
|
|
12991
|
+
const testCatalogUuid = testCatalogMap.get(test.id);
|
|
12992
|
+
if (!testCatalogUuid) {
|
|
12993
|
+
throw new Error(`Test catalog entry not found for test: ${test.file}:${test.title}`);
|
|
12994
|
+
}
|
|
12995
|
+
testCatalogUuids.push(testCatalogUuid);
|
|
12996
|
+
testRunToCatalogMap.set(testCatalogUuid, test.id);
|
|
12997
|
+
}
|
|
12998
|
+
const result = await apiClient.assignTestsBulk({
|
|
12999
|
+
testIds: testCatalogUuids
|
|
13000
|
+
});
|
|
13001
|
+
for (const assignment of result.successful) {
|
|
13002
|
+
const testRunId = testRunToCatalogMap.get(assignment.testId);
|
|
13003
|
+
if (testRunId) {
|
|
13004
|
+
assignmentMap.set(testRunId, assignment.id);
|
|
13005
|
+
}
|
|
13006
|
+
}
|
|
13007
|
+
const conflicts = [];
|
|
13008
|
+
for (const conflict of result.conflicts) {
|
|
13009
|
+
const testRunId = testRunToCatalogMap.get(conflict.testId);
|
|
13010
|
+
if (testRunId) {
|
|
13011
|
+
const test = tests.find((t) => t.id === testRunId);
|
|
13012
|
+
if (test) {
|
|
13013
|
+
conflicts.push({
|
|
13014
|
+
test,
|
|
13015
|
+
assignee: conflict.assignedTo
|
|
13016
|
+
});
|
|
13017
|
+
}
|
|
13018
|
+
}
|
|
13019
|
+
}
|
|
13020
|
+
if (conflicts.length > 0) {
|
|
13021
|
+
const successfullyClaimed = tests.filter((test) => assignmentMap.has(test.id));
|
|
13022
|
+
if (successfullyClaimed.length === 0) {
|
|
13023
|
+
const conflictList = conflicts.slice(0, 3).map((c) => `${c.test.file}: ${c.test.title} (claimed by ${c.assignee})`).join("\n\u2022 ");
|
|
13024
|
+
const moreCount = conflicts.length - 3;
|
|
12935
13025
|
setLoadError(
|
|
12936
|
-
|
|
13026
|
+
`All selected tests are already claimed by others:
|
|
12937
13027
|
\u2022 ${conflictList}${moreCount > 0 ? `
|
|
12938
13028
|
\u2022 ... and ${moreCount} more` : ""}
|
|
12939
13029
|
|
|
@@ -12942,28 +13032,22 @@ Please select different tests.`
|
|
|
12942
13032
|
setStep("error");
|
|
12943
13033
|
return;
|
|
12944
13034
|
}
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
assignmentMap.set(assignment.testRunId, assignment.id);
|
|
12948
|
-
});
|
|
12949
|
-
setAssignmentIds(assignmentMap);
|
|
13035
|
+
setSelectedTests(successfullyClaimed);
|
|
13036
|
+
console.log(`Skipped ${conflicts.length} already claimed test(s), continuing with ${successfullyClaimed.length} test(s)`);
|
|
12950
13037
|
}
|
|
13038
|
+
setAssignmentIds(assignmentMap);
|
|
13039
|
+
const testsToLoad = conflicts.length > 0 ? tests.filter((test) => assignmentMap.has(test.id)) : tests;
|
|
12951
13040
|
setStep("loading-details");
|
|
12952
|
-
setLoadingProgress({ current: 0, total:
|
|
12953
|
-
const
|
|
12954
|
-
const
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
batch.map((test) => apiClient.getTestDetail(test.id))
|
|
12959
|
-
);
|
|
12960
|
-
testDetails.push(...batchResults);
|
|
12961
|
-
setLoadingProgress({ current: testDetails.length, total: tests.length });
|
|
12962
|
-
}
|
|
13041
|
+
setLoadingProgress({ current: 0, total: testsToLoad.length });
|
|
13042
|
+
const testIds = testsToLoad.map((test) => test.id);
|
|
13043
|
+
const testDetailsArray = await apiClient.getTestDetailsBulk(testIds);
|
|
13044
|
+
const testDetails = testDetailsArray.filter(
|
|
13045
|
+
(detail) => detail !== null
|
|
13046
|
+
);
|
|
12963
13047
|
const testContexts = testDetails.map((test) => ({ test }));
|
|
12964
13048
|
const prompt = buildFixPrompt(testContexts);
|
|
12965
13049
|
setStep("fixing");
|
|
12966
|
-
onStartFix(prompt,
|
|
13050
|
+
onStartFix(prompt, testsToLoad);
|
|
12967
13051
|
} catch (err) {
|
|
12968
13052
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
12969
13053
|
if (errorMessage.includes("network") || errorMessage.includes("fetch")) {
|
|
@@ -12991,7 +13075,7 @@ Press ESC to go back and try again.`);
|
|
|
12991
13075
|
};
|
|
12992
13076
|
const handleTestCancel = () => {
|
|
12993
13077
|
setSelectedRun(null);
|
|
12994
|
-
setAssignments(
|
|
13078
|
+
setAssignments(/* @__PURE__ */ new Map());
|
|
12995
13079
|
setStep("select-run");
|
|
12996
13080
|
};
|
|
12997
13081
|
const markAssignmentsComplete = async (fixSessionId) => {
|
|
@@ -13003,8 +13087,7 @@ Press ESC to go back and try again.`);
|
|
|
13003
13087
|
Array.from(assignmentIds.values()).map(
|
|
13004
13088
|
(assignmentId) => apiClient.completeAssignment({
|
|
13005
13089
|
assignmentId,
|
|
13006
|
-
status: "completed"
|
|
13007
|
-
fixSessionId
|
|
13090
|
+
status: "completed"
|
|
13008
13091
|
})
|
|
13009
13092
|
)
|
|
13010
13093
|
);
|