(
opts: AuthAssertionOpts = {},
)
| 103 | * and return immediately so the runner's normal fill+press hits the |
| 104 | * pre-mounted chat. */ |
| 105 | export function buildAuthPreFill( |
| 106 | opts: AuthAssertionOpts = {}, |
| 107 | ): (page: Page) => Promise<void> { |
| 108 | const click = opts.click ?? defaultClick; |
| 109 | const detectTimeout = opts.detectTimeoutMs ?? SIGN_IN_DETECT_TIMEOUT_MS; |
| 110 | return async (page: Page): Promise<void> => { |
| 111 | let isIdiomaticShape = false; |
| 112 | try { |
| 113 | await page.waitForSelector(SIGN_IN_BUTTON_SELECTOR, { |
| 114 | state: "visible", |
| 115 | timeout: detectTimeout, |
| 116 | }); |
| 117 | isIdiomaticShape = true; |
| 118 | } catch { |
| 119 | // Sign-in button not visible — assume legacy shape (demo loads |
| 120 | // directly into authenticated state, chat already mounted). The |
| 121 | // runner's normal fill+press will hit it without preFill help. |
| 122 | isIdiomaticShape = false; |
| 123 | } |
| 124 | |
| 125 | if (!isIdiomaticShape) return; |
| 126 | |
| 127 | // Idiomatic shape — click sign-in to mount the chat tree. |
| 128 | await click(page, SIGN_IN_BUTTON_SELECTOR); |
| 129 | try { |
| 130 | await page.waitForSelector( |
| 131 | '[data-testid="copilot-chat-textarea"], [data-testid="copilot-chat-input"] textarea, textarea', |
| 132 | { |
| 133 | state: "visible", |
| 134 | timeout: POST_SIGN_IN_CHAT_TIMEOUT_MS, |
| 135 | }, |
| 136 | ); |
| 137 | } catch { |
| 138 | throw new Error( |
| 139 | `auth: chat textarea did not mount within ${POST_SIGN_IN_CHAT_TIMEOUT_MS}ms after sign-in — <CopilotKit> may have failed to handshake with the runtime`, |
| 140 | ); |
| 141 | } |
| 142 | }; |
| 143 | } |
| 144 | |
| 145 | export function buildAuthAssertion( |
| 146 | opts: AuthAssertionOpts = {}, |
no test coverage detected
searching dependent graphs…