From d67b85e4b57755f79d1e447e2fc00ca812ceac7f Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 24 Jun 2026 21:46:03 +0200 Subject: [PATCH] Harden AI handoff smoke selectors --- docs/CODEX_EXECUTION_LOG.md | 19 ++++++++++++++++++- scripts/verify_ai_handoff_interactions.sh | 10 ++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index 743d08a3..9f03549d 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -3653,12 +3653,29 @@ Tested: - `python -m pytest backend\tests\test_sprint101_ai_handoff_interaction_smoke.py -q` (`1 passed`) - `bash -n scripts/verify_ai_handoff_interactions.sh` - Local Node Playwright availability check failed with `ERR_MODULE_NOT_FOUND`, so live browser-click execution requires Playwright to be installed or exposed in the runner environment. +- `python -m compileall backend/app` +- `cd backend && python -m pytest -q` (`324 passed`) +- `cd frontend && npm run typecheck` +- `cd frontend && npm run build` +- `bash scripts/run_readiness_check.sh` (`324 passed`; frontend typecheck/build passed; Alembic head `202606120900`; live smoke syntax passed) +- `cd backend && python -m alembic heads` (`202606120900 (head)`) +- `cd backend && python -m alembic upgrade head --sql` +- `bash -n scripts/live_migration_smoke.sh` +- Tower deploy from commit `aab51ed` completed; all-in-one container published on `0.0.0.0:1202->80/tcp`. +- Deploy-time live migration smoke passed after the database became ready on attempt 3; PostGIS reported `3.6 USE_GEOS=1 USE_PROJ=1 USE_STATS=1`, required runtime schema objects were present and Alembic head was `202606120900`. +- Deploy-time browser runtime verification passed for frontend, API proxy and icon. +- Live smoke passed: `bash scripts/verify_demo_raster_workflow.sh http://192.168.10.150:1202`. +- Live smoke passed: `bash scripts/verify_workbench_default_state.sh http://192.168.10.150:1202`. +- Live smoke passed: `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202`. +- Live smoke passed: `bash scripts/verify_browser_runtime.sh http://192.168.10.150:1202`. +- Live browser-click validation with Codex Playwright plus installed Chrome passed against `http://192.168.10.150:1202`: the smoke seeded the demo workflow, generated a raster tile manifest, selected the raster in Data, opened the Dataset inspector tab, clicked `Use in Detection Lab`, selected `yolo-configured`, verified Detection Lab dataset and manifest values, clicked `Use in Segmentation Lab`, verified Segmentation Lab dataset and manifest values, and observed no console/page errors. Open: -- Complete broad validation, deploy and live runtime checks for this pass. +- None for this pass. Limitations: - Test/smoke tooling only; no product behavior, API contract, migration, AI dependency, provider fetching or model behavior changes. +- `scripts/verify_ai_handoff_interactions.sh` requires a runner with Playwright plus a browser. This Codex environment had Playwright available through the Node REPL and used installed Chrome; plain local `node` still reports `ERR_MODULE_NOT_FOUND` for `playwright`. Next recommended pass: - After validation and deploy, keep using the AI handoff smoke as the browser-level regression guard for raster-to-AI workspace wiring. diff --git a/scripts/verify_ai_handoff_interactions.sh b/scripts/verify_ai_handoff_interactions.sh index 676c8307..da8accde 100755 --- a/scripts/verify_ai_handoff_interactions.sh +++ b/scripts/verify_ai_handoff_interactions.sh @@ -88,6 +88,7 @@ async function selectDataset(page, datasetId) { const datasetButton = page.locator(`[data-testid="dataset-select-${datasetId}"]`) await datasetButton.waitFor({ state: 'visible', timeout: 15000 }) await datasetButton.click() + await page.locator('[data-testid="workbench-inspector-panel"]').getByText('Dataset', { exact: true }).click() } async function assertNoRuntimeErrors(page, consoleErrors) { @@ -112,9 +113,10 @@ page.on('pageerror', (error) => { try { await page.goto(baseUrl, { waitUntil: 'networkidle' }) - await page.getByRole('button', { name: /Load demo workflow/i }).waitFor({ state: 'visible', timeout: 20000 }) - await page.getByRole('button', { name: /Load demo workflow/i }).click() - await page.locator(`[data-testid="dataset-select-${rasterDatasetId}"]`).waitFor({ state: 'visible', timeout: 30000 }) + const demoLoadButton = page.getByRole('button', { name: /Load demo workflow/i }) + if (await demoLoadButton.isVisible({ timeout: 5000 }).catch(() => false)) { + await demoLoadButton.click() + } await selectDataset(page, rasterDatasetId) const detectionHandoff = page.getByRole('button', { name: 'Use in Detection Lab' }) @@ -124,7 +126,7 @@ try { await page.locator('[data-testid="workspace-nav-ai"]').waitFor({ state: 'visible', timeout: 10000 }) const detectionPanel = page.locator('.detection-lab-shell') await detectionPanel.waitFor({ state: 'visible', timeout: 10000 }) - await detectionPanel.getByLabel('Model').selectOption('yolo-configured') + await detectionPanel.locator('select').nth(1).selectOption('yolo-configured') const detectionDatasetValue = await detectionPanel.getByLabel('Raster dataset').inputValue() assert(detectionDatasetValue === rasterDatasetId, `detection dataset handoff mismatch: ${detectionDatasetValue}`) const detectionManifestValue = await detectionPanel.getByPlaceholder('Raster tile manifest path').inputValue()