Skip to content

Commit e65dfe8

Browse files
cklinCopilot
andcommitted
Fix flaky query history reveal test via stable TreeItem ids
The query history tree data provider never set an id on its TreeItems, so VS Code identified tree nodes by their label plus their position in the list. When multiple history items share the same label, that positional identity is ambiguous, so treeView.reveal could resolve to the wrong item or fail outright ("Data tree node not found") when the list was re-sorted or refreshed. This mainly affects tests. The default label format includes the query start time, so real query history labels are effectively unique and users are unlikely to hit this (the only exception being a user who customises the label format to something non-unique). In query-history-manager.test.ts the label format is overridden to just the query name, producing identical labels; this made the "should not change the selection" cases flaky, reproducing locally around 50% of the time and disappearing entirely after this change. Because the impact is effectively test-only, no changelog entry is added. Set a stable, unique id on each tree item so reveal resolves deterministically regardless of duplicate labels or sort order. The id must be unique per item: getQueryId is not sufficient on its own because a multi-query run produces several local-query items that share the same initialInfo.id, so for local queries we also include the per-result output base name (VS Code de-duplicates nodes that share an id, which would otherwise break reveal/selection for the colliding items). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f0809f2f-2c92-4acf-8f51-468c5e79c14a
1 parent cb12678 commit e65dfe8

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

extensions/ql-vscode/src/query-history/history-tree-data-provider.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { env, EventEmitter, ThemeColor, ThemeIcon, TreeItem } from "vscode";
33
import { DisposableObject } from "../common/disposable-object";
44
import { assertNever } from "../common/helpers-pure";
55
import type { QueryHistoryInfo } from "./query-history-info";
6-
import { getLanguage } from "./query-history-info";
6+
import { getLanguage, getQueryId } from "./query-history-info";
77
import { QueryStatus } from "./query-status";
88
import type { HistoryItemLabelProvider } from "./history-item-label-provider";
99
import type { LanguageContextStore } from "../language-context-store";
@@ -17,6 +17,25 @@ export enum SortOrder {
1717
CountDesc = "CountDesc",
1818
}
1919

20+
/**
21+
* Computes a stable, unique id for a query history item, suitable for use as a
22+
* `TreeItem.id`. `getQueryId` alone is not unique because a multi-query run
23+
* produces several local-query items that share the same `initialInfo.id`; for
24+
* those we also include the (per-result) output base name.
25+
*/
26+
function getTreeItemId(element: QueryHistoryInfo): string {
27+
switch (element.t) {
28+
case "local":
29+
return `local:${element.initialInfo.id}:${
30+
element.completedQuery?.query.outputBaseName ?? ""
31+
}`;
32+
case "variant-analysis":
33+
return `variant-analysis:${getQueryId(element)}`;
34+
default:
35+
assertNever(element);
36+
}
37+
}
38+
2039
/**
2140
* Tree data provider for the query history view.
2241
*/
@@ -54,6 +73,22 @@ export class HistoryTreeDataProvider
5473
async getTreeItem(element: QueryHistoryInfo): Promise<TreeItem> {
5574
const treeItem = new TreeItem(this.labelProvider.getLabel(element));
5675

76+
// Give the tree item a stable, unique id. Without this, VS Code identifies
77+
// tree nodes by their label plus their position in the list. When multiple
78+
// history items share the same label, that positional identity is ambiguous
79+
// and makes `treeView.reveal` resolve to the wrong item (or fail outright)
80+
// when the list is re-sorted or refreshed. The default label format includes
81+
// the start time, so labels are effectively unique in practice and users are
82+
// unlikely to hit this; it mainly affects tests (and any user who customises
83+
// the label format to something non-unique).
84+
//
85+
// `getQueryId` is not guaranteed to be unique: a multi-query run produces
86+
// several local-query items that share the same `initialInfo.id`. Those
87+
// items differ by their output base name, so we include it to keep the id
88+
// unique (VS Code de-duplicates nodes that share an id, which would break
89+
// reveal/selection for all but one of them).
90+
treeItem.id = getTreeItemId(element);
91+
5792
treeItem.command = {
5893
title: "Query History Item",
5994
command: "codeQLQueryHistory.itemClicked",

0 commit comments

Comments
 (0)