or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

choice-prompts.mdconfirmation-prompts.mdcore-prompting.mdindex.mdnumber-date-prompts.mdtesting.mdtext-prompts.md

testing.mddocs/

0

# Testing Utilities

1

2

Functions for programmatic testing, response injection, and pre-answering questions during automated testing scenarios. These utilities enable deterministic testing of prompt-based applications without user interaction.

3

4

```javascript

5

const prompts = require('prompts');

6

// Or for specific imports:

7

const { inject, override } = require('prompts');

8

```

9

10

## Capabilities

11

12

### Inject Function

13

14

Programmatically inject responses to simulate user input during testing. Injected values are consumed in order and removed from the internal queue as they are used.

15

16

```javascript { .api }

17

/**

18

* Programmatically inject responses for testing

19

* @param answers - Array of values to inject as responses

20

*/

21

function inject(answers: any[]): void;

22

```

23

24

The inject function accepts an array of values that will be used as responses to prompts in the order they are provided. Each value can be:

25

- **Simple value**: Used as a direct response to the next prompt

26

- **Array of values**: Used for prompts that might be asked multiple times

27

- **Error instance**: Simulates user cancellation/abort

28

29

**Usage Examples:**

30

31

```javascript

32

const prompts = require('prompts');

33

34

// Basic injection for testing

35

prompts.inject(['alice', 25, true]);

36

37

const response = await prompts([

38

{ type: 'text', name: 'name', message: 'Your name?' },

39

{ type: 'number', name: 'age', message: 'Your age?' },

40

{ type: 'confirm', name: 'subscribe', message: 'Subscribe?' }

41

]);

42

43

// Result: { name: 'alice', age: 25, subscribe: true }

44

45

// Inject array values for repeated prompts

46

prompts.inject([

47

'user1',

48

['red', 'blue'], // For multiselect prompt

49

'completed'

50

]);

51

52

// Inject error to simulate cancellation

53

prompts.inject([

54

'alice',

55

new Error('User cancelled'),

56

'fallback'

57

]);

58

59

// Test complex scenarios

60

prompts.inject([

61

'setup-wizard',

62

true, // confirm to continue

63

['database', 'auth'], // multiselect features

64

'production' // environment

65

]);

66

67

const config = await prompts([

68

{ type: 'text', name: 'projectName', message: 'Project name?' },

69

{ type: 'confirm', name: 'useDefaults', message: 'Use defaults?' },

70

{ type: 'multiselect', name: 'features', message: 'Select features:', choices: [...] },

71

{ type: 'select', name: 'env', message: 'Environment:', choices: [...] }

72

]);

73

```

74

75

### Override Function

76

77

Pre-answer questions by providing an object with answers mapped to question names. This allows selective answering of specific prompts while letting others proceed normally.

78

79

```javascript { .api }

80

/**

81

* Pre-answer questions by question name

82

* @param answers - Object mapping question names to their answers

83

*/

84

function override(answers: Record<string, any>): void;

85

```

86

87

The override function takes an object where keys are question names and values are the answers to provide for those questions. Questions with overridden answers will be skipped during prompting.

88

89

**Usage Examples:**

90

91

```javascript

92

const prompts = require('prompts');

93

94

// Override specific questions

95

prompts.override({

96

username: 'alice',

97

environment: 'production'

98

});

99

100

const response = await prompts([

101

{ type: 'text', name: 'username', message: 'Username?' }, // Skipped, uses 'alice'

102

{ type: 'number', name: 'port', message: 'Port?' }, // User prompted

103

{ type: 'select', name: 'environment', message: 'Env?', choices: [...] } // Skipped, uses 'production'

104

]);

105

106

// Combine with command-line arguments

107

const prompts = require('prompts');

108

const yargs = require('yargs');

109

110

// Use command-line args as overrides

111

prompts.override(yargs.argv);

112

113

// Now CLI args like --username=alice --port=3000 will pre-answer those questions

114

115

// Override from environment variables

116

prompts.override({

117

apiKey: process.env.API_KEY,

118

database: process.env.DATABASE_URL,

119

environment: process.env.NODE_ENV

120

});

121

122

// Override for testing specific scenarios

123

prompts.override({

124

confirmDeletion: true,

125

backupFirst: false,

126

targetEnvironment: 'staging'

127

});

128

```

129

130

## Testing Patterns

131

132

### Unit Testing with Injection

