or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

fake-server-with-clock.mdfake-server.mdfake-xhr.mdindex.md

fake-xhr.mddocs/

0

# XMLHttpRequest Mocking

1

2

Low-level XMLHttpRequest replacement providing complete control over the request/response lifecycle, response types, and progress events. This gives you fine-grained control over every aspect of HTTP request simulation.

3

4

## Capabilities

5

6

### Fake XHR Activation

7

8

Enable fake XMLHttpRequest globally or for specific scopes.

9

10

```javascript { .api }

11

/**

12

* @typedef {Object} FakeXHRModule

13

* @property {XHRUtilities} xhr - XHR utilities

14

* @property {Function} FakeXMLHttpRequest - FakeXMLHttpRequest constructor

15

* @property {Function} useFakeXMLHttpRequest - Function that returns FakeXMLHttpRequest constructor

16

*/

17

18

/**

19

* Replace global XMLHttpRequest with fake implementation

20

* @returns {Function} FakeXMLHttpRequest constructor

21

*/

22

function useFakeXMLHttpRequest() {

23

// Implementation

24

}

25

26

/**

27

* Create fake XMLHttpRequest for specific global scope

28

* @param {Object} globalScope - Global object (window in browser, global in Node.js)

29

* @returns {FakeXHRModule} Object with xhr utilities and FakeXMLHttpRequest

30

*/

31

function fakeXMLHttpRequestFor(globalScope) {

32

// Implementation

33

}

34

```

35

36

**Usage Example:**

37

38

```javascript

39

const nise = require("nise");

40

41

// Replace global XMLHttpRequest

42

const FakeXHR = nise.fakeXhr.useFakeXMLHttpRequest();

43

44

// Now all XMLHttpRequest usage in your code uses the fake

45

const xhr = new XMLHttpRequest(); // Actually creates FakeXMLHttpRequest

46

47

// Restore original later

48

FakeXHR.restore();

49

```

50

51

### FakeXMLHttpRequest Constructor

52

53

Create individual fake XMLHttpRequest instances.

54

55

```javascript { .api }

56

/**

57

* @typedef {Object} FakeXHRConfig

58

* @property {function(string): void} [logger] - Custom logging function

59

* @property {boolean} [useImmediateExceptions] - Throw errors immediately vs on next tick

60

* @property {function(Function, number): *} [setTimeout] - Custom setTimeout function

61

*/

62

63

/**

64

* Create a new fake XMLHttpRequest instance

65

* @param {FakeXHRConfig} [config] - Optional configuration

66

*/

67

function FakeXMLHttpRequest(config) {

68

// Implementation

69

}

70

```

71

72

### Standard XMLHttpRequest Interface

73

74

Complete XMLHttpRequest API implementation.

75

76

```javascript { .api }

77

/**

78

* Initialize a request

79

* @param {string} method - HTTP method

80

* @param {string} url - Request URL

81

* @param {boolean} [async] - Async flag (default: true)

82

* @param {string} [username] - Optional username for authentication

83

* @param {string} [password] - Optional password for authentication

84

* @returns {void}

85

*/

86

open(method, url, async, username, password) {

87

// Implementation

88

}

89

90

/**

91

* Send the request

92

* @param {string|FormData|ArrayBuffer} [data] - Optional request body data

93

* @returns {void}

94

*/

95

send(data) {

96

// Implementation

97

}

98

99

/**

100

* Set a request header

101

* @param {string} header - Header name

102

* @param {string} value - Header value (must be string)

103

* @returns {void}

104

*/

105

setRequestHeader(header, value) {

106

// Implementation

107

}

108

109

/**

110

* Get a response header value

111

* @param {string} header - Header name

112

* @returns {string|null} Header value or null if not found

113

*/

114

getResponseHeader(header) {

115

// Implementation

116

}

117

118

/**

119

* Get all response headers as a string

120

* @returns {string} All headers in HTTP format

121

*/

122

getAllResponseHeaders() {

123

// Implementation

124

}

125

126

/**

127

* Abort the current request

128

* @returns {void}

129

*/

130

abort() {

131

// Implementation

132

}

133

134

/**

135

* Override the MIME type of the response

136

* @param {string} type - MIME type to use

137

* @returns {void}

138

*/

139

overrideMimeType(type) {

140

// Implementation

141

}

142

```

143

144

### XMLHttpRequest Properties

145

146

All standard XMLHttpRequest properties are supported.

147

148

