summaryrefslogtreecommitdiffstats
path: root/remote/shared/webdriver/test/xpcshell/test_Errors.js
blob: e688d529cadeda3f84dfefbf8bf41c5ab25625a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const { error } = ChromeUtils.importESModule(
  "chrome://remote/content/shared/webdriver/Errors.sys.mjs"
);

const errors = [
  error.WebDriverError,

  error.DetachedShadowRootError,
  error.ElementClickInterceptedError,
  error.ElementNotAccessibleError,
  error.ElementNotInteractableError,
  error.InsecureCertificateError,
  error.InvalidArgumentError,
  error.InvalidCookieDomainError,
  error.InvalidElementStateError,
  error.InvalidSelectorError,
  error.InvalidSessionIDError,
  error.JavaScriptError,
  error.MoveTargetOutOfBoundsError,
  error.NoSuchAlertError,
  error.NoSuchElementError,
  error.NoSuchFrameError,
  error.NoSuchHandleError,
  error.NoSuchNodeError,
  error.NoSuchScriptError,
  error.NoSuchShadowRootError,
  error.NoSuchWindowError,
  error.ScriptTimeoutError,
  error.SessionNotCreatedError,
  error.StaleElementReferenceError,
  error.TimeoutError,
  error.UnableToSetCookieError,
  error.UnexpectedAlertOpenError,
  error.UnknownCommandError,
  error.UnknownError,
  error.UnsupportedOperationError,
];

function notok(condition) {
  ok(!condition);
}

add_task(function test_isError() {
  notok(error.isError(null));
  notok(error.isError([]));
  notok(error.isError(new Date()));

  ok(error.isError(new Components.Exception()));
  ok(error.isError(new Error()));
  ok(error.isError(new EvalError()));
  ok(error.isError(new InternalError()));
  ok(error.isError(new RangeError()));
  ok(error.isError(new ReferenceError()));
  ok(error.isError(new SyntaxError()));
  ok(error.isError(new TypeError()));
  ok(error.isError(new URIError()));

  errors.forEach(err => ok(error.isError(new err())));
});

add_task(function test_isWebDriverError() {
  notok(error.isWebDriverError(new Components.Exception()));
  notok(error.isWebDriverError(new Error()));
  notok(error.isWebDriverError(new EvalError()));
  notok(error.isWebDriverError(new InternalError()));
  notok(error.isWebDriverError(new RangeError()));
  notok(error.isWebDriverError(new ReferenceError()));
  notok(error.isWebDriverError(new SyntaxError()));
  notok(error.isWebDriverError(new TypeError()));
  notok(error.isWebDriverError(new URIError()));

  errors.forEach(err => ok(error.isWebDriverError(new err())));
});

add_task(function test_wrap() {
  // webdriver-derived errors should not be wrapped
  errors.forEach(err => {
    const unwrappedError = new err("foo");
    const wrappedError = error.wrap(unwrappedError);

    ok(wrappedError instanceof error.WebDriverError);
    ok(wrappedError instanceof err);
    equal(wrappedError.name, unwrappedError.name);
    equal(wrappedError.status, unwrappedError.status);
    equal(wrappedError.message, "foo");
  });

  // JS errors should be wrapped in UnknownError and retain their type
  // as part of the message field.
  const jsErrors = [
    Error,
    EvalError,
    InternalError,
    RangeError,
    ReferenceError,
    SyntaxError,
    TypeError,
    URIError,
  ];

  jsErrors.forEach(err => {
    const originalError = new err("foo");
    const wrappedError = error.wrap(originalError);

    ok(wrappedError instanceof error.UnknownError);
    equal(wrappedError.name, "UnknownError");
    equal(wrappedError.status, "unknown error");
    equal(wrappedError.message, `${originalError.name}: foo`);
  });
});

add_task(function test_stringify() {
  equal("<unprintable error>", error.stringify());
  equal("<unprintable error>", error.stringify("foo"));
  equal("[object Object]", error.stringify({}));
  equal("[object Object]\nfoo", error.stringify({ stack: "foo" }));
  equal("Error: foo", error.stringify(new Error("foo")).split("\n")[0]);

  errors.forEach(err => {
    const e = new err("foo");

    equal(`${e.name}: foo`, error.stringify(e).split("\n")[0]);
  });
});

add_task(function test_constructor_from_error() {
  const data = { a: 3, b: "bar" };
  const origError = new error.WebDriverError("foo", data);

  errors.forEach(err => {
    const newError = new err(origError);

    ok(newError instanceof err);
    equal(newError.message, origError.message);
    equal(newError.stack, origError.stack);
    equal(newError.data, origError.data);
  });
});

add_task(function test_stack() {
  equal("string", typeof error.stack());
  ok(error.stack().includes("test_stack"));
  ok(!error.stack().includes("add_task"));
});

