]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/BIP39.git/blame - tests.js
Merge pull request #27 from dangershony/master
[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();
454 }
455 next();
3eef9d0d 456 });
59193779
IC
457});
458},
459
88e2cdaa 460// BIP39 seed is set from phrase
c196ad55
IC
461function() {
462page.open(url, function(status) {
463 // set the phrase
464 var expected = "20da140d3dd1df8713cefcc4d54ce0e445b4151027a1ab567b832f6da5fcc5afc1c3a3f199ab78b8e0ab4652efd7f414ac2c9a3b81bceb879a70f377aa0a58f3";
465 page.evaluate(function() {
466 $(".phrase").val("abandon abandon ability");
467 $(".phrase").trigger("input");
468 });
469 // check the address is generated correctly
3eef9d0d 470 waitForGenerate(function() {
c196ad55
IC
471 var actual = page.evaluate(function() {
472 return $(".seed").val();
473 });
474 if (actual != expected) {
475 console.log("BIP39 seed is incorrectly generated from mnemonic");
476 console.log("Expected: " + expected);
477 console.log("Actual: " + actual);
478 fail();
479 }
480 next();
3eef9d0d 481 });
c196ad55
IC
482});
483},
484
88e2cdaa 485// BIP32 root key is set from phrase
ec60b662
IC
486function() {
487page.open(url, function(status) {
488 // set the phrase
489 var expected = "xprv9s21ZrQH143K2jkGDCeTLgRewT9F2pH5JZs2zDmmjXes34geVnFiuNa8KTvY5WoYvdn4Ag6oYRoB6cXtc43NgJAEqDXf51xPm6fhiMCKwpi";
490 page.evaluate(function() {
491 $(".phrase").val("abandon abandon ability");
492 $(".phrase").trigger("input");
493 });
494 // check the address is generated correctly
3eef9d0d 495 waitForGenerate(function() {
ec60b662
IC
496 var actual = page.evaluate(function() {
497 return $(".root-key").val();
498 });
499 if (actual != expected) {
500 console.log("Root key is incorrectly generated from mnemonic");
501 console.log("Expected: " + expected);
502 console.log("Actual: " + actual);
503 fail();
504 }
505 next();
3eef9d0d 506 });
ec60b662
IC
507});
508},
509
88e2cdaa 510// Tabs show correct addresses when changed
cf7258fd
IC
511function() {
512page.open(url, function(status) {
513 // set the phrase
514 var expected = "17uQ7s2izWPwBmEVFikTmZUjbBKWYdJchz";
515 page.evaluate(function() {
516 $(".phrase").val("abandon abandon ability");
517 $(".phrase").trigger("input");
518 });
519 // change tabs
520 waitForGenerate(function() {
521 page.evaluate(function() {
522 $("#bip32-tab a").click();
523 });
524 // check the address is generated correctly
525 waitForGenerate(function() {
526 var actual = page.evaluate(function() {
527 return $(".address:first").text();
528 });
529 if (actual != expected) {
530 console.log("Clicking tab generates incorrect address");
531 console.log("Expected: " + expected);
532 console.log("Actual: " + actual);
533 fail();
534 }
535 next();
536 });
537 });
538});
539},
88e2cdaa
IC
540
541// BIP44 derivation path is shown
d077e1e7
IC
542function() {
543page.open(url, function(status) {
544 // set the phrase
545 var expected = "m/44'/0'/0'/0";
546 page.evaluate(function() {
547 $(".phrase").val("abandon abandon ability");
548 $(".phrase").trigger("input");
549 });
550 // check the derivation path of the first address
551 waitForGenerate(function() {
552 var actual = page.evaluate(function() {
553 return $("#bip44 .path").val();
554 });
555 if (actual != expected) {
556 console.log("BIP44 derivation path is incorrect");
557 console.log("Expected: " + expected);
558 console.log("Actual: " + actual);
559 fail();
560 }
561 next();
562 });
563});
564},
565
88e2cdaa 566// BIP44 extended private key is shown
4fd2925d
IC
567function() {
568page.open(url, function(status) {
569 // set the phrase
570 var expected = "xprvA2DxxvPZcyRvYgZMGS53nadR32mVDeCyqQYyFhrCVbJNjPoxMeVf7QT5g7mQASbTf9Kp4cryvcXnu2qurjWKcrdsr91jXymdCDNxKgLFKJG";
571 page.evaluate(function() {
572 $(".phrase").val("abandon abandon ability");
573 $(".phrase").trigger("input");
574 });
06286adb 575 // check the BIP44 extended private key
4fd2925d
IC
576 waitForGenerate(function() {
577 var actual = page.evaluate(function() {
578 return $(".extended-priv-key").val();
579 });
580 if (actual != expected) {
581 console.log("BIP44 extended private key is incorrect");
582 console.log("Expected: " + expected);
583 console.log("Actual: " + actual);
584 fail();
585 }
586 next();
587 });
588});
589},
590
88e2cdaa 591// BIP44 extended public key is shown
39fd45bb
IC
592function() {
593page.open(url, function(status) {
594 // set the phrase
595 var expected = "xpub6FDKNRvTTLzDmAdpNTc49ia9b4byd6vqCdUa46Fp3vqMcC96uBoufCmZXQLiN5AK3iSCJMhf9gT2sxkpyaPepRuA7W3MujV5tGmF5VfbueM";
596 page.evaluate(function() {
597 $(".phrase").val("abandon abandon ability");
598 $(".phrase").trigger("input");
599 });
06286adb 600 // check the BIP44 extended public key
39fd45bb
IC
601 waitForGenerate(function() {
602 var actual = page.evaluate(function() {
603 return $(".extended-pub-key").val();
604 });
605 if (actual != expected) {
606 console.log("BIP44 extended public key is incorrect");
607 console.log("Expected: " + expected);
608 console.log("Actual: " + actual);
609 fail();
610 }
611 next();
612 });
613});
614},
615
06286adb
IC
616// BIP44 purpose field changes address list
617function() {
618page.open(url, function(status) {
619 // set the phrase
620 var expected = "1JbDzRJ2cDT8aat2xwKd6Pb2zzavow5MhF";
621 page.evaluate(function() {
622 $(".phrase").val("abandon abandon ability");
623 $(".phrase").trigger("input");
624 });
625 waitForGenerate(function() {
626 // change the bip44 purpose field to 45
627 page.evaluate(function() {
628 $("#bip44 .purpose").val("45");
629 $("#bip44 .purpose").trigger("input");
630 });
631 waitForGenerate(function() {
632 // check the address for the new derivation path
633 var actual = page.evaluate(function() {
634 return $(".address:first").text();
635 });
636 if (actual != expected) {
637 console.log("BIP44 purpose field generates incorrect address");
638 console.log("Expected: " + expected);
639 console.log("Actual: " + actual);
640 fail();
641 }
642 next();
643 });
644 });
645});
646},
647
88e2cdaa 648// BIP44 coin field changes address list
9eb72cdf
IC
649function() {
650page.open(url, function(status) {
651 // set the phrase
652 var expected = "1F6dB2djQYrxoyfZZmfr6D5voH8GkJTghk";
653 page.evaluate(function() {
654 $(".phrase").val("abandon abandon ability");
655 $(".phrase").trigger("input");
656 });
657 waitForGenerate(function() {
658 // change the bip44 purpose field to 45
659 page.evaluate(function() {
660 $("#bip44 .coin").val("1");
661 $("#bip44 .coin").trigger("input");
662 });
663 waitForGenerate(function() {
664 // check the address for the new derivation path
665 var actual = page.evaluate(function() {
666 return $(".address:first").text();
667 });
668 if (actual != expected) {
669 console.log("BIP44 coin field generates incorrect address");
670 console.log("Expected: " + expected);
671 console.log("Actual: " + actual);
672 fail();
673 }
674 next();
675 });
676 });
677});
678},
679
88e2cdaa 680// BIP44 account field changes address list
048bc3e0
IC
681function() {
682page.open(url, function(status) {
683 // set the phrase
684 var expected = "1Nq2Wmu726XHCuGhctEtGmhxo3wzk5wZ1H";
685 page.evaluate(function() {
686 $(".phrase").val("abandon abandon ability");
687 $(".phrase").trigger("input");
688 });
689 waitForGenerate(function() {
690 // change the bip44 purpose field to 45
691 page.evaluate(function() {
692 $("#bip44 .account").val("1");
693 $("#bip44 .account").trigger("input");
694 });
695 waitForGenerate(function() {
696 // check the address for the new derivation path
697 var actual = page.evaluate(function() {
698 return $(".address:first").text();
699 });
700 if (actual != expected) {
701 console.log("BIP44 account field generates incorrect address");
702 console.log("Expected: " + expected);
703 console.log("Actual: " + actual);
704 fail();
705 }
706 next();
707 });
708 });
709});
710},
711
fa4da086
IC
712// BIP44 change field changes address list
713function() {
714page.open(url, function(status) {
715 // set the phrase
716 var expected = "1KAGfWgqfVbSSXY56fNQ7YnhyKuoskHtYo";
717 page.evaluate(function() {
718 $(".phrase").val("abandon abandon ability");
719 $(".phrase").trigger("input");
720 });
721 waitForGenerate(function() {
722 // change the bip44 purpose field to 45
723 page.evaluate(function() {
724 $("#bip44 .change").val("1");
725 $("#bip44 .change").trigger("input");
726 });
727 waitForGenerate(function() {
728 // check the address for the new derivation path
729 var actual = page.evaluate(function() {
730 return $(".address:first").text();
731 });
732 if (actual != expected) {
733 console.log("BIP44 change field generates incorrect address");
734 console.log("Expected: " + expected);
735 console.log("Actual: " + actual);
736 fail();
737 }
738 next();
739 });
740 });
741});
742},
048bc3e0 743
88e2cdaa 744// BIP32 derivation path can be set
651382a3
IC
745function() {
746page.open(url, function(status) {
747 // set the phrase
748 var expected = "16pYQQdLD1hH4hwTGLXBaZ9Teboi1AGL8L";
749 page.evaluate(function() {
750 $(".phrase").val("abandon abandon ability");
751 $(".phrase").trigger("input");
752 });
753 // change tabs
754 waitForGenerate(function() {
755 page.evaluate(function() {
756 $("#bip32-tab a").click();
757 });
758 // set the derivation path to m/1
759 waitForGenerate(function() {
760 page.evaluate(function() {
761 $("#bip32 .path").val("m/1");
762 $("#bip32 .path").trigger("input");
763 });
764 // check the address is generated correctly
765 waitForGenerate(function() {
766 var actual = page.evaluate(function() {
767 return $(".address:first").text();
768 });
769 if (actual != expected) {
770 console.log("Custom BIP32 path generates incorrect address");
771 console.log("Expected: " + expected);
772 console.log("Actual: " + actual);
773 fail();
774 }
775 next();
776 });
777 });
778 });
779});
780},
781
88e2cdaa 782// BIP32 can use hardened derivation paths
651382a3
IC
783function() {
784page.open(url, function(status) {
785 // set the phrase
786 var expected = "14aXZeprXAE3UUKQc4ihvwBvww2LuEoHo4";
787 page.evaluate(function() {
788 $(".phrase").val("abandon abandon ability");
789 $(".phrase").trigger("input");
790 });
791 // change tabs
792 waitForGenerate(function() {
793 page.evaluate(function() {
794 $("#bip32-tab a").click();
795 });
796 // set the derivation path to m/0'
797 waitForGenerate(function() {
798 page.evaluate(function() {
799 $("#bip32 .path").val("m/0'");
800 $("#bip32 .path").trigger("input");
801 });
802 // check the address is generated correctly
803 waitForGenerate(function() {
804 var actual = page.evaluate(function() {
805 return $(".address:first").text();
806 });
807 if (actual != expected) {
808 console.log("Hardened BIP32 path generates incorrect address");
809 console.log("Expected: " + expected);
810 console.log("Actual: " + actual);
811 fail();
812 }
813 next();
814 });
815 });
816 });
817});
818},
819
88e2cdaa 820// BIP32 extended private key is shown
9e9dcfda
IC
821function() {
822page.open(url, function(status) {
823 // set the phrase
824 var expected = "xprv9va99uTVE5aLiutUVLTyfxfe8v8aaXjSQ1XxZbK6SezYVuikA9MnjQVTA8rQHpNA5LKvyQBpLiHbBQiiccKiBDs7eRmBogsvq3THFeLHYbe";
825 page.evaluate(function() {
826 $(".phrase").val("abandon abandon ability");
827 $(".phrase").trigger("input");
828 });
829 // change tabs
830 waitForGenerate(function() {
831 page.evaluate(function() {
832 $("#bip32-tab a").click();
833 });
834 // check the extended private key is generated correctly
835 waitForGenerate(function() {
836 var actual = page.evaluate(function() {
837 return $(".extended-priv-key").val();
838 });
839 if (actual != expected) {
840 console.log("BIP32 extended private key is incorrect");
841 console.log("Expected: " + expected);
842 console.log("Actual: " + actual);
843 fail();
844 }
845 next();
846 });
847 });
848});
849},
850
88e2cdaa 851// BIP32 extended public key is shown
9e9dcfda
IC
852function() {
853page.open(url, function(status) {
854 // set the phrase
855 var expected = "xpub69ZVZQzP4T8dwPxwbMzz36cNgwy4yzTHmETZMyihzzXXNi3thgg3HCow1RtY252wdw5rS8369xKnraN5Q93y3FkFfJp2XEHWUrkyXsjS93P";
856 page.evaluate(function() {
857 $(".phrase").val("abandon abandon ability");
858 $(".phrase").trigger("input");
859 });
860 // change tabs
861 waitForGenerate(function() {
862 page.evaluate(function() {
863 $("#bip32-tab a").click();
864 });
865 // check the extended public key is generated correctly
866 waitForGenerate(function() {
867 var actual = page.evaluate(function() {
868 return $(".extended-pub-key").val();
869 });
870 if (actual != expected) {
871 console.log("BIP32 extended public key is incorrect");
872 console.log("Expected: " + expected);
873 console.log("Actual: " + actual);
874 fail();
875 }
876 next();
877 });
878 });
879});
880},
88e2cdaa
IC
881
882// Derivation path is shown in table
5f844c62
IC
883function() {
884page.open(url, function(status) {
885 // set the phrase
886 var expected = "m/44'/0'/0'/0/0";
887 page.evaluate(function() {
888 $(".phrase").val("abandon abandon ability");
889 $(".phrase").trigger("input");
890 });
891 // check for derivation path in table
892 waitForGenerate(function() {
893 var actual = page.evaluate(function() {
894 return $(".index:first").text();
895 });
896 if (actual != expected) {
897 console.log("Derivation path shown incorrectly in table");
898 console.log("Expected: " + expected);
899 console.log("Actual: " + actual);
900 fail();
901 }
902 next();
903 });
904});
905},
906
88e2cdaa 907// Derivation path for address can be hardened
4974fd7f
IC
908function() {
909page.open(url, function(status) {
910 // set the phrase
911 var expected = "18exLzUv7kfpiXRzmCjFDoC9qwNLFyvwyd";
912 page.evaluate(function() {
913 $(".phrase").val("abandon abandon ability");
914 $(".phrase").trigger("input");
915 });
916 // change tabs
917 waitForGenerate(function() {
918 page.evaluate(function() {
919 $("#bip32-tab a").click();
920 });
921 waitForGenerate(function() {
922 // select the hardened addresses option
923 page.evaluate(function() {
924 $(".hardened-addresses").prop("checked", true);
925 $(".hardened-addresses").trigger("change");
926 });
927 waitForGenerate(function() {
928 // check the generated address is hardened
929 var actual = page.evaluate(function() {
930 return $(".address:first").text();
931 });
932 if (actual != expected) {
933 console.log("Hardened address is incorrect");
934 console.log("Expected: " + expected);
935 console.log("Actual: " + actual);
936 fail();
937 }
938 next();
939 });
940 });
941 });
942});
943},
944
88e2cdaa 945// Derivation path visibility can be toggled
a775b5c6
IC
946function() {
947page.open(url, function(status) {
948 // set the phrase
949 page.evaluate(function() {
950 $(".phrase").val("abandon abandon ability");
951 $(".phrase").trigger("input");
952 });
953 // check the path is not shown
954 waitForGenerate(function() {
955 // toggle path visibility
956 page.evaluate(function() {
957 $(".index-toggle").click();
958 });
959 // check the path is not visible
960 var isInvisible = page.evaluate(function() {
961 return $(".index:first span").hasClass("invisible");
962 });
963 if (!isInvisible) {
964 console.log("Toggled derivation path is visible");
965 fail();
966 }
967 next();
968 });
969});
970},
971
88e2cdaa 972// Address is shown
06c4c6e3
IC
973function() {
974page.open(url, function(status) {
975 var expected = "1Di3Vp7tBWtyQaDABLAjfWtF6V7hYKJtug";
976 // set the phrase
977 page.evaluate(function() {
978 $(".phrase").val("abandon abandon ability").trigger("input");
979 });
980 // get the address
981 waitForGenerate(function() {
982 var actual = page.evaluate(function() {
983 return $(".address:first").text();
984 });
985 if (actual != expected) {
986 console.log("Address is not shown");
987 console.log("Expected: " + expected);
988 console.log("Got: " + actual);
989 fail();
990 }
991 next();
992 });
993});
994},
995
88e2cdaa
IC
996// Addresses are shown in order of derivation path
997// Address visibility can be toggled
998// Private key is shown
999// Private key visibility can be toggled
1000
1001// More addresses can be generated
1002// A custom number of additional addresses can be generated
1003// Additional addresses are shown in order of derivation path
1004
1005// BIP32 root key can be set by the user
54563907
IC
1006// Setting BIP32 root key clears the existing phrase, passphrase and seed
1007// Clearing of phrase, passphrase and seed can be cancelled by user
88e2cdaa
IC
1008// Custom BIP32 root key is used when changing the derivation path
1009
1010// Incorrect mnemonic shows error
1011// Incorrect word shows suggested replacement
1012// Incorrect BIP32 root key shows error
1013// Derivation path not starting with m shows error
1014// Derivation path containing invalid characters shows useful error
1015
1016// Github Issue 11: Default word length is 15
1017// https://github.com/dcpos/bip39/issues/11
1018
1019// Github Issue 12: Generate more rows with private keys hidden
1020// https://github.com/dcpos/bip39/issues/12
1021
1022// Github Issue 19: Mnemonic is not sensitive to whitespace
1023// https://github.com/dcpos/bip39/issues/19
1024
1025// Github Issue 23: Use correct derivation path when changing tabs
1026// https://github.com/dcpos/bip39/issues/23
1027
1028];
1029
1030console.log("Running tests...");
fb372687 1031tests = shuffle(tests);
88e2cdaa 1032next();