]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blame - tests.js
Tests for namecoin and peercoin
[perso/Immae/Projets/Cryptomonnaies/BIP39.git] / tests.js
CommitLineData
88e2cdaa
IC
1// Usage:
2// $ phantomjs tests.js
3
4
5var page = require('webpage').create();
6var url = 'src/index.html';
3eef9d0d 7var testMaxTime = 5000;
88e2cdaa
IC
8
9page.onResourceError = function(e) {
10 console.log("Error loading " + e.url);
11 phantom.exit();
12}
13
14function fail() {
15 console.log("Failed");
16 phantom.exit();
17}
18
3eef9d0d
IC
19function waitForGenerate(fn, maxTime) {
20 if (!maxTime) {
21 maxTime = testMaxTime;
22 }
23 var start = new Date().getTime();
24 var prevAddressCount = -1;
25 var wait = function keepWaiting() {
26 var now = new Date().getTime();
27 var hasTimedOut = now - start > maxTime;
28 var addressCount = page.evaluate(function() {
29 return $(".address").length;
30 });
31 var hasFinished = addressCount > 0 && addressCount == prevAddressCount;
32 prevAddressCount = addressCount;
33 if (hasFinished) {
34 fn();
35 }
36 else if (hasTimedOut) {
37 console.log("Test timed out");
38 fn();
39 }
40 else {
41 setTimeout(keepWaiting, 100);
42 }
43 }
44 wait();
45}
46
88e2cdaa
IC
47function next() {
48 if (tests.length > 0) {
49 var testsStr = tests.length == 1 ? "test" : "tests";
50 console.log(tests.length + " " + testsStr + " remaining");
51 tests.shift()();
52 }
53 else {
54 console.log("Finished with 0 failures");
55 phantom.exit();
56 }
57}
58
fb372687
IC
59/**
60 * Randomize array element order in-place.
61 * Using Durstenfeld shuffle algorithm.
62 * See http://stackoverflow.com/a/12646864
63 */
64function shuffle(array) {
65 for (var i = array.length - 1; i > 0; i--) {
66 var j = Math.floor(Math.random() * (i + 1));
67 var temp = array[i];
68 array[i] = array[j];
69 array[j] = temp;
70 }
71 return array;
72}
73
88e2cdaa
IC
74tests = [
75
76// Page loads with status of 'success'
77function() {
78page.open(url, function(status) {
79 if (status != "success") {
80 console.log("Page did not load with status 'success'");
81 fail();
82 }
83 next();
84});
85},
86
87// Page has text
88function() {
89page.open(url, function(status) {
90 var content = page.evaluate(function() {
91 return document.body.textContent.trim();
92 });
93 if (!content) {
94 console.log("Page does not have text");
95 fail();
96 }
97 next();
98});
99},
100
101// Entering mnemonic generates addresses
102function() {
103page.open(url, function(status) {
88e2cdaa
IC
104 // set the phrase
105 page.evaluate(function() {
106 $(".phrase").val("abandon abandon ability").trigger("input");
107 });
108 // get the address
3eef9d0d 109 waitForGenerate(function() {
06c4c6e3
IC
110 var addressCount = page.evaluate(function() {
111 return $(".address").length;
88e2cdaa 112 });
06c4c6e3
IC
113 if (addressCount != 20) {
114 console.log("Mnemonic did not generate addresses");
88e2cdaa
IC
115 console.log("Expected: " + expected);
116 console.log("Got: " + actual);
117 fail();
118 }
119 next();
3eef9d0d 120 });
88e2cdaa
IC
121});
122},
123
124// Random button generates random mnemonic
125function() {
126page.open(url, function(status) {
127 // check initial phrase is empty
128 var phrase = page.evaluate(function() {
129 return $(".phrase").text();
130 });
131 if (phrase != "") {
132 console.log("Initial phrase is not blank");
133 fail();
134 }
135 // press the 'generate' button
136 page.evaluate(function() {
137 $(".generate").click();
138 });
139 // get the new phrase
3eef9d0d 140 waitForGenerate(function() {
88e2cdaa
IC
141 var phrase = page.evaluate(function() {
142 return $(".phrase").val();
143 });
144 if (phrase.length <= 0) {
145 console.log("Phrase not generated by pressing button");
146 fail();
147 }
148 next();
3eef9d0d 149 });
88e2cdaa
IC
150});
151},
152
153// Mnemonic length can be customized
154function() {
155page.open(url, function(status) {
156 // set the length to 6
54563907 157 var expectedLength = "6";
88e2cdaa 158 page.evaluate(function() {
54563907
IC
159 $(".strength option[selected]").removeAttr("selected");
160 $(".strength option[value=6]").prop("selected", true);
88e2cdaa
IC
161 });
162 // press the 'generate' button
163 page.evaluate(function() {
164 $(".generate").click();
165 });
166 // check the new phrase is six words long
3eef9d0d 167 waitForGenerate(function() {
88e2cdaa
IC
168 var actualLength = page.evaluate(function() {
169 var words = $(".phrase").val().split(" ");
170 return words.length;
171 });
172 if (actualLength != expectedLength) {
173 console.log("Phrase not generated with correct length");
174 console.log("Expected: " + expectedLength);
175 console.log("Actual: " + actualLength);
176 fail();
177 }
54563907 178 next();
3eef9d0d 179 });
88e2cdaa
IC
180});
181},
182
88e2cdaa 183// Passphrase can be set
54563907
IC
184function() {
185page.open(url, function(status) {
186 // set the phrase and passphrase
187 var expected = "15pJzUWPGzR7avffV9nY5by4PSgSKG9rba";
188 page.evaluate(function() {
189 $(".phrase").val("abandon abandon ability");
190 $(".passphrase").val("secure_passphrase").trigger("input");
191 });
192 // check the address is generated correctly
3eef9d0d 193 waitForGenerate(function() {
54563907
IC
194 var actual = page.evaluate(function() {
195 return $(".address:first").text();
196 });
197 if (actual != expected) {
198 console.log("Passphrase results in wrong address");
199 console.log("Expected: " + expected);
200 console.log("Actual: " + actual);
201 fail();
202 }
203 next();
3eef9d0d 204 });
54563907
IC
205});
206},
207
88e2cdaa 208// Network can be set to bitcoin testnet
54563907
IC
209function() {
210page.open(url, function(status) {
59193779 211 // set the phrase and coin
54563907
IC
212 var expected = "mucaU5iiDaJDb69BHLeDv8JFfGiyg2nJKi";
213 page.evaluate(function() {
214 $(".phrase").val("abandon abandon ability");
215 $(".phrase").trigger("input");
216 $(".network option[selected]").removeAttr("selected");
217 $(".network option[value=1]").prop("selected", true);
218 $(".network").trigger("change");
219 });
220 // check the address is generated correctly
3eef9d0d 221 waitForGenerate(function() {
54563907
IC
222 var actual = page.evaluate(function() {
223 return $(".address:first").text();
224 });
225 if (actual != expected) {
226 console.log("Bitcoin testnet address is incorrect");
227 console.log("Expected: " + expected);
228 console.log("Actual: " + actual);
229 fail();
230 }
231 next();
3eef9d0d 232 });
54563907
IC
233});
234},
235
88e2cdaa 236// Network can be set to litecoin
59193779
IC
237function() {
238page.open(url, function(status) {
239 // set the phrase and coin
240 var expected = "LQ4XU8RX2ULPmPq9FcUHdVmPVchP9nwXdn";
241 page.evaluate(function() {
242 $(".phrase").val("abandon abandon ability");
243 $(".phrase").trigger("input");
244 $(".network option[selected]").removeAttr("selected");
245 $(".network option[value=2]").prop("selected", true);
246 $(".network").trigger("change");
247 });
248 // check the address is generated correctly
3eef9d0d 249 waitForGenerate(function() {
59193779
IC
250 var actual = page.evaluate(function() {
251 return $(".address:first").text();
252 });
253 if (actual != expected) {
254 console.log("Litecoin address is incorrect");
255 console.log("Expected: " + expected);
256 console.log("Actual: " + actual);
257 fail();
258 }
259 next();
3eef9d0d 260 });
59193779
IC
261});
262},
263
88e2cdaa 264// Network can be set to dogecoin
59193779
IC
265function() {
266page.open(url, function(status) {
267 // set the phrase and coin
268 var expected = "DPQH2AtuzkVSG6ovjKk4jbUmZ6iXLpgbJA";
269 page.evaluate(function() {
270 $(".phrase").val("abandon abandon ability");
271 $(".phrase").trigger("input");
272 $(".network option[selected]").removeAttr("selected");
273 $(".network option[value=3]").prop("selected", true);
274 $(".network").trigger("change");
275 });
276 // check the address is generated correctly
3eef9d0d 277 waitForGenerate(function() {
59193779
IC
278 var actual = page.evaluate(function() {
279 return $(".address:first").text();
280 });
281 if (actual != expected) {
282 console.log("Dogecoin address is incorrect");
283 console.log("Expected: " + expected);
284 console.log("Actual: " + actual);
285 fail();
286 }
287 next();
3eef9d0d 288 });
59193779
IC
289});
290},
291
88e2cdaa 292// Network can be set to shadowcash
59193779
IC
293function() {
294page.open(url, function(status) {
295 // set the phrase and coin
296 var expected = "SiSZtfYAXEFvMm3XM8hmtkGDyViRwErtCG";
297 page.evaluate(function() {
298 $(".phrase").val("abandon abandon ability");
299 $(".phrase").trigger("input");
300 $(".network option[selected]").removeAttr("selected");
301 $(".network option[value=4]").prop("selected", true);
302 $(".network").trigger("change");
303 });
304 // check the address is generated correctly
3eef9d0d 305 waitForGenerate(function() {
59193779
IC
306 var actual = page.evaluate(function() {
307 return $(".address:first").text();
308 });
309 if (actual != expected) {
310 console.log("Shadowcash address is incorrect");
311 console.log("Expected: " + expected);
312 console.log("Actual: " + actual);
313 fail();
314 }
315 next();
3eef9d0d 316 });
59193779
IC
317});
318},
319
88e2cdaa 320// Network can be set to shadowcash testnet
59193779
IC
321function() {
322page.open(url, function(status) {
323 // set the phrase and coin
324 var expected = "tM2EDpVKaTiEg2NZg3yKg8eqjLr55BErHe";
325 page.evaluate(function() {
326 $(".phrase").val("abandon abandon ability");
327 $(".phrase").trigger("input");
328 $(".network option[selected]").removeAttr("selected");
329 $(".network option[value=5]").prop("selected", true);
330 $(".network").trigger("change");
331 });
332 // check the address is generated correctly
3eef9d0d 333 waitForGenerate(function() {
59193779
IC
334 var actual = page.evaluate(function() {
335 return $(".address:first").text();
336 });
337 if (actual != expected) {
338 console.log("Shadowcash testnet address is incorrect");
339 console.log("Expected: " + expected);
340 console.log("Actual: " + actual);
341 fail();
342 }
343 next();
3eef9d0d 344 });
59193779
IC
345});
346},
347
88e2cdaa 348// Network can be set to viacoin
59193779
IC
349function() {
350page.open(url, function(status) {
351 // set the phrase and coin
352 var expected = "Vq9Eq4N5SQnjqZvxtxzo7hZPW5XnyJsmXT";
353 page.evaluate(function() {
354 $(".phrase").val("abandon abandon ability");
355 $(".phrase").trigger("input");
356 $(".network option[selected]").removeAttr("selected");
357 $(".network option[value=6]").prop("selected", true);
358 $(".network").trigger("change");
359 });
360 // check the address is generated correctly
3eef9d0d 361 waitForGenerate(function() {
59193779
IC
362 var actual = page.evaluate(function() {
363 return $(".address:first").text();
364 });
365 if (actual != expected) {
366 console.log("Viacoin address is incorrect");
367 console.log("Expected: " + expected);
368 console.log("Actual: " + actual);
369 fail();
370 }
371 next();
3eef9d0d 372 });
59193779
IC
373});
374},
375
88e2cdaa 376// Network can be set to viacoin testnet
59193779
IC
377function() {
378page.open(url, function(status) {
379 // set the phrase and coin
380 var expected = "tM2EDpVKaTiEg2NZg3yKg8eqjLr55BErHe";
381 page.evaluate(function() {
382 $(".phrase").val("abandon abandon ability");
383 $(".phrase").trigger("input");
384 $(".network option[selected]").removeAttr("selected");
385 $(".network option[value=7]").prop("selected", true);
386 $(".network").trigger("change");
387 });
388 // check the address is generated correctly
3eef9d0d 389 waitForGenerate(function() {
59193779
IC
390 var actual = page.evaluate(function() {
391 return $(".address:first").text();
392 });
393 if (actual != expected) {
394 console.log("Viacoin testnet address is incorrect");
395 console.log("Expected: " + expected);
396 console.log("Actual: " + actual);
397 fail();
398 }
399 next();
3eef9d0d 400 });
59193779
IC
401});
402},
403
88e2cdaa 404// Network can be set to jumbucks
59193779
IC
405function() {
406page.open(url, function(status) {
407 // set the phrase and coin
408 var expected = "JLEXccwDXADK4RxBPkRez7mqsHVoJBEUew";
409 page.evaluate(function() {
410 $(".phrase").val("abandon abandon ability");
411 $(".phrase").trigger("input");
412 $(".network option[selected]").removeAttr("selected");
413 $(".network option[value=8]").prop("selected", true);
414 $(".network").trigger("change");
415 });
416 // check the address is generated correctly
3eef9d0d 417 waitForGenerate(function() {
59193779
IC
418 var actual = page.evaluate(function() {
419 return $(".address:first").text();
420 });
421 if (actual != expected) {
422 console.log("Jumbucks address is incorrect");
423 console.log("Expected: " + expected);
424 console.log("Actual: " + actual);
425 fail();
426 }
427 next();
3eef9d0d 428 });
59193779
IC
429});
430},
431
88e2cdaa 432// Network can be set to clam
59193779
IC
433function() {
434page.open(url, function(status) {
435 // set the phrase and coin
436 var expected = "xCp4sakjVx4pUAZ6cBCtuin8Ddb6U1sk9y";
437 page.evaluate(function() {
438 $(".phrase").val("abandon abandon ability");
439 $(".phrase").trigger("input");
440 $(".network option[selected]").removeAttr("selected");
441 $(".network option[value=9]").prop("selected", true);
442 $(".network").trigger("change");
443 });
444 // check the address is generated correctly
3eef9d0d 445 waitForGenerate(function() {
59193779
IC
446 var actual = page.evaluate(function() {
447 return $(".address:first").text();
448 });
449 if (actual != expected) {
450 console.log("CLAM address is incorrect");
451 console.log("Expected: " + expected);
452 console.log("Actual: " + actual);
453 fail();
f3fad1b5
IC
454 }
455 next();
456 });
457});
458},
459
460// Network can be set to dash
461function() {
462page.open(url, function(status) {
463 // set the phrase and coin
464 var expected = "XdbhtMuGsPSkE6bPdNTHoFSszQKmK4S5LT";
465 page.evaluate(function() {
466 $(".phrase").val("abandon abandon ability");
467 $(".phrase").trigger("input");
468 $(".network option[selected]").removeAttr("selected");
469 $(".network option[value=10]").prop("selected", true);
470 $(".network").trigger("change");
471 });
472 // check the address is generated correctly
473 waitForGenerate(function() {
474 var actual = page.evaluate(function() {
475 return $(".address:first").text();
476 });
477 if (actual != expected) {
478 console.log("DASH address is incorrect");
479 console.log("Expected: " + expected);
480 console.log("Actual: " + actual);
481 fail();
59193779 482 }
bfb3dab6
IC
483 next();
484 });
485});
486},
487
488// Network can be set to namecoin
489function() {
490page.open(url, function(status) {
491 // set the phrase and coin
492 var expected = "Mw2vK2Bvex1yYtYF6sfbEg2YGoUc98YUD2";
493 page.evaluate(function() {
494 $(".phrase").val("abandon abandon ability");
495 $(".phrase").trigger("input");
496 $(".network option[selected]").removeAttr("selected");
497 $(".network option[value=11]").prop("selected", true);
498 $(".network").trigger("change");
499 });
500 // check the address is generated correctly
501 waitForGenerate(function() {
502 var actual = page.evaluate(function() {
503 return $(".address:first").text();
504 });
505 if (actual != expected) {
506 console.log("Namecoin address is incorrect");
507 console.log("Expected: " + expected);
508 console.log("Actual: " + actual);
509 fail();
510 }
511 next();
512 });
513});
514},
515
516// Network can be set to peercoin
517function() {
518page.open(url, function(status) {
519 // set the phrase and coin
520 var expected = "PVAiioTaK2eDHSEo3tppT9AVdBYqxRTBAm";
521 page.evaluate(function() {
522 $(".phrase").val("abandon abandon ability");
523 $(".phrase").trigger("input");
524 $(".network option[selected]").removeAttr("selected");
525 $(".network option[value=12]").prop("selected", true);
526 $(".network").trigger("change");
527 });
528 // check the address is generated correctly
529 waitForGenerate(function() {
530 var actual = page.evaluate(function() {
531 return $(".address:first").text();
532 });
533 if (actual != expected) {
534 console.log("Peercoin address is incorrect");
535 console.log("Expected: " + expected);
536 console.log("Actual: " + actual);
537 fail();
538 }
59193779 539 next();
3eef9d0d 540 });
59193779
IC
541});
542},
543
88e2cdaa 544// BIP39 seed is set from phrase
c196ad55
IC
545function() {
546page.open(url, function(status) {
547 // set the phrase
548 var expected = "20da140d3dd1df8713cefcc4d54ce0e445b4151027a1ab567b832f6da5fcc5afc1c3a3f199ab78b8e0ab4652efd7f414ac2c9a3b81bceb879a70f377aa0a58f3";
549 page.evaluate(function() {
550 $(".phrase").val("abandon abandon ability");
551 $(".phrase").trigger("input");
552 });
553 // check the address is generated correctly
3eef9d0d 554 waitForGenerate(function() {
c196ad55
IC
555 var actual = page.evaluate(function() {
556 return $(".seed").val();
557 });
558 if (actual != expected) {
559 console.log("BIP39 seed is incorrectly generated from mnemonic");
560 console.log("Expected: " + expected);
561 console.log("Actual: " + actual);
562 fail();
563 }
564 next();
3eef9d0d 565 });
c196ad55
IC
566});
567},
568
88e2cdaa 569// BIP32 root key is set from phrase
ec60b662
IC
570function() {
571page.open(url, function(status) {
572 // set the phrase
573 var expected = "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
574 page.evaluate(function() {
575 $(".phrase").val("abandon abandon ability");
576 $(".phrase").trigger("input");
577 });
578 // check the address is generated correctly
3eef9d0d 579 waitForGenerate(function() {
ec60b662
IC
580 var actual = page.evaluate(function() {
581 return $(".root-key").val();
582 });
583 if (actual != expected) {
584 console.log("Root key is incorrectly generated from mnemonic");
585 console.log("Expected: " + expected);
586 console.log("Actual: " + actual);
587 fail();
588 }
589 next();
3eef9d0d 590 });
ec60b662
IC
591});
592},
593
88e2cdaa 594// Tabs show correct addresses when changed
cf7258fd
IC
595function() {
596page.open(url, function(status) {
597 // set the phrase
598 var expected = "17uQ7s2izWPwBmEVFikTmZUjbBKWYdJchz";
599 page.evaluate(function() {
600 $(".phrase").val("abandon abandon ability");
601 $(".phrase").trigger("input");
602 });
603 // change tabs
604 waitForGenerate(function() {
605 page.evaluate(function() {
606 $("#bip32-tab a").click();
607 });
608 // check the address is generated correctly
609 waitForGenerate(function() {
610 var actual = page.evaluate(function() {
611 return $(".address:first").text();
612 });
613 if (actual != expected) {
614 console.log("Clicking tab generates incorrect address");
615 console.log("Expected: " + expected);
616 console.log("Actual: " + actual);
617 fail();
618 }
619 next();
620 });
621 });
622});
623},
88e2cdaa
IC
624
625// BIP44 derivation path is shown
d077e1e7
IC
626function() {
627page.open(url, function(status) {
628 // set the phrase
629 var expected = "m/44'/0'/0'/0";
630 page.evaluate(function() {
631 $(".phrase").val("abandon abandon ability");
632 $(".phrase").trigger("input");
633 });
634 // check the derivation path of the first address
635 waitForGenerate(function() {
636 var actual = page.evaluate(function() {
637 return $("#bip44 .path").val();
638 });
639 if (actual != expected) {
640 console.log("BIP44 derivation path is incorrect");
641 console.log("Expected: " + expected);
642 console.log("Actual: " + actual);
643 fail();
644 }
645 next();
646 });
647});
648},
649
88e2cdaa 650// BIP44 extended private key is shown
4fd2925d
IC
651function() {
652page.open(url, function(status) {
653 // set the phrase
654 var expected = "xprvA2DxxvPZcyRvYgZMGS53nadR32mVDeCyqQYyFhrCVbJNjPoxMeVf7QT5g7mQASbTf9Kp4cryvcXnu2qurjWKcrdsr91jXymdCDNxKgLFKJG";
655 page.evaluate(function() {
656 $(".phrase").val("abandon abandon ability");
657 $(".phrase").trigger("input");
658 });
06286adb 659 // check the BIP44 extended private key
4fd2925d
IC
660 waitForGenerate(function() {
661 var actual = page.evaluate(function() {
662 return $(".extended-priv-key").val();
663 });
664 if (actual != expected) {
665 console.log("BIP44 extended private key is incorrect");
666 console.log("Expected: " + expected);
667 console.log("Actual: " + actual);
668 fail();
669 }
670 next();
671 });
672});
673},
674
88e2cdaa 675// BIP44 extended public key is shown
39fd45bb
IC
676function() {
677page.open(url, function(status) {
678 // set the phrase
679 var expected = "xpub6FDKNRvTTLzDmAdpNTc49ia9b4byd6vqCdUa46Fp3vqMcC96uBoufCmZXQLiN5AK3iSCJMhf9gT2sxkpyaPepRuA7W3MujV5tGmF5VfbueM";
680 page.evaluate(function() {
681 $(".phrase").val("abandon abandon ability");
682 $(".phrase").trigger("input");
683 });
06286adb 684 // check the BIP44 extended public key
39fd45bb
IC
685 waitForGenerate(function() {
686 var actual = page.evaluate(function() {
687 return $(".extended-pub-key").val();
688 });
689 if (actual != expected) {
690 console.log("BIP44 extended public key is incorrect");
691 console.log("Expected: " + expected);
692 console.log("Actual: " + actual);
693 fail();
694 }
695 next();
696 });
697});
698},
699
06286adb
IC
700// BIP44 purpose field changes address list
701function() {
702page.open(url, function(status) {
703 // set the phrase
704 var expected = "1JbDzRJ2cDT8aat2xwKd6Pb2zzavow5MhF";
705 page.evaluate(function() {
706 $(".phrase").val("abandon abandon ability");
707 $(".phrase").trigger("input");
708 });
709 waitForGenerate(function() {
710 // change the bip44 purpose field to 45
711 page.evaluate(function() {
712 $("#bip44 .purpose").val("45");
713 $("#bip44 .purpose").trigger("input");
714 });
715 waitForGenerate(function() {
716 // check the address for the new derivation path
717 var actual = page.evaluate(function() {
718 return $(".address:first").text();
719 });
720 if (actual != expected) {
721 console.log("BIP44 purpose field generates incorrect address");
722 console.log("Expected: " + expected);
723 console.log("Actual: " + actual);
724 fail();
725 }
726 next();
727 });
728 });
729});
730},
731
88e2cdaa 732// BIP44 coin field changes address list
9eb72cdf
IC
733function() {
734page.open(url, function(status) {
735 // set the phrase
736 var expected = "1F6dB2djQYrxoyfZZmfr6D5voH8GkJTghk";
737 page.evaluate(function() {
738 $(".phrase").val("abandon abandon ability");
739 $(".phrase").trigger("input");
740 });
741 waitForGenerate(function() {
742 // change the bip44 purpose field to 45
743 page.evaluate(function() {
744 $("#bip44 .coin").val("1");
745 $("#bip44 .coin").trigger("input");
746 });
747 waitForGenerate(function() {
748 // check the address for the new derivation path
749 var actual = page.evaluate(function() {
750 return $(".address:first").text();
751 });
752 if (actual != expected) {
753 console.log("BIP44 coin field generates incorrect address");
754 console.log("Expected: " + expected);
755 console.log("Actual: " + actual);
756 fail();
757 }
758 next();
759 });
760 });
761});
762},
763
88e2cdaa 764// BIP44 account field changes address list
048bc3e0
IC
765function() {
766page.open(url, function(status) {
767 // set the phrase
768 var expected = "1Nq2Wmu726XHCuGhctEtGmhxo3wzk5wZ1H";
769 page.evaluate(function() {
770 $(".phrase").val("abandon abandon ability");
771 $(".phrase").trigger("input");
772 });
773 waitForGenerate(function() {
774 // change the bip44 purpose field to 45
775 page.evaluate(function() {
776 $("#bip44 .account").val("1");
777 $("#bip44 .account").trigger("input");
778 });
779 waitForGenerate(function() {
780 // check the address for the new derivation path
781 var actual = page.evaluate(function() {
782 return $(".address:first").text();
783 });
784 if (actual != expected) {
785 console.log("BIP44 account field generates incorrect address");
786 console.log("Expected: " + expected);
787 console.log("Actual: " + actual);
788 fail();
789 }
790 next();
791 });
792 });
793});
794},
795
fa4da086
IC
796// BIP44 change field changes address list
797function() {
798page.open(url, function(status) {
799 // set the phrase
800 var expected = "1KAGfWgqfVbSSXY56fNQ7YnhyKuoskHtYo";
801 page.evaluate(function() {
802 $(".phrase").val("abandon abandon ability");
803 $(".phrase").trigger("input");
804 });
805 waitForGenerate(function() {
806 // change the bip44 purpose field to 45
807 page.evaluate(function() {
808 $("#bip44 .change").val("1");
809 $("#bip44 .change").trigger("input");
810 });
811 waitForGenerate(function() {
812 // check the address for the new derivation path
813 var actual = page.evaluate(function() {
814 return $(".address:first").text();
815 });
816 if (actual != expected) {
817 console.log("BIP44 change field generates incorrect address");
818 console.log("Expected: " + expected);
819 console.log("Actual: " + actual);
820 fail();
821 }
822 next();
823 });
824 });
825});
826},
048bc3e0 827
88e2cdaa 828// BIP32 derivation path can be set
651382a3
IC
829function() {
830page.open(url, function(status) {
831 // set the phrase
832 var expected = "16pYQQdLD1hH4hwTGLXBaZ9Teboi1AGL8L";
833 page.evaluate(function() {
834 $(".phrase").val("abandon abandon ability");
835 $(".phrase").trigger("input");
836 });
837 // change tabs
838 waitForGenerate(function() {
839 page.evaluate(function() {
840 $("#bip32-tab a").click();
841 });
842 // set the derivation path to m/1
843 waitForGenerate(function() {
844 page.evaluate(function() {
845 $("#bip32 .path").val("m/1");
846 $("#bip32 .path").trigger("input");
847 });
848 // check the address is generated correctly
849 waitForGenerate(function() {
850 var actual = page.evaluate(function() {
851 return $(".address:first").text();
852 });
853 if (actual != expected) {
854 console.log("Custom BIP32 path generates incorrect address");
855 console.log("Expected: " + expected);
856 console.log("Actual: " + actual);
857 fail();
858 }
859 next();
860 });
861 });
862 });
863});
864},
865
88e2cdaa 866// BIP32 can use hardened derivation paths
651382a3
IC
867function() {
868page.open(url, function(status) {
869 // set the phrase
870 var expected = "14aXZeprXAE3UUKQc4ihvwBvww2LuEoHo4";
871 page.evaluate(function() {
872 $(".phrase").val("abandon abandon ability");
873 $(".phrase").trigger("input");
874 });
875 // change tabs
876 waitForGenerate(function() {
877 page.evaluate(function() {
878 $("#bip32-tab a").click();
879 });
880 // set the derivation path to m/0'
881 waitForGenerate(function() {
882 page.evaluate(function() {
883 $("#bip32 .path").val("m/0'");
884 $("#bip32 .path").trigger("input");
885 });
886 // check the address is generated correctly
887 waitForGenerate(function() {
888 var actual = page.evaluate(function() {
889 return $(".address:first").text();
890 });
891 if (actual != expected) {
892 console.log("Hardened BIP32 path generates incorrect address");
893 console.log("Expected: " + expected);
894 console.log("Actual: " + actual);
895 fail();
896 }
897 next();
898 });
899 });
900 });
901});
902},
903
88e2cdaa 904// BIP32 extended private key is shown
9e9dcfda
IC
905function() {
906page.open(url, function(status) {
907 // set the phrase
908 var expected = "xprv9va99uTVE5aLiutUVLTyfxfe8v8aaXjSQ1XxZbK6SezYVuikA9MnjQVTA8rQHpNA5LKvyQBpLiHbBQiiccKiBDs7eRmBogsvq3THFeLHYbe";
909 page.evaluate(function() {
910 $(".phrase").val("abandon abandon ability");
911 $(".phrase").trigger("input");
912 });
913 // change tabs
914 waitForGenerate(function() {
915 page.evaluate(function() {
916 $("#bip32-tab a").click();
917 });
918 // check the extended private key is generated correctly
919 waitForGenerate(function() {
920 var actual = page.evaluate(function() {
921 return $(".extended-priv-key").val();
922 });
923 if (actual != expected) {
924 console.log("BIP32 extended private key is incorrect");
925 console.log("Expected: " + expected);
926 console.log("Actual: " + actual);
927 fail();
928 }
929 next();
930 });
931 });
932});
933},
934
88e2cdaa 935// BIP32 extended public key is shown
9e9dcfda
IC
936function() {
937page.open(url, function(status) {
938 // set the phrase
939 var expected = "xpub69ZVZQzP4T8dwPxwbMzz36cNgwy4yzTHmETZMyihzzXXNi3thgg3HCow1RtY252wdw5rS8369xKnraN5Q93y3FkFfJp2XEHWUrkyXsjS93P";
940 page.evaluate(function() {
941 $(".phrase").val("abandon abandon ability");
942 $(".phrase").trigger("input");
943 });
944 // change tabs
945 waitForGenerate(function() {
946 page.evaluate(function() {
947 $("#bip32-tab a").click();
948 });
949 // check the extended public key is generated correctly
950 waitForGenerate(function() {
951 var actual = page.evaluate(function() {
952 return $(".extended-pub-key").val();
953 });
954 if (actual != expected) {
955 console.log("BIP32 extended public key is incorrect");
956 console.log("Expected: " + expected);
957 console.log("Actual: " + actual);
958 fail();
959 }
960 next();
961 });
962 });
963});
964},
88e2cdaa
IC
965
966// Derivation path is shown in table
5f844c62
IC
967function() {
968page.open(url, function(status) {
969 // set the phrase
970 var expected = "m/44'/0'/0'/0/0";
971 page.evaluate(function() {
972 $(".phrase").val("abandon abandon ability");
973 $(".phrase").trigger("input");
974 });
975 // check for derivation path in table
976 waitForGenerate(function() {
977 var actual = page.evaluate(function() {
978 return $(".index:first").text();
979 });
980 if (actual != expected) {
981 console.log("Derivation path shown incorrectly in table");
982 console.log("Expected: " + expected);
983 console.log("Actual: " + actual);
984 fail();
985 }
986 next();
987 });
988});
989},
990
88e2cdaa 991// Derivation path for address can be hardened
4974fd7f
IC
992function() {
993page.open(url, function(status) {
994 // set the phrase
995 var expected = "18exLzUv7kfpiXRzmCjFDoC9qwNLFyvwyd";
996 page.evaluate(function() {
997 $(".phrase").val("abandon abandon ability");
998 $(".phrase").trigger("input");
999 });
1000 // change tabs
1001 waitForGenerate(function() {
1002 page.evaluate(function() {
1003 $("#bip32-tab a").click();
1004 });
1005 waitForGenerate(function() {
1006 // select the hardened addresses option
1007 page.evaluate(function() {
1008 $(".hardened-addresses").prop("checked", true);
1009 $(".hardened-addresses").trigger("change");
1010 });
1011 waitForGenerate(function() {
1012 // check the generated address is hardened
1013 var actual = page.evaluate(function() {
1014 return $(".address:first").text();
1015 });
1016 if (actual != expected) {
1017 console.log("Hardened address is incorrect");
1018 console.log("Expected: " + expected);
1019 console.log("Actual: " + actual);
1020 fail();
1021 }
1022 next();
1023 });
1024 });
1025 });
1026});
1027},
1028
88e2cdaa 1029// Derivation path visibility can be toggled
a775b5c6
IC
1030function() {
1031page.open(url, function(status) {
1032 // set the phrase
1033 page.evaluate(function() {
1034 $(".phrase").val("abandon abandon ability");
1035 $(".phrase").trigger("input");
1036 });
a775b5c6
IC
1037 waitForGenerate(function() {
1038 // toggle path visibility
1039 page.evaluate(function() {
1040 $(".index-toggle").click();
1041 });
1042 // check the path is not visible
1043 var isInvisible = page.evaluate(function() {
1044 return $(".index:first span").hasClass("invisible");
1045 });
1046 if (!isInvisible) {
1047 console.log("Toggled derivation path is visible");
1048 fail();
1049 }
1050 next();
1051 });
1052});
1053},
1054
88e2cdaa 1055// Address is shown
06c4c6e3
IC
1056function() {
1057page.open(url, function(status) {
1058 var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
1059 // set the phrase
1060 page.evaluate(function() {
1061 $(".phrase").val("abandon abandon ability").trigger("input");
1062 });
1063 // get the address
1064 waitForGenerate(function() {
1065 var actual = page.evaluate(function() {
1066 return $(".address:first").text();
1067 });
1068 if (actual != expected) {
1069 console.log("Address is not shown");
1070 console.log("Expected: " + expected);
1071 console.log("Got: " + actual);
1072 fail();
1073 }
1074 next();
1075 });
1076});
1077},
1078
88e2cdaa 1079// Addresses are shown in order of derivation path
3f1faa4d
IC
1080function() {
1081page.open(url, function(status) {
1082 // set the phrase
1083 page.evaluate(function() {
1084 $(".phrase").val("abandon abandon ability").trigger("input");
1085 });
1086 // get the derivation paths
1087 waitForGenerate(function() {
1088 var paths = page.evaluate(function() {
1089 return $(".index").map(function(i, e) {
1090 return $(e).text();
1091 });
1092 });
1093 if (paths.length != 20) {
1094 console.log("Total paths is less than expected: " + paths.length);
1095 fail();
1096 }
1097 for (var i=0; i<paths.length; i++) {
1098 var expected = "m/44'/0'/0'/0/" + i;
1099 var actual = paths[i];
1100 if (actual != expected) {
1101 console.log("Path " + i + " is incorrect");
1102 console.log("Expected: " + expected);
1103 console.log("Actual: " + actual);
1104 fail();
1105 }
1106 }
1107 next();
1108 });
1109});
1110},
21372fab 1111
88e2cdaa 1112// Address visibility can be toggled
21372fab
IC
1113function() {
1114page.open(url, function(status) {
1115 // set the phrase
1116 page.evaluate(function() {
1117 $(".phrase").val("abandon abandon ability");
1118 $(".phrase").trigger("input");
1119 });
1120 waitForGenerate(function() {
1121 // toggle address visibility
1122 page.evaluate(function() {
1123 $(".address-toggle").click();
1124 });
1125 // check the address is not visible
1126 var isInvisible = page.evaluate(function() {
1127 return $(".address:first span").hasClass("invisible");
1128 });
1129 if (!isInvisible) {
1130 console.log("Toggled address is visible");
1131 fail();
1132 }
1133 next();
1134 });
1135});
1136},
1137
88e2cdaa 1138// Private key is shown
8cd5e231
IC
1139function() {
1140page.open(url, function(status) {
1141 var expected = "L26cVSpWFkJ6aQkPkKmTzLqTdLJ923e6CzrVh9cmx21QHsoUmrEE";
1142 // set the phrase
1143 page.evaluate(function() {
1144 $(".phrase").val("abandon abandon ability").trigger("input");
1145 });
1146 // get the address
1147 waitForGenerate(function() {
1148 var actual = page.evaluate(function() {
1149 return $(".privkey:first").text();
1150 });
1151 if (actual != expected) {
1152 console.log("Private key is not shown");
1153 console.log("Expected: " + expected);
1154 console.log("Got: " + actual);
1155 fail();
1156 }
1157 next();
1158 });
1159});
1160},
1161
88e2cdaa 1162// Private key visibility can be toggled
6848d03b
IC
1163function() {
1164page.open(url, function(status) {
1165 // set the phrase
1166 page.evaluate(function() {
1167 $(".phrase").val("abandon abandon ability");
1168 $(".phrase").trigger("input");
1169 });
1170 waitForGenerate(function() {
1171 // toggle private key visibility
1172 page.evaluate(function() {
1173 $(".private-key-toggle").click();
1174 });
1175 // check the private key is not visible
1176 var isInvisible = page.evaluate(function() {
1177 return $(".privkey:first span").hasClass("invisible");
1178 });
1179 if (!isInvisible) {
1180 console.log("Toggled private key is visible");
1181 fail();
1182 }
1183 next();
1184 });
1185});
1186},
88e2cdaa
IC
1187
1188// More addresses can be generated
1189// A custom number of additional addresses can be generated
1190// Additional addresses are shown in order of derivation path
1191
1192// BIP32 root key can be set by the user
54563907
IC
1193// Setting BIP32 root key clears the existing phrase, passphrase and seed
1194// Clearing of phrase, passphrase and seed can be cancelled by user
88e2cdaa
IC
1195// Custom BIP32 root key is used when changing the derivation path
1196
1197// Incorrect mnemonic shows error
1198// Incorrect word shows suggested replacement
1199// Incorrect BIP32 root key shows error
1200// Derivation path not starting with m shows error
1201// Derivation path containing invalid characters shows useful error
1202
1203// Github Issue 11: Default word length is 15
1204// https://github.com/dcpos/bip39/issues/11
1205
1206// Github Issue 12: Generate more rows with private keys hidden
1207// https://github.com/dcpos/bip39/issues/12
1208
1209// Github Issue 19: Mnemonic is not sensitive to whitespace
1210// https://github.com/dcpos/bip39/issues/19
1211
1212// Github Issue 23: Use correct derivation path when changing tabs
1213// https://github.com/dcpos/bip39/issues/23
1214
f3d0aca1
IC
1215// Github Issue 26: When using a Root key derrived altcoins are incorrect
1216// https://github.com/dcpos/bip39/issues/26
1217
88e2cdaa
IC
1218];
1219
1220console.log("Running tests...");
fb372687 1221tests = shuffle(tests);
88e2cdaa 1222next();