add_task(function test_toJSON() {
  errors.forEach(err => {
    const e0 = new err();
    const e0_json = e0.toJSON();
    equal(e0_json.error, e0.status);
    equal(e0_json.message, "");
    equal(e0_json.stacktrace, e0.stack);
    equal(e0_json.data, undefined);

    // message property
    const e1 = new err("a");
    const e1_json = e1.toJSON();

    equal(e1_json.message, e1.message);
    equal(e1_json.stacktrace, e1.stack);
    equal(e1_json.data, undefined);

    // message and optional data property
    const data = { a: 3, b: "bar" };
    const e2 = new err("foo", data);
    const e2_json = e2.toJSON();

    equal(e2.status, e2_json.error);
    equal(e2.message, e2_json.message);
    equal(e2_json.data, data);
  });
});

add_task(function test_fromJSON() {
  errors.forEach(err => {
    Assert.throws(
      () => err.fromJSON({ error: "foo" }),
      /Not of WebDriverError descent/
    );
    Assert.throws(
      () => err.fromJSON({ error: "Error" }),
      /Not of WebDriverError descent/
    );
    Assert.throws(() => err.fromJSON({}), /Undeserialisable error type/);
    Assert.throws(() => err.fromJSON(undefined), /TypeError/);

    // message and stack
    const e1 = new err("1");
    const e1_json = { error: e1.status, message: "3", stacktrace: "4" };
    const e1_fromJSON = error.WebDriverError.fromJSON(e1_json);

    ok(e1_fromJSON instanceof error.WebDriverError);
    ok(e1_fromJSON instanceof err);
    equal(e1_fromJSON.name, e1.name);
    equal(e1_fromJSON.status, e1_json.error);
    equal(e1_fromJSON.message, e1_json.message);
    equal(e1_fromJSON.stack, e1_json.stacktrace);

    // message and optional data
    const e2_data = { a: 3, b: "bar" };
    const e2 = new err("1", e2_data);
    const e2_json = { error: e1.status, message: "3", data: e2_data };
    const e2_fromJSON = error.WebDriverError.fromJSON(e2_json);

    ok(e2_fromJSON instanceof error.WebDriverError);
    ok(e2_fromJSON instanceof err);
    equal(e2_fromJSON.name, e2.name);
    equal(e2_fromJSON.status, e2_json.error);
    equal(e2_fromJSON.message, e2_json.message);
    equal(e2_fromJSON.data, e2_json.data);

    // parity with toJSON
    const e3_data = { a: 3, b: "bar" };
    const e3 = new err("1", e3_data);
    const e3_json = e3.toJSON();
    const e3_fromJSON = error.WebDriverError.fromJSON(e3_json);

    equal(e3_json.error, e3_fromJSON.status);
    equal(e3_json.message, e3_fromJSON.message);
    equal(e3_json.stacktrace, e3_fromJSON.stack);
  });
});

