@inquirer/testing 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -73,11 +73,42 @@ describe('input prompt', () => {
73
73
 
74
74
  - `answer` (`Promise`) - Resolves when an answer is provided and valid
75
75
  - `getScreen` (`({ raw?: boolean }) => string`) - Returns the current screen content. By default strips ANSI codes
76
+ - `nextRender` (`() => Promise<void>`) - Wait for the next screen update. Use after triggering async actions (e.g. pressing enter with validation). Coalesces rapid back-to-back renders so a single `await nextRender()` captures the final settled state
76
77
  - `events` - Utilities to interact with the prompt:
77
78
  - `keypress(key: string | KeyObject)` - Trigger a keypress event
78
79
  - `type(text: string)` - Type text into the prompt
79
80
  - `getFullOutput` (`() => Promise<string>`) - Returns the full output interpreted through a virtual terminal, resolving ANSI escape sequences into the actual screen state
80
81
 
82
+ ### Async actions and `nextRender()`
83
+
84
+ When a keypress triggers an asynchronous action (such as input validation), the screen won't update synchronously. Use `nextRender()` to wait for the prompt to settle before reading the screen:
85
+
86
+ ```ts
87
+ import { render } from '@inquirer/testing';
88
+ import input from '@inquirer/input';
89
+
90
+ it('shows a validation error', async () => {
91
+ const { answer, events, getScreen, nextRender } = await render(input, {
92
+ message: 'Enter a number',
93
+ validate: (value) => /^\d+$/.test(value) || 'Must be a number',
94
+ });
95
+
96
+ events.type('abc');
97
+ events.keypress('enter');
98
+
99
+ await nextRender(); // wait for validation to complete and the error to render
100
+ expect(getScreen()).toContain('Must be a number');
101
+
102
+ events.keypress('backspace');
103
+ events.keypress('backspace');
104
+ events.keypress('backspace');
105
+ events.type('42');
106
+ events.keypress('enter');
107
+
108
+ await expect(answer).resolves.toEqual('42');
109
+ });
110
+ ```
111
+
81
112
  ### Unit Testing Example
82
113
 
83
114
  You can refer to the [`@inquirer/input` test suite](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/input/input.test.ts) for a comprehensive unit testing example using `render()`.
package/dist/index.d.ts CHANGED
@@ -19,5 +19,6 @@ export declare function render<Value, const Config>(prompt: Prompt<Value, Config
19
19
  getFullOutput: ({ raw }?: {
20
20
  raw?: boolean;
21
21
  }) => Promise<string>;
22
+ nextRender: () => Promise<void>;
22
23
  }>;
23
24
  export {};
package/dist/index.js CHANGED
@@ -30,6 +30,20 @@ export async function render(prompt, config, options) {
30
30
  }
31
31
  },
32
32
  };
33
+ let rendersConsumed = output.writeCount;
34
+ function nextRender() {
35
+ const waitForRender = output.writeCount > rendersConsumed
36
+ ? Promise.resolve()
37
+ : new Promise((resolve) => output.once('render', resolve));
38
+ // After detecting a render, let the event loop settle so that multiple
39
+ // synchronous-ish renders (e.g. validation: loading → error) are coalesced.
40
+ return waitForRender.then(() => new Promise((resolve) => {
41
+ setImmediate(() => {
42
+ rendersConsumed = output.writeCount;
43
+ resolve();
44
+ });
45
+ }));
46
+ }
33
47
  return {
34
48
  answer,
35
49
  input,
@@ -44,5 +58,6 @@ export async function render(prompt, config, options) {
44
58
  return fullOutput;
45
59
  return interpretTerminalOutput(fullOutput);
46
60
  },
61
+ nextRender,
47
62
  };
48
63
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inquirer/testing",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Inquirer testing utilities",
5
5
  "keywords": [
6
6
  "answer",
@@ -167,5 +167,5 @@
167
167
  },
168
168
  "main": "./dist/index.js",
169
169
  "types": "./dist/index.d.ts",
170
- "gitHead": "fd001c191cfb287b430d5e90cb159cf8f6500dc5"
170
+ "gitHead": "526eca2e64853510821ffd457561840ec0cbfb93"
171
171
  }