--- name: pw_wait_predicate kind: function lang: ts domain: browser version: "1.0.0" purity: impure signature: "async (page: Page, predicate: string | ((arg?: unknown) => unknown), opts?: PwWaitOptions) => Promise" description: "Polls an arbitrary predicate inside the page context until it returns truthy or times out. Thin wrapper around page.waitForFunction with friendlier defaults and custom error messages. Use to wait for CSS class changes, DOM counts, or any computed condition." tags: [playwright, e2e, browser, wait] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] params: - name: page desc: "Playwright Page." - name: predicate desc: "JS expression as string OR function evaluated in page context. Returns truthy to stop polling." - name: opts desc: "{timeoutMs?, pollMs?, arg?, message?}." output: "Resolved value of the predicate (page.waitForFunction jsonValue)." tested: true tests: ["defaults applied", "arg passed through", "jsonValue returned", "message wraps timeout"] test_file_path: "frontend/functions/browser/pw_wait_predicate.test.ts" file_path: "frontend/functions/browser/pw_wait_predicate.ts" --- ## Ejemplo ```typescript import { pw_wait_predicate } from "./pw_wait_predicate"; // Wait for at least one red-bordered card to appear await pw_wait_predicate( page, () => document.querySelectorAll('[data-card-id].border-red').length > 0, { timeoutMs: 2000, message: "no red-bordered card appeared" }, ); // Wait for exactly 1 highlighted card using an arg await pw_wait_predicate( page, (sel) => document.querySelectorAll(sel as string).length === 1, { arg: ".highlighted", timeoutMs: 3000, pollMs: 50 }, ); ``` ## Cuando usarla Cuando `waitForSelector` no basta porque la condicion depende de una clase CSS compuesta, un conteo exacto de elementos, o cualquier expresion calculada en el contexto de la pagina. Usar antes de assertions que requieren un estado DOM especifico que tarda en estabilizarse. ## Gotchas - `predicate` se ejecuta en el contexto de la pagina (sandbox del browser), no en Node. No puede cerrar sobre variables de Node; usa `opts.arg` para pasar datos. - Si `predicate` es una funcion, Playwright la serializa a string para enviarla al browser. No uses referencias externas ni closures de Node dentro de ella. - `opts.message` solo se usa cuando `waitForFunction` lanza; no modifica el valor de retorno en caso de exito. - `playwright` debe estar instalada en el proyecto consumidor como peer dependency. El registry no la instala. - Con `polling: number`, Playwright hace polling activo (busy loop con sleeps cortos). Un `pollMs` muy bajo (< 50) puede saturar la CPU del browser en tests largos.