```javascript { .api }

149

/**

150

* @typedef {Object} FakeXMLHttpRequest

151

* @property {0} UNSENT - State constant

152

* @property {1} OPENED - State constant

153

* @property {2} HEADERS_RECEIVED - State constant

154

* @property {3} LOADING - State constant

155

* @property {4} DONE - State constant

156

* @property {number} readyState - Current state

157

* @property {number} status - HTTP status code

158

* @property {string} statusText - HTTP status text

159

* @property {string} responseURL - Response URL

160

* @property {*} response - Response data

161

* @property {string} responseText - Response as text

162

* @property {Document|null} responseXML - Response as XML document

163

* @property {string} responseType - Expected response type ("", "text", "json", "blob", "arraybuffer", "document")

164

* @property {number} timeout - Request timeout in milliseconds (if supported by platform)

165

* @property {boolean} withCredentials - Whether to send credentials (if CORS is supported)

166

* @property {XMLHttpRequestUpload} upload - Upload event target

167

* @property {function(Event): void|null} onreadystatechange - Ready state change event handler

168

* @property {function(ProgressEvent): void|null} onloadstart - Load start event handler

169

* @property {function(ProgressEvent): void|null} onprogress - Progress event handler

170

* @property {function(ProgressEvent): void|null} onload - Load event handler

171

* @property {function(ProgressEvent): void|null} onloadend - Load end event handler

172

* @property {function(ProgressEvent): void|null} onerror - Error event handler

173

* @property {function(ProgressEvent): void|null} onabort - Abort event handler

174

* @property {function(ProgressEvent): void|null} ontimeout - Timeout event handler

175

*/

176

```

177

178

### Mock-Specific Methods

179

180

Additional methods for controlling the fake XMLHttpRequest behavior.

181

182

```javascript { .api }

183

/**

184

* Set the response status code

185

* @param {number} status - HTTP status code

186

* @returns {void}

187

*/

188

setStatus(status) {

189

// Implementation

190

}

191

192

/**

193

* Set response headers

194

* @param {Object.<string, string>} headers - Object with header name/value pairs

195

* @returns {void}

196

*/

197

setResponseHeaders(headers) {

198

// Implementation

199

}

200

201

/**

202

* Set the response body

203

* @param {string|ArrayBuffer|Blob} body - Response body data

204

* @returns {void}

205

*/

206

setResponseBody(body) {

207

// Implementation

208

}

209

210

/**

211

* Set complete response (status, headers, and body)

212

* @param {number} status - HTTP status code

213

* @param {Object.<string, string>} headers - Response headers object

214

* @param {string|ArrayBuffer} body - Response body

215

* @returns {void}

216

*/

217

respond(status, headers, body) {

218

// Implementation

219

}

220

221

/**

222

* Trigger an error state

223

* @returns {void}

224

*/

225

error() {

226

// Implementation

227

}

228

229

/**

230

* Trigger a timeout

231

* @returns {void}

232

*/

233

triggerTimeout() {

234

// Implementation

235

}

236

```

237

238

**Usage Example:**

239

240

```javascript

241

const nise = require("nise");

242

243

// Create fake XHR instance

244

const xhr = new nise.fakeXhr.FakeXMLHttpRequest();

245

246

// Set up event handlers

247

xhr.onreadystatechange = function() {

248

if (xhr.readyState === 4) {

249

console.log(`Response: ${xhr.responseText}`);

250

}

251

};

252

253

// Initialize and send request

254

xhr.open("GET", "/api/data");

255

xhr.send();

256

257

// Simulate response

258

xhr.respond(200, { "Content-Type": "application/json" }, '{"data": "test"}');

259

```

260

261

### Progress Events

262

263

Simulate upload and download progress events.

264

265

```javascript { .api }

266

/**

267

* @typedef {Object} ProgressEventInit

268

* @property {number} loaded - Bytes loaded

269

* @property {number} total - Total bytes

270

*/

271

272

/**

273

* Simulate upload progress

274

* @param {ProgressEventInit} progressEventRaw - Progress event data

275

* @returns {void}

276

*/

277

uploadProgress(progressEventRaw) {

278

// Implementation

279

}

280

281

/**

282

* Simulate download progress

283

* @param {ProgressEventInit} progressEventRaw - Progress event data

284

* @returns {void}

285

*/

286

downloadProgress(progressEventRaw) {

287

// Implementation

288

}

289

290

/**

291

* Simulate upload error

292

* @param {*} error - Error details

293

* @returns {void}

294

*/

295

uploadError(error) {

296

// Implementation

297

}

298

```

299

300

**Usage Example:**

301

302

```javascript

303

const xhr = new nise.fakeXhr.FakeXMLHttpRequest();

304

305

xhr.upload.onprogress = function(event) {

306

console.log(`Upload: ${event.loaded}/${event.total}`);

307

};

308

309

xhr.onprogress = function(event) {

310

console.log(`Download: ${event.loaded}/${event.total}`);

311

};

312

313

xhr.open("POST", "/upload");

314

xhr.send(new FormData());

315

316

// Simulate upload progress

317

xhr.uploadProgress({ loaded: 50, total: 100 });

318

xhr.uploadProgress({ loaded: 100, total: 100 });

319

320

// Simulate response with download progress

321

xhr.setStatus(200);

322

xhr.setResponseHeaders({ "Content-Length": "1000" });

323

xhr.downloadProgress({ loaded: 500, total: 1000 });

324

xhr.setResponseBody("response data");

325

xhr.downloadProgress({ loaded: 1000, total: 1000 });

326

```

