Distinguish main matches from related suggestions and ship 0.1.9
This commit is contained in:
1 parent
a8ba594d0e
commit
b0bdfc7816
40 files changed
+2463
-185
No files matched your search
@@ -48,7 +48,7 @@ loaded fonts, image pixels, and genuine worker inference counters in debug mode.
|
||||
## Artifacts and limits
|
||||
|
||||
Outputs under docs/screenshots are launcher-empty.png, search-light.png, search-dark.png,
|
||||
media-search.png and performance-details.png, plus capture-manifest.json. The
|
||||
media-search.png, related-suggestions.png and performance-details.png, plus capture-manifest.json. The
|
||||
manifest contains actual fixture queries, counts/selection, measured response
|
||||
metrics, device/model, viewport, PNG SHA256, runner/browser versions, Git base
|
||||
commit and dirty-state flag. The base commit does not identify uncommitted
|
||||
@@ -56,6 +56,12 @@ source exactly. It also records the actual frontend package version and built
|
||||
index SHA-256. The compact empty-bar capture has no manufactured results and
|
||||
uses the genuine ready backend. The ephemeral API token is never saved in the manifest.
|
||||
|
||||
The 0.1.9 capture also records exact hashes of the shared service, relevance
|
||||
policy, frontend and capture sources. It checks that related suggestions start
|
||||
collapsed and are skipped by result keyboard navigation, remain accessible when
|
||||
expanded, and restore a visible primary selection when collapsed. The extra
|
||||
related-suggestions image shows actual expanded neighbors, not invented results.
|
||||
|
||||
Captures are **browser-rendered production UI with the actual CPU engine**.
|
||||
They omit native window chrome. They do not establish native WebView visual QA,
|
||||
OS integration, playback codec parity, production relevance, GPU behavior or
|
||||
|
||||
@@ -25,6 +25,12 @@ const out = resolve(
|
||||
repository,
|
||||
process.env.SEARCHI_CAPTURE_OUTPUT ?? "docs/screenshots",
|
||||
);
|
||||
const frontendVersion = JSON.parse(await readFile(
|
||||
resolve(repository, "apps/desktop/package.json"), "utf8")).version;
|
||||
if (process.env.SEARCHI_CAPTURE_EXPECTED_VERSION) {
|
||||
assert.equal(frontendVersion, process.env.SEARCHI_CAPTURE_EXPECTED_VERSION,
|
||||
"Frontend metadata must match the version intended for this capture");
|
||||
}
|
||||
const infoResponse = await fetch(new URL("/capture-info", target), {
|
||||
signal: AbortSignal.timeout(15000),
|
||||
});
|
||||
@@ -35,6 +41,10 @@ assert(
|
||||
"Requires an initialized real-engine capture backend",
|
||||
);
|
||||
await mkdir(out, { recursive: true });
|
||||
assert(process.env.SEARCHI_CAPTURE_BACKEND_EXE,
|
||||
"Set SEARCHI_CAPTURE_BACKEND_EXE to the actual owned backend executable for provenance");
|
||||
const captureBackendSha256 = createHash("sha256")
|
||||
.update(await readFile(process.env.SEARCHI_CAPTURE_BACKEND_EXE)).digest("hex");
|
||||
const browser = await chromium.launch({
|
||||
headless: true,
|
||||
args: [
|
||||
@@ -47,6 +57,7 @@ const failures = [];
|
||||
const evidence = [];
|
||||
const measured = [];
|
||||
let latestMeasured;
|
||||
const isRelated = (result) => result.match_kind?.endsWith("_related") === true;
|
||||
const source = {
|
||||
base_commit: execFileSync("git", ["rev-parse", "HEAD"], {
|
||||
cwd: repository,
|
||||
@@ -58,6 +69,17 @@ const source = {
|
||||
encoding: "utf8",
|
||||
}).trim().length > 0,
|
||||
};
|
||||
source.source_sha256 = {};
|
||||
for (const name of [
|
||||
"crates/searchi-service/src/lib.rs", "crates/searchi-service/src/relevance.rs",
|
||||
"apps/desktop/src/main.ts", "apps/desktop/src/style.css",
|
||||
"tools/desktop-capture/backend/src/main.rs", "tools/desktop-capture/capture.mjs",
|
||||
"tools/relevance-eval/policies/evidence-v1.json",
|
||||
]) {
|
||||
source.source_sha256[name] = createHash("sha256")
|
||||
.update(await readFile(resolve(repository, name))).digest("hex");
|
||||
}
|
||||
source.capture_backend_sha256 = captureBackendSha256;
|
||||
try {
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 1440, height: 1000 },
|
||||
@@ -139,6 +161,8 @@ try {
|
||||
query: text,
|
||||
mode: debug ? "debug" : "basic",
|
||||
result_count: body.results.length,
|
||||
main_result_count: body.results.filter((result) => !isRelated(result)).length,
|
||||
related_result_count: body.results.filter(isRelated).length,
|
||||
metrics: body.metrics,
|
||||
first_filename: body.results[0]?.filename,
|
||||
first_source: body.results[0]?.source,
|
||||
@@ -160,7 +184,7 @@ try {
|
||||
{
|
||||
query: text,
|
||||
filename: latestMeasured.first_filename,
|
||||
count: latestMeasured.result_count,
|
||||
count: latestMeasured.main_result_count,
|
||||
},
|
||||
{ timeout: 60000 },
|
||||
);
|
||||
@@ -168,15 +192,22 @@ try {
|
||||
(await page.locator("#results .result").count()) > 0,
|
||||
`Real query returned no matches: ${text}`,
|
||||
);
|
||||
assert.equal(await page.locator("#related-results .result").count(), 0,
|
||||
"Collapsed related neighbors must stay out of keyboard/focusable result rows");
|
||||
assert.equal(await page.locator("#related-suggestions").evaluate((element) => element.open),
|
||||
false, "Related suggestions must be collapsed for a new query");
|
||||
await page.locator("#results .result").first().click();
|
||||
await page.waitForFunction(
|
||||
() => !document.querySelector("#preview")?.hidden,
|
||||
);
|
||||
if (text === "cancel the supplier partnership") {
|
||||
assert(
|
||||
!body.results.some((result) => ["Mountain Lake.jpg", "Night Pier.jpg"].includes(result.filename)),
|
||||
"Contract results must not contain the unrelated fixture photos",
|
||||
body.results.filter((result) => ["Mountain Lake.jpg", "Night Pier.jpg"].includes(result.filename))
|
||||
.every(isRelated),
|
||||
"Contract photos must remain related suggestions rather than primary results",
|
||||
);
|
||||
assert(body.results.some((result) => result.filename === "Mountain Lake.jpg"),
|
||||
"Eligible mountain photo must remain accessible as a related suggestion");
|
||||
assert.equal(
|
||||
latestMeasured.first_filename,
|
||||
"Supplier Agreement.pdf",
|
||||
@@ -251,12 +282,13 @@ try {
|
||||
literal_query_marks: true,
|
||||
actual_page_explanation: true,
|
||||
why_disclosure_collapsed_by_default: true,
|
||||
unrelated_photos_removed: true,
|
||||
unrelated_photos_in_collapsed_related_group: true,
|
||||
};
|
||||
}
|
||||
if (text === "mountains reflected in calm water") {
|
||||
assert(body.results.every((result) => result.match_kind === "semantic_image"),
|
||||
"Visual search shortlist must not contain the unrelated fixture documents");
|
||||
assert(body.results.filter((result) => !isRelated(result))
|
||||
.every((result) => result.match_kind === "semantic_image"),
|
||||
"Visual search primary results must not contain unrelated fixture documents");
|
||||
assert.equal(
|
||||
latestMeasured.first_filename,
|
||||
"Mountain Lake.jpg",
|
||||
@@ -267,7 +299,7 @@ try {
|
||||
0,
|
||||
"Meaning-only photo result must not invent word-level alignment",
|
||||
);
|
||||
latestMeasured.ui_checks = { meaning_only_image_has_no_text_marks: true, unrelated_documents_removed: true };
|
||||
latestMeasured.ui_checks = { meaning_only_image_has_no_text_marks: true, related_sources_retained: true };
|
||||
}
|
||||
await page.evaluate(
|
||||
() =>
|
||||
@@ -298,6 +330,9 @@ try {
|
||||
query: queryText,
|
||||
mode: latestMeasured.mode,
|
||||
result_count: latestMeasured.result_count,
|
||||
main_result_count: latestMeasured.main_result_count,
|
||||
related_result_count: latestMeasured.related_result_count,
|
||||
related_expanded: await page.locator("#related-suggestions").evaluate((element) => element.open),
|
||||
selected_filename: selected,
|
||||
first_source_kind: latestMeasured.first_source?.kind,
|
||||
first_source_number: latestMeasured.first_source?.number,
|
||||
@@ -322,7 +357,28 @@ try {
|
||||
}
|
||||
const documentQuery = "cancel the supplier partnership";
|
||||
await query(documentQuery);
|
||||
await page.locator("#query").press("ArrowDown");
|
||||
assert.equal(await page.locator("#preview-title").innerText(), "Supplier Agreement.pdf",
|
||||
"Collapsed related suggestions must not enter arrow-key selection");
|
||||
latestMeasured.ui_checks.collapsed_related_skipped_by_keyboard = true;
|
||||
await screenshot("search-light", documentQuery);
|
||||
await page.locator("#related-suggestions > summary").focus();
|
||||
await page.locator("#related-suggestions > summary").press("ArrowDown");
|
||||
await page.locator("#related-results .result").first().waitFor({ state: "visible" });
|
||||
assert.equal(await page.locator("#related-results .result").count(),
|
||||
latestMeasured.related_result_count, "Expanding must restore every actual related neighbor");
|
||||
assert.equal(await page.locator("#preview-title").innerText(),
|
||||
await page.locator("#related-results .result strong").first().innerText(),
|
||||
"ArrowDown on related disclosure must select its first actual candidate");
|
||||
await page.locator("#results .result").first().click();
|
||||
assert(await page.locator("#related-results .result").filter({ hasText: "Mountain Lake.jpg" }).count(),
|
||||
"Expanded related suggestions must expose the actual mountain candidate");
|
||||
await screenshot("related-suggestions", documentQuery);
|
||||
await page.locator("#related-results .result").first().click();
|
||||
await page.locator("#related-suggestions > summary").click();
|
||||
await page.waitForFunction(() => document.querySelector("#preview-title")?.textContent === "Supplier Agreement.pdf");
|
||||
assert.equal(await page.locator("#preview-title").innerText(), "Supplier Agreement.pdf",
|
||||
"Collapsing related suggestions must restore visible primary selection");
|
||||
await page.emulateMedia({ colorScheme: "dark" });
|
||||
await screenshot("search-dark", documentQuery);
|
||||
await page.emulateMedia({ colorScheme: "light" });
|
||||
@@ -402,7 +458,7 @@ try {
|
||||
kind: "browser-rendered-production-ui-real-cpu-engine",
|
||||
source,
|
||||
frontend_build: {
|
||||
version: JSON.parse(await readFile(resolve(repository, "apps/desktop/package.json"), "utf8")).version,
|
||||
version: frontendVersion,
|
||||
index_sha256: createHash("sha256").update(await readFile(resolve(repository, "apps/desktop/dist/index.html"))).digest("hex"),
|
||||
},
|
||||
viewport: { width: 1440, height: 1000 },
|
||||
|
||||
Reference in new issue
Block a user