Harden AI handoff smoke selectors
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-06-24 21:46:03 +02:00
parent aab51edee4
commit d67b85e4b5
2 changed files with 24 additions and 5 deletions
+18 -1
View File
@@ -3653,12 +3653,29 @@ Tested:
- `python -m pytest backend\tests\test_sprint101_ai_handoff_interaction_smoke.py -q` (`1 passed`) - `python -m pytest backend\tests\test_sprint101_ai_handoff_interaction_smoke.py -q` (`1 passed`)
- `bash -n scripts/verify_ai_handoff_interactions.sh` - `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. - 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: Open:
- Complete broad validation, deploy and live runtime checks for this pass. - None for this pass.
Limitations: Limitations:
- Test/smoke tooling only; no product behavior, API contract, migration, AI dependency, provider fetching or model behavior changes. - 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: 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. - After validation and deploy, keep using the AI handoff smoke as the browser-level regression guard for raster-to-AI workspace wiring.
+6 -4
View File
@@ -88,6 +88,7 @@ async function selectDataset(page, datasetId) {
const datasetButton = page.locator(`[data-testid="dataset-select-${datasetId}"]`) const datasetButton = page.locator(`[data-testid="dataset-select-${datasetId}"]`)
await datasetButton.waitFor({ state: 'visible', timeout: 15000 }) await datasetButton.waitFor({ state: 'visible', timeout: 15000 })
await datasetButton.click() await datasetButton.click()
await page.locator('[data-testid="workbench-inspector-panel"]').getByText('Dataset', { exact: true }).click()
} }
async function assertNoRuntimeErrors(page, consoleErrors) { async function assertNoRuntimeErrors(page, consoleErrors) {
@@ -112,9 +113,10 @@ page.on('pageerror', (error) => {
try { try {
await page.goto(baseUrl, { waitUntil: 'networkidle' }) await page.goto(baseUrl, { waitUntil: 'networkidle' })
await page.getByRole('button', { name: /Load demo workflow/i }).waitFor({ state: 'visible', timeout: 20000 }) const demoLoadButton = page.getByRole('button', { name: /Load demo workflow/i })
await page.getByRole('button', { name: /Load demo workflow/i }).click() if (await demoLoadButton.isVisible({ timeout: 5000 }).catch(() => false)) {
await page.locator(`[data-testid="dataset-select-${rasterDatasetId}"]`).waitFor({ state: 'visible', timeout: 30000 }) await demoLoadButton.click()
}
await selectDataset(page, rasterDatasetId) await selectDataset(page, rasterDatasetId)
const detectionHandoff = page.getByRole('button', { name: 'Use in Detection Lab' }) 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 }) await page.locator('[data-testid="workspace-nav-ai"]').waitFor({ state: 'visible', timeout: 10000 })
const detectionPanel = page.locator('.detection-lab-shell') const detectionPanel = page.locator('.detection-lab-shell')
await detectionPanel.waitFor({ state: 'visible', timeout: 10000 }) 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() const detectionDatasetValue = await detectionPanel.getByLabel('Raster dataset').inputValue()
assert(detectionDatasetValue === rasterDatasetId, `detection dataset handoff mismatch: ${detectionDatasetValue}`) assert(detectionDatasetValue === rasterDatasetId, `detection dataset handoff mismatch: ${detectionDatasetValue}`)
const detectionManifestValue = await detectionPanel.getByPlaceholder('Raster tile manifest path').inputValue() const detectionManifestValue = await detectionPanel.getByPlaceholder('Raster tile manifest path').inputValue()