add_task(function test_WebDriverError() {
  let err = new error.WebDriverError("foo");
  equal("WebDriverError", err.name);
  equal("foo", err.message);
  equal("webdriver error", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_DetachedShadowRootError() {
  let err = new error.DetachedShadowRootError("foo");
  equal("DetachedShadowRootError", err.name);
  equal("foo", err.message);
  equal("detached shadow root", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_ElementClickInterceptedError() {
  let otherEl = {
    hasAttribute: attr => attr in otherEl,
    getAttribute: attr => (attr in otherEl ? otherEl[attr] : null),
    nodeType: 1,
    localName: "a",
  };
  let obscuredEl = {
    hasAttribute: attr => attr in obscuredEl,
    getAttribute: attr => (attr in obscuredEl ? obscuredEl[attr] : null),
    nodeType: 1,
    localName: "b",
    ownerDocument: {
      elementFromPoint() {
        return otherEl;
      },
    },
    style: {
      pointerEvents: "auto",
    },
  };

  let err1 = new error.ElementClickInterceptedError(
    undefined,
    undefined,
    obscuredEl,
    { x: 1, y: 2 }
  );
  equal("ElementClickInterceptedError", err1.name);
  equal(
    "Element <b> is not clickable at point (1,2) " +
      "because another element <a> obscures it",
    err1.message
  );
  equal("element click intercepted", err1.status);
  ok(err1 instanceof error.WebDriverError);

  obscuredEl.style.pointerEvents = "none";
  let err2 = new error.ElementClickInterceptedError(
    undefined,
    undefined,
    obscuredEl,
    { x: 1, y: 2 }
  );
  equal(
    "Element <b> is not clickable at point (1,2) " +
      "because it does not have pointer events enabled, " +
      "and element <a> would receive the click instead",
    err2.message
  );
});

add_task(function test_ElementNotAccessibleError() {
  let err = new error.ElementNotAccessibleError("foo");
  equal("ElementNotAccessibleError", err.name);
  equal("foo", err.message);
  equal("element not accessible", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_ElementNotInteractableError() {
  let err = new error.ElementNotInteractableError("foo");
  equal("ElementNotInteractableError", err.name);
  equal("foo", err.message);
  equal("element not interactable", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_InsecureCertificateError() {
  let err = new error.InsecureCertificateError("foo");
  equal("InsecureCertificateError", err.name);
  equal("foo", err.message);
  equal("insecure certificate", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_InvalidArgumentError() {
  let err = new error.InvalidArgumentError("foo");
  equal("InvalidArgumentError", err.name);
  equal("foo", err.message);
  equal("invalid argument", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_InvalidCookieDomainError() {
  let err = new error.InvalidCookieDomainError("foo");
  equal("InvalidCookieDomainError", err.name);
  equal("foo", err.message);
  equal("invalid cookie domain", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_InvalidElementStateError() {
  let err = new error.InvalidElementStateError("foo");
  equal("InvalidElementStateError", err.name);
  equal("foo", err.message);
  equal("invalid element state", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_InvalidSelectorError() {
  let err = new error.InvalidSelectorError("foo");
  equal("InvalidSelectorError", err.name);
  equal("foo", err.message);
  equal("invalid selector", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_InvalidSessionIDError() {
  let err = new error.InvalidSessionIDError("foo");
  equal("InvalidSessionIDError", err.name);
  equal("foo", err.message);
  equal("invalid session id", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_JavaScriptError() {
  let err = new error.JavaScriptError("foo");
  equal("JavaScriptError", err.name);
  equal("foo", err.message);
  equal("javascript error", err.status);
  ok(err instanceof error.WebDriverError);

  equal("", new error.JavaScriptError(undefined).message);

  let superErr = new RangeError("foo");
  let inheritedErr = new error.JavaScriptError(superErr);
  equal("RangeError: foo", inheritedErr.message);
  equal(superErr.stack, inheritedErr.stack);
});

add_task(function test_MoveTargetOutOfBoundsError() {
  let err = new error.MoveTargetOutOfBoundsError("foo");
  equal("MoveTargetOutOfBoundsError", err.name);
  equal("foo", err.message);
  equal("move target out of bounds", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchAlertError() {
  let err = new error.NoSuchAlertError("foo");
  equal("NoSuchAlertError", err.name);
  equal("foo", err.message);
  equal("no such alert", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchElementError() {
  let err = new error.NoSuchElementError("foo");
  equal("NoSuchElementError", err.name);
  equal("foo", err.message);
  equal("no such element", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchFrameError() {
  let err = new error.NoSuchFrameError("foo");
  equal("NoSuchFrameError", err.name);
  equal("foo", err.message);
  equal("no such frame", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchNodeError() {
  let err = new error.NoSuchNodeError("foo");
  equal("NoSuchNodeError", err.name);
  equal("foo", err.message);
  equal("no such node", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchScriptError() {
  let err = new error.NoSuchScriptError("foo");
  equal("NoSuchScriptError", err.name);
  equal("foo", err.message);
  equal("no such script", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchShadowRootError() {
  let err = new error.NoSuchShadowRootError("foo");
  equal("NoSuchShadowRootError", err.name);
  equal("foo", err.message);
  equal("no such shadow root", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_NoSuchWindowError() {
  let err = new error.NoSuchWindowError("foo");
  equal("NoSuchWindowError", err.name);
  equal("foo", err.message);
  equal("no such window", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_ScriptTimeoutError() {
  let err = new error.ScriptTimeoutError("foo");
  equal("ScriptTimeoutError", err.name);
  equal("foo", err.message);
  equal("script timeout", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_SessionNotCreatedError() {
  let err = new error.SessionNotCreatedError("foo");
  equal("SessionNotCreatedError", err.name);
  equal("foo", err.message);
  equal("session not created", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_StaleElementReferenceError() {
  let err = new error.StaleElementReferenceError("foo");
  equal("StaleElementReferenceError", err.name);
  equal("foo", err.message);
  equal("stale element reference", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_TimeoutError() {
  let err = new error.TimeoutError("foo");
  equal("TimeoutError", err.name);
  equal("foo", err.message);
  equal("timeout", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_UnableToSetCookieError() {
  let err = new error.UnableToSetCookieError("foo");
  equal("UnableToSetCookieError", err.name);
  equal("foo", err.message);
  equal("unable to set cookie", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_UnexpectedAlertOpenError() {
  let err = new error.UnexpectedAlertOpenError("foo");
  equal("UnexpectedAlertOpenError", err.name);
  equal("foo", err.message);
  equal("unexpected alert open", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_UnknownCommandError() {
  let err = new error.UnknownCommandError("foo");
  equal("UnknownCommandError", err.name);
  equal("foo", err.message);
  equal("unknown command", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_UnknownError() {
  let err = new error.UnknownError("foo");
  equal("UnknownError", err.name);
  equal("foo", err.message);
  equal("unknown error", err.status);
  ok(err instanceof error.WebDriverError);
});

add_task(function test_UnsupportedOperationError() {
  let err = new error.UnsupportedOperationError("foo");
  equal("UnsupportedOperationError", err.name);
  equal("foo", err.message);
  equal("unsupported operation", err.status);
  ok(err instanceof error.WebDriverError);
});