327

328

### Request Filtering

329

330

Filter requests to allow some to pass through to real XMLHttpRequest.

331

332

```javascript { .api }

333

/**

334

* Add a filter function to determine which requests should use real XHR

335

* @param {function(string, string, boolean, string=, string=): boolean} filterFn - Function that returns true to use real XHR

336

* @returns {void}

337

*/

338

static addFilter(filterFn) {

339

// Implementation

340

}

341

342

/**

343

* Enable request filtering

344

* @type {boolean}

345

*/

346

static useFilters = false;

347

348

/**

349

* Convert fake XHR to real XHR for this request

350

* @param {FakeXMLHttpRequest} fakeXhr - The fake XHR instance

351

* @param {Array} xhrArgs - Arguments passed to open()

352

* @returns {void}

353

*/

354

static defake(fakeXhr, xhrArgs) {

355

// Implementation

356

}

357

```

358

359

**Usage Example:**

360

361

```javascript

362

const nise = require("nise");

363

364

// Enable filtering

365

nise.fakeXhr.FakeXMLHttpRequest.useFilters = true;

366

367

// Add filter to allow real requests to external APIs

368

nise.fakeXhr.FakeXMLHttpRequest.addFilter(function(method, url) {

369

// Use real XHR for external URLs

370

return url.startsWith("https://api.external.com");

371

});

372

373

// Replace global XHR

374

const FakeXHR = nise.fakeXhr.useFakeXMLHttpRequest();

375

376

// Internal requests use fake XHR

377

const internalXhr = new XMLHttpRequest();

378

internalXhr.open("GET", "/api/internal"); // Uses fake XHR

379

380

// External requests use real XHR

381

const externalXhr = new XMLHttpRequest();

382

externalXhr.open("GET", "https://api.external.com/data"); // Uses real XHR

383

```

384

385

### Response Type Handling

386

387

Support for different response types (text, json, blob, arraybuffer, document).

388

389

```javascript { .api }

390

/**

391

* @typedef {Object} ResponseTypeHandling - Response type conversion and validation

392

* @property {string} responseType - Set before send() to specify expected response type ("", "text", "json", "blob", "arraybuffer", "document")

393

* @property {*} response - Response data in the format specified by responseType

394

* @property {string} responseText - Response as text (for responseType "" or "text")

395

* @property {Document|null} responseXML - Response as XML document (for responseType "document" or XML content)

396

*/

397

```

398

399

**Usage Example:**

400

401

```javascript

402

const xhr = new nise.fakeXhr.FakeXMLHttpRequest();

403

404

// JSON response

405

xhr.open("GET", "/api/data");

406

xhr.responseType = "json";

407

xhr.send();

408

xhr.respond(200, { "Content-Type": "application/json" }, '{"name": "Alice"}');

409

console.log(xhr.response); // {name: "Alice"} (parsed object)

410

411

// ArrayBuffer response

412

const xhr2 = new nise.fakeXhr.FakeXMLHttpRequest();

413

xhr2.open("GET", "/api/binary");

414

xhr2.responseType = "arraybuffer";

415

xhr2.send();

416

xhr2.respond(200, {}, "binary data");

417

console.log(xhr2.response instanceof ArrayBuffer); // true

418

```

419

420

### Static Utilities

421

422

Utility methods and properties available on the FakeXMLHttpRequest constructor.

423

424

```javascript { .api }

425

/**

426

* HTTP status codes mapping

427

* @type {Object.<number, string>}

428

*/

429

static statusCodes = {};

430

431

/**

432

* Parse XML text into Document

433

* @param {string} text - XML text to parse

434

* @returns {Document|null} Parsed document or null if parsing failed

435

*/

436

static parseXML(text) {

437

// Implementation

438

}

439

440

/**

441

* Callback called when new FakeXMLHttpRequest instances are created

442

* @type {function(FakeXMLHttpRequest): void|null}

443

*/

444

static onCreate = null;

445

```

446

447

**Usage Example:**

448

449

```javascript

450

const nise = require("nise");

451

452

// Set up onCreate callback for all new XHR instances

453

nise.fakeXhr.FakeXMLHttpRequest.onCreate = function(xhr) {

454

console.log("New XHR created:", xhr);

455

// Could set default headers, event handlers, etc.

456

};

457

458

// Check status codes

459

console.log(nise.fakeXhr.FakeXMLHttpRequest.statusCodes[404]); // "Not Found"

460

461

// Parse XML

462

const doc = nise.fakeXhr.FakeXMLHttpRequest.parseXML("<root><item>test</item></root>");

463

console.log(doc.querySelector("item").textContent); // "test"

464

```