Repository navigation
Description
Problem
Google Flow renders its UI in the account's language, not the requested
locale. The video-generation design spike confirmed Flow ignores
locale="en-US" + ?hl=en — the test account's Flow renders in Portuguese
(Vídeo, Imagem, Criar, ...). See
docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md
§10.4.
Several UiAutomationTransport selectors (the working t2i /
generate_images path) match on localized button text, so they only
work for accounts whose Flow language happens to be in our hard-coded list.
Current state — src/gflow_cli/api/transports/ui_automation.py
Language-agnostic already (good — keep):
PROMPT_INPUT_SELECTORS— leads with thedata-slate-editorstructural selector.SUBMIT_BUTTON_SELECTORS— leads with thearrow_forwardicon ligature.GEN_SETTINGS_BUTTON_SELECTORS— allcrop_*icon ligatures.- Aspect / count tabs —
_ASPECT_TAB(numeric ratios16:9,9:16, ...) and
_COUNT_TAB(1x,x2, ...). Numbers/symbols are not translated.
Fragile:
ONBOARDING_SELECTORS(~line 158) — purely localized button text
(Agree/Aceitar/I agree/Concordo/Accept/
Create with Flow/Criar com o Flow/Get Started/Começar), with
no structural anchor at all. An account whose Flow renders in an unlisted
language (German, Japanese, ...) cannot pass the onboarding gate.NEW_PROJECT_SELECTORS(~line 142) and theSUBMIT_BUTTON_SELECTORStail —
localized-text fallbacks (Novo projeto/Nuevo proyecto/
Nouveau projet;aria-label*="Create"). These work today only because the
icon selector leads — maintenance debt and a silent-failure risk.
Why it works today
t2i is not broken — the icon-ligature selectors lead and match, and the
test accounts happen to be in covered languages. The risk is silent: onboarding
fails only for an uncovered language, with no obvious error.
Proposed fix (structural-first)
Flow is built on Radix UI + Material Symbols. Both expose developer
strings that are never translated:
- Radix code tokens —
role,aria-controls/aria-haspopup,radix-*ids. - Material Symbols icon ligatures —
i.google-symbols:text('...'). - Structural attrs —
data-slate-editor, child order.
Rework ui_automation.py selectors to lead with structural anchors and keep at
most one localized-text entry as a last-resort diagnostic fallback (or drop it).
Priority: give ONBOARDING_SELECTORS a real structural anchor.
Scope / sequencing
- Out of scope for the current video Phase 0 work. Do not change t2i
selectors until this is planned as its own task — t2i works and must not
regress. - The video spike (
scripts/smoke_video_editor.py) is establishing the
discovery pattern:_dump_region()dumps each control's structural
fingerprint (role / aria-* / id / icon ligatures) so selectors are derived
from real DOM evidence, not guessed. Once the video work proves the pattern,
t2i adopts it.
References
docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md
§6, §10.4scripts/smoke_video_editor.py—_dump_region, structural §6 selectorssrc/gflow_cli/api/transports/ui_automation.py—ONBOARDING_SELECTORS,
NEW_PROJECT_SELECTORS
Activity
docs(image): Phase 7 partial pass — race fix verified, count-tab sele…
fix(image): locale-invariant count tab — position-first selectors (#24 …
chore(image): add DOM dump diagnostic for count-tab discovery (#24)
fix(image): thread output_dir to client constructor so transport _out…
fix(image): filter count-tab selectors by 1x/xN text pattern (DOM-evi…
ffroliva commentedon May 23, 2026
Status update — partial fix landed, ONBOARDING_SELECTORS still pending.
Done (count tabs):
_COUNT_TAB_TEXT_RE = ^(1x|x[2-4])$inui_automation.py:253filters tabs by the digit+x text that Flow renders identically in every locale (numbers/symbols are not translated, per the issue body)._set_countfalls back to positional.nth(count - 1)when the read-back text is unrecognised — locale-invariant click. Seeui_automation.py:1013.2a6de4d,38d391a,c5c8d4a.Still pending (the issue's stated #1 priority):
ONBOARDING_SELECTORS(ui_automation.py:183-193) remains nine purely-localized button-text selectors with no structural anchor (Agree/Aceitar/I agree/Concordo/Accept/Create with Flow/Criar com o Flow/Get Started/Começar). An account whose Flow renders in an unlisted language (German, Japanese, ...) cannot pass onboarding.NEW_PROJECT_SELECTORSlocalized fallbacks +SUBMIT_BUTTON_SELECTORStail — icon-first selectors lead, so these work today; the localized fallbacks are maintenance debt per the issue body.KNOWN_ISSUES.md now carries an Open entry pointing at this issue. Recommend leaving this open until
ONBOARDING_SELECTORSgets a structural anchor.docs+test(image): polish — record mode-switch in debugging, surface W…
fix(image): switch to Image mode in editor + live verify on ffroliva (#…
Merge pull request #51 from ffroliva/feat/locale-agnostic-selectors
ffroliva commentedon May 24, 2026
Status update — 2026-05-24, develop / post-v0.8.1 (unreleased)
Phase 1 (env override) shipped via #51 — Playwright
launch_persistent_context(locale=...)now readsGFLOW_CLI_LOCALE(defaulten-US). Documented in.env.templateanddocs/CONFIGURATION.mdas of #53.Live-verified end-to-end with
GFLOW_CLI_LOCALE=pt-BR uv run pytest -m e2e tests/e2e/test_video_t2v_e2e.py:~2.5 MBmp4ftypisomMEDIA_GENERATION_STATUS_SUCCESSFUL,video_saved bytes=2558991Still required for Phase 2 (drop
--lang=en-US):ONBOARDING_SELECTORS, parts ofNEW_PROJECT_SELECTORS/SUBMIT_BUTTON_SELECTORS, and I2V frame-slot labels via the hardenedscripts/dev/capture_locale_invariants.py(filed separately).ja-JP), drop the--lang=en-USChromium arg fromUiAutomationTransport.setup.KNOWN_ISSUES.md § issue #24now carries the same Progress block.fix(image): re-introduce i2i ref-attach (#50) with locale-agnostic me…
fix(image): locale-agnostic i2i media-dialog selectors + upload fallback
ffroliva commentedon May 24, 2026
Resolved (with one focused follow-up tracked separately)
This umbrella issue is closed. The locale-agnostic selector work shipped across multiple PRs; the last narrow remaining gap has its own issue.
What landed under this umbrella
GFLOW_CLI_LOCALEenv override (Playwrightlaunch_persistent_context(locale=...)); locale-agnostic count-tabs (^(1x|x[2-4])$regex on locale-stable digit-x text); locale-agnostic image-mode tab viaaria-controls*='IMAGE'(structural)._attach_referencesfor i2i — replaced text-basedhas-text('Upload media')with Material Symbols icon ligature (button:has(i.google-symbols:text-is('upload'))) scoped to the open Radix popover. Added structural iconless selector for "Add to Prompt" and a fail-loudRuntimeErrordistinguishing Chrome profile language from Google account language. Resolved #56.reference_attachedstructlog assertion so the e2e can't silently pass on a text-only image again.Key learning (committed to agent memory as a durable rule)
Flow renders dialog labels in the Chrome profile language preference —
--lang=en-USChromium launch arg does NOT override it (it's a server-side preference). The durable selector pattern across the codebase is nowbutton:has(i.google-symbols:text('<ligature>'))with:text-is(...)exact-match when sibling icons would otherwise collide (e.g.uploadvsdrive_folder_upload).One follow-up tracked separately: #63
FRAME_SLOT_BY_LABEL(div[aria-haspopup='dialog']:has-text('{label}')) atsrc/gflow_cli/api/transports/ui_automation_video.py:138is still text-based and would hit the same hang on a non-EN profile forgflow video i2vStart/End frame attach. Spun off to #63 with the full repro shape, suggested fix (mirror PR #60), and test plan (mirror PR #61).Thanks
Multi-PR multi-contributor effort — @svasakorn shipped the i2i half (PR #60 + #61) with proper fail-loud guards and the right framing of the icon-ligature vs text-label distinction; the council audit fixes (PR #53) made sure the documentation kept up.
Closing.
chore(selectors): address PR #70 review gaps — tier counts, locale co…
14 remaining items
fix(transports): exit Agent mode before mode switch so the gen panel …
fix(image): switch to Image mode in editor + live verify on ffroliva (f…
feat: locale-agnostic selectors (issue ffroliva#24) and multi-locale …
Merge pull request ffroliva#51 from ffroliva/feat/locale-agnostic-sel…
docs: post-PR-48/ffroliva#51 council audit fixes (T1+T2)
fix(image): re-introduce i2i ref-attach (ffroliva#50) with locale-agn…
feat(selectors): structural-first cascade for onboarding + I2V frame …
chore(selectors): address PR ffroliva#70 review gaps — tier counts, l…
test(e2e): adapt t2v assertion to VideoResult wrapper + record de-DE …
Merge pull request ffroliva#70 from ffroliva/feature/issue-24-phase2-…
chore(plan): refresh PLAN.md to develop ground truth
docs: record ffroliva#63 closure in KNOWN_ISSUES + CHANGELOG
chore(plan): record PR ffroliva#90 / ffroliva#63 closure in PLAN.md
fix(transports): locale-invariant NEW_PROJECT + SUBMIT selectors and …
fix(transports): exit Agent mode before mode switch so the gen panel …