133

134

```javascript

135

const prompts = require('prompts');

136

137

describe('User Setup', () => {

138

it('should create user with valid inputs', async () => {

139

// Arrange

140

prompts.inject(['John Doe', 'john@example.com', 30, true]);

141

142

// Act

143

const user = await createUserInteractively();

144

145

// Assert

146

expect(user.name).toBe('John Doe');

147

expect(user.email).toBe('john@example.com');

148

expect(user.age).toBe(30);

149

expect(user.newsletter).toBe(true);

150

});

151

152

it('should handle user cancellation', async () => {

153

// Arrange

154

prompts.inject(['John', new Error('Cancelled by user')]);

155

156

// Act & Assert

157

await expect(createUserInteractively()).rejects.toThrow('User cancelled setup');

158

});

159

});

160

```

161

162

### Integration Testing with Override

163

164

```javascript

165

const prompts = require('prompts');

166

167

describe('CLI Application', () => {

168

beforeEach(() => {

169

// Reset any previous overrides

170

prompts.override({});

171

});

172

173

it('should use production config when specified', async () => {

174

// Arrange

175

prompts.override({

176

environment: 'production',

177

confirm: true

178

});

179

180

// Act

181

const config = await loadConfiguration();

182

183

// Assert

184

expect(config.environment).toBe('production');

185

expect(config.debug).toBe(false);

186

});

187

});

188

```

189

190

### Testing Multiselect and Complex Inputs

191

192

```javascript

193

// Test multiselect inputs

194

prompts.inject([

195

['option1', 'option3'], // Array for multiselect

196

true, // Confirmation

197

'custom-value' // Text input

198

]);

199

200

// Test autocomplete inputs

201

prompts.inject([

202

'java', // Will match 'JavaScript' in autocomplete

203

2 // Select index 2 from filtered results

204

]);

205

206

// Test conditional prompts

207

prompts.inject([

208

'pizza', // Triggers additional topping question

209

'pepperoni', // Topping selection

210

true // Final confirmation

211

]);

212

```

213

214

## Testing Best Practices

215

216

### Clean State Management

217

218

```javascript

219

beforeEach(() => {

220

// Clear any previous injections and overrides

221

prompts.inject([]);

222

prompts.override({});

223

});

224

```

225

226

### Error Simulation

227

228

```javascript

229

// Simulate different types of cancellation

230

prompts.inject([

231

'valid-input',

232

new Error('User pressed Ctrl+C'),

233

'recovery-value'

234

]);

235

236

// Test partial completion scenarios

237

prompts.inject([

238

'first-answer',

239

'second-answer',

240

new Error('Connection lost') // Simulate interruption

241

]);

242

```

243

244

### Environment-Specific Testing

245

246

```javascript

247

// Test different environments

248

const testCases = [

249

{ env: 'development', debug: true },

250

{ env: 'staging', debug: false },

251

{ env: 'production', debug: false }

252

];

253

254

testCases.forEach(({ env, debug }) => {

255

it(`should configure correctly for ${env}`, async () => {

256

prompts.override({ environment: env });

257

const config = await setupEnvironment();

258

expect(config.debug).toBe(debug);

259

});

260

});

261

```

262

263

## Injection Behavior

264

265

### Value Consumption

266

- Injected values are consumed in FIFO (first-in, first-out) order

267

- Each prompt consumes exactly one injected value

268

- If no injected value is available, the prompt displays normally to the user

269

- Used values are removed from the injection queue

270

271

### Array Values

272

- Array values are used for prompts that return arrays (multiselect, list)

273

- For single-value prompts, the entire array is used as the value

274

- For multiselect prompts, array items are treated as selected values

275

276

### Error Handling

277

- Error instances in the injection queue simulate user cancellation

278

- The error is thrown when that position in the queue is reached

279

- Subsequent prompts will use remaining injected values after error handling

280

281

## Override Behavior

282

283

### Name Matching

284

- Override keys must exactly match the `name` property of questions

285

- Case-sensitive matching

286

- Questions without matching override names prompt normally

287

288

### Value Types

289

- Override values can be any type appropriate for the question

290

- No type checking is performed; ensure values match expected types

291

- Invalid values may cause prompt errors

292

293

### Persistence

294

- Override values persist until explicitly cleared with `prompts.override({})`

295

- New override calls merge with existing overrides

296

- Set a key to `undefined` to remove a specific override