{"record":{"id":"cf0d53fcb47c8192","repo":"affaan-m/ECC","slug":"condition-not-met-within-timeout-s","errorCode":null,"errorMessage":"Condition not met within {timeout}s","messagePattern":"Condition not met within (.+?)s","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"skills/windows-desktop-e2e/SKILL.md","lineNumber":175,"sourceCode":"        return spec\n\n    def wait_window(self, title, timeout=ACTION_TIMEOUT):\n        \"\"\"Wait for a new top-level window (dialogs, child windows).\"\"\"\n        dlg = Desktop(backend=\"uia\").window(title=title)\n        dlg.wait(\"visible\", timeout=timeout)\n        return dlg\n\n    def wait_until(self, fn, timeout=ACTION_TIMEOUT, interval=0.3):\n        \"\"\"Poll an arbitrary condition — use when UIA events are unreliable.\"\"\"\n        deadline = time.time() + timeout\n        while time.time() < deadline:\n            try:\n                if fn():\n                    return True\n            except Exception:\n                pass\n            time.sleep(interval)\n        raise TimeoutError(f\"Condition not met within {timeout}s\")\n\n    # --- Actions ---\n\n    def click(self, spec):\n        self.wait_visible(spec)\n        spec.click_input()\n\n    def type_text(self, spec, text):\n        self.wait_visible(spec)\n        ctrl = spec.wrapper_object()\n        try:\n            ctrl.set_edit_text(text)\n        except Exception as e:\n            # Qt 5.x fallback: UIA Value Pattern may be incomplete\n            import sys, pywinauto.keyboard as kb\n            print(f\"[windows-desktop-e2e] set_edit_text failed ({e}), using keyboard fallback\", file=sys.stderr)\n            ctrl.click_input()\n            kb.send_keys(\"^a\")","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/skills/windows-desktop-e2e/SKILL.md#L157-L193","documentation":"A TimeoutError raised by wait_until() in a Windows desktop UI automation helper when a polled condition fn() never returns truthy within the timeout window. wait_until is the fallback path used when UIA events are unreliable. It polls every `interval` seconds until `timeout` elapses, swallowing per-iteration exceptions.","triggerScenarios":"Calling wait_until(fn, timeout, interval) where fn() keeps returning False, or keeps raising exceptions, for the full timeout. Common when the target control never appears, the wrong window is focused, or the automation selector does not match the rendered UI.","commonSituations":"UI changed between recordings so the selector no longer resolves; the app is slow to render under CI load; a modal blocked the target; the test machine is locked/screensaver-on so UIA returns nothing; DPI scaling mismatch hid the control.","solutions":["Increase timeout only after confirming the control is reachable; first capture a screenshot at failure time to see the real UI state.","Verify the spec/selector still matches the current build of the app under test.","Make sure the test session is interactive (not locked) and the app window is foregrounded before polling.","Replace blind polling with a UIA event listener where possible; wait_until is explicitly the fallback for when events are unreliable.","Log the last exception swallowed inside the loop so silent failures during polling are diagnosable."],"exampleFix":"# before\nwhile time.time() < deadline:\n    try:\n        if fn():\n            return True\n    except Exception:\n        pass\n    time.sleep(interval)\nraise TimeoutError(f\"Condition not met within {timeout}s\")\n\n# after: capture the last error for diagnosis\nlast_err = None\nwhile time.time() < deadline:\n    try:\n        if fn():\n            return True\n    except Exception as e:\n        last_err = e\n    time.sleep(interval)\nraise TimeoutError(f\"Condition not met within {timeout}s; last error: {last_err}\")","handlingStrategy":"retry","validationCode":"def condition_likely_reachable(spec) -> bool:\n    # precondition: window is foreground and control exists in the tree\n    try:\n        return app.top_window().exists() and spec.exists(timeout=1)\n    except Exception:\n        return False\n\nif not condition_likely_reachable(spec):\n    raise RuntimeError(\"target window/control not present; aborting before wait_until\")","typeGuard":"null","tryCatchPattern":"try:\n    helper.wait_until(lambda: spec.exists(), timeout=30)\nexcept TimeoutError as e:\n    screenshot(\"artifacts/wait_timeout.png\")\n    raise AssertionError(f\"{e}; see artifacts/wait_timeout.png\") from e","preventionTips":["Foreground the app window and confirm the session is interactive before polling.","Capture a screenshot on timeout for postmortem.","Prefer UIA event listeners over blind polling.","Log the last exception swallowed inside the poll loop."],"tags":["python","ui-automation","windows","timeout","polling"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}