MCPcopy
hub / github.com/google-gemini/gemini-cli / waitUntilReady

Method waitUntilReady

packages/cli/src/test-utils/render.tsx:209–307  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

207 };
208
209 async waitUntilReady() {
210 const startRenderCount = this.renderCount;
211 if (!vi.isFakeTimers()) {
212 // Give Ink a chance to start its rendering loop
213 await new Promise((resolve) => setImmediate(resolve));
214 }
215 await act(async () => {
216 if (vi.isFakeTimers()) {
217 await vi.advanceTimersByTimeAsync(50);
218 } else {
219 // Wait for at least one render to be called if we haven't rendered yet or since start of this call,
220 // but don't wait forever as some renders might be synchronous or skipped.
221 if (this.renderCount === startRenderCount) {
222 const renderPromise = new Promise((resolve) =>
223 this.once('render', resolve),
224 );
225 const timeoutPromise = new Promise((resolve) =>
226 setTimeout(resolve, 1000),
227 );
228 await Promise.race([renderPromise, timeoutPromise]);
229 }
230 }
231 });
232
233 let attempts = 0;
234 const maxAttempts = 50;
235
236 let lastCurrent = '';
237 let lastExpected = '';
238
239 while (attempts < maxAttempts) {
240 // Ensure all pending writes to the terminal are processed.
241 await this.queue.promise;
242
243 const currentFrame = stripAnsi(
244 this.lastFrame({ allowEmpty: true }),
245 ).trim();
246 const expectedFrame = this.normalizeFrame(
247 stripAnsi(
248 (this.lastRenderStaticContent ?? '') + (this.lastRenderOutput ?? ''),
249 ),
250 ).trim();
251
252 lastCurrent = currentFrame;
253 lastExpected = expectedFrame;
254
255 const isMatch = () => {
256 if (expectedFrame === '...') {
257 // '...' is our fallback when output isn't in metrics, meaning Ink rendered *something*
258 // but we don't know what it is. If terminal has content, we consider it a match.
259 // However, if the component rendered null, both would be empty, but our fallback
260 // made expectedFrame '...'. In that case, we can't easily know if it's ready,
261 // but we can assume if there are no pending writes, it's ready.
262 return currentFrame !== '' || this.pendingWrites === 0;
263 }
264
265 // If Ink expects nothing (no new static content and no dynamic output),
266 // we consider it a match because the terminal buffer will just hold the historical static content.

Callers 15

renderFunction · 0.95
renderHookWithProvidersFunction · 0.80
waitForNextEventMethod · 0.80
renderWithTokensFunction · 0.80
renderWithMockedStatsFunction · 0.80
Banner.test.tsxFile · 0.80
renderDialogFunction · 0.80

Calls 1

lastFrameMethod · 0.80

Tested by 4

renderWithTokensFunction · 0.64
renderWithMockedStatsFunction · 0.64
renderDialogFunction · 0.64
renderComponentFunction · 0.64