Skip to content

Commit cb5bb71

Browse files
committed
Add wait-for-window-title regex (appear/vanish)
1 parent fbce852 commit cb5bb71

15 files changed

Lines changed: 258 additions & 12 deletions

File tree

README/WHATS_NEW_zh-CN.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-23) — 等待窗口标题(正则)
4+
5+
阻塞直到窗口标题符合正则(或消失)。完整参考:[`docs/source/Zh/doc/new_features/v126_features_doc.rst`](../docs/source/Zh/doc/new_features/v126_features_doc.rst)
6+
7+
- **`wait_until_window_title`**(`AC_wait_window_title`):`wait_for_window` 以子字符串比对且仅等*出现*;`wait_until_window_closed` 为子字符串消失。本功能默认以正则表达式比对(`regex=False` 改子字符串),并可等待标题消失(`present=False`)——例如等标签页导览至 `r".*— Checkout$"`。标题来源可注入、无头可测。
8+
39
## 本次更新 (2026-06-23) — 表格 / 网格单元格定位
410

511
依(行、列)从单元格边界框定位表格单元格。完整参考:[`docs/source/Zh/doc/new_features/v125_features_doc.rst`](../docs/source/Zh/doc/new_features/v125_features_doc.rst)

README/WHATS_NEW_zh-TW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-23) — 等待視窗標題(正則)
4+
5+
阻塞直到視窗標題符合正則(或消失)。完整參考:[`docs/source/Zh/doc/new_features/v126_features_doc.rst`](../docs/source/Zh/doc/new_features/v126_features_doc.rst)
6+
7+
- **`wait_until_window_title`**(`AC_wait_window_title`):`wait_for_window` 以子字串比對且僅等*出現*;`wait_until_window_closed` 為子字串消失。本功能預設以正則表達式比對(`regex=False` 改子字串),並可等待標題消失(`present=False`)——例如等分頁導覽至 `r".*— Checkout$"`。標題來源可注入、無頭可測。
8+
39
## 本次更新 (2026-06-23) — 表格 / 格線儲存格定位
410

511
依(列、欄)從儲存格邊界框定位表格儲存格。完整參考:[`docs/source/Zh/doc/new_features/v125_features_doc.rst`](../docs/source/Zh/doc/new_features/v125_features_doc.rst)

WHATS_NEW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# What's New — AutoControl
22

3+
## What's new (2026-06-23) — Wait for Window Title (Regex)
4+
5+
Block until a window title matches a regex (or vanishes). Full reference: [`docs/source/Eng/doc/new_features/v126_features_doc.rst`](docs/source/Eng/doc/new_features/v126_features_doc.rst).
6+
7+
- **`wait_until_window_title`** (`AC_wait_window_title`): `wait_for_window` matches a title substring and only waits for *appear*; `wait_until_window_closed` is substring vanish. This matches a regular expression by default (`regex=False` for substring) and can wait for the title to vanish (`present=False`) — e.g. wait for a tab to navigate to `r".*— Checkout$"`. Injectable title source, headless-testable.
8+
39
## What's new (2026-06-23) — Grid / Table Cell Addressing
410

511
Address a table cell by (row, column) from cell bounding boxes. Full reference: [`docs/source/Eng/doc/new_features/v125_features_doc.rst`](docs/source/Eng/doc/new_features/v125_features_doc.rst).
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Wait for Window Title (Regex)
2+
=============================
3+
4+
``wait_for_window`` matches a window title by *substring* and only waits for it to
5+
*appear*; ``wait_until_window_closed`` is the substring vanish. Neither supports a
6+
regular-expression title or "wait until the active window's title matches P" —
7+
e.g. waiting for a browser tab to finish navigating to ``r".*— Checkout$"``. This
8+
adds a regex title wait to the ``smart_waits`` family.
9+
10+
The title source is injectable, so the loop is headless-testable without real
11+
windows. Imports no ``PySide6``.
12+
13+
Headless API
14+
------------
15+
16+
.. code-block:: python
17+
18+
from je_auto_control import wait_until_window_title
19+
20+
wait_until_window_title(r".*— Checkout$", timeout_s=20) # tab navigated
21+
wait_until_window_title("Updating", present=False) # dialog gone
22+
wait_until_window_title("Checkout", regex=False) # substring mode
23+
24+
By default ``pattern`` is a regular expression (``re.search``); pass
25+
``regex=False`` for a plain substring test. ``present=False`` waits for the title
26+
to *vanish*. The result is a ``WaitOutcome`` (``succeeded`` / ``reason`` /
27+
``elapsed_s`` / ``samples_taken``); ``title_lister`` is injectable for tests.
28+
29+
Executor commands
30+
-----------------
31+
32+
``AC_wait_window_title`` takes ``pattern`` plus ``present`` / ``regex`` /
33+
``timeout_s`` / ``poll_interval_s`` and returns the ``WaitOutcome`` dict. It is
34+
exposed as the MCP tool ``ac_wait_window_title`` and as a Script Builder command
35+
under **Flow**.

docs/source/Eng/eng_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ Comprehensive guides for all AutoControl features.
148148
doc/new_features/v123_features_doc
149149
doc/new_features/v124_features_doc
150150
doc/new_features/v125_features_doc
151+
doc/new_features/v126_features_doc
151152
doc/ocr_backends/ocr_backends_doc
152153
doc/observability/observability_doc
153154
doc/operations_layer/operations_layer_doc
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
等待視窗標題(正則)
2+
==================
3+
4+
``wait_for_window`` 以*子字串*比對視窗標題且僅等待其*出現*;``wait_until_window_closed`` 為子字串消失。兩者都
5+
不支援正則表達式標題或「等到使用中視窗標題符合 P」——例如等待瀏覽器分頁導覽至 ``r".*— Checkout$"``。本功能
6+
為 ``smart_waits`` 家族加入正則標題等待。
7+
8+
標題來源可注入,因此迴圈可在無真實視窗下做無頭測試。不匯入 ``PySide6``。
9+
10+
無頭 API
11+
--------
12+
13+
.. code-block:: python
14+
15+
from je_auto_control import wait_until_window_title
16+
17+
wait_until_window_title(r".*— Checkout$", timeout_s=20) # 分頁已導覽
18+
wait_until_window_title("Updating", present=False) # 對話框消失
19+
wait_until_window_title("Checkout", regex=False) # 子字串模式
20+
21+
預設 ``pattern`` 為正則表達式(``re.search``);傳入 ``regex=False`` 改用純子字串比對。``present=False`` 等待
22+
標題*消失*。結果為 ``WaitOutcome``(``succeeded`` / ``reason`` / ``elapsed_s`` / ``samples_taken``);
23+
``title_lister`` 可注入以供測試。
24+
25+
執行器命令
26+
----------
27+
28+
``AC_wait_window_title`` 接受 ``pattern`` 以及 ``present`` / ``regex`` / ``timeout_s`` / ``poll_interval_s``,
29+
並回傳 ``WaitOutcome`` dict。它以 MCP 工具 ``ac_wait_window_title`` 以及 Script Builder 中 **Flow** 分類下的命令
30+
提供。

docs/source/Zh/zh_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ AutoControl 所有功能的完整使用指南。
148148
doc/new_features/v123_features_doc
149149
doc/new_features/v124_features_doc
150150
doc/new_features/v125_features_doc
151+
doc/new_features/v126_features_doc
151152
doc/ocr_backends/ocr_backends_doc
152153
doc/observability/observability_doc
153154
doc/operations_layer/operations_layer_doc

je_auto_control/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@
624624
wait_until_file, wait_until_gone, wait_until_image_gone,
625625
wait_until_pixel_changes, wait_until_port, wait_until_process,
626626
wait_until_region_idle, wait_until_screen_stable, wait_until_text_gone,
627-
wait_until_window_closed,
627+
wait_until_window_closed, wait_until_window_title,
628628
)
629629
# Visual regression (golden-image comparison)
630630
from je_auto_control.utils.visual_regression import (
@@ -1261,7 +1261,7 @@ def start_autocontrol_gui(*args, **kwargs):
12611261
"wait_until_clipboard_changes", "wait_until_window_closed",
12621262
"wait_until_file", "wait_until_port", "wait_until_process",
12631263
"wait_until_gone", "wait_until_image_gone", "wait_until_text_gone",
1264-
"wait_until_color",
1264+
"wait_until_color", "wait_until_window_title",
12651265
# Visual regression + state machine
12661266
"take_golden", "compare_to_golden", "image_difference",
12671267
"DiffResult", "MaskRegion",

je_auto_control/gui/script_builder/command_schema.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,18 @@ def _add_flow_specs(specs: List[CommandSpec]) -> None:
512512
),
513513
description="Block until a colour fills (or leaves) a screen region.",
514514
))
515+
specs.append(CommandSpec(
516+
"AC_wait_window_title", "Flow", "Wait for Window Title",
517+
fields=(
518+
FieldSpec("pattern", FieldType.STRING, placeholder="Checkout$"),
519+
FieldSpec("present", FieldType.BOOL, optional=True, default=True),
520+
FieldSpec("regex", FieldType.BOOL, optional=True, default=True),
521+
FieldSpec("timeout_s", FieldType.FLOAT, optional=True, default=10.0),
522+
FieldSpec("poll_interval_s", FieldType.FLOAT, optional=True,
523+
default=0.2, min_value=0.01),
524+
),
525+
description="Block until a window title matches a regex (or vanishes).",
526+
))
515527
specs.append(CommandSpec(
516528
"AC_loop", "Flow", "Loop (N times)",
517529
fields=(

je_auto_control/utils/executor/action_executor.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,17 @@ def _wait_text_gone(text: str, timeout_s: float = 10.0,
384384
).to_dict()
385385

386386

387+
def _wait_window_title(pattern: str, present: bool = True, regex: bool = True,
388+
timeout_s: float = 10.0,
389+
poll_interval_s: float = 0.2) -> Dict[str, Any]:
390+
"""Executor adapter: wait for a window title (regex) to appear / vanish."""
391+
from je_auto_control.utils.smart_waits import wait_until_window_title
392+
return wait_until_window_title(
393+
pattern, present=bool(present), regex=bool(regex),
394+
timeout_s=float(timeout_s), poll_interval_s=float(poll_interval_s),
395+
).to_dict()
396+
397+
387398
def _wait_color(target_rgb: Any, region: Any = None,
388399
tolerance: int = 10, min_fraction: float = 0.5,
389400
present: bool = True, timeout_s: float = 10.0,
@@ -5080,6 +5091,7 @@ def __init__(self):
50805091
"AC_wait_image_gone": _wait_image_gone,
50815092
"AC_wait_text_gone": _wait_text_gone,
50825093
"AC_wait_color": _wait_color,
5094+
"AC_wait_window_title": _wait_window_title,
50835095
"AC_wait_window_closed": _wait_window_closed,
50845096

50855097
# Cost telemetry (LLM token + USD tracking)

0 commit comments

Comments